Commit dc867bc7 authored by Matt Roper's avatar Matt Roper
Browse files

drm/i915/gen11: Convert combo PHY logic to use new 'enum phy' namespace



Convert the code that operates directly on gen11 combo PHY's to use the
new namespace.  Combo PHY registers are those named "ICL_PORT_*" plus
ICL_DPHY_CHKN.

Note that a lot of the PHY programming happens in the MIPI DSI code.
For clarity I've added a for_each_dsi_phy() to loop over the phys used
by DSI.  Since DSI always uses A & B on gen11, port=phy in all cases so
it doesn't actually matter which form we use in the DSI code.  I've used
the phy iterator in code that's explicitly working with the combo PHY,
but left the rest of the DSI code using the port iterator and namespace
to minimize patch deltas.  We can switch the rest of the DSI code over
to use phy terminology later if this winds up being too confusing.

v6: Drop an include of drm/i915_drm.h; that was previously included just
    for the definition of 'enum port' which this patch removes the need
    for.  (Jose)

Cc: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190709183934.445-4-matthew.d.roper@intel.com
parent befa372b
......@@ -202,63 +202,62 @@ static void dsi_program_swing_and_deemphasis(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port;
enum phy phy;
u32 tmp;
int lane;
for_each_dsi_port(port, intel_dsi->ports) {
for_each_dsi_phy(phy, intel_dsi->phys) {
/*
* Program voltage swing and pre-emphasis level values as per
* table in BSPEC under DDI buffer programing
*/
tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port));
tmp = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK);
tmp |= SCALING_MODE_SEL(0x2);
tmp |= TAP2_DISABLE | TAP3_DISABLE;
tmp |= RTERM_SELECT(0x6);
I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp);
I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), tmp);
tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port));
tmp = I915_READ(ICL_PORT_TX_DW5_AUX(phy));
tmp &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK);
tmp |= SCALING_MODE_SEL(0x2);
tmp |= TAP2_DISABLE | TAP3_DISABLE;
tmp |= RTERM_SELECT(0x6);
I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp);
I915_WRITE(ICL_PORT_TX_DW5_AUX(phy), tmp);
tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port));
tmp = I915_READ(ICL_PORT_TX_DW2_LN0(phy));
tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
RCOMP_SCALAR_MASK);
tmp |= SWING_SEL_UPPER(0x2);
tmp |= SWING_SEL_LOWER(0x2);
tmp |= RCOMP_SCALAR(0x98);
I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp);
I915_WRITE(ICL_PORT_TX_DW2_GRP(phy), tmp);
tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port));
tmp = I915_READ(ICL_PORT_TX_DW2_AUX(phy));
tmp &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
RCOMP_SCALAR_MASK);
tmp |= SWING_SEL_UPPER(0x2);
tmp |= SWING_SEL_LOWER(0x2);
tmp |= RCOMP_SCALAR(0x98);
I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp);
I915_WRITE(ICL_PORT_TX_DW2_AUX(phy), tmp);
tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port));
tmp = I915_READ(ICL_PORT_TX_DW4_AUX(phy));
tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
CURSOR_COEFF_MASK);
tmp |= POST_CURSOR_1(0x0);
tmp |= POST_CURSOR_2(0x0);
tmp |= CURSOR_COEFF(0x3f);
I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp);
I915_WRITE(ICL_PORT_TX_DW4_AUX(phy), tmp);
for (lane = 0; lane <= 3; lane++) {
/* Bspec: must not use GRP register for write */
tmp = I915_READ(ICL_PORT_TX_DW4_LN(lane, port));
tmp = I915_READ(ICL_PORT_TX_DW4_LN(lane, phy));
tmp &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
CURSOR_COEFF_MASK);
tmp |= POST_CURSOR_1(0x0);
tmp |= POST_CURSOR_2(0x0);
tmp |= CURSOR_COEFF(0x3f);
I915_WRITE(ICL_PORT_TX_DW4_LN(lane, port), tmp);
I915_WRITE(ICL_PORT_TX_DW4_LN(lane, phy), tmp);
}
}
}
......@@ -364,10 +363,10 @@ static void gen11_dsi_power_up_lanes(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port;
enum phy phy;
for_each_dsi_port(port, intel_dsi->ports)
intel_combo_phy_power_up_lanes(dev_priv, port, true,
for_each_dsi_phy(phy, intel_dsi->phys)
intel_combo_phy_power_up_lanes(dev_priv, phy, true,
intel_dsi->lane_count, false);
}
......@@ -375,46 +374,46 @@ static void gen11_dsi_config_phy_lanes_sequence(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
enum port port;
enum phy phy;
u32 tmp;
int lane;
/* Step 4b(i) set loadgen select for transmit and aux lanes */
for_each_dsi_port(port, intel_dsi->ports) {
tmp = I915_READ(ICL_PORT_TX_DW4_AUX(port));
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = I915_READ(ICL_PORT_TX_DW4_AUX(phy));
tmp &= ~LOADGEN_SELECT;
I915_WRITE(ICL_PORT_TX_DW4_AUX(port), tmp);
I915_WRITE(ICL_PORT_TX_DW4_AUX(phy), tmp);
for (lane = 0; lane <= 3; lane++) {
tmp = I915_READ(ICL_PORT_TX_DW4_LN(lane, port));
tmp = I915_READ(ICL_PORT_TX_DW4_LN(lane, phy));
tmp &= ~LOADGEN_SELECT;
if (lane != 2)
tmp |= LOADGEN_SELECT;
I915_WRITE(ICL_PORT_TX_DW4_LN(lane, port), tmp);
I915_WRITE(ICL_PORT_TX_DW4_LN(lane, phy), tmp);
}
}
/* Step 4b(ii) set latency optimization for transmit and aux lanes */
for_each_dsi_port(port, intel_dsi->ports) {
tmp = I915_READ(ICL_PORT_TX_DW2_AUX(port));
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = I915_READ(ICL_PORT_TX_DW2_AUX(phy));
tmp &= ~FRC_LATENCY_OPTIM_MASK;
tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
I915_WRITE(ICL_PORT_TX_DW2_AUX(port), tmp);
tmp = I915_READ(ICL_PORT_TX_DW2_LN0(port));
I915_WRITE(ICL_PORT_TX_DW2_AUX(phy), tmp);
tmp = I915_READ(ICL_PORT_TX_DW2_LN0(phy));
tmp &= ~FRC_LATENCY_OPTIM_MASK;
tmp |= FRC_LATENCY_OPTIM_VAL(0x5);
I915_WRITE(ICL_PORT_TX_DW2_GRP(port), tmp);
I915_WRITE(ICL_PORT_TX_DW2_GRP(phy), tmp);
/* For EHL set latency optimization for PCS_DW1 lanes */
if (IS_ELKHARTLAKE(dev_priv)) {
tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(port));
tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(phy));
tmp &= ~LATENCY_OPTIM_MASK;
tmp |= LATENCY_OPTIM_VAL(0);
I915_WRITE(ICL_PORT_PCS_DW1_AUX(port), tmp);
I915_WRITE(ICL_PORT_PCS_DW1_AUX(phy), tmp);
tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(phy));
tmp &= ~LATENCY_OPTIM_MASK;
tmp |= LATENCY_OPTIM_VAL(0x1);
I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), tmp);
I915_WRITE(ICL_PORT_PCS_DW1_GRP(phy), tmp);
}
}
......@@ -425,16 +424,16 @@ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder)
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
u32 tmp;
enum port port;
enum phy phy;
/* clear common keeper enable bit */
for_each_dsi_port(port, intel_dsi->ports) {
tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(port));
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = I915_READ(ICL_PORT_PCS_DW1_LN0(phy));
tmp &= ~COMMON_KEEPER_EN;
I915_WRITE(ICL_PORT_PCS_DW1_GRP(port), tmp);
tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(port));
I915_WRITE(ICL_PORT_PCS_DW1_GRP(phy), tmp);
tmp = I915_READ(ICL_PORT_PCS_DW1_AUX(phy));
tmp &= ~COMMON_KEEPER_EN;
I915_WRITE(ICL_PORT_PCS_DW1_AUX(port), tmp);
I915_WRITE(ICL_PORT_PCS_DW1_AUX(phy), tmp);
}
/*
......@@ -442,33 +441,33 @@ static void gen11_dsi_voltage_swing_program_seq(struct intel_encoder *encoder)
* Note: loadgen select program is done
* as part of lane phy sequence configuration
*/
for_each_dsi_port(port, intel_dsi->ports) {
tmp = I915_READ(ICL_PORT_CL_DW5(port));
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = I915_READ(ICL_PORT_CL_DW5(phy));
tmp |= SUS_CLOCK_CONFIG;
I915_WRITE(ICL_PORT_CL_DW5(port), tmp);
I915_WRITE(ICL_PORT_CL_DW5(phy), tmp);
}
/* Clear training enable to change swing values */
for_each_dsi_port(port, intel_dsi->ports) {
tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port));
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
tmp &= ~TX_TRAINING_EN;
I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp);
tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port));
I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), tmp);
tmp = I915_READ(ICL_PORT_TX_DW5_AUX(phy));
tmp &= ~TX_TRAINING_EN;
I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp);
I915_WRITE(ICL_PORT_TX_DW5_AUX(phy), tmp);
}
/* Program swing and de-emphasis */
dsi_program_swing_and_deemphasis(encoder);
/* Set training enable to trigger update */
for_each_dsi_port(port, intel_dsi->ports) {
tmp = I915_READ(ICL_PORT_TX_DW5_LN0(port));
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = I915_READ(ICL_PORT_TX_DW5_LN0(phy));
tmp |= TX_TRAINING_EN;
I915_WRITE(ICL_PORT_TX_DW5_GRP(port), tmp);
tmp = I915_READ(ICL_PORT_TX_DW5_AUX(port));
I915_WRITE(ICL_PORT_TX_DW5_GRP(phy), tmp);
tmp = I915_READ(ICL_PORT_TX_DW5_AUX(phy));
tmp |= TX_TRAINING_EN;
I915_WRITE(ICL_PORT_TX_DW5_AUX(port), tmp);
I915_WRITE(ICL_PORT_TX_DW5_AUX(phy), tmp);
}
}
......@@ -497,6 +496,7 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder)
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
u32 tmp;
enum port port;
enum phy phy;
/* Program T-INIT master registers */
for_each_dsi_port(port, intel_dsi->ports) {
......@@ -546,10 +546,10 @@ static void gen11_dsi_setup_dphy_timings(struct intel_encoder *encoder)
}
if (IS_ELKHARTLAKE(dev_priv)) {
for_each_dsi_port(port, intel_dsi->ports) {
tmp = I915_READ(ICL_DPHY_CHKN(port));
for_each_dsi_phy(phy, intel_dsi->phys) {
tmp = I915_READ(ICL_DPHY_CHKN(phy));
tmp |= ICL_DPHY_CHKN_AFE_OVER_PPI_STRAP;
I915_WRITE(ICL_DPHY_CHKN(port), tmp);
I915_WRITE(ICL_DPHY_CHKN(phy), tmp);
}
}
}
......@@ -559,15 +559,12 @@ static void gen11_dsi_gate_clocks(struct intel_encoder *encoder)
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
u32 tmp;
enum port port;
enum phy phy;
mutex_lock(&dev_priv->dpll_lock);
tmp = I915_READ(ICL_DPCLKA_CFGCR0);
for_each_dsi_port(port, intel_dsi->ports) {
phy = intel_port_to_phy(dev_priv, port);
for_each_dsi_phy(phy, intel_dsi->phys)
tmp |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
}
I915_WRITE(ICL_DPCLKA_CFGCR0, tmp);
mutex_unlock(&dev_priv->dpll_lock);
......@@ -578,15 +575,12 @@ static void gen11_dsi_ungate_clocks(struct intel_encoder *encoder)
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
u32 tmp;
enum port port;
enum phy phy;
mutex_lock(&dev_priv->dpll_lock);
tmp = I915_READ(ICL_DPCLKA_CFGCR0);
for_each_dsi_port(port, intel_dsi->ports) {
phy = intel_port_to_phy(dev_priv, port);
for_each_dsi_phy(phy, intel_dsi->phys)
tmp &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
}
I915_WRITE(ICL_DPCLKA_CFGCR0, tmp);
mutex_unlock(&dev_priv->dpll_lock);
......@@ -598,22 +592,19 @@ static void gen11_dsi_map_pll(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
struct intel_shared_dpll *pll = crtc_state->shared_dpll;
enum port port;
enum phy phy;
u32 val;
mutex_lock(&dev_priv->dpll_lock);
val = I915_READ(ICL_DPCLKA_CFGCR0);
for_each_dsi_port(port, intel_dsi->ports) {
phy = intel_port_to_phy(dev_priv, port);
for_each_dsi_phy(phy, intel_dsi->phys) {
val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
val |= ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
}
I915_WRITE(ICL_DPCLKA_CFGCR0, val);
for_each_dsi_port(port, intel_dsi->ports) {
phy = intel_port_to_phy(dev_priv, port);
for_each_dsi_phy(phy, intel_dsi->phys) {
val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
}
I915_WRITE(ICL_DPCLKA_CFGCR0, val);
......
......@@ -6,13 +6,13 @@
#include "intel_combo_phy.h"
#include "intel_drv.h"
#define for_each_combo_port(__dev_priv, __port) \
for ((__port) = PORT_A; (__port) < I915_MAX_PORTS; (__port)++) \
for_each_if(intel_port_is_combophy(__dev_priv, __port))
#define for_each_combo_phy(__dev_priv, __phy) \
for ((__phy) = PHY_A; (__phy) < I915_MAX_PHYS; (__phy)++) \
for_each_if(intel_phy_is_combo(__dev_priv, __phy))
#define for_each_combo_port_reverse(__dev_priv, __port) \
for ((__port) = I915_MAX_PORTS; (__port)-- > PORT_A;) \
for_each_if(intel_port_is_combophy(__dev_priv, __port))
#define for_each_combo_phy_reverse(__dev_priv, __phy) \
for ((__phy) = I915_MAX_PHYS; (__phy)-- > PHY_A;) \
for_each_if(intel_phy_is_combo(__dev_priv, __phy))
enum {
PROCMON_0_85V_DOT_0,
......@@ -38,18 +38,17 @@ static const struct cnl_procmon {
};
/*
* CNL has just one set of registers, while ICL has two sets: one for port A and
* the other for port B. The CNL registers are equivalent to the ICL port A
* registers, that's why we call the ICL macros even though the function has CNL
* on its name.
* CNL has just one set of registers, while gen11 has a set for each combo PHY.
* The CNL registers are equivalent to the gen11 PHY A registers, that's why we
* call the ICL macros even though the function has CNL on its name.
*/
static const struct cnl_procmon *
cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum port port)
cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
{
const struct cnl_procmon *procmon;
u32 val;
val = I915_READ(ICL_PORT_COMP_DW3(port));
val = I915_READ(ICL_PORT_COMP_DW3(phy));
switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {
default:
MISSING_CASE(val);
......@@ -75,32 +74,32 @@ cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum port port)
}
static void cnl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
enum port port)
enum phy phy)
{
const struct cnl_procmon *procmon;
u32 val;
procmon = cnl_get_procmon_ref_values(dev_priv, port);
procmon = cnl_get_procmon_ref_values(dev_priv, phy);
val = I915_READ(ICL_PORT_COMP_DW1(port));
val = I915_READ(ICL_PORT_COMP_DW1(phy));
val &= ~((0xff << 16) | 0xff);
val |= procmon->dw1;
I915_WRITE(ICL_PORT_COMP_DW1(port), val);
I915_WRITE(ICL_PORT_COMP_DW1(phy), val);
I915_WRITE(ICL_PORT_COMP_DW9(port), procmon->dw9);
I915_WRITE(ICL_PORT_COMP_DW10(port), procmon->dw10);
I915_WRITE(ICL_PORT_COMP_DW9(phy), procmon->dw9);
I915_WRITE(ICL_PORT_COMP_DW10(phy), procmon->dw10);
}
static bool check_phy_reg(struct drm_i915_private *dev_priv,
enum port port, i915_reg_t reg, u32 mask,
enum phy phy, i915_reg_t reg, u32 mask,
u32 expected_val)
{
u32 val = I915_READ(reg);
if ((val & mask) != expected_val) {
DRM_DEBUG_DRIVER("Port %c combo PHY reg %08x state mismatch: "
DRM_DEBUG_DRIVER("Combo PHY %c reg %08x state mismatch: "
"current %08x mask %08x expected %08x\n",
port_name(port),
phy_name(phy),
reg.reg, val, mask, expected_val);
return false;
}
......@@ -109,18 +108,18 @@ static bool check_phy_reg(struct drm_i915_private *dev_priv,
}
static bool cnl_verify_procmon_ref_values(struct drm_i915_private *dev_priv,
enum port port)
enum phy phy)
{
const struct cnl_procmon *procmon;
bool ret;
procmon = cnl_get_procmon_ref_values(dev_priv, port);
procmon = cnl_get_procmon_ref_values(dev_priv, phy);
ret = check_phy_reg(dev_priv, port, ICL_PORT_COMP_DW1(port),
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
ret &= check_phy_reg(dev_priv, port, ICL_PORT_COMP_DW9(port),
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW9(phy),
-1U, procmon->dw9);
ret &= check_phy_reg(dev_priv, port, ICL_PORT_COMP_DW10(port),
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW10(phy),
-1U, procmon->dw10);
return ret;
......@@ -134,15 +133,15 @@ static bool cnl_combo_phy_enabled(struct drm_i915_private *dev_priv)
static bool cnl_combo_phy_verify_state(struct drm_i915_private *dev_priv)
{
enum port port = PORT_A;
enum phy phy = PHY_A;
bool ret;
if (!cnl_combo_phy_enabled(dev_priv))
return false;
ret = cnl_verify_procmon_ref_values(dev_priv, port);
ret = cnl_verify_procmon_ref_values(dev_priv, phy);
ret &= check_phy_reg(dev_priv, port, CNL_PORT_CL1CM_DW5,
ret &= check_phy_reg(dev_priv, phy, CNL_PORT_CL1CM_DW5,
CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE);
return ret;
......@@ -157,7 +156,7 @@ static void cnl_combo_phys_init(struct drm_i915_private *dev_priv)
I915_WRITE(CHICKEN_MISC_2, val);
/* Dummy PORT_A to get the correct CNL register from the ICL macro */
cnl_set_procmon_ref_values(dev_priv, PORT_A);
cnl_set_procmon_ref_values(dev_priv, PHY_A);
val = I915_READ(CNL_PORT_COMP_DW0);
val |= COMP_INIT;
......@@ -181,39 +180,39 @@ static void cnl_combo_phys_uninit(struct drm_i915_private *dev_priv)
}
static bool icl_combo_phy_enabled(struct drm_i915_private *dev_priv,
enum port port)
enum phy phy)
{
/* The PHY C added by EHL has no PHY_MISC register */
if (IS_ELKHARTLAKE(dev_priv) && port == PORT_C)
return I915_READ(ICL_PORT_COMP_DW0(port)) & COMP_INIT;
if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_C)
return I915_READ(ICL_PORT_COMP_DW0(phy)) & COMP_INIT;
else
return !(I915_READ(ICL_PHY_MISC(port)) &
return !(I915_READ(ICL_PHY_MISC(phy)) &
ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN) &&
(I915_READ(ICL_PORT_COMP_DW0(port)) & COMP_INIT);
(I915_READ(ICL_PORT_COMP_DW0(phy)) & COMP_INIT);
}
static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
enum port port)
enum phy phy)
{
bool ret;
if (!icl_combo_phy_enabled(dev_priv, port))
if (!icl_combo_phy_enabled(dev_priv, phy))
return false;
ret = cnl_verify_procmon_ref_values(dev_priv, port);
ret = cnl_verify_procmon_ref_values(dev_priv, phy);
if (port == PORT_A)
ret &= check_phy_reg(dev_priv, port, ICL_PORT_COMP_DW8(port),
if (phy == PHY_A)
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy),
IREFGEN, IREFGEN);
ret &= check_phy_reg(dev_priv, port, ICL_PORT_CL_DW5(port),
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_CL_DW5(phy),
CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE);
return ret;
}
void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
enum port port, bool is_dsi,
enum phy phy, bool is_dsi,
int lane_count, bool lane_reversal)
{
u8 lane_mask;
......@@ -258,10 +257,10 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
}
}
val = I915_READ(ICL_PORT_CL_DW10(port));
val = I915_READ(ICL_PORT_CL_DW10(phy));
val &= ~PWR_DOWN_LN_MASK;
val |= lane_mask << PWR_DOWN_LN_SHIFT;
I915_WRITE(ICL_PORT_CL_DW10(port), val);
I915_WRITE(ICL_PORT_CL_DW10(phy), val);
}
static u32 ehl_combo_phy_a_mux(struct drm_i915_private *i915, u32 val)
......@@ -292,14 +291,14 @@ static u32 ehl_combo_phy_a_mux(struct drm_i915_private *i915, u32 val)
static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
{
enum port port;
enum phy phy;
for_each_combo_port(dev_priv, port) {
for_each_combo_phy(dev_priv, phy) {
u32 val;
if (icl_combo_phy_verify_state(dev_priv, port)) {
DRM_DEBUG_DRIVER("Port %c combo PHY already enabled, won't reprogram it.\n",
port_name(port));
if (icl_combo_phy_verify_state(dev_priv, phy)) {
DRM_DEBUG_DRIVER("Combo PHY %c already enabled, won't reprogram it.\n",
phy_name(phy));
continue;
}
......@@ -308,7 +307,7 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
* register for it and no need to program the
* DE_IO_COMP_PWR_DOWN setting on PHY C.
*/
if (IS_ELKHARTLAKE(dev_priv) && port == PORT_C)
if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_C)
goto skip_phy_misc;
/*
......@@ -319,59 +318,59 @@ static void icl_combo_phys_init(struct drm_i915_private *dev_priv)
* based on whether our VBT indicates the presence of any
* "internal" child devices.
*/
val = I915_READ(ICL_PHY_MISC(port));
if (IS_ELKHARTLAKE(dev_priv) && port == PORT_A)
val = I915_READ(ICL_PHY_MISC(phy));
if (IS_ELKHARTLAKE(dev_priv) && phy == PHY_A)
val = ehl_combo_phy_a_mux(dev_priv, val);
val &= ~ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN;
I915_WRITE(ICL_PHY_MISC(port), val);
I915_WRITE(ICL_PHY_MISC(phy), val);
skip_phy_misc:
cnl_set_procmon_ref_values(dev_priv, port);
cnl_set_procmon_ref_values(dev_priv, phy);
if (port == PORT_A) {
val = I915_READ(ICL_PORT_COMP_DW8(port));
if (phy == PHY_A) {
val = I915_READ(ICL_PORT_COMP_DW8(phy));
val |= IREFGEN;
I915_WRITE(ICL_PORT_COMP_DW8(port), val);
I915_WRITE(ICL_PORT_COMP_DW8(phy), val);
}
val = I915_READ(ICL_PORT_COMP_DW0(port));
val = I915_READ(ICL_PORT_COMP_DW0(phy));
val |= COMP_INIT;
I915_WRITE(ICL_PORT_COMP_DW0(port), val);
I915_WRITE(ICL_PORT_COMP_DW0(phy), val);
val = I915_READ(ICL_PORT_CL_DW5(port));
val = I915_READ(ICL_PORT_CL_DW5(phy));
val |= CL_POWER_DOWN_ENABLE;
I915_WRITE(ICL_PORT_CL_DW5(port), val);
I915_WRITE(ICL_PORT_CL_DW5(phy), val);
}
}
static void icl_combo_phys_uninit(struct drm_i915_private *dev_priv)
{
enum port port;
enum phy phy;
for_each_combo_port_reverse(dev_priv, port) {
for_each_combo_phy_reverse(dev_priv, phy) {
u32 val;
if (port == PORT_A &&
!icl_combo_phy_verify_state(dev_priv, port))
DRM_WARN("Port %c combo PHY HW state changed unexpectedly\n",
port_name(port));
if (phy == PHY_A &&
!icl_combo_phy_verify_state(dev_priv, phy))
DRM_WARN("Combo PHY %c HW state changed unexpectedly\n",
phy_name(phy));
/*
* Although EHL adds a combo PHY C, there's no PHY_MISC
* register for it and no need to program the
* DE_IO_COMP_PWR_DOWN setting on PHY C.
*/