diff options
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_cx0_phy.c | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index ee6902118860..0600fdcd06ef 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -2528,13 +2528,23 @@ static u32 intel_cx0_get_pclk_refclk_ack(u8 lane_mask) return val; } -/* FIXME: Some Type-C cases need not reset both the lanes. Handle those cases. */ -static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, enum port port, +static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, + struct intel_encoder *encoder, bool lane_reversal) { + enum port port = encoder->port; enum phy phy = intel_port_to_phy(i915, port); + bool both_lanes = intel_tc_port_fia_max_lane_count(enc_to_dig_port(encoder)) > 2; u8 lane_mask = lane_reversal ? INTEL_CX0_LANE1 : INTEL_CX0_LANE0; + u32 lane_pipe_reset = both_lanes ? + XELPDP_LANE_PIPE_RESET(0) | + XELPDP_LANE_PIPE_RESET(1) : + XELPDP_LANE_PIPE_RESET(0); + u32 lane_phy_current_status = both_lanes ? + XELPDP_LANE_PHY_CURRENT_STATUS(0) | + XELPDP_LANE_PHY_CURRENT_STATUS(1) : + XELPDP_LANE_PHY_CURRENT_STATUS(0); if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL1(port), XELPDP_PORT_BUF_SOC_PHY_READY, @@ -2545,23 +2555,24 @@ static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, enum port po intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1), - XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1)); + lane_pipe_reset); if (__intel_de_wait_for_register(i915, XELPDP_PORT_BUF_CTL2(port), - XELPDP_LANE_PHY_CURRENT_STATUS(0) | - XELPDP_LANE_PHY_CURRENT_STATUS(1), - XELPDP_LANE_PHY_CURRENT_STATUS(0) | - XELPDP_LANE_PHY_CURRENT_STATUS(1), + lane_phy_current_status, lane_phy_current_status, XELPDP_PORT_RESET_START_TIMEOUT_US, 0, NULL)) drm_warn(&i915->drm, "PHY %c failed to bring out of Lane reset after %dus.\n", phy_name(phy), XELPDP_PORT_RESET_START_TIMEOUT_US); intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(port), - intel_cx0_get_pclk_refclk_request(INTEL_CX0_BOTH_LANES), + intel_cx0_get_pclk_refclk_request(both_lanes ? + INTEL_CX0_BOTH_LANES : + INTEL_CX0_LANE0), intel_cx0_get_pclk_refclk_request(lane_mask)); if (__intel_de_wait_for_register(i915, XELPDP_PORT_CLOCK_CTL(port), - intel_cx0_get_pclk_refclk_ack(INTEL_CX0_BOTH_LANES), + intel_cx0_get_pclk_refclk_ack(both_lanes ? + INTEL_CX0_BOTH_LANES : + INTEL_CX0_LANE0), intel_cx0_get_pclk_refclk_ack(lane_mask), XELPDP_REFCLK_ENABLE_TIMEOUT_US, 0, NULL)) drm_warn(&i915->drm, "PHY %c failed to request refclk after %dus.\n", @@ -2571,13 +2582,9 @@ static void intel_cx0_phy_lane_reset(struct drm_i915_private *i915, enum port po CX0_P2_STATE_RESET); intel_cx0_setup_powerdown(i915, port); - intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), - XELPDP_LANE_PIPE_RESET(0) | XELPDP_LANE_PIPE_RESET(1), - 0); + intel_de_rmw(i915, XELPDP_PORT_BUF_CTL2(port), lane_pipe_reset, 0); - if (intel_de_wait_for_clear(i915, XELPDP_PORT_BUF_CTL2(port), - XELPDP_LANE_PHY_CURRENT_STATUS(0) | - XELPDP_LANE_PHY_CURRENT_STATUS(1), + if (intel_de_wait_for_clear(i915, XELPDP_PORT_BUF_CTL2(port), lane_phy_current_status, XELPDP_PORT_RESET_END_TIMEOUT)) drm_warn(&i915->drm, "PHY %c failed to bring out of Lane reset after %dms.\n", phy_name(phy), XELPDP_PORT_RESET_END_TIMEOUT); @@ -2705,7 +2712,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder, intel_program_port_clock_ctl(encoder, crtc_state, lane_reversal); /* 2. Bring PHY out of reset. */ - intel_cx0_phy_lane_reset(i915, encoder->port, lane_reversal); + intel_cx0_phy_lane_reset(i915, encoder, lane_reversal); /* * 3. Change Phy power state to Ready. |