mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
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: Aditya Swarup <aditya.swarup@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210125140753.347998-7-aditya.swarup@intel.com
This commit is contained in:
parent
80d0f76588
commit
d6d2bc996e
|
|
@ -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;
|
||||
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, ICL_DPCLKA_CFGCR0);
|
||||
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)) {
|
||||
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
|
||||
* 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,13 +3279,21 @@ 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,
|
||||
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)
|
||||
continue;
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user