The Apple iMac10,1 and iMac11,2 (RV730/DCE3.2) drive their internal eDP panel through an LVTMA power sequencer whose enable bit (PWRSEQ_EN in LVTMA_PWRSEQ_CNTL) is programmed exactly once, by EFI at cold boot. Apple's minimal ATOM tables never touch it afterwards, so any GPU re-initialisation - S3 resume or a GPU-lockup reset - clears PWRSEQ_EN and the panel comes back dark while the rest of the GPU resumes fine.
The driver never programs this register itself; on every other radeon board the platform firmware maintains it across a re-POST, which is why this only bites the Apple machines. Re-assert PWRSEQ_EN in the eDP DPMS-on path when it is found cleared; the hardware then runs the DIGON->DE->VARY_BL->BLON power-on sequence on its own. Both failure paths pass through here, as radeon_gpu_reset() restores the modeset state via radeon_resume_kms(), so a single site covers resume and reset. The write is gated to Apple parts and to exactly DCE3.2 (ASIC_IS_DCE32 is >= RV730, so DCE4+ must be excluded - Apple also shipped DCE5, e.g. the 2011 MacBook Pro, where the register lives at a different offset). It is skipped when the sequencer is already enabled, so lit panels, DCE4+ boards and non-Apple boards are untouched. DCE3.2 places the register 0x18 above the documented R600 offset. Only iMac11,2 is verified on hardware; iMac10,1 shares the same RV730 design and Apple EFI behaviour. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/5719 Signed-off-by: Mario Limonciello <[email protected]> --- drivers/gpu/drm/radeon/atombios_encoders.c | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 8b3f8303a967e..5b9c72bf40994 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1646,6 +1646,38 @@ radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode) } } +/* + * Apple's EFI enables the internal eDP panel power sequencer + * (LVTMA_PWRSEQ_CNTL) exactly once, at cold boot, and its minimal ATOM tables + * never touch it afterwards. Any GPU re-initialisation - S3 resume or a GPU + * reset - clears PWRSEQ_EN, so the panel comes back dark on the DCE3.2 iMacs + * (iMac10,1 / iMac11,2, RV730). Re-assert PWRSEQ_EN when we find it cleared; + * the hardware then runs the DIGON->DE->VARY_BL->BLON power-on sequence itself. + * DCE3.2 places the register 0x18 above the R600 offset. + * + * This is restricted to Apple DCE3.2 parts: the register lives at a different + * offset on DCE4+ (which Apple also shipped, e.g. the 2011 MacBook Pro), and + * non-Apple boards program the sequencer from their own firmware. The + * read-modify-write only fires when the sequencer is actually disabled, so a + * lit panel is never disturbed. + * + * https://gitlab.freedesktop.org/drm/amd/-/issues/5719 + */ +static void radeon_atom_apple_edp_pwrseq_restore(struct radeon_device *rdev) +{ + u32 pwrseq_cntl = R600_LVTMA_PWRSEQ_CNTL + 0x18; + + if (rdev->pdev->subsystem_vendor != PCI_VENDOR_ID_APPLE) + return; + if (!ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) + return; + + if (!(RREG32(pwrseq_cntl) & AVIVO_LVTMA_PWRSEQ_EN)) + WREG32(pwrseq_cntl, AVIVO_LVTMA_PWRSEQ_EN | + AVIVO_LVTMA_SYNCEN_OVRD | + AVIVO_LVTMA_DIGON); +} + static void radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) { @@ -1711,6 +1743,10 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); } if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { + /* restore the panel power sequencer on Apple eDP iMacs + * that lose it across resume/reset (see helper above) + */ + radeon_atom_apple_edp_pwrseq_restore(rdev); if (rdev->mode_info.bl_encoder) atombios_set_backlight_level(radeon_encoder, dig->backlight_level); else -- 2.43.0
