aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2015-04-07 09:52:42 -0400
committerAlex Deucher <alexander.deucher@amd.com>2015-04-27 09:54:55 -0400
commit0f55db36d49d45b80eff0c0a2a498766016f458b (patch)
tree7604d53da685ea0e8a44e078bb01b714e1a9c728
parent362ff251390f3d1f8fe94666f4fc4e5876381114 (diff)
drm/radeon: only mark audio as connected if the monitor supports it (v3)
Otherwise the driver may try and send audio which may confuse the monitor. v2: set pin to NULL if no audio v3: avoid crash with analog encoders Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c8
2 files changed, 21 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index 2c17df978d61..8b82abb78df1 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -460,30 +460,33 @@ void radeon_audio_detect(struct drm_connector *connector,
460 if (!connector || !connector->encoder) 460 if (!connector || !connector->encoder)
461 return; 461 return;
462 462
463 if (!radeon_encoder_is_digital(connector->encoder))
464 return;
465
463 rdev = connector->encoder->dev->dev_private; 466 rdev = connector->encoder->dev->dev_private;
464 radeon_encoder = to_radeon_encoder(connector->encoder); 467 radeon_encoder = to_radeon_encoder(connector->encoder);
465 dig = radeon_encoder->enc_priv; 468 dig = radeon_encoder->enc_priv;
466 469
467 if (status == connector_status_connected) { 470 if (!dig->afmt)
468 struct radeon_connector *radeon_connector; 471 return;
469 int sink_type;
470
471 if (!drm_detect_monitor_audio(radeon_connector_edid(connector))) {
472 radeon_encoder->audio = NULL;
473 return;
474 }
475 472
476 radeon_connector = to_radeon_connector(connector); 473 if (status == connector_status_connected) {
477 sink_type = radeon_dp_getsinktype(radeon_connector); 474 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
478 475
479 if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && 476 if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort &&
480 sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) 477 radeon_dp_getsinktype(radeon_connector) ==
478 CONNECTOR_OBJECT_ID_DISPLAYPORT)
481 radeon_encoder->audio = rdev->audio.dp_funcs; 479 radeon_encoder->audio = rdev->audio.dp_funcs;
482 else 480 else
483 radeon_encoder->audio = rdev->audio.hdmi_funcs; 481 radeon_encoder->audio = rdev->audio.hdmi_funcs;
484 482
485 dig->afmt->pin = radeon_audio_get_pin(connector->encoder); 483 dig->afmt->pin = radeon_audio_get_pin(connector->encoder);
486 radeon_audio_enable(rdev, dig->afmt->pin, 0xf); 484 if (drm_detect_monitor_audio(radeon_connector_edid(connector))) {
485 radeon_audio_enable(rdev, dig->afmt->pin, 0xf);
486 } else {
487 radeon_audio_enable(rdev, dig->afmt->pin, 0);
488 dig->afmt->pin = NULL;
489 }
487 } else { 490 } else {
488 radeon_audio_enable(rdev, dig->afmt->pin, 0); 491 radeon_audio_enable(rdev, dig->afmt->pin, 0);
489 dig->afmt->pin = NULL; 492 dig->afmt->pin = NULL;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index cebb65e07e1d..d17d251dbd4f 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1379,8 +1379,10 @@ out:
1379 /* updated in get modes as well since we need to know if it's analog or digital */ 1379 /* updated in get modes as well since we need to know if it's analog or digital */
1380 radeon_connector_update_scratch_regs(connector, ret); 1380 radeon_connector_update_scratch_regs(connector, ret);
1381 1381
1382 if (radeon_audio != 0) 1382 if (radeon_audio != 0) {
1383 radeon_connector_get_edid(connector);
1383 radeon_audio_detect(connector, ret); 1384 radeon_audio_detect(connector, ret);
1385 }
1384 1386
1385exit: 1387exit:
1386 pm_runtime_mark_last_busy(connector->dev->dev); 1388 pm_runtime_mark_last_busy(connector->dev->dev);
@@ -1717,8 +1719,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
1717 1719
1718 radeon_connector_update_scratch_regs(connector, ret); 1720 radeon_connector_update_scratch_regs(connector, ret);
1719 1721
1720 if (radeon_audio != 0) 1722 if (radeon_audio != 0) {
1723 radeon_connector_get_edid(connector);
1721 radeon_audio_detect(connector, ret); 1724 radeon_audio_detect(connector, ret);
1725 }
1722 1726
1723out: 1727out:
1724 pm_runtime_mark_last_busy(connector->dev->dev); 1728 pm_runtime_mark_last_busy(connector->dev->dev);