On Tue, May 19, 2026 at 3:19 AM Gilles Risch <[email protected]> wrote:
>
> The Apple iMac11,1 (late 2009) has an integrated ATI Mobility Radeon
> HD 4850 (RV770/M98L) with a 2560x1440 internal panel connected via an
> internal DisplayPort path. This machine suffers from a similar problem
> as the iMac10,1 (late 2009) and the iMac11,2 (mid 2010). Without this
> fix the display stays dark under KMS. Two issues are addressed:
>
> 1. The RV770 implements DCE3.1 and not DCE3.2. ASIC_IS_DCE32() starts at
> CHIP_RV730 which is newer than RV770, so the RV770 never matched the
> DCE3.2 PLL and encoder logic. Introduce ASIC_IS_DCE31() starting at
> CHIP_RV770 to fix this.
>
> 2. Apple routed the internal display through Link B of the DIG encoder
> instead of Link A, as observed in the kernel display connector log.
> The same quirk already exists for iMac10,1 and iMac11,2 - iMac11,1
> was simply missing from the list.
>
> Note: resume from suspend still results in a dark screen as the DP
> re-driver chips on the mainboard lose their state during power-off.
> This will be addressed in a follow-up patch.
>
> Fixes freedesktop issue 164
> Link: https://gitlab.freedesktop.org/xorg/driver/xf86-video-ati/-/issues/164
>
> Signed-off-by: Gilles Risch <[email protected]>
> ---
> v3: No code changes.
>
> drivers/gpu/drm/radeon/atombios_crtc.c | 4 ++--
> drivers/gpu/drm/radeon/atombios_encoders.c | 9 +++++----
> drivers/gpu/drm/radeon/radeon.h | 1 +
> 3 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c
> b/drivers/gpu/drm/radeon/atombios_crtc.c
> index 2fc0334e0d6c..3c6d332739e3 100644
> --- a/drivers/gpu/drm/radeon/atombios_crtc.c
> +++ b/drivers/gpu/drm/radeon/atombios_crtc.c
> @@ -580,7 +580,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
> radeon_crtc->pll_flags |=
> (/*RADEON_PLL_USE_FRAC_FB_DIV |*/
> RADEON_PLL_PREFER_CLOSEST_LOWER);
>
> - if (ASIC_IS_DCE32(rdev) && mode->clock > 200000) /*
> range limits??? */
> + if (ASIC_IS_DCE31(rdev) && mode->clock > 200000) /*
> range limits??? */
> radeon_crtc->pll_flags |=
> RADEON_PLL_PREFER_HIGH_FB_DIV;
> else
> radeon_crtc->pll_flags |=
> RADEON_PLL_PREFER_LOW_REF_DIV;
> @@ -594,7 +594,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
> if (((rdev->family == CHIP_RS780) || (rdev->family ==
> CHIP_RS880))
> && !radeon_crtc->ss_enabled)
> radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
> - if (ASIC_IS_DCE32(rdev) && mode->clock > 165000)
> + if (ASIC_IS_DCE31(rdev) && mode->clock > 165000)
Can you switch these to dmi matches as well? This change will also
change the behavior for other boards with respect to the PLL
calculations which are often pretty sensitive and may cause
regressions.
Alex
> radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
> } else {
> radeon_crtc->pll_flags |= RADEON_PLL_LEGACY;
> diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c
> b/drivers/gpu/drm/radeon/atombios_encoders.c
> index 5cfd8fcfa5e8..4e984973c043 100644
> --- a/drivers/gpu/drm/radeon/atombios_encoders.c
> +++ b/drivers/gpu/drm/radeon/atombios_encoders.c
> @@ -2123,12 +2123,13 @@ int radeon_atom_pick_dig_encoder(struct drm_encoder
> *encoder, int fe_idx)
> }
>
> /*
> - * On DCE32 any encoder can drive any block so usually just use crtc
> id,
> - * but Apple thinks different at least on iMac10,1 and iMac11,2, so
> there use linkb,
> - * otherwise the internal eDP panel will stay dark.
> + * On DCE31 and DCE32 any encoder can drive any block so usually just
> use crtc id,
> + * but Apple thinks different at least on iMac10,1, iMac11,1 and
> iMac11,2,
> + * so there use linkb, otherwise the internal eDP panel will stay
> dark.
> */
> - if (ASIC_IS_DCE32(rdev)) {
> + if (ASIC_IS_DCE31(rdev)) {
> if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1") ||
> + dmi_match(DMI_PRODUCT_NAME, "iMac11,1") ||
> dmi_match(DMI_PRODUCT_NAME, "iMac11,2"))
> enc_idx = (dig->linkb) ? 1 : 0;
> else
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 527b9d19d730..6b7c0abe49fb 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -2625,6 +2625,7 @@ void r100_pll_errata_after_index(struct radeon_device
> *rdev);
> (rdev->family == CHIP_RS740) || \
> (rdev->family >= CHIP_R600))
> #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620))
> +#define ASIC_IS_DCE31(rdev) ((rdev->family >= CHIP_RV770))
> #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730))
> #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR))
> #define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM) && \
> --
> 2.47.3
>