On Sun, Sep 13, 2026 at 10:20 PM Mario Limonciello <[email protected]> wrote: > > 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]>
Acked-by: Alex Deucher <[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 >
