diff options
| author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2026-06-12 20:36:48 +0300 |
|---|---|---|
| committer | Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | 2026-06-24 13:53:32 +0300 |
| commit | 2ee8dbd880b14fb0b5115bf2353c7900aa33b95b (patch) | |
| tree | 1840b65b5df221c3ac0505271fde3ed4ae9ce110 /drivers | |
| parent | 914a76a9f08366434bf595700f62026b7a19a9cc (diff) | |
| download | ath-2ee8dbd880b14fb0b5115bf2353c7900aa33b95b.tar.gz | |
drm/i915/cdclk: Fix up CDCLK_FREQ_DECIMAL without a full PLL re-enable
The GOP (and even Bspec on some platforms) is a bit inconsistent
on what the CDCLK_FREQ_DECIMAL divider should be. Currently any
mismatch there causes a full CDCLK PLL disable+re-enable, which
we really don't want to do if any displays are currently active.
Let's instead just reprogram CDCLK_FREQ_DECIMAL when that is the
only thing amiss. For any other (more serious) mismatch we still
punt to the full PLL reprogramming.
We also need to tweak the bxt_cdclk_cd2x_pipe() stuff a bit to
consistently select pipe==NONE since we have no idea which pipes
are enabled at this point. Since we're not actually changing the
CDCLK frequency here we don't need to sync the update to any
pipe.
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/work_items/16209
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260612173653.7830-2-ville.syrjala@linux.intel.com
Reviewed-by: Michał Grzelak <michal.grzelak@intel.com>
(cherry picked from commit 3f9de66f8acbf8ff45a91b4920605ed10c6b7c06)
Fixes: ba91b9eecb47 ("drm/i915/cdclk: Decouple cdclk from state->modeset")
Fixes: d66a21947e21 ("drm/i915/bxt: Sanitize CDCLK to fix breakage during S4 resume")
Fixes: c73666f394fc ("drm/i915/skl: If needed sanitize bios programmed cdclk")
Cc: <stable@vger.kernel.org> # v4.5+
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_cdclk.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 189ae2d3cfc9e..7bc9b956554ba 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1256,9 +1256,22 @@ static void skl_sanitize_cdclk(struct intel_display *display) cdctl = intel_de_read(display, CDCLK_CTL); expected = (cdctl & CDCLK_FREQ_SEL_MASK) | skl_cdclk_decimal(display->cdclk.hw.cdclk); - if (cdctl == expected) - /* All well; nothing to sanitize */ - return; + + if (cdctl != expected) { + cdctl &= ~CDCLK_FREQ_DECIMAL_MASK; + cdctl |= expected & CDCLK_FREQ_DECIMAL_MASK; + + if (cdctl != expected) + goto sanitize; + + drm_dbg_kms(display->drm, "Sanitizing CDCLK decimal divider (CDCLK_CTL 0x%x, expected 0x%x)\n", + intel_de_read(display, CDCLK_CTL), expected); + + intel_de_write(display, CDCLK_CTL, expected); + } + + /* All well; nothing to sanitize */ + return; sanitize: drm_dbg_kms(display->drm, "Sanitizing cdclk programmed by pre-os\n"); @@ -2354,11 +2367,25 @@ static void bxt_sanitize_cdclk(struct intel_display *display) * (PIPE_NONE). */ cdctl &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE); - expected &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE); + cdctl |= bxt_cdclk_cd2x_pipe(display, INVALID_PIPE); - if (cdctl == expected) - /* All well; nothing to sanitize */ - return; + if (cdctl != expected) { + if (DISPLAY_VER(display) < 20) { + cdctl &= ~CDCLK_FREQ_DECIMAL_MASK; + cdctl |= expected & CDCLK_FREQ_DECIMAL_MASK; + } + + if (cdctl != expected) + goto sanitize; + + drm_dbg_kms(display->drm, "Sanitizing CDCLK decimal divider (CDCLK_CTL 0x%x, expected 0x%x)\n", + intel_de_read(display, CDCLK_CTL), expected); + + intel_de_write(display, CDCLK_CTL, expected); + } + + /* All well; nothing to sanitize */ + return; sanitize: drm_dbg_kms(display->drm, "Sanitizing cdclk programmed by pre-os\n"); |
