aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c96
1 files changed, 74 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index cabe32df7cd5..c585da8d6627 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -127,6 +127,9 @@ struct intel_sdvo_priv {
127 /* DDC bus used by this SDVO output */ 127 /* DDC bus used by this SDVO output */
128 uint8_t ddc_bus; 128 uint8_t ddc_bus;
129 129
130 /* Mac mini hack -- use the same DDC as the analog connector */
131 struct i2c_adapter *analog_ddc_bus;
132
130 int save_sdvo_mult; 133 int save_sdvo_mult;
131 u16 save_active_outputs; 134 u16 save_active_outputs;
132 struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; 135 struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
@@ -1496,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
1496 return (caps > 1); 1499 return (caps > 1);
1497} 1500}
1498 1501
1502static struct drm_connector *
1503intel_find_analog_connector(struct drm_device *dev)
1504{
1505 struct drm_connector *connector;
1506 struct intel_output *intel_output;
1507
1508 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1509 intel_output = to_intel_output(connector);
1510 if (intel_output->type == INTEL_OUTPUT_ANALOG)
1511 return connector;
1512 }
1513 return NULL;
1514}
1515
1516static int
1517intel_analog_is_connected(struct drm_device *dev)
1518{
1519 struct drm_connector *analog_connector;
1520 analog_connector = intel_find_analog_connector(dev);
1521
1522 if (!analog_connector)
1523 return false;
1524
1525 if (analog_connector->funcs->detect(analog_connector) ==
1526 connector_status_disconnected)
1527 return false;
1528
1529 return true;
1530}
1531
1499enum drm_connector_status 1532enum drm_connector_status
1500intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) 1533intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
1501{ 1534{
@@ -1506,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
1506 1539
1507 edid = drm_get_edid(&intel_output->base, 1540 edid = drm_get_edid(&intel_output->base,
1508 intel_output->ddc_bus); 1541 intel_output->ddc_bus);
1542
1543 /* when there is no edid and no monitor is connected with VGA
1544 * port, try to use the CRT ddc to read the EDID for DVI-connector
1545 */
1546 if (edid == NULL &&
1547 sdvo_priv->analog_ddc_bus &&
1548 !intel_analog_is_connected(intel_output->base.dev))
1549 edid = drm_get_edid(&intel_output->base,
1550 sdvo_priv->analog_ddc_bus);
1509 if (edid != NULL) { 1551 if (edid != NULL) {
1510 /* Don't report the output as connected if it's a DVI-I 1552 /* Don't report the output as connected if it's a DVI-I
1511 * connector with a non-digital EDID coming out. 1553 * connector with a non-digital EDID coming out.
@@ -1559,31 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
1559static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) 1601static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
1560{ 1602{
1561 struct intel_output *intel_output = to_intel_output(connector); 1603 struct intel_output *intel_output = to_intel_output(connector);
1604 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
1605 int num_modes;
1562 1606
1563 /* set the bus switch and get the modes */ 1607 /* set the bus switch and get the modes */
1564 intel_ddc_get_modes(intel_output); 1608 num_modes = intel_ddc_get_modes(intel_output);
1565 1609
1566#if 0 1610 /*
1567 struct drm_device *dev = encoder->dev; 1611 * Mac mini hack. On this device, the DVI-I connector shares one DDC
1568 struct drm_i915_private *dev_priv = dev->dev_private; 1612 * link between analog and digital outputs. So, if the regular SDVO
1569 /* Mac mini hack. On this device, I get DDC through the analog, which 1613 * DDC fails, check to see if the analog output is disconnected, in
1570 * load-detects as disconnected. I fail to DDC through the SDVO DDC, 1614 * which case we'll look there for the digital DDC data.
1571 * but it does load-detect as connected. So, just steal the DDC bits
1572 * from analog when we fail at finding it the right way.
1573 */ 1615 */
1574 crt = xf86_config->output[0]; 1616 if (num_modes == 0 &&
1575 intel_output = crt->driver_private; 1617 sdvo_priv->analog_ddc_bus &&
1576 if (intel_output->type == I830_OUTPUT_ANALOG && 1618 !intel_analog_is_connected(intel_output->base.dev)) {
1577 crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { 1619 struct i2c_adapter *digital_ddc_bus;
1578 I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); 1620
1579 edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); 1621 /* Switch to the analog ddc bus and try that
1580 xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true); 1622 */
1581 } 1623 digital_ddc_bus = intel_output->ddc_bus;
1582 if (edid_mon) { 1624 intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
1583 xf86OutputSetEDID(output, edid_mon); 1625
1584 modes = xf86OutputGetEDIDModes(output); 1626 (void) intel_ddc_get_modes(intel_output);
1627
1628 intel_output->ddc_bus = digital_ddc_bus;
1585 } 1629 }
1586#endif
1587} 1630}
1588 1631
1589/* 1632/*
@@ -1758,6 +1801,8 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
1758 intel_i2c_destroy(intel_output->i2c_bus); 1801 intel_i2c_destroy(intel_output->i2c_bus);
1759 if (intel_output->ddc_bus) 1802 if (intel_output->ddc_bus)
1760 intel_i2c_destroy(intel_output->ddc_bus); 1803 intel_i2c_destroy(intel_output->ddc_bus);
1804 if (sdvo_priv->analog_ddc_bus)
1805 intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
1761 1806
1762 if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) 1807 if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
1763 drm_mode_destroy(connector->dev, 1808 drm_mode_destroy(connector->dev,
@@ -2177,10 +2222,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
2177 } 2222 }
2178 2223
2179 /* setup the DDC bus. */ 2224 /* setup the DDC bus. */
2180 if (output_device == SDVOB) 2225 if (output_device == SDVOB) {
2181 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); 2226 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
2182 else 2227 sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
2228 "SDVOB/VGA DDC BUS");
2229 } else {
2183 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); 2230 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
2231 sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
2232 "SDVOC/VGA DDC BUS");
2233 }
2184 2234
2185 if (intel_output->ddc_bus == NULL) 2235 if (intel_output->ddc_bus == NULL)
2186 goto err_i2c; 2236 goto err_i2c;
@@ -2248,6 +2298,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
2248 return true; 2298 return true;
2249 2299
2250err_i2c: 2300err_i2c:
2301 if (sdvo_priv->analog_ddc_bus != NULL)
2302 intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
2251 if (intel_output->ddc_bus != NULL) 2303 if (intel_output->ddc_bus != NULL)
2252 intel_i2c_destroy(intel_output->ddc_bus); 2304 intel_i2c_destroy(intel_output->ddc_bus);
2253 if (intel_output->i2c_bus != NULL) 2305 if (intel_output->i2c_bus != NULL)