diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_tc.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_tc.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index f43e48c9a067..2556fea500d7 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -22,8 +22,17 @@ enum tc_port_mode { TC_PORT_LEGACY, }; +struct intel_tc_port; + +struct intel_tc_phy_ops { + u32 (*hpd_live_status)(struct intel_tc_port *tc); +}; + struct intel_tc_port { struct intel_digital_port *dig_port; + + const struct intel_tc_phy_ops *phy_ops; + struct mutex lock; /* protects the TypeC port mode */ intel_wakeref_t lock_wakeref; enum intel_display_power_domain lock_power_domain; @@ -329,10 +338,6 @@ static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) if (intel_de_read(i915, SDEISR) & isr_bit) mask |= BIT(TC_PORT_LEGACY); - /* The sink can be connected only in a single mode. */ - if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(tc, mask); - return mask; } @@ -495,6 +500,10 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) } } +static const struct intel_tc_phy_ops icl_tc_phy_ops = { + .hpd_live_status = icl_tc_phy_hpd_live_status, +}; + /* * ADLP TC PHY handlers * -------------------- @@ -521,10 +530,6 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) if (intel_de_read(i915, SDEISR) & isr_bit) mask |= BIT(TC_PORT_LEGACY); - /* The sink can be connected only in a single mode. */ - if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(tc, mask); - return mask; } @@ -574,6 +579,10 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; } +static const struct intel_tc_phy_ops adlp_tc_phy_ops = { + .hpd_live_status = adlp_tc_phy_hpd_live_status, +}; + /* * Generic TC PHY handlers * ----------------------- @@ -581,11 +590,15 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct drm_i915_private *i915 = tc_to_i915(tc); + u32 mask; - if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_hpd_live_status(tc); + mask = tc->phy_ops->hpd_live_status(tc); + + /* The sink can be connected only in a single mode. */ + if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1)) + tc_port_fixup_legacy_flag(tc, mask); - return icl_tc_phy_hpd_live_status(tc); + return mask; } static bool tc_phy_is_ready(struct intel_tc_port *tc) @@ -1197,6 +1210,11 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) dig_port->tc = tc; tc->dig_port = dig_port; + if (DISPLAY_VER(i915) >= 13) + tc->phy_ops = &adlp_tc_phy_ops; + else + tc->phy_ops = &icl_tc_phy_ops; + snprintf(tc->port_name, sizeof(tc->port_name), "%c/TC#%d", port_name(port), tc_port + 1); |
