Skip to content

Commit b8a13e8

Browse files
committed
drm/i915: Remove AUX CH sanitation
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. The reason being that we want to start initializing ports in VBT order to deal with VBTs that declare child devices with seemingly conflicting ports. As the encoder initialization can fail for other reasons (at least for eDP+AUX) we can't know upfront which way the conflicts should be resolved. Note that the old way of sanitizing gave priority to the last port declared in the VBT, but now we sort of do the opposite by favoring the first encoder to successfully initialize. The reason for the old "last port wins" preference was eg. Asrock B250M-HDV where port A (eDP) and port E (DP->VGA) have an AUX CH conflict and we need to prefer port E. However with the new way port A (eDP) will be probed first, but will fail to probe due to HPD and thus port E will still win in the end. v2: Pimp the commit message (Jani) Reviewed-by: Jani Nikula <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 49d4648 commit b8a13e8

File tree

4 files changed

+50
-62
lines changed

4 files changed

+50
-62
lines changed

drivers/gpu/drm/i915/display/g4x_dp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,9 @@ bool g4x_dp_init(struct drm_i915_private *dev_priv,
13781378
intel_infoframe_init(dig_port);
13791379

13801380
dig_port->aux_ch = intel_dp_aux_ch(intel_encoder);
1381+
if (dig_port->aux_ch == AUX_CH_NONE)
1382+
goto err_init_connector;
1383+
13811384
if (!intel_dp_init_connector(dig_port, intel_connector))
13821385
goto err_init_connector;
13831386

drivers/gpu/drm/i915/display/intel_bios.c

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,56 +2230,6 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
22302230
return 0;
22312231
}
22322232

2233-
static enum port get_port_by_aux_ch(struct drm_i915_private *i915, u8 aux_ch)
2234-
{
2235-
enum port port;
2236-
2237-
if (!aux_ch)
2238-
return PORT_NONE;
2239-
2240-
for_each_port(port) {
2241-
const struct intel_bios_encoder_data *devdata =
2242-
i915->display.vbt.ports[port];
2243-
2244-
if (devdata && aux_ch == devdata->child.aux_channel)
2245-
return port;
2246-
}
2247-
2248-
return PORT_NONE;
2249-
}
2250-
2251-
static void sanitize_aux_ch(struct intel_bios_encoder_data *devdata,
2252-
enum port port)
2253-
{
2254-
struct drm_i915_private *i915 = devdata->i915;
2255-
struct child_device_config *child;
2256-
enum port p;
2257-
2258-
p = get_port_by_aux_ch(i915, devdata->child.aux_channel);
2259-
if (p == PORT_NONE)
2260-
return;
2261-
2262-
drm_dbg_kms(&i915->drm,
2263-
"port %c trying to use the same AUX CH (0x%x) as port %c, "
2264-
"disabling port %c DP support\n",
2265-
port_name(port), devdata->child.aux_channel,
2266-
port_name(p), port_name(p));
2267-
2268-
/*
2269-
* If we have multiple ports supposedly sharing the aux channel, then DP
2270-
* couldn't exist on the shared port. Otherwise they share the same aux
2271-
* channel and system couldn't communicate with them separately.
2272-
*
2273-
* Give inverse child device order the priority, last one wins. Yes,
2274-
* there are real machines (eg. Asrock B250M-HDV) where VBT has both
2275-
* port A and port E with the same AUX ch and we must pick port E :(
2276-
*/
2277-
child = &i915->display.vbt.ports[p]->child;
2278-
2279-
child->device_type &= ~DEVICE_TYPE_DISPLAYPORT_OUTPUT;
2280-
child->aux_channel = 0;
2281-
}
2282-
22832233
static u8 dvo_port_type(u8 dvo_port)
22842234
{
22852235
switch (dvo_port) {
@@ -2688,9 +2638,6 @@ static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
26882638

26892639
sanitize_device_type(devdata, port);
26902640

2691-
if (intel_bios_encoder_supports_dp(devdata))
2692-
sanitize_aux_ch(devdata, port);
2693-
26942641
i915->display.vbt.ports[port] = devdata;
26952642
}
26962643

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4938,8 +4938,11 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
49384938
dig_port->dp.output_reg = INVALID_MMIO_REG;
49394939
dig_port->max_lanes = intel_ddi_max_lanes(dig_port);
49404940

4941-
if (need_aux_ch(encoder, init_dp))
4941+
if (need_aux_ch(encoder, init_dp)) {
49424942
dig_port->aux_ch = intel_dp_aux_ch(encoder);
4943+
if (dig_port->aux_ch == AUX_CH_NONE)
4944+
goto err;
4945+
}
49434946

49444947
if (intel_phy_is_tc(dev_priv, phy)) {
49454948
bool is_legacy =

drivers/gpu/drm/i915/display/intel_dp_aux.c

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -792,25 +792,60 @@ static enum aux_ch default_aux_ch(struct intel_encoder *encoder)
792792
return (enum aux_ch)encoder->port;
793793
}
794794

795+
static struct intel_encoder *
796+
get_encoder_by_aux_ch(struct intel_encoder *encoder,
797+
enum aux_ch aux_ch)
798+
{
799+
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
800+
struct intel_encoder *other;
801+
802+
for_each_intel_encoder(&i915->drm, other) {
803+
if (other == encoder)
804+
continue;
805+
806+
if (!intel_encoder_is_dig_port(other))
807+
continue;
808+
809+
if (enc_to_dig_port(other)->aux_ch == aux_ch)
810+
return other;
811+
}
812+
813+
return NULL;
814+
}
815+
795816
enum aux_ch intel_dp_aux_ch(struct intel_encoder *encoder)
796817
{
797818
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
819+
struct intel_encoder *other;
820+
const char *source;
798821
enum aux_ch aux_ch;
799822

800823
aux_ch = intel_bios_dp_aux_ch(encoder->devdata);
801-
if (aux_ch != AUX_CH_NONE) {
802-
drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] using AUX %c (VBT)\n",
803-
encoder->base.base.id, encoder->base.name,
804-
aux_ch_name(aux_ch));
805-
return aux_ch;
824+
source = "VBT";
825+
826+
if (aux_ch == AUX_CH_NONE) {
827+
aux_ch = default_aux_ch(encoder);
828+
source = "platform default";
806829
}
807830

808-
aux_ch = default_aux_ch(encoder);
831+
if (aux_ch == AUX_CH_NONE)
832+
return AUX_CH_NONE;
833+
834+
/* FIXME validate aux_ch against platform caps */
835+
836+
other = get_encoder_by_aux_ch(encoder, aux_ch);
837+
if (other) {
838+
drm_dbg_kms(&i915->drm,
839+
"[ENCODER:%d:%s] AUX CH %c already claimed by [ENCODER:%d:%s]\n",
840+
encoder->base.base.id, encoder->base.name, aux_ch_name(aux_ch),
841+
other->base.base.id, other->base.name);
842+
return AUX_CH_NONE;
843+
}
809844

810845
drm_dbg_kms(&i915->drm,
811-
"[ENCODER:%d:%s] using AUX %c (platform default)\n",
846+
"[ENCODER:%d:%s] Using AUX CH %c (%s)\n",
812847
encoder->base.base.id, encoder->base.name,
813-
aux_ch_name(aux_ch));
848+
aux_ch_name(aux_ch), source);
814849

815850
return aux_ch;
816851
}

0 commit comments

Comments
 (0)