aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-05-18 19:35:51 -0400
committerDave Airlie <airlied@redhat.com>2010-05-18 19:35:51 -0400
commit05ea893c46805b2981ea8ba6df881e3d65edd63b (patch)
treeea381e22d99f49bd2c95238f88491d48b797a17b /drivers/gpu/drm/i915/intel_sdvo.c
parent26481fb15644b5fd85d4cea020f74a234cdf6803 (diff)
parenta7c542782e92f9487c62a571565637be3d6b0ffd (diff)
Merge remote branch 'anholt/drm-intel-next' into drm-next
* anholt/drm-intel-next: (515 commits) drm/i915: Fix out of tree builds drm/i915: move fence lru to struct drm_i915_fence_reg drm/i915: don't allow tiling changes on pinned buffers v2 drm/i915: Be extra careful about A/D matching for multifunction SDVO drm/i915: Fix DDC bus selection for multifunction SDVO drm/i915: cleanup mode setting before unmapping registers drm/i915: Make fbc control wrapper functions drm/i915: Wait for the GPU whilst shrinking, if truly desperate. drm/i915: Use spatio-temporal dithering on PCH [MTD] Remove zero-length files mtdbdi.c and internal.ho pata_pcmcia / ide-cs: Fix bad hashes for Transcend and kingston IDs libata: Fix several inaccuracies in developer's guide slub: Fix bad boundary check in init_kmem_cache_nodes() raid6: fix recovery performance regression KEYS: call_sbin_request_key() must write lock keyrings before modifying them KEYS: Use RCU dereference wrappers in keyring key type code KEYS: find_keyring_by_name() can gain access to a freed keyring ALSA: hda: Fix 0 dB for Packard Bell models using Conexant CX20549 (Venice) ALSA: hda - Add quirk for Dell Inspiron 19T using a Conexant CX20582 ALSA: take tu->qlock with irqs disabled ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c86
1 files changed, 30 insertions, 56 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index ca372abc36c..aba72c489a2 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1504,16 +1504,17 @@ intel_analog_is_connected(struct drm_device *dev)
1504} 1504}
1505 1505
1506enum drm_connector_status 1506enum drm_connector_status
1507intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) 1507intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
1508{ 1508{
1509 struct drm_encoder *encoder = intel_attached_encoder(connector); 1509 struct drm_encoder *encoder = intel_attached_encoder(connector);
1510 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); 1510 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
1511 struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; 1511 struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
1512 struct intel_connector *intel_connector = to_intel_connector(connector);
1513 struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv;
1512 enum drm_connector_status status = connector_status_connected; 1514 enum drm_connector_status status = connector_status_connected;
1513 struct edid *edid = NULL; 1515 struct edid *edid = NULL;
1514 1516
1515 edid = drm_get_edid(connector, 1517 edid = drm_get_edid(connector, intel_encoder->ddc_bus);
1516 intel_encoder->ddc_bus);
1517 1518
1518 /* This is only applied to SDVO cards with multiple outputs */ 1519 /* This is only applied to SDVO cards with multiple outputs */
1519 if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { 1520 if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
@@ -1526,8 +1527,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
1526 */ 1527 */
1527 while(temp_ddc > 1) { 1528 while(temp_ddc > 1) {
1528 sdvo_priv->ddc_bus = temp_ddc; 1529 sdvo_priv->ddc_bus = temp_ddc;
1529 edid = drm_get_edid(connector, 1530 edid = drm_get_edid(connector, intel_encoder->ddc_bus);
1530 intel_encoder->ddc_bus);
1531 if (edid) { 1531 if (edid) {
1532 /* 1532 /*
1533 * When we can get the EDID, maybe it is the 1533 * When we can get the EDID, maybe it is the
@@ -1544,28 +1544,25 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
1544 /* when there is no edid and no monitor is connected with VGA 1544 /* when there is no edid and no monitor is connected with VGA
1545 * port, try to use the CRT ddc to read the EDID for DVI-connector 1545 * port, try to use the CRT ddc to read the EDID for DVI-connector
1546 */ 1546 */
1547 if (edid == NULL && 1547 if (edid == NULL && sdvo_priv->analog_ddc_bus &&
1548 sdvo_priv->analog_ddc_bus &&
1549 !intel_analog_is_connected(connector->dev)) 1548 !intel_analog_is_connected(connector->dev))
1550 edid = drm_get_edid(connector, 1549 edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus);
1551 sdvo_priv->analog_ddc_bus); 1550
1552 if (edid != NULL) { 1551 if (edid != NULL) {
1553 /* Don't report the output as connected if it's a DVI-I 1552 bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
1554 * connector with a non-digital EDID coming out. 1553 bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK);
1555 */
1556 if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
1557 if (edid->input & DRM_EDID_INPUT_DIGITAL)
1558 sdvo_priv->is_hdmi =
1559 drm_detect_hdmi_monitor(edid);
1560 else
1561 status = connector_status_disconnected;
1562 }
1563 1554
1564 kfree(edid); 1555 /* DDC bus is shared, match EDID to connector type */
1565 connector->display_info.raw_edid = NULL; 1556 if (is_digital && need_digital)
1557 sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
1558 else if (is_digital != need_digital)
1559 status = connector_status_disconnected;
1566 1560
1567 } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) 1561 connector->display_info.raw_edid = NULL;
1562 } else
1568 status = connector_status_disconnected; 1563 status = connector_status_disconnected;
1564
1565 kfree(edid);
1569 1566
1570 return status; 1567 return status;
1571} 1568}
@@ -1601,8 +1598,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
1601 1598
1602 if ((sdvo_connector->output_flag & response) == 0) 1599 if ((sdvo_connector->output_flag & response) == 0)
1603 ret = connector_status_disconnected; 1600 ret = connector_status_disconnected;
1604 else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) 1601 else if (response & SDVO_TMDS_MASK)
1605 ret = intel_sdvo_hdmi_sink_detect(connector, response); 1602 ret = intel_sdvo_hdmi_sink_detect(connector);
1606 else 1603 else
1607 ret = connector_status_connected; 1604 ret = connector_status_connected;
1608 1605
@@ -2054,40 +2051,17 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
2054 * outputs, then LVDS outputs. 2051 * outputs, then LVDS outputs.
2055 */ 2052 */
2056static void 2053static void
2057intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv) 2054intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv,
2055 struct intel_sdvo_priv *sdvo, u32 reg)
2058{ 2056{
2059 uint16_t mask = 0; 2057 struct sdvo_device_mapping *mapping;
2060 unsigned int num_bits;
2061 2058
2062 /* Make a mask of outputs less than or equal to our own priority in the 2059 if (IS_SDVOB(reg))
2063 * list. 2060 mapping = &(dev_priv->sdvo_mappings[0]);
2064 */ 2061 else
2065 switch (dev_priv->controlled_output) { 2062 mapping = &(dev_priv->sdvo_mappings[1]);
2066 case SDVO_OUTPUT_LVDS1:
2067 mask |= SDVO_OUTPUT_LVDS1;
2068 case SDVO_OUTPUT_LVDS0:
2069 mask |= SDVO_OUTPUT_LVDS0;
2070 case SDVO_OUTPUT_TMDS1:
2071 mask |= SDVO_OUTPUT_TMDS1;
2072 case SDVO_OUTPUT_TMDS0:
2073 mask |= SDVO_OUTPUT_TMDS0;
2074 case SDVO_OUTPUT_RGB1:
2075 mask |= SDVO_OUTPUT_RGB1;
2076 case SDVO_OUTPUT_RGB0:
2077 mask |= SDVO_OUTPUT_RGB0;
2078 break;
2079 }
2080
2081 /* Count bits to find what number we are in the priority list. */
2082 mask &= dev_priv->caps.output_flags;
2083 num_bits = hweight16(mask);
2084 if (num_bits > 3) {
2085 /* if more than 3 outputs, default to DDC bus 3 for now */
2086 num_bits = 3;
2087 }
2088 2063
2089 /* Corresponds to SDVO_CONTROL_BUS_DDCx */ 2064 sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4);
2090 dev_priv->ddc_bus = 1 << num_bits;
2091} 2065}
2092 2066
2093static bool 2067static bool
@@ -2866,7 +2840,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
2866 goto err_i2c; 2840 goto err_i2c;
2867 } 2841 }
2868 2842
2869 intel_sdvo_select_ddc_bus(sdvo_priv); 2843 intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg);
2870 2844
2871 /* Set the input timing to the screen. Assume always input 0. */ 2845 /* Set the input timing to the screen. Assume always input 0. */
2872 intel_sdvo_set_target_input(intel_encoder, true, false); 2846 intel_sdvo_set_target_input(intel_encoder, true, false);