diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 91 |
1 files changed, 87 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index de5144c8c153..82678d30ab06 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -462,14 +462,63 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
462 | } | 462 | } |
463 | 463 | ||
464 | /** | 464 | /** |
465 | * Don't check status code from this as it switches the bus back to the | 465 | * Try to read the response after issuie the DDC switch command. But it |
466 | * SDVO chips which defeats the purpose of doing a bus switch in the first | 466 | * is noted that we must do the action of reading response and issuing DDC |
467 | * place. | 467 | * switch command in one I2C transaction. Otherwise when we try to start |
468 | * another I2C transaction after issuing the DDC bus switch, it will be | ||
469 | * switched to the internal SDVO register. | ||
468 | */ | 470 | */ |
469 | static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, | 471 | static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, |
470 | u8 target) | 472 | u8 target) |
471 | { | 473 | { |
472 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1); | 474 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
475 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | ||
476 | struct i2c_msg msgs[] = { | ||
477 | { | ||
478 | .addr = sdvo_priv->slave_addr >> 1, | ||
479 | .flags = 0, | ||
480 | .len = 2, | ||
481 | .buf = out_buf, | ||
482 | }, | ||
483 | /* the following two are to read the response */ | ||
484 | { | ||
485 | .addr = sdvo_priv->slave_addr >> 1, | ||
486 | .flags = 0, | ||
487 | .len = 1, | ||
488 | .buf = cmd_buf, | ||
489 | }, | ||
490 | { | ||
491 | .addr = sdvo_priv->slave_addr >> 1, | ||
492 | .flags = I2C_M_RD, | ||
493 | .len = 1, | ||
494 | .buf = ret_value, | ||
495 | }, | ||
496 | }; | ||
497 | |||
498 | intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | ||
499 | &target, 1); | ||
500 | /* write the DDC switch command argument */ | ||
501 | intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target); | ||
502 | |||
503 | out_buf[0] = SDVO_I2C_OPCODE; | ||
504 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | ||
505 | cmd_buf[0] = SDVO_I2C_CMD_STATUS; | ||
506 | cmd_buf[1] = 0; | ||
507 | ret_value[0] = 0; | ||
508 | ret_value[1] = 0; | ||
509 | |||
510 | ret = i2c_transfer(intel_output->i2c_bus, msgs, 3); | ||
511 | if (ret != 3) { | ||
512 | /* failure in I2C transfer */ | ||
513 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | ||
514 | return; | ||
515 | } | ||
516 | if (ret_value[0] != SDVO_CMD_STATUS_SUCCESS) { | ||
517 | DRM_DEBUG_KMS("DDC switch command returns response %d\n", | ||
518 | ret_value[0]); | ||
519 | return; | ||
520 | } | ||
521 | return; | ||
473 | } | 522 | } |
474 | 523 | ||
475 | static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) | 524 | static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1) |
@@ -1579,6 +1628,32 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1579 | edid = drm_get_edid(&intel_output->base, | 1628 | edid = drm_get_edid(&intel_output->base, |
1580 | intel_output->ddc_bus); | 1629 | intel_output->ddc_bus); |
1581 | 1630 | ||
1631 | /* This is only applied to SDVO cards with multiple outputs */ | ||
1632 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) { | ||
1633 | uint8_t saved_ddc, temp_ddc; | ||
1634 | saved_ddc = sdvo_priv->ddc_bus; | ||
1635 | temp_ddc = sdvo_priv->ddc_bus >> 1; | ||
1636 | /* | ||
1637 | * Don't use the 1 as the argument of DDC bus switch to get | ||
1638 | * the EDID. It is used for SDVO SPD ROM. | ||
1639 | */ | ||
1640 | while(temp_ddc > 1) { | ||
1641 | sdvo_priv->ddc_bus = temp_ddc; | ||
1642 | edid = drm_get_edid(&intel_output->base, | ||
1643 | intel_output->ddc_bus); | ||
1644 | if (edid) { | ||
1645 | /* | ||
1646 | * When we can get the EDID, maybe it is the | ||
1647 | * correct DDC bus. Update it. | ||
1648 | */ | ||
1649 | sdvo_priv->ddc_bus = temp_ddc; | ||
1650 | break; | ||
1651 | } | ||
1652 | temp_ddc >>= 1; | ||
1653 | } | ||
1654 | if (edid == NULL) | ||
1655 | sdvo_priv->ddc_bus = saved_ddc; | ||
1656 | } | ||
1582 | /* when there is no edid and no monitor is connected with VGA | 1657 | /* when there is no edid and no monitor is connected with VGA |
1583 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1658 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
1584 | */ | 1659 | */ |
@@ -2270,6 +2345,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2270 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2345 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2271 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2346 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2272 | (1 << INTEL_ANALOG_CLONE_BIT); | 2347 | (1 << INTEL_ANALOG_CLONE_BIT); |
2348 | } else if (flags & SDVO_OUTPUT_CVBS0) { | ||
2349 | |||
2350 | sdvo_priv->controlled_output = SDVO_OUTPUT_CVBS0; | ||
2351 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
2352 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2353 | sdvo_priv->is_tv = true; | ||
2354 | intel_output->needs_tv_clock = true; | ||
2355 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2273 | } else if (flags & SDVO_OUTPUT_LVDS0) { | 2356 | } else if (flags & SDVO_OUTPUT_LVDS0) { |
2274 | 2357 | ||
2275 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | 2358 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; |