diff options
author | Zhenyu Wang <zhenyuw@linux.intel.com> | 2010-09-19 01:09:06 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-10-19 04:17:41 -0400 |
commit | a9756bb5b25d5d997df0c5d8c95db01292191bea (patch) | |
tree | c1d27fcd8a006cef31f40b71b01ed9e11168d938 /drivers/gpu | |
parent | 8fe9790d1652e7c306c862ea102a5e6126b412e1 (diff) |
drm/i915: Enable DisplayPort audio
This will turn on DP audio output by checking monitor's audio
capability.
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
[ickle: rebase onto recent changes and rearranged for clarity]
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 350c541e8e6c..42cd528286a5 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1458,9 +1458,8 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | static enum drm_connector_status | 1460 | static enum drm_connector_status |
1461 | ironlake_dp_detect(struct drm_connector *connector) | 1461 | ironlake_dp_detect(struct intel_dp *intel_dp) |
1462 | { | 1462 | { |
1463 | struct intel_dp *intel_dp = intel_attached_dp(connector); | ||
1464 | enum drm_connector_status status; | 1463 | enum drm_connector_status status; |
1465 | 1464 | ||
1466 | /* Can't disconnect eDP */ | 1465 | /* Can't disconnect eDP */ |
@@ -1470,8 +1469,8 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1470 | status = connector_status_disconnected; | 1469 | status = connector_status_disconnected; |
1471 | if (intel_dp_aux_native_read(intel_dp, | 1470 | if (intel_dp_aux_native_read(intel_dp, |
1472 | 0x000, intel_dp->dpcd, | 1471 | 0x000, intel_dp->dpcd, |
1473 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | 1472 | sizeof (intel_dp->dpcd)) |
1474 | { | 1473 | == sizeof(intel_dp->dpcd)) { |
1475 | if (intel_dp->dpcd[0] != 0) | 1474 | if (intel_dp->dpcd[0] != 0) |
1476 | status = connector_status_connected; | 1475 | status = connector_status_connected; |
1477 | } | 1476 | } |
@@ -1480,25 +1479,13 @@ ironlake_dp_detect(struct drm_connector *connector) | |||
1480 | return status; | 1479 | return status; |
1481 | } | 1480 | } |
1482 | 1481 | ||
1483 | /** | ||
1484 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. | ||
1485 | * | ||
1486 | * \return true if DP port is connected. | ||
1487 | * \return false if DP port is disconnected. | ||
1488 | */ | ||
1489 | static enum drm_connector_status | 1482 | static enum drm_connector_status |
1490 | intel_dp_detect(struct drm_connector *connector, bool force) | 1483 | g4x_dp_detect(struct intel_dp *intel_dp) |
1491 | { | 1484 | { |
1492 | struct intel_dp *intel_dp = intel_attached_dp(connector); | ||
1493 | struct drm_device *dev = intel_dp->base.base.dev; | 1485 | struct drm_device *dev = intel_dp->base.base.dev; |
1494 | struct drm_i915_private *dev_priv = dev->dev_private; | 1486 | struct drm_i915_private *dev_priv = dev->dev_private; |
1495 | uint32_t temp, bit; | ||
1496 | enum drm_connector_status status; | 1487 | enum drm_connector_status status; |
1497 | 1488 | uint32_t temp, bit; | |
1498 | intel_dp->has_audio = false; | ||
1499 | |||
1500 | if (HAS_PCH_SPLIT(dev)) | ||
1501 | return ironlake_dp_detect(connector); | ||
1502 | 1489 | ||
1503 | switch (intel_dp->output_reg) { | 1490 | switch (intel_dp->output_reg) { |
1504 | case DP_B: | 1491 | case DP_B: |
@@ -1520,14 +1507,47 @@ intel_dp_detect(struct drm_connector *connector, bool force) | |||
1520 | return connector_status_disconnected; | 1507 | return connector_status_disconnected; |
1521 | 1508 | ||
1522 | status = connector_status_disconnected; | 1509 | status = connector_status_disconnected; |
1523 | if (intel_dp_aux_native_read(intel_dp, | 1510 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, |
1524 | 0x000, intel_dp->dpcd, | ||
1525 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | 1511 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1526 | { | 1512 | { |
1527 | if (intel_dp->dpcd[0] != 0) | 1513 | if (intel_dp->dpcd[0] != 0) |
1528 | status = connector_status_connected; | 1514 | status = connector_status_connected; |
1529 | } | 1515 | } |
1530 | return status; | 1516 | |
1517 | return bit; | ||
1518 | } | ||
1519 | |||
1520 | /** | ||
1521 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. | ||
1522 | * | ||
1523 | * \return true if DP port is connected. | ||
1524 | * \return false if DP port is disconnected. | ||
1525 | */ | ||
1526 | static enum drm_connector_status | ||
1527 | intel_dp_detect(struct drm_connector *connector, bool force) | ||
1528 | { | ||
1529 | struct intel_dp *intel_dp = intel_attached_dp(connector); | ||
1530 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1531 | enum drm_connector_status status; | ||
1532 | struct edid *edid = NULL; | ||
1533 | |||
1534 | intel_dp->has_audio = false; | ||
1535 | |||
1536 | if (HAS_PCH_SPLIT(dev)) | ||
1537 | status = ironlake_dp_detect(intel_dp); | ||
1538 | else | ||
1539 | status = g4x_dp_detect(intel_dp); | ||
1540 | if (status != connector_status_connected) | ||
1541 | return status; | ||
1542 | |||
1543 | edid = drm_get_edid(connector, &intel_dp->adapter); | ||
1544 | if (edid) { | ||
1545 | intel_dp->has_audio = drm_detect_monitor_audio(edid); | ||
1546 | connector->display_info.raw_edid = NULL; | ||
1547 | kfree(edid); | ||
1548 | } | ||
1549 | |||
1550 | return connector_status_connected; | ||
1531 | } | 1551 | } |
1532 | 1552 | ||
1533 | static int intel_dp_get_modes(struct drm_connector *connector) | 1553 | static int intel_dp_get_modes(struct drm_connector *connector) |