aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c74
1 files changed, 69 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 42cd528286a5..891f4f1d63b1 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -48,6 +48,7 @@ struct intel_dp {
48 uint32_t DP; 48 uint32_t DP;
49 uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; 49 uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE];
50 bool has_audio; 50 bool has_audio;
51 int force_audio;
51 int dpms_mode; 52 int dpms_mode;
52 uint8_t link_bw; 53 uint8_t link_bw;
53 uint8_t lane_count; 54 uint8_t lane_count;
@@ -57,6 +58,8 @@ struct intel_dp {
57 bool is_pch_edp; 58 bool is_pch_edp;
58 uint8_t train_set[4]; 59 uint8_t train_set[4];
59 uint8_t link_status[DP_LINK_STATUS_SIZE]; 60 uint8_t link_status[DP_LINK_STATUS_SIZE];
61
62 struct drm_property *force_audio_property;
60}; 63};
61 64
62/** 65/**
@@ -1540,11 +1543,15 @@ intel_dp_detect(struct drm_connector *connector, bool force)
1540 if (status != connector_status_connected) 1543 if (status != connector_status_connected)
1541 return status; 1544 return status;
1542 1545
1543 edid = drm_get_edid(connector, &intel_dp->adapter); 1546 if (intel_dp->force_audio) {
1544 if (edid) { 1547 intel_dp->has_audio = intel_dp->force_audio > 0;
1545 intel_dp->has_audio = drm_detect_monitor_audio(edid); 1548 } else {
1546 connector->display_info.raw_edid = NULL; 1549 edid = drm_get_edid(connector, &intel_dp->adapter);
1547 kfree(edid); 1550 if (edid) {
1551 intel_dp->has_audio = drm_detect_monitor_audio(edid);
1552 connector->display_info.raw_edid = NULL;
1553 kfree(edid);
1554 }
1548 } 1555 }
1549 1556
1550 return connector_status_connected; 1557 return connector_status_connected;
@@ -1589,6 +1596,46 @@ static int intel_dp_get_modes(struct drm_connector *connector)
1589 return 0; 1596 return 0;
1590} 1597}
1591 1598
1599static int
1600intel_dp_set_property(struct drm_connector *connector,
1601 struct drm_property *property,
1602 uint64_t val)
1603{
1604 struct intel_dp *intel_dp = intel_attached_dp(connector);
1605 int ret;
1606
1607 ret = drm_connector_property_set_value(connector, property, val);
1608 if (ret)
1609 return ret;
1610
1611 if (property == intel_dp->force_audio_property) {
1612 if (val == intel_dp->force_audio)
1613 return 0;
1614
1615 intel_dp->force_audio = val;
1616
1617 if (val > 0 && intel_dp->has_audio)
1618 return 0;
1619 if (val < 0 && !intel_dp->has_audio)
1620 return 0;
1621
1622 intel_dp->has_audio = val > 0;
1623 goto done;
1624 }
1625
1626 return -EINVAL;
1627
1628done:
1629 if (intel_dp->base.base.crtc) {
1630 struct drm_crtc *crtc = intel_dp->base.base.crtc;
1631 drm_crtc_helper_set_mode(crtc, &crtc->mode,
1632 crtc->x, crtc->y,
1633 crtc->fb);
1634 }
1635
1636 return 0;
1637}
1638
1592static void 1639static void
1593intel_dp_destroy (struct drm_connector *connector) 1640intel_dp_destroy (struct drm_connector *connector)
1594{ 1641{
@@ -1618,6 +1665,7 @@ static const struct drm_connector_funcs intel_dp_connector_funcs = {
1618 .dpms = drm_helper_connector_dpms, 1665 .dpms = drm_helper_connector_dpms,
1619 .detect = intel_dp_detect, 1666 .detect = intel_dp_detect,
1620 .fill_modes = drm_helper_probe_single_connector_modes, 1667 .fill_modes = drm_helper_probe_single_connector_modes,
1668 .set_property = intel_dp_set_property,
1621 .destroy = intel_dp_destroy, 1669 .destroy = intel_dp_destroy,
1622}; 1670};
1623 1671
@@ -1682,6 +1730,20 @@ bool intel_dpd_is_edp(struct drm_device *dev)
1682 return false; 1730 return false;
1683} 1731}
1684 1732
1733static void
1734intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector)
1735{
1736 struct drm_device *dev = connector->dev;
1737
1738 intel_dp->force_audio_property =
1739 drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
1740 if (intel_dp->force_audio_property) {
1741 intel_dp->force_audio_property->values[0] = -1;
1742 intel_dp->force_audio_property->values[1] = 1;
1743 drm_connector_attach_property(connector, intel_dp->force_audio_property, 0);
1744 }
1745}
1746
1685void 1747void
1686intel_dp_init(struct drm_device *dev, int output_reg) 1748intel_dp_init(struct drm_device *dev, int output_reg)
1687{ 1749{
@@ -1808,6 +1870,8 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1808 } 1870 }
1809 } 1871 }
1810 1872
1873 intel_dp_add_properties(intel_dp, connector);
1874
1811 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written 1875 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
1812 * 0xd. Failure to do so will result in spurious interrupts being 1876 * 0xd. Failure to do so will result in spurious interrupts being
1813 * generated on the port when a cable is not attached. 1877 * generated on the port when a cable is not attached.