Commit d6d2bc99 authored by Aditya Swarup's avatar Aditya Swarup Committed by Lucas De Marchi
Browse files

drm/i915/adl_s: Configure Port clock registers for ADL-S



Add changes to configure port clock registers for ADL-S. Combo phy port
clocks are configured by DPCLKA_CFGCR0 and DPCLKA_CFGCR1 registers.

The DDI to internal clock mappings in DPCLKA_CFGCR0 register for ADL-S
translates to
DDI A -> DDIA
DDI B -> USBC1
DDI I -> USBC2

For DPCLKA_CFGCR1
DDI J -> USBC3
DDI K -> USBC4

Bspec: 50287
Bspec: 53812
Bspec: 53723

v2: Replace I915_READ() with intel_de_read().(Jani)

v3:
- Use reg variable to assign ADLS specific registers inorder to replace
  branching with intel_de_read/write() calls.(mdroper)
- Reuse icl_get_ddi_pll() for ADLS to fix issue with updating active
  dpll on driver load.(aswarup)

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: default avatarAditya Swarup <aditya.swarup@intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210125140753.347998-7-aditya.swarup@intel.com
parent 80d0f765
Loading
Loading
Loading
Loading
+41 −21
Original line number Diff line number Diff line
@@ -3163,25 +3163,30 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
	u32 val;

	mutex_lock(&dev_priv->dpll.lock);

	val = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
	drm_WARN_ON(&dev_priv->drm,
		    (val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0);

	if (intel_phy_is_combo(dev_priv, phy)) {
		u32 mask, sel;

		if (IS_ROCKETLAKE(dev_priv)) {
	u32 val, mask, sel;
	i915_reg_t reg;

	if (IS_ALDERLAKE_S(dev_priv)) {
		reg = ADLS_DPCLKA_CFGCR(phy);
		mask = ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy);
		sel = ((pll->info->id) << ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy));
	} else if (IS_ROCKETLAKE(dev_priv)) {
		reg = ICL_DPCLKA_CFGCR0;
		mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
		sel = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
	} else {
		reg = ICL_DPCLKA_CFGCR0;
		mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
		sel = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
	}

	mutex_lock(&dev_priv->dpll.lock);

	val = intel_de_read(dev_priv, reg);
	drm_WARN_ON(&dev_priv->drm,
		    (val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0);

	if (intel_phy_is_combo(dev_priv, phy)) {
		/*
		 * Even though this register references DDIs, note that we
		 * want to pass the PHY rather than the port (DDI).  For
@@ -3194,12 +3199,12 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
		 */
		val &= ~mask;
		val |= sel;
		intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
		intel_de_posting_read(dev_priv, ICL_DPCLKA_CFGCR0);
		intel_de_write(dev_priv, reg, val);
		intel_de_posting_read(dev_priv, reg);
	}

	val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, phy);
	intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
	intel_de_write(dev_priv, reg, val);

	mutex_unlock(&dev_priv->dpll.lock);
}
@@ -3222,12 +3227,19 @@ static void icl_unmap_plls_to_ports(struct intel_encoder *encoder)
	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
	enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
	u32 val;
	i915_reg_t reg;

	mutex_lock(&dev_priv->dpll.lock);

	val = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
	if (IS_ALDERLAKE_S(dev_priv))
		reg = ADLS_DPCLKA_CFGCR(phy);
	else
		reg = ICL_DPCLKA_CFGCR0;

	val = intel_de_read(dev_priv, reg);
	val |= icl_dpclka_cfgcr0_clk_off(dev_priv, phy);
	intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);

	intel_de_write(dev_priv, reg, val);

	mutex_unlock(&dev_priv->dpll.lock);
}
@@ -3267,12 +3279,20 @@ static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
				      u32 port_mask, bool ddi_clk_needed)
{
	enum port port;
	bool ddi_clk_off;
	u32 val;
	i915_reg_t reg;

	val = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
	for_each_port_masked(port, port_mask) {
		enum phy phy = intel_port_to_phy(dev_priv, port);
		bool ddi_clk_off = val & icl_dpclka_cfgcr0_clk_off(dev_priv,

		if (IS_ALDERLAKE_S(dev_priv))
			reg = ADLS_DPCLKA_CFGCR(phy);
		else
			reg = ICL_DPCLKA_CFGCR0;

		val = intel_de_read(dev_priv, reg);
		ddi_clk_off = val & icl_dpclka_cfgcr0_clk_off(dev_priv,
							      phy);

		if (ddi_clk_needed == !ddi_clk_off)
@@ -3289,7 +3309,7 @@ static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
			   "PHY %c is disabled/in DSI mode with an ungated DDI clock, gate it\n",
			   phy_name(phy));
		val |= icl_dpclka_cfgcr0_clk_off(dev_priv, phy);
		intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
		intel_de_write(dev_priv, reg, val);
	}
}

