if (tc_port == PORT_TC_NONE || intel_dig_port->tc_type == TC_PORT_TBT)
return;
@@ -3009,7 +3010,8 @@ static void icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port)
ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
- lane_info = (I915_READ(PORT_TX_DFLEXDPSP) &
+ fia = intel_tc_port_to_fia(dev_priv, tc_port);
+ lane_info = (I915_READ(PORT_TX_DFLEXDPSP(fia)) &
DP_LANE_ASSIGNMENT_MASK(tc_port)) >>
DP_LANE_ASSIGNMENT_SHIFT(tc_port);
@@ -3598,7 +3600,8 @@ static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
- u32 val = I915_READ(PORT_TX_DFLEXDPMLE1);
+ enum display_fia fia = intel_tc_port_to_fia(dev_priv, tc_port);
+ u32 val = I915_READ(PORT_TX_DFLEXDPMLE1(fia));
bool lane_reversal = dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
val &= ~DFLEXDPMLE1_DPMLETC_MASK(tc_port);
@@ -3617,7 +3620,7 @@ static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
default:
MISSING_CASE(pipe_config->lane_count);
}
- I915_WRITE(PORT_TX_DFLEXDPMLE1, val);
+ I915_WRITE(PORT_TX_DFLEXDPMLE1(fia), val);
}
static void
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 8592a7d422de..6217b5bcea2a 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6590,6 +6590,33 @@ enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv, enum port port)
return port - PORT_C;
}
+static bool intel_has_modular_fia(struct drm_i915_private *dev_priv)
+{
+ if (!INTEL_INFO(dev_priv)->display.has_modular_fia)
+ return false;
+
+ return I915_READ(PORT_TX_DFLEXDPSP(FIA_1)) & MODULAR_FIA_MASK;
+}
+
+enum display_fia intel_tc_port_to_fia(struct drm_i915_private *dev_priv,
+ enum tc_port tc_port)
+{
+ if (!intel_has_modular_fia(dev_priv))
+ return FIA_1;
+
+ switch (tc_port) {
+ case PORT_TC1:
+ case PORT_TC2:
+ return FIA_1;
+ case PORT_TC3:
+ case PORT_TC4:
+ return FIA_2;
+ default:
+ WARN_ON(tc_port);
+ return FIA_1;
+ }
+}
+
enum intel_display_power_domain intel_port_to_power_domain(enum port port)
{
switch (port) {
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index ee6b8194a459..12ded01ed5d3 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -196,6 +196,12 @@ enum tc_port_type {
TC_PORT_LEGACY,
};
+enum display_fia {
+ FIA_1 = 0,
+ FIA_2,
+ FIA_3,
+};
+
enum dpio_channel {
DPIO_CH0,
DPIO_CH1
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 4336df46fe78..5ed6e49fef33 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -218,13 +218,15 @@ static int intel_dp_get_fia_supported_lane_count(struct intel_dp *intel_dp)
enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
intel_wakeref_t wakeref;
u32 lane_info;
+ enum display_fia fia;
if (tc_port == PORT_TC_NONE || dig_port->tc_type != TC_PORT_TYPEC)
return 4;
+ fia = intel_tc_port_to_fia(dev_priv, tc_port);
lane_info = 0;
with_intel_display_power(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref)
- lane_info = (I915_READ(PORT_TX_DFLEXDPSP) &
+ lane_info = (I915_READ(PORT_TX_DFLEXDPSP(fia)) &
DP_LANE_ASSIGNMENT_MASK(tc_port)) >>
DP_LANE_ASSIGNMENT_SHIFT(tc_port);
@@ -5300,12 +5302,14 @@ static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
{
enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
u32 val;
+ enum display_fia fia;
if (dig_port->tc_type != TC_PORT_LEGACY &&
dig_port->tc_type != TC_PORT_TYPEC)
return true;
- val = I915_READ(PORT_TX_DFLEXDPPMS);
+ fia = intel_tc_port_to_fia(dev_priv, tc_port);
+ val = I915_READ(PORT_TX_DFLEXDPPMS(fia));
if (!(val & DP_PHY_MODE_STATUS_COMPLETED(tc_port))) {
DRM_DEBUG_KMS("DP PHY for TC port %d not ready\n", tc_port);
WARN_ON(dig_port->tc_legacy_port);
@@ -5316,10 +5320,10 @@ static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
* This function may be called many times in a row without an HPD event
* in between, so try to avoid the write when we can.
*/
- val = I915_READ(PORT_TX_DFLEXDPCSSS);
+ val = I915_READ(PORT_TX_DFLEXDPCSSS(fia));
if (!(val & DP_PHY_MODE_STATUS_NOT_SAFE(tc_port))) {
val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
- I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+ I915_WRITE(PORT_TX_DFLEXDPCSSS(fia), val);
}
/*
@@ -5327,7 +5331,7 @@ static bool icl_tc_phy_connect(struct drm_i915_private *dev_priv,
* became disconnected. Not necessary for legacy mode.
*/
if (dig_port->tc_type == TC_PORT_TYPEC &&
- !(I915_READ(PORT_TX_DFLEXDPSP) & TC_LIVE_STATE_TC(tc_port))) {
+ !(I915_READ(PORT_TX_DFLEXDPSP(fia)) & TC_LIVE_STATE_TC(tc_port))) {
DRM_DEBUG_KMS("TC PHY %d sudden disconnect.\n", tc_port);
icl_tc_phy_disconnect(dev_priv, dig_port);
return false;
@@ -5344,10 +5348,13 @@ void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv,
struct intel_digital_port *dig_port)
{
enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
+ enum display_fia fia;
if (dig_port->tc_type == TC_PORT_UNKNOWN)
return;
+ fia = intel_tc_port_to_fia(dev_priv, tc_port);
+
/*
* TBT disconnection flow is read the live status, what was done in
* caller.
@@ -5356,9 +5363,9 @@ void icl_tc_phy_disconnect(struct drm_i915_private *dev_priv,
dig_port->tc_type == TC_PORT_LEGACY) {
u32 val;
- val = I915_READ(PORT_TX_DFLEXDPCSSS);
+ val = I915_READ(PORT_TX_DFLEXDPCSSS(fia));
val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc_port);
- I915_WRITE(PORT_TX_DFLEXDPCSSS, val);
+ I915_WRITE(PORT_TX_DFLEXDPCSSS(fia), val);
}
DRM_DEBUG_KMS("Port %c TC type %s disconnected\n",
@@ -5383,6 +5390,7 @@ static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
{
enum port port = intel_dig_port->base.port;
enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
+ enum display_fia fia = intel_tc_port_to_fia(dev_priv, tc_port);
bool is_legacy, is_typec, is_tbt;
u32 dpsp;
@@ -5402,7 +5410,8 @@ static bool icl_tc_port_connected(struct drm_i915_private *dev_priv,
* The spec says we shouldn't be using the ISR bits for detecting
* between TC and TBT. We should use DFLEXDPSP.
*/
- dpsp = I915_READ(PORT_TX_DFLEXDPSP);
+
+ dpsp = I915_READ(PORT_TX_DFLEXDPSP(fia));
is_typec = dpsp & TC_LIVE_STATE_TC(tc_port);
is_tbt = dpsp & TC_LIVE_STATE_TBT(tc_port);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7e6009cefb18..8047f1bed314 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2201,9 +2201,13 @@ enum i915_power_well_id {
#define DW6_OLDO_DYN_PWR_DOWN_EN (1 << 28)
#define FIA1_BASE 0x163000
+#define FIA2_BASE 0x16E000
+#define FIA3_BASE 0x16F000
+#define _FIA(fia) _PICK((fia), FIA1_BASE, FIA2_BASE, FIA3_BASE)
+#define _MMIO_FIA(fia, off) _MMIO(_FIA(fia) + (off))
/* ICL PHY DFLEX registers */
-#define PORT_TX_DFLEXDPMLE1 _MMIO(FIA1_BASE + 0x008C0)
+#define PORT_TX_DFLEXDPMLE1(fia) _MMIO_FIA((fia), 0x008C0)
#define DFLEXDPMLE1_DPMLETC_MASK(tc_port) (0xf << (4 * (tc_port)))
#define DFLEXDPMLE1_DPMLETC_ML0(tc_port) (1 << (4 * (tc_port)))
#define DFLEXDPMLE1_DPMLETC_ML1_0(tc_port) (3 << (4 * (tc_port)))
@@ -11461,17 +11465,18 @@ enum skl_power_gate {
_ICL_DSC1_RC_BUF_THRESH_1_UDW_PB, \
_ICL_DSC1_RC_BUF_THRESH_1_UDW_PC)
-#define PORT_TX_DFLEXDPSP _MMIO(FIA1_BASE + 0x008A0)
+#define PORT_TX_DFLEXDPSP(fia) _MMIO_FIA((fia), 0x008A0)
+#define MODULAR_FIA_MASK (1 << 4)
#define TC_LIVE_STATE_TBT(tc_port) (1 << ((tc_port) * 8 + 6))
#define TC_LIVE_STATE_TC(tc_port) (1 << ((tc_port) * 8 + 5))
#define DP_LANE_ASSIGNMENT_SHIFT(tc_port) ((tc_port) * 8)
#define DP_LANE_ASSIGNMENT_MASK(tc_port) (0xf << ((tc_port) * 8))
#define DP_LANE_ASSIGNMENT(tc_port, x) ((x) << ((tc_port) * 8))
-#define PORT_TX_DFLEXDPPMS _MMIO(FIA1_BASE + 0x00890)
+#define PORT_TX_DFLEXDPPMS(fia) _MMIO_FIA((fia), 0x00890)
#define DP_PHY_MODE_STATUS_COMPLETED(tc_port) (1 << (tc_port))
-#define PORT_TX_DFLEXDPCSSS _MMIO(FIA1_BASE + 0x00894)
+#define PORT_TX_DFLEXDPCSSS(fia) _MMIO_FIA((fia), 0x00894)
#define DP_PHY_MODE_STATUS_NOT_SAFE(tc_port) (1 << (tc_port))
#endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index ddafc819bf30..e9dc86ed517b 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -136,6 +136,7 @@ enum intel_ppgtt_type {
func(has_gmch); \
func(has_hotplug); \
func(has_ipc); \
+ func(has_modular_fia); \
func(has_overlay); \
func(has_psr); \
func(overlay_needs_physical); \
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 1d58f7ec5d84..e30cb4be4997 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1477,6 +1477,8 @@ bool intel_port_is_combophy(struct drm_i915_private *dev_priv, enum port port);
bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port);
enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
enum port port);
+enum display_fia intel_tc_port_to_fia(struct drm_i915_private *dev_priv,
+ enum tc_port tc_port);
int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
--
2.21.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx