aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-07-20 18:44:45 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-18 10:46:19 -0400
commitf899fc64cda8569d0529452aafc0da31c042df2e (patch)
tree61b6d32abe3524b83abc9d8b9382e3f82225cd64 /drivers/gpu/drm/i915/intel_sdvo.c
parent373a3cf744c774478f44921c50011b896ab08f9d (diff)
drm/i915: use GMBUS to manage i2c links
Use the GMBUS interface rather than direct bit banging to grab the EDID over DDC (and for other forms of auxiliary communication with external display controllers). The hope is that this method will be much faster and more reliable than bit banging for fetching EDIDs from buggy monitors or through switches, though we still preserve the bit banging as a fallback in case GMBUS fails. Based on an original patch by Jesse Barnes. Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c163
1 files changed, 47 insertions, 116 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index f7030e481083..2b3b4754c97d 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -65,6 +65,7 @@ static const char *tv_format_names[] = {
65struct intel_sdvo { 65struct intel_sdvo {
66 struct intel_encoder base; 66 struct intel_encoder base;
67 67
68 struct i2c_adapter *i2c;
68 u8 slave_addr; 69 u8 slave_addr;
69 70
70 /* Register for the SDVO device: SDVOB or SDVOC */ 71 /* Register for the SDVO device: SDVOB or SDVOC */
@@ -264,7 +265,7 @@ static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch)
264 }; 265 };
265 int ret; 266 int ret;
266 267
267 if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) 268 if ((ret = i2c_transfer(intel_sdvo->i2c, msgs, 2)) == 2)
268 { 269 {
269 *ch = buf[0]; 270 *ch = buf[0];
270 return true; 271 return true;
@@ -286,7 +287,7 @@ static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch
286 } 287 }
287 }; 288 };
288 289
289 return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1; 290 return i2c_transfer(intel_sdvo->i2c, msgs, 1) == 1;
290} 291}
291 292
292#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} 293#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
@@ -566,7 +567,7 @@ static int intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo,
566 ret_value[0] = 0; 567 ret_value[0] = 0;
567 ret_value[1] = 0; 568 ret_value[1] = 0;
568 569
569 ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3); 570 ret = i2c_transfer(intel_sdvo->i2c, msgs, 3);
570 if (ret < 0) 571 if (ret < 0)
571 return ret; 572 return ret;
572 if (ret != 3) { 573 if (ret != 3) {
@@ -1375,6 +1376,19 @@ intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo)
1375 return (caps > 1); 1376 return (caps > 1);
1376} 1377}
1377 1378
1379static struct edid *
1380intel_sdvo_get_edid(struct drm_connector *connector, int ddc)
1381{
1382 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1383 int ret;
1384
1385 ret = intel_sdvo_set_control_bus_switch(intel_sdvo, ddc);
1386 if (ret)
1387 return NULL;
1388
1389 return drm_get_edid(connector, intel_sdvo->i2c);
1390}
1391
1378static struct drm_connector * 1392static struct drm_connector *
1379intel_find_analog_connector(struct drm_device *dev) 1393intel_find_analog_connector(struct drm_device *dev)
1380{ 1394{
@@ -1418,28 +1432,12 @@ intel_analog_is_connected(struct drm_device *dev)
1418static struct edid * 1432static struct edid *
1419intel_sdvo_get_analog_edid(struct drm_connector *connector) 1433intel_sdvo_get_analog_edid(struct drm_connector *connector)
1420{ 1434{
1421 struct intel_encoder *encoder = intel_attached_encoder(connector); 1435 struct drm_i915_private *dev_priv = connector->dev->dev_private;
1422 struct drm_device *dev = connector->dev;
1423 struct i2c_adapter *ddc;
1424 struct edid *edid;
1425 u32 ddc_reg;
1426
1427 if (!intel_analog_is_connected(dev))
1428 return NULL;
1429
1430 if (HAS_PCH_SPLIT(dev))
1431 ddc_reg = PCH_GPIOA;
1432 else
1433 ddc_reg = GPIOA;
1434 1436
1435 ddc = intel_i2c_create(encoder, ddc_reg, "SDVO/VGA DDC BUS"); 1437 if (!intel_analog_is_connected(connector->dev))
1436 if (ddc == NULL)
1437 return NULL; 1438 return NULL;
1438 1439
1439 edid = drm_get_edid(connector, ddc); 1440 return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
1440 intel_i2c_destroy(ddc);
1441
1442 return edid;
1443} 1441}
1444 1442
1445enum drm_connector_status 1443enum drm_connector_status
@@ -1449,28 +1447,26 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
1449 enum drm_connector_status status; 1447 enum drm_connector_status status;
1450 struct edid *edid; 1448 struct edid *edid;
1451 1449
1452 edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); 1450 edid = intel_sdvo_get_edid(connector, intel_sdvo->ddc_bus);
1453 1451
1454 if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { 1452 if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) {
1455 u8 saved_ddc = intel_sdvo->ddc_bus, ddc; 1453 u8 ddc;
1456 1454
1457 /* 1455 /*
1458 * Don't use the 1 as the argument of DDC bus switch to get 1456 * Don't use the 1 as the argument of DDC bus switch to get
1459 * the EDID. It is used for SDVO SPD ROM. 1457 * the EDID. It is used for SDVO SPD ROM.
1460 */ 1458 */
1461 for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) { 1459 for (ddc = intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) {
1462 intel_sdvo->ddc_bus = ddc; 1460 edid = intel_sdvo_get_edid(connector, ddc);
1463 edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); 1461 if (edid) {
1464 if (edid) 1462 /*
1463 * If we found the EDID on the other bus,
1464 * assume that is the correct DDC bus.
1465 */
1466 intel_sdvo->ddc_bus = ddc;
1465 break; 1467 break;
1468 }
1466 } 1469 }
1467
1468 /*
1469 * If we found the EDID on the other bus, maybe that is the
1470 * correct DDC bus.
1471 */
1472 if (edid == NULL)
1473 intel_sdvo->ddc_bus = saved_ddc;
1474 } 1470 }
1475 1471
1476 /* 1472 /*
@@ -1546,12 +1542,9 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
1546{ 1542{
1547 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); 1543 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1548 struct edid *edid; 1544 struct edid *edid;
1549 int num_modes;
1550 1545
1551 /* set the bus switch and get the modes */ 1546 /* set the bus switch and get the modes */
1552 num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); 1547 edid = intel_sdvo_get_edid(connector, intel_sdvo->ddc_bus);
1553 if (num_modes)
1554 return;
1555 1548
1556 /* 1549 /*
1557 * Mac mini hack. On this device, the DVI-I connector shares one DDC 1550 * Mac mini hack. On this device, the DVI-I connector shares one DDC
@@ -1559,7 +1552,9 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
1559 * DDC fails, check to see if the analog output is disconnected, in 1552 * DDC fails, check to see if the analog output is disconnected, in
1560 * which case we'll look there for the digital DDC data. 1553 * which case we'll look there for the digital DDC data.
1561 */ 1554 */
1562 edid = intel_sdvo_get_analog_edid(connector); 1555 if (edid == NULL)
1556 edid = intel_sdvo_get_analog_edid(connector);
1557
1563 if (edid != NULL) { 1558 if (edid != NULL) {
1564 drm_mode_connector_update_edid_property(connector, edid); 1559 drm_mode_connector_update_edid_property(connector, edid);
1565 drm_add_edid_modes(connector, edid); 1560 drm_add_edid_modes(connector, edid);
@@ -1678,7 +1673,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
1678 * Assume that the preferred modes are 1673 * Assume that the preferred modes are
1679 * arranged in priority order. 1674 * arranged in priority order.
1680 */ 1675 */
1681 intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); 1676 intel_ddc_get_modes(connector, intel_sdvo->i2c);
1682 if (list_empty(&connector->probed_modes) == false) 1677 if (list_empty(&connector->probed_modes) == false)
1683 goto end; 1678 goto end;
1684 1679
@@ -2004,30 +1999,6 @@ intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device)
2004 &intel_sdvo->is_hdmi, 1); 1999 &intel_sdvo->is_hdmi, 1);
2005} 2000}
2006 2001
2007static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
2008 struct i2c_msg msgs[], int num)
2009{
2010 struct intel_sdvo *intel_sdvo;
2011 const struct i2c_algorithm *algo;
2012 int ret;
2013
2014 intel_sdvo = container_of(i2c_adap->algo_data,
2015 struct intel_sdvo,
2016 base);
2017 algo = intel_sdvo->base.i2c_bus->algo;
2018
2019 ret = intel_sdvo_set_control_bus_switch(intel_sdvo,
2020 intel_sdvo->ddc_bus);
2021 if (ret)
2022 return ret;
2023
2024 return algo->master_xfer(i2c_adap, msgs, num);
2025}
2026
2027static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {
2028 .master_xfer = intel_sdvo_master_xfer,
2029};
2030
2031static u8 2002static u8
2032intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) 2003intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
2033{ 2004{
@@ -2540,9 +2511,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
2540 struct drm_i915_private *dev_priv = dev->dev_private; 2511 struct drm_i915_private *dev_priv = dev->dev_private;
2541 struct intel_encoder *intel_encoder; 2512 struct intel_encoder *intel_encoder;
2542 struct intel_sdvo *intel_sdvo; 2513 struct intel_sdvo *intel_sdvo;
2543 u8 ch[0x40];
2544 int i; 2514 int i;
2545 u32 i2c_reg, ddc_reg;
2546 2515
2547 intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); 2516 intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
2548 if (!intel_sdvo) 2517 if (!intel_sdvo)
@@ -2555,82 +2524,49 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
2555 /* encoder type will be decided later */ 2524 /* encoder type will be decided later */
2556 drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); 2525 drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0);
2557 2526
2558 if (HAS_PCH_SPLIT(dev)) { 2527 intel_sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter;
2559 i2c_reg = PCH_GPIOE;
2560 ddc_reg = PCH_GPIOE;
2561 } else {
2562 i2c_reg = GPIOE;
2563 ddc_reg = GPIOE;
2564 }
2565
2566 /* setup the DDC bus. */
2567 if (IS_SDVOB(sdvo_reg))
2568 intel_encoder->i2c_bus =
2569 intel_i2c_create(intel_encoder,
2570 i2c_reg, "SDVOCTRL_E for SDVOB");
2571 else
2572 intel_encoder->i2c_bus =
2573 intel_i2c_create(intel_encoder,
2574 i2c_reg, "SDVOCTRL_E for SDVOC");
2575
2576 if (!intel_encoder->i2c_bus)
2577 goto err_inteloutput;
2578 2528
2579 intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); 2529 intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
2580 2530
2581 /* Save the bit-banging i2c functionality for use by the DDC wrapper */
2582 intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
2583
2584 /* Read the regs to test if we can talk to the device */ 2531 /* Read the regs to test if we can talk to the device */
2585 for (i = 0; i < 0x40; i++) { 2532 for (i = 0; i < 0x40; i++) {
2586 if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) { 2533 u8 byte;
2534
2535 if (!intel_sdvo_read_byte(intel_sdvo, i, &byte)) {
2587 DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", 2536 DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
2588 IS_SDVOB(sdvo_reg) ? 'B' : 'C'); 2537 IS_SDVOB(sdvo_reg) ? 'B' : 'C');
2589 goto err_i2c; 2538 goto err;
2590 } 2539 }
2591 } 2540 }
2592 2541
2593 /* setup the DDC bus. */ 2542 if (IS_SDVOB(sdvo_reg))
2594 if (IS_SDVOB(sdvo_reg)) {
2595 intel_encoder->ddc_bus =
2596 intel_i2c_create(intel_encoder,
2597 ddc_reg, "SDVOB DDC BUS");
2598 dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; 2543 dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
2599 } else { 2544 else
2600 intel_encoder->ddc_bus =
2601 intel_i2c_create(intel_encoder,
2602 ddc_reg, "SDVOC DDC BUS");
2603 dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; 2545 dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
2604 }
2605 if (intel_encoder->ddc_bus == NULL)
2606 goto err_i2c;
2607
2608 /* Wrap with our custom algo which switches to DDC mode */
2609 intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
2610 2546
2611 drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); 2547 drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
2612 2548
2613 /* In default case sdvo lvds is false */ 2549 /* In default case sdvo lvds is false */
2614 if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) 2550 if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
2615 goto err_i2c; 2551 goto err;
2616 2552
2617 if (intel_sdvo_output_setup(intel_sdvo, 2553 if (intel_sdvo_output_setup(intel_sdvo,
2618 intel_sdvo->caps.output_flags) != true) { 2554 intel_sdvo->caps.output_flags) != true) {
2619 DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", 2555 DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
2620 IS_SDVOB(sdvo_reg) ? 'B' : 'C'); 2556 IS_SDVOB(sdvo_reg) ? 'B' : 'C');
2621 goto err_i2c; 2557 goto err;
2622 } 2558 }
2623 2559
2624 intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); 2560 intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);
2625 2561
2626 /* Set the input timing to the screen. Assume always input 0. */ 2562 /* Set the input timing to the screen. Assume always input 0. */
2627 if (!intel_sdvo_set_target_input(intel_sdvo)) 2563 if (!intel_sdvo_set_target_input(intel_sdvo))
2628 goto err_i2c; 2564 goto err;
2629 2565
2630 if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, 2566 if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo,
2631 &intel_sdvo->pixel_clock_min, 2567 &intel_sdvo->pixel_clock_min,
2632 &intel_sdvo->pixel_clock_max)) 2568 &intel_sdvo->pixel_clock_max))
2633 goto err_i2c; 2569 goto err;
2634 2570
2635 DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " 2571 DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
2636 "clock range %dMHz - %dMHz, " 2572 "clock range %dMHz - %dMHz, "
@@ -2650,12 +2586,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
2650 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); 2586 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
2651 return true; 2587 return true;
2652 2588
2653err_i2c: 2589err:
2654 if (intel_encoder->ddc_bus != NULL)
2655 intel_i2c_destroy(intel_encoder->ddc_bus);
2656 if (intel_encoder->i2c_bus != NULL)
2657 intel_i2c_destroy(intel_encoder->i2c_bus);
2658err_inteloutput:
2659 drm_encoder_cleanup(&intel_encoder->base); 2590 drm_encoder_cleanup(&intel_encoder->base);
2660 kfree(intel_sdvo); 2591 kfree(intel_sdvo);
2661 2592