diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp_aux.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp_aux.c | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index 5a176bfb10a2..705915d50565 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -6,9 +6,11 @@ #include "i915_drv.h" #include "i915_reg.h" #include "i915_trace.h" +#include "intel_bios.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dp_aux.h" +#include "intel_dp_aux_regs.h" #include "intel_pps.h" #include "intel_tc.h" @@ -117,6 +119,32 @@ static u32 skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index) return index ? 0 : 1; } +static int intel_dp_aux_sync_len(void) +{ + int precharge = 16; /* 10-16 */ + int preamble = 16; + + return precharge + preamble; +} + +static int intel_dp_aux_fw_sync_len(void) +{ + int precharge = 16; /* 10-16 */ + int preamble = 8; + + return precharge + preamble; +} + +static int g4x_dp_aux_precharge_len(void) +{ + int precharge_min = 10; + int preamble = 16; + + /* HW wants the length of the extra precharge in 2us units */ + return (intel_dp_aux_sync_len() - + precharge_min - preamble) / 2; +} + static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, int send_bytes, u32 aux_clock_divider) @@ -139,7 +167,7 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, timeout | DP_AUX_CH_CTL_RECEIVE_ERROR | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - (3 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | + (g4x_dp_aux_precharge_len() << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT); } @@ -163,8 +191,8 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp, DP_AUX_CH_CTL_TIME_OUT_MAX | DP_AUX_CH_CTL_RECEIVE_ERROR | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) | - DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); + DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(intel_dp_aux_fw_sync_len()) | + DP_AUX_CH_CTL_SYNC_PULSE_SKL(intel_dp_aux_sync_len()); if (intel_tc_port_in_tbt_alt_mode(dig_port)) ret |= DP_AUX_CH_CTL_TBT_IO; @@ -204,8 +232,19 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, for (i = 0; i < ARRAY_SIZE(ch_data); i++) ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i); - if (is_tc_port) + if (is_tc_port) { intel_tc_port_lock(dig_port); + /* + * Abort transfers on a disconnected port as required by + * DP 1.4a link CTS 4.2.1.5, also avoiding the long AUX + * timeouts that would otherwise happen. + * TODO: abort the transfer on non-TC ports as well. + */ + if (!intel_tc_port_connected_locked(&dig_port->base)) { + ret = -ENXIO; + goto out_unlock; + } + } aux_domain = intel_aux_power_domain(dig_port); @@ -366,7 +405,7 @@ out: intel_pps_unlock(intel_dp, pps_wakeref); intel_display_power_put_async(i915, aux_domain, aux_wakeref); - +out_unlock: if (is_tc_port) intel_tc_port_unlock(dig_port); @@ -737,3 +776,37 @@ void intel_dp_aux_init(struct intel_dp *intel_dp) intel_dp->aux.transfer = intel_dp_aux_transfer; cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE); } + +static enum aux_ch default_aux_ch(struct intel_encoder *encoder) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + + /* SKL has DDI E but no AUX E */ + if (DISPLAY_VER(i915) == 9 && encoder->port == PORT_E) + return AUX_CH_A; + + return (enum aux_ch)encoder->port; +} + +enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum aux_ch aux_ch; + + aux_ch = intel_bios_dp_aux_ch(encoder->devdata); + if (aux_ch != AUX_CH_NONE) { + drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] using AUX %c (VBT)\n", + encoder->base.base.id, encoder->base.name, + aux_ch_name(aux_ch)); + return aux_ch; + } + + aux_ch = default_aux_ch(encoder); + + drm_dbg_kms(&i915->drm, + "[ENCODER:%d:%s] using AUX %c (platform default)\n", + encoder->base.base.id, encoder->base.name, + aux_ch_name(aux_ch)); + + return aux_ch; +} |