+9 −2
Original line number Diff line number Diff line
@@ -10598,20 +10598,27 @@ static void icl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
	struct intel_shared_dpll *pll;
	enum intel_dpll_id id;
	bool pll_active;
	i915_reg_t reg;
	u32 temp;
	if (intel_phy_is_combo(dev_priv, phy)) {
		u32 mask, shift;
		if (IS_ROCKETLAKE(dev_priv)) {
		if (IS_ALDERLAKE_S(dev_priv)) {
			reg = ADLS_DPCLKA_CFGCR(phy);
			mask = ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy);
			shift = ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy);
		} else if (IS_ROCKETLAKE(dev_priv)) {
			reg = ICL_DPCLKA_CFGCR0;
			mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
			shift = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
		} else {
			reg = ICL_DPCLKA_CFGCR0;
			mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
			shift = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
		}
		temp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0) & mask;
		temp = intel_de_read(dev_priv, reg) & mask;
		id = temp >> shift;
		port_dpll_id = ICL_PORT_DPLL_DEFAULT;
	} else if (intel_phy_is_tc(dev_priv, phy)) {
+22 −1
Original line number Diff line number Diff line
@@ -10307,7 +10307,7 @@ enum skl_power_gate {

/* ICL Clocks */
#define ICL_DPCLKA_CFGCR0			_MMIO(0x164280)
#define  ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)	(1 << _PICK(phy, 10, 11, 24))
#define  ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)	(1 << _PICK(phy, 10, 11, 24, 4, 5))
#define  RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)	REG_BIT((phy) + 10)
#define  ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)	(1 << ((tc_port) < TC_PORT_4 ? \
						       (tc_port) + 12 : \
@@ -10342,6 +10342,27 @@ enum skl_power_gate {
#define   DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_DPLL_MAP(clk_sel, phy) \
	(((clk_sel) >> DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy)) + _DG1_PHY_DPLL_MAP(phy))

/* ADLS Clocks */
#define _ADLS_DPCLKA_CFGCR0			0x164280
#define _ADLS_DPCLKA_CFGCR1			0x1642BC
#define ADLS_DPCLKA_CFGCR(phy)			_MMIO_PHY((phy) / 3, \
							  _ADLS_DPCLKA_CFGCR0, \
							  _ADLS_DPCLKA_CFGCR1)
#define  ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy)		(((phy) % 3) * 2)
/* ADLS DPCLKA_CFGCR0 DDI mask */
#define  ADLS_DPCLKA_DDII_SEL_MASK			REG_GENMASK(5, 4)
#define  ADLS_DPCLKA_DDIB_SEL_MASK			REG_GENMASK(3, 2)
#define  ADLS_DPCLKA_DDIA_SEL_MASK			REG_GENMASK(1, 0)
/* ADLS DPCLKA_CFGCR1 DDI mask */
#define  ADLS_DPCLKA_DDIK_SEL_MASK			REG_GENMASK(3, 2)
#define  ADLS_DPCLKA_DDIJ_SEL_MASK			REG_GENMASK(1, 0)
#define  ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy)	_PICK((phy), \
							ADLS_DPCLKA_DDIA_SEL_MASK, \
							ADLS_DPCLKA_DDIB_SEL_MASK, \
							ADLS_DPCLKA_DDII_SEL_MASK, \
							ADLS_DPCLKA_DDIJ_SEL_MASK, \
							ADLS_DPCLKA_DDIK_SEL_MASK)

/* CNL PLL */
#define DPLL0_ENABLE		0x46010
#define DPLL1_ENABLE		0x46014