Commit 968290fa authored by Gustavo Sousa's avatar Gustavo Sousa
Browse files

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: default avatarDnyaneshwar 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: default avatarGustavo Sousa <gustavo.sousa@intel.com>
parent 67ccf6c6
Loading
Loading
Loading
Loading
+28 −3
Original line number Diff line number Diff line
@@ -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);
	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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -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,