From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Stop with the VBT AUX CH sanitation, and instead just check that the appropriate AUX CH is still available when initializing a DP/TC port. Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/display/g4x_dp.c | 3 ++ drivers/gpu/drm/i915/display/intel_bios.c | 56 --------------------- drivers/gpu/drm/i915/display/intel_ddi.c | 3 ++ drivers/gpu/drm/i915/display/intel_dp_aux.c | 51 ++++++++++++++++--- 4 files changed, 49 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index b5b0b323c1f4..6c9b9c8ef790 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -1376,8 +1376,11 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv, if (port != PORT_A) intel_infoframe_init(dig_port); dig_port->aux_ch = intel_dp_aux_ch(intel_encoder); + if (dig_port->aux_ch == AUX_CH_NONE) + goto err_init_connector; + if (!intel_dp_init_connector(dig_port, intel_connector)) goto err_init_connector; return true; diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 682c9cb6a736..de3c5493f38f 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -2223,61 +2223,8 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin) vbt_pin); return 0; } -static struct intel_encoder * -get_encoder_by_aux_ch(struct drm_i915_private *i915, u8 aux_ch) -{ - struct intel_encoder *encoder; - - if (!aux_ch) - return NULL; - - for_each_intel_encoder(&i915->drm, encoder) { - const struct intel_bios_encoder_data *devdata = encoder->devdata; - - if (devdata && aux_ch == devdata->child.aux_channel) - return encoder; - } - - return NULL; -} - -static void sanitize_aux_ch(struct intel_bios_encoder_data *devdata, - enum port port) -{ - struct drm_i915_private *i915 = devdata->i915; - struct child_device_config *child = &devdata->child; - struct intel_encoder *other; - - other = get_encoder_by_aux_ch(i915, devdata->child.aux_channel); - if (!other) - return; - - /* - * Pre-HSW uses separate DP and HDMI encoders - * for the same port. Let them pass. - */ - if (!HAS_DDI(i915) && devdata == other->devdata) - return; - - drm_dbg_kms(&i915->drm, - "port %c trying to use the same AUX CH (0x%x) as port %c, " - "disabling port %c DP support\n", - port_name(port), devdata->child.aux_channel, - port_name(other->port), port_name(port)); - - /* - * If we have multiple ports supposedly sharing the aux channel, then DP - * couldn't exist on the shared port. Otherwise they share the same aux - * channel and system couldn't communicate with them separately. - * - * First successfully initialized encoder wins. - */ - child->device_type &= ~DEVICE_TYPE_DISPLAYPORT_OUTPUT; - child->aux_channel = 0; -} - static u8 dvo_port_type(u8 dvo_port) { switch (dvo_port) { case DVO_PORT_HDMIA: @@ -2688,11 +2635,8 @@ void intel_bios_encoder_sanitize(struct intel_bios_encoder_data *devdata, enum port port) { if (!devdata) return; - - if (intel_bios_encoder_supports_dp(devdata)) - sanitize_aux_ch(devdata, port); } static bool has_ddi_port_info(struct drm_i915_private *i915) { diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 6deaa3433958..70b161d53c17 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4555,9 +4555,12 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, dig_port->saved_port_bits |= DDI_BUF_PORT_REVERSAL; dig_port->dp.output_reg = INVALID_MMIO_REG; dig_port->max_lanes = intel_ddi_max_lanes(dig_port); + dig_port->aux_ch = intel_dp_aux_ch(encoder); + if (dig_port->aux_ch == AUX_CH_NONE) + goto err; if (intel_phy_is_tc(dev_priv, phy)) { bool is_legacy = !intel_bios_encoder_supports_typec_usb(devdata) && diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index 96967e21c94c..927c877938b4 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -749,26 +749,61 @@ static enum aux_ch default_aux_ch(struct intel_encoder *encoder) return (enum aux_ch)encoder->port; } +static struct intel_encoder * +get_encoder_by_aux_ch(struct intel_encoder *encoder, + enum aux_ch aux_ch) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_encoder *other; + + for_each_intel_encoder(&i915->drm, other) { + if (other == encoder) + continue; + + if (!intel_encoder_is_dig_port(other)) + continue; + + if (enc_to_dig_port(other)->aux_ch == aux_ch) + return other; + } + + return NULL; +} + enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_encoder *other; + const char *source; 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; + source = "VBT"; + + if (aux_ch == AUX_CH_NONE) { + aux_ch = default_aux_ch(encoder); + source = "platform default"; } - aux_ch = default_aux_ch(encoder); + if (aux_ch == AUX_CH_NONE) + return AUX_CH_NONE; + + /* FIXME validate aux_ch against platform caps */ + + other = get_encoder_by_aux_ch(encoder, aux_ch); + if (other) { + drm_dbg_kms(&i915->drm, + "[ENCODER:%d:%s] AUX CH %c already claimed by [ENCODER:%d:%s]\n", + encoder->base.base.id, encoder->base.name, aux_ch_name(aux_ch), + other->base.base.id, other->base.name); + return AUX_CH_NONE; + } drm_dbg_kms(&i915->drm, - "[ENCODER:%d:%s] using AUX %c (platform default)\n", + "[ENCODER:%d:%s] Using AUX CH %c (%s)\n", encoder->base.base.id, encoder->base.name, - aux_ch_name(aux_ch)); + aux_ch_name(aux_ch), source); return aux_ch; } -- 2.39.2