summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sousa <gustavo.sousa@intel.com>2025-12-22 19:18:48 -0300
committerGustavo Sousa <gustavo.sousa@intel.com>2026-01-05 16:44:26 -0300
commit968290fa8a42d9d2d2fd0fcdeb82d7533e83071d (patch)
tree9d182900dd1ce662d0288341475bd9e9e388ab9f
parent67ccf6c60bc324d78c24893e8c1eb6a62973838d (diff)
drm/i915/cdclk: Implement Wa_13012396614
A new workaround was defined for Xe3_LPD, which requires a tweak on how we handle MDCLK selection. Implement it. Reviewed-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com> Link: https://patch.msgid.link/20251222-display-wa-13012396614-timing-of-mdclk-source-selection-v1-2-a2f7e9447f7a@intel.com Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c31
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_wa.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_wa.h1
3 files changed, 31 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 0aa59d624095..7443e5285942 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -39,6 +39,7 @@
#include "intel_display_regs.h"
#include "intel_display_types.h"
#include "intel_display_utils.h"
+#include "intel_display_wa.h"
#include "intel_dram.h"
#include "intel_mchbar_regs.h"
#include "intel_pci_config.h"
@@ -1858,6 +1859,20 @@ static void bxt_de_pll_enable(struct intel_display *display, int vco)
static void icl_cdclk_pll_disable(struct intel_display *display)
{
+ /*
+ * Wa_13012396614:
+ * Fixes: A sporadic race condition between MDCLK selection and PLL
+ * enabling.
+ * Workaround:
+ * Change programming of MDCLK source selection in CDCLK_CTL:
+ * - When disabling the CDCLK PLL, first set MDCLK source to be CD2XCLK.
+ * - When enabling the CDCLK PLL, update MDCLK source selection only
+ * after the PLL is enabled (which is already done as part of the
+ * normal flow of _bxt_set_cdclk()).
+ */
+ if (intel_display_wa(display, 13012396614))
+ intel_de_rmw(display, CDCLK_CTL, MDCLK_SOURCE_SEL_MASK, MDCLK_SOURCE_SEL_CD2XCLK);
+
intel_de_rmw(display, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_PLL_ENABLE, 0);
@@ -2147,10 +2162,20 @@ static u32 bxt_cdclk_ctl(struct intel_display *display,
cdclk >= 500000)
val |= BXT_CDCLK_SSA_PRECHARGE_ENABLE;
- if (DISPLAY_VER(display) >= 20)
- val |= xe2lpd_mdclk_source_sel(display);
- else
+ if (DISPLAY_VER(display) >= 20) {
+ /*
+ * Wa_13012396614 requires selecting CD2XCLK as MDCLK source
+ * prior to disabling the PLL, which is already handled by
+ * icl_cdclk_pll_disable(). Here we are just making sure
+ * we keep the expected value.
+ */
+ if (intel_display_wa(display, 13012396614) && vco == 0)
+ val |= MDCLK_SOURCE_SEL_CD2XCLK;
+ else
+ val |= xe2lpd_mdclk_source_sel(display);
+ } else {
val |= skl_cdclk_decimal(cdclk);
+ }
return val;
}
diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c
index 2b360447e92e..581d943b9bdc 100644
--- a/drivers/gpu/drm/i915/display/intel_display_wa.c
+++ b/drivers/gpu/drm/i915/display/intel_display_wa.c
@@ -62,6 +62,8 @@ static bool intel_display_needs_wa_16025573575(struct intel_display *display)
bool __intel_display_wa(struct intel_display *display, enum intel_display_wa wa, const char *name)
{
switch (wa) {
+ case INTEL_DISPLAY_WA_13012396614:
+ return DISPLAY_VERx100(display) == 3000;
case INTEL_DISPLAY_WA_14011503117:
return DISPLAY_VER(display) == 13;
case INTEL_DISPLAY_WA_14025769978:
diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h
index 56b586e38306..40f989f19df1 100644
--- a/drivers/gpu/drm/i915/display/intel_display_wa.h
+++ b/drivers/gpu/drm/i915/display/intel_display_wa.h
@@ -27,6 +27,7 @@ bool intel_display_needs_wa_16023588340(struct intel_display *display);
* number.
*/
enum intel_display_wa {
+ INTEL_DISPLAY_WA_13012396614,
INTEL_DISPLAY_WA_14011503117,
INTEL_DISPLAY_WA_14025769978,
INTEL_DISPLAY_WA_15018326506,