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

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
...@@ -3163,25 +3163,30 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder, ...@@ -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 drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_shared_dpll *pll = crtc_state->shared_dpll; struct intel_shared_dpll *pll = crtc_state->shared_dpll;
enum phy phy = intel_port_to_phy(dev_priv, encoder->port); enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
u32 val; 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); mutex_lock(&dev_priv->dpll.lock);
val = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0); val = intel_de_read(dev_priv, reg);
drm_WARN_ON(&dev_priv->drm, drm_WARN_ON(&dev_priv->drm,
(val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0); (val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0);
if (intel_phy_is_combo(dev_priv, phy)) { if (intel_phy_is_combo(dev_priv, phy)) {
u32 mask, sel;
if (IS_ROCKETLAKE(dev_priv)) {
mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
sel = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
} else {
mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
sel = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
}
/* /*
* Even though this register references DDIs, note that we * Even though this register references DDIs, note that we
* want to pass the PHY rather than the port (DDI). For * 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, ...@@ -3194,12 +3199,12 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
*/ */
val &= ~mask; val &= ~mask;
val |= sel; val |= sel;
intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val); intel_de_write(dev_priv, reg, val);
intel_de_posting_read(dev_priv, ICL_DPCLKA_CFGCR0); intel_de_posting_read(dev_priv, reg);
} }
val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, 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);
mutex_unlock(&dev_priv->dpll.lock); mutex_unlock(&dev_priv->dpll.lock);
} }
...@@ -3222,12 +3227,19 @@ static void icl_unmap_plls_to_ports(struct intel_encoder *encoder) ...@@ -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); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port); enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
u32 val; u32 val;
i915_reg_t reg;
mutex_lock(&dev_priv->dpll.lock); 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); 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); mutex_unlock(&dev_priv->dpll.lock);
} }
...@@ -3267,13 +3279,21 @@ static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv, ...@@ -3267,13 +3279,21 @@ static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
u32 port_mask, bool ddi_clk_needed) u32 port_mask, bool ddi_clk_needed)
{ {
enum port port; enum port port;
bool ddi_clk_off;
u32 val; u32 val;
i915_reg_t reg;
val = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0);
for_each_port_masked(port, port_mask) { for_each_port_masked(port, port_mask) {
enum phy phy = intel_port_to_phy(dev_priv, port); enum phy phy = intel_port_to_phy(dev_priv, port);
bool ddi_clk_off = val & icl_dpclka_cfgcr0_clk_off(dev_priv,
phy); 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) if (ddi_clk_needed == !ddi_clk_off)
continue; continue;
...@@ -3289,7 +3309,7 @@ static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv, ...@@ -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 %c is disabled/in DSI mode with an ungated DDI clock, gate it\n",
phy_name(phy)); phy_name(phy));
val |= icl_dpclka_cfgcr0_clk_off(dev_priv, 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);
} }
} }
......
...@@ -10598,20 +10598,27 @@ static void icl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port, ...@@ -10598,20 +10598,27 @@ static void icl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
struct intel_shared_dpll *pll; struct intel_shared_dpll *pll;
enum intel_dpll_id id; enum intel_dpll_id id;
bool pll_active; bool pll_active;
i915_reg_t reg;
u32 temp; u32 temp;
if (intel_phy_is_combo(dev_priv, phy)) { if (intel_phy_is_combo(dev_priv, phy)) {
u32 mask, shift; 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); mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
shift = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy); shift = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
} else { } else {
reg = ICL_DPCLKA_CFGCR0;
mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy); mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
shift = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(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; id = temp >> shift;
port_dpll_id = ICL_PORT_DPLL_DEFAULT; port_dpll_id = ICL_PORT_DPLL_DEFAULT;
} else if (intel_phy_is_tc(dev_priv, phy)) { } else if (intel_phy_is_tc(dev_priv, phy)) {
......
...@@ -10307,7 +10307,7 @@ enum skl_power_gate { ...@@ -10307,7 +10307,7 @@ enum skl_power_gate {
/* ICL Clocks */ /* ICL Clocks */
#define ICL_DPCLKA_CFGCR0 _MMIO(0x164280) #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 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 ? \ #define ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port) (1 << ((tc_port) < TC_PORT_4 ? \
(tc_port) + 12 : \ (tc_port) + 12 : \
...@@ -10342,6 +10342,27 @@ enum skl_power_gate { ...@@ -10342,6 +10342,27 @@ enum skl_power_gate {
#define DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_DPLL_MAP(clk_sel, phy) \ #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)) (((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 */ /* CNL PLL */
#define DPLL0_ENABLE 0x46010 #define DPLL0_ENABLE 0x46010
#define DPLL1_ENABLE 0x46014 #define DPLL1_ENABLE 0x46014
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment