Hardware
| Component |
Detail |
| Laptop |
Lenovo Yoga C740-15IML (81TD) |
| CPU |
Intel Core i7-10510U (Comet Lake-U) |
| iGPU |
Intel UHD 620 (PCI device 8086:9B41) |
| Panel |
LG LP156WFC-SPU1, 1920×1080 60 Hz, eDP 1.4 |
| DVMT |
Pre-allocated 64 MB, CFG Lock unlocked |
Software
| Component |
Version |
| macOS |
Tahoe 26.5.1 (25F80) — also reproduced on Sequoia 15.x and Sonoma 14.x |
| OpenCore |
Latest stable |
| Lilu |
1.7.3 (dortania nightly) |
| WhateverGreen |
1.7.1 (dortania nightly) |
| SMBIOS |
MacBookPro16,1 |
Framebuffer configuration
AAPL,ig-platform-id = 00009B3E (0x3E9B0000, CFL mobile, 3 connectors)
device-id = 9B3E0000
framebuffer-patch-enable = 01000000
framebuffer-stolenmem = 00003001
framebuffer-fbmem = 00009000
enable-backlight-registers-alternative-fix = 01000000
enable-backlight-smoother = 01000000
enable-dpcd-max-link-rate-fix = 01000000
dpcd-max-link-rate = 0A000000
AAPL00,override-no-connect = <EDID blob, see attached>
Boot args: -v debug=0x100 keepsyms=1 -amfipassbeta -vi2c-force-polling agdpmod=vit9696 watchdog=0
Panel characteristics (verified in Linux)
From Linux i915_display_info (see attached):
[CONNECTOR:106:eDP-1]: status: connected
DPCD rev: 13
port_clock=270000, lane_count=2
[ENCODER:105:DDI A/PHY A]
mode: 1920x1080 @ 60 Hz, pixel clock 138600 kHz
The panel is on DDI A (matching con0 busId=0x00 in the 0x3E9B0000 framebuffer), 2 lanes, 2.7 Gbps. Linux drives it without issues.
Critical detail: this panel reports MAX_LINK_RATE = 0x00 in DPCD register 0x00A. Per the eDP 1.4 specification, this means the panel uses the SUPPORTED_LINK_RATES table (DPCD 0x00010–0x0001F) instead of the legacy MAX_LINK_RATE register. Linux's i915 driver handles this by parsing the rate table and using LINK_RATE_SET (DPCD 0x00115) for link training instead of LINK_BW_SET.
Symptoms — three distinct failure modes depending on configuration
1. Without enable-dpcd-max-link-rate-fix → Divide-by-zero kernel panic
The CFL framebuffer driver reads MAX_LINK_RATE = 0 from DPCD, passes it into SetupDPTimings, and divides by zero.
panic(cpu 6): Kernel trap at 0x..., type = 0=divide error
AppleIntelFramebufferController::SetupDPTimings + 0x1a6
← SetupClocks + 0x5cf
← hwSetMode + 0x295
← AppleIntelFramebuffer::setDisplayMode + 0xe46
Panicked task: pid 198: WindowServer
Full panic report: error-1-divide-by-zero.txt
2. With enable-dpcd-max-link-rate-fix + dpcd-max-link-rate = 0x0A → Black screen with backlight
The divide-by-zero is avoided (the fix substitutes 0x0A for the zero value). The driver proceeds to program the pixel clock (confirmed: IOFBCurrentPixelClock = 0x842DE40 = 138.6 MHz in ioreg). An AppleBacklightDisplay object is created for the correct panel (vendor 0x30E4 / product 0x0630). The backlight turns on.
However, the actual eDP link training fails silently — the panel never receives valid pixel data. WindowServer's main thread blocks indefinitely inside the IOGraphics kernel stack waiting for a
modeset completion event that never arrives. After 120 seconds, watchdogd kills WindowServer, which causes a watchdog panic.
From the WindowServer crash stackshot (see error-2-watchdog.txt):
- Thread 912 (WindowServer main, ws_main_thread): state
TH_WAIT|TH_UNINT, blocked inside AppleIntelCFLGraphicsFramebuffer / IOGraphicsFamily, holding the controller mutex.
- All subsequent calls to
system_profiler SPDisplaysDataType and pmset sleepnow also hang, confirming a kernel-level deadlock on the framebuffer lock.
Full ioreg dump showing the successfully programmed but non-functional framebuffer: igpu-e1.txt
3. Without EDID injection (AAPL00,override-no-connect removed) → Boot hang
The driver attempts to read EDID via the eDP AUX channel. On this panel, AUX communication for EDID appears to work (Linux reads it fine), but the Apple driver's AUX transaction stalls during early framebuffer initialization, hanging the boot process before WindowServer even starts. Adding EDID injection reliably bypasses this hang.
The key finding: sleep-wake retraining succeeds
With any configuration that avoids the divide-by-zero panic (i.e., with enable-dpcd-max-link-rate-fix), the internal display lights up perfectly after a lid-close sleep/wake cycle:
- Boot with the fix → black screen + backlight (link training failed)
- Close the laptop lid → system enters sleep
- Wait ~2 minutes, open lid → system wakes
- Internal display shows the login screen at 1920×1080 with full GPU acceleration and Metal 3 support
This is 100% reproducible across macOS Tahoe, Sequoia, and Sonoma. It proves:
- The framebuffer configuration, connector mapping, and DDI port assignment are all correct.
- The panel hardware and AUX channel are fully functional.
- The Apple CFL driver can successfully train this panel's eDP link — but only on the re-training path triggered by display wake, not on the initial training path at boot/first modeset.
Root cause hypothesis
The panel uses eDP 1.4 SUPPORTED_LINK_RATES table and does not populate the legacy MAX_LINK_RATE register (reports 0x00). The WEG enable-dpcd-max-link-rate-fix correctly substitutes a valid rate value (0x0A = HBR) to prevent the divide-by-zero. However, the underlying Apple CFL framebuffer driver still uses LINK_BW_SET (DPCD 0x00100) for link training rather than LINK_RATE_SET (DPCD 0x00115). This panel may require LINK_RATE_SET for initial link training but may be more tolerant during re-training (wake path), or the wake path may use a different initialization sequence that happens to work.
The Linux kernel has explicit handling for this case (see recent patches for eDP 1.4 rate table support in both i915 and MSM DP drivers), and the WEG PR #72 mentions awareness of this issue but may not fully address the initial training path in the CFL driver.
Attempted configurations (all tested, none fix the initial boot)
| Configuration |
Result |
| ig-platform-id 0x3E9B0000 only |
Divide-by-zero panic |
+ enable-dpcd-max-link-rate-fix + dpcd-max-link-rate=0x0A |
Black screen, watchdog panic |
+ enable-dpcd-max-link-rate-fix (no manual rate, auto-probe) |
Black screen, watchdog panic |
+ force-online |
Kernel deadlock on phantom connectors (unrelated) |
+ enable-force-complete-modeset on con0 |
Black screen, watchdog panic |
| ig-platform-id 0x3EA50005 + device-id 0x3EA5 |
Divide-by-zero panic |
| ig-platform-id 0x3EA50009 + device-id 0x9BC8 |
Divide-by-zero panic |
| Any of the above + lid close/open |
Display works perfectly |
Current workaround
A LaunchDaemon that triggers pmset displaysleepnow followed by caffeinate -u 25 seconds after boot, forcing a display sleep/wake cycle that retrains the link. Functional but inelegant.
Attached files
See list below.
Lenovo-Yoga-C740-15IML-OpenCore-Hackintosh
linux-i915-display-info.txt
error-1-divide-by-zero.txt
error-2-watchdog.txt
igpu-e1.txt
igpu-e1a-auto-probe.txt
ioreg-fb0.txt
linux-dmesg-edp.txt
Hardware
Software
Framebuffer configuration
Boot args:
-v debug=0x100 keepsyms=1 -amfipassbeta -vi2c-force-polling agdpmod=vit9696 watchdog=0Panel characteristics (verified in Linux)
From Linux
i915_display_info(see attached):The panel is on DDI A (matching con0 busId=0x00 in the 0x3E9B0000 framebuffer), 2 lanes, 2.7 Gbps. Linux drives it without issues.
Critical detail: this panel reports
MAX_LINK_RATE = 0x00in DPCD register 0x00A. Per the eDP 1.4 specification, this means the panel uses theSUPPORTED_LINK_RATEStable (DPCD 0x00010–0x0001F) instead of the legacyMAX_LINK_RATEregister. Linux's i915 driver handles this by parsing the rate table and usingLINK_RATE_SET(DPCD 0x00115) for link training instead ofLINK_BW_SET.Symptoms — three distinct failure modes depending on configuration
1. Without
enable-dpcd-max-link-rate-fix→ Divide-by-zero kernel panicThe CFL framebuffer driver reads
MAX_LINK_RATE = 0from DPCD, passes it intoSetupDPTimings, and divides by zero.Full panic report:
error-1-divide-by-zero.txt2. With
enable-dpcd-max-link-rate-fix+dpcd-max-link-rate = 0x0A→ Black screen with backlightThe divide-by-zero is avoided (the fix substitutes 0x0A for the zero value). The driver proceeds to program the pixel clock (confirmed:
IOFBCurrentPixelClock = 0x842DE40= 138.6 MHz in ioreg). AnAppleBacklightDisplayobject is created for the correct panel (vendor 0x30E4 / product 0x0630). The backlight turns on.However, the actual eDP link training fails silently — the panel never receives valid pixel data. WindowServer's main thread blocks indefinitely inside the IOGraphics kernel stack waiting for a
modeset completion event that never arrives. After 120 seconds,
watchdogdkills WindowServer, which causes a watchdog panic.From the WindowServer crash stackshot (see
error-2-watchdog.txt):TH_WAIT|TH_UNINT, blocked insideAppleIntelCFLGraphicsFramebuffer/IOGraphicsFamily, holding the controller mutex.system_profiler SPDisplaysDataTypeandpmset sleepnowalso hang, confirming a kernel-level deadlock on the framebuffer lock.Full ioreg dump showing the successfully programmed but non-functional framebuffer:
igpu-e1.txt3. Without EDID injection (
AAPL00,override-no-connectremoved) → Boot hangThe driver attempts to read EDID via the eDP AUX channel. On this panel, AUX communication for EDID appears to work (Linux reads it fine), but the Apple driver's AUX transaction stalls during early framebuffer initialization, hanging the boot process before WindowServer even starts. Adding EDID injection reliably bypasses this hang.
The key finding: sleep-wake retraining succeeds
With any configuration that avoids the divide-by-zero panic (i.e., with
enable-dpcd-max-link-rate-fix), the internal display lights up perfectly after a lid-close sleep/wake cycle:This is 100% reproducible across macOS Tahoe, Sequoia, and Sonoma. It proves:
Root cause hypothesis
The panel uses eDP 1.4
SUPPORTED_LINK_RATEStable and does not populate the legacyMAX_LINK_RATEregister (reports 0x00). The WEGenable-dpcd-max-link-rate-fixcorrectly substitutes a valid rate value (0x0A = HBR) to prevent the divide-by-zero. However, the underlying Apple CFL framebuffer driver still usesLINK_BW_SET(DPCD 0x00100) for link training rather thanLINK_RATE_SET(DPCD 0x00115). This panel may requireLINK_RATE_SETfor initial link training but may be more tolerant during re-training (wake path), or the wake path may use a different initialization sequence that happens to work.The Linux kernel has explicit handling for this case (see recent patches for eDP 1.4 rate table support in both i915 and MSM DP drivers), and the WEG PR #72 mentions awareness of this issue but may not fully address the initial training path in the CFL driver.
Attempted configurations (all tested, none fix the initial boot)
enable-dpcd-max-link-rate-fix+dpcd-max-link-rate=0x0Aenable-dpcd-max-link-rate-fix(no manual rate, auto-probe)force-onlineenable-force-complete-modeseton con0Current workaround
A LaunchDaemon that triggers
pmset displaysleepnowfollowed bycaffeinate -u25 seconds after boot, forcing a display sleep/wake cycle that retrains the link. Functional but inelegant.Attached files
See list below.
Lenovo-Yoga-C740-15IML-OpenCore-Hackintosh
linux-i915-display-info.txt
error-1-divide-by-zero.txt
error-2-watchdog.txt
igpu-e1.txt
igpu-e1a-auto-probe.txt
ioreg-fb0.txt
linux-dmesg-edp.txt