aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLyude Paul <lyude@redhat.com>2018-08-30 13:16:28 -0400
committerBen Skeggs <bskeggs@redhat.com>2018-09-06 16:54:27 -0400
commitd5986a1c4dcd00cb8b9eee4a56ee93868222a9a2 (patch)
tree871d62fe80539cd12ffd22d4bc4849ab0cb0f7a7
parent2f7ca781fd382cf8dde73ed36dfdd93fd05b3332 (diff)
drm/nouveau: Fix nouveau_connector_ddc_detect()
It looks like that when we moved over to using drm_connector_for_each_possible_encoder() in nouveau, that one rather important part of this function got dropped by accident: /* Right v here */ for (i = 0; nv_encoder = NULL, i < DRM_CONNECTOR_MAX_ENCODER; i++) { int id = connector->encoder_ids[i]; if (id == 0) break; Since it's rather difficult to notice: the conditional in this loop is actually: nv_encoder = NULL, i < DRM_CONNECTOR_MAX_ENCODER Meaning that all early breaks result in nv_encoder keeping it's value, otherwise nv_encoder = NULL. Ugh. Since this got dropped, nouveau_connector_ddc_detect() now returns an encoder for every single connector, regardless of whether or not it's detected: [ 1780.056185] nouveau 0000:01:00.0: DRM: DDC responded, but no EDID for DP-2 So: fix this to ensure we only return an encoder if we actually found one, and clean up the rest of the function while we're at it since it's nearly impossible to read properly. Changes since v1: - Don't skip ddc probing for LVDS if we can't switch DDC through vga-switcheroo, just do the DDC probing without calling vga_switcheroo_lock_ddc() - skeggsb Signed-off-by: Lyude Paul <lyude@redhat.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Fixes: ddba766dd07e ("drm/nouveau: Use drm_connector_for_each_possible_encoder()") Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 76660bc1ccfb..259ee5039125 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -412,9 +412,10 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
412 struct nouveau_connector *nv_connector = nouveau_connector(connector); 412 struct nouveau_connector *nv_connector = nouveau_connector(connector);
413 struct nouveau_drm *drm = nouveau_drm(dev); 413 struct nouveau_drm *drm = nouveau_drm(dev);
414 struct nvkm_gpio *gpio = nvxx_gpio(&drm->client.device); 414 struct nvkm_gpio *gpio = nvxx_gpio(&drm->client.device);
415 struct nouveau_encoder *nv_encoder = NULL; 415 struct nouveau_encoder *nv_encoder = NULL, *found = NULL;
416 struct drm_encoder *encoder; 416 struct drm_encoder *encoder;
417 int i, panel = -ENODEV; 417 int i, ret, panel = -ENODEV;
418 bool switcheroo_ddc = false;
418 419
419 /* eDP panels need powering on by us (if the VBIOS doesn't default it 420 /* eDP panels need powering on by us (if the VBIOS doesn't default it
420 * to on) before doing any AUX channel transactions. LVDS panel power 421 * to on) before doing any AUX channel transactions. LVDS panel power
@@ -431,37 +432,43 @@ nouveau_connector_ddc_detect(struct drm_connector *connector)
431 drm_connector_for_each_possible_encoder(connector, encoder, i) { 432 drm_connector_for_each_possible_encoder(connector, encoder, i) {
432 nv_encoder = nouveau_encoder(encoder); 433 nv_encoder = nouveau_encoder(encoder);
433 434
434 if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { 435 switch (nv_encoder->dcb->type) {
435 int ret = nouveau_dp_detect(nv_encoder); 436 case DCB_OUTPUT_DP:
437 ret = nouveau_dp_detect(nv_encoder);
436 if (ret == NOUVEAU_DP_MST) 438 if (ret == NOUVEAU_DP_MST)
437 return NULL; 439 return NULL;
438 if (ret == NOUVEAU_DP_SST) 440 else if (ret == NOUVEAU_DP_SST)
439 break; 441 found = nv_encoder;
440 } else 442
441 if ((vga_switcheroo_handler_flags() & 443 break;
442 VGA_SWITCHEROO_CAN_SWITCH_DDC) && 444 case DCB_OUTPUT_LVDS:
443 nv_encoder->dcb->type == DCB_OUTPUT_LVDS && 445 switcheroo_ddc = !!(vga_switcheroo_handler_flags() &
444 nv_encoder->i2c) { 446 VGA_SWITCHEROO_CAN_SWITCH_DDC);
445 int ret; 447 /* fall-through */
446 vga_switcheroo_lock_ddc(dev->pdev); 448 default:
447 ret = nvkm_probe_i2c(nv_encoder->i2c, 0x50); 449 if (!nv_encoder->i2c)
448 vga_switcheroo_unlock_ddc(dev->pdev);
449 if (ret)
450 break; 450 break;
451 } else 451
452 if (nv_encoder->i2c) { 452 if (switcheroo_ddc)
453 vga_switcheroo_lock_ddc(dev->pdev);
453 if (nvkm_probe_i2c(nv_encoder->i2c, 0x50)) 454 if (nvkm_probe_i2c(nv_encoder->i2c, 0x50))
454 break; 455 found = nv_encoder;
456 if (switcheroo_ddc)
457 vga_switcheroo_unlock_ddc(dev->pdev);
458
459 break;
455 } 460 }
461 if (found)
462 break;
456 } 463 }
457 464
458 /* eDP panel not detected, restore panel power GPIO to previous 465 /* eDP panel not detected, restore panel power GPIO to previous
459 * state to avoid confusing the SOR for other output types. 466 * state to avoid confusing the SOR for other output types.
460 */ 467 */
461 if (!nv_encoder && panel == 0) 468 if (!found && panel == 0)
462 nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel); 469 nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
463 470
464 return nv_encoder; 471 return found;
465} 472}
466 473
467static struct nouveau_encoder * 474static struct nouveau_encoder *