diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 368 |
1 files changed, 274 insertions, 94 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f03473779feb..5371d9332554 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "drm.h" | 31 | #include "drm.h" |
32 | #include "drm_crtc.h" | 32 | #include "drm_crtc.h" |
33 | #include "intel_drv.h" | 33 | #include "intel_drv.h" |
34 | #include "drm_edid.h" | ||
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 36 | #include "i915_drv.h" |
36 | #include "intel_sdvo_regs.h" | 37 | #include "intel_sdvo_regs.h" |
@@ -55,6 +56,12 @@ struct intel_sdvo_priv { | |||
55 | /* Pixel clock limitations reported by the SDVO device, in kHz */ | 56 | /* Pixel clock limitations reported by the SDVO device, in kHz */ |
56 | int pixel_clock_min, pixel_clock_max; | 57 | int pixel_clock_min, pixel_clock_max; |
57 | 58 | ||
59 | /* | ||
60 | * For multiple function SDVO device, | ||
61 | * this is for current attached outputs. | ||
62 | */ | ||
63 | uint16_t attached_output; | ||
64 | |||
58 | /** | 65 | /** |
59 | * This is set if we're going to treat the device as TV-out. | 66 | * This is set if we're going to treat the device as TV-out. |
60 | * | 67 | * |
@@ -68,12 +75,23 @@ struct intel_sdvo_priv { | |||
68 | * This is set if we treat the device as HDMI, instead of DVI. | 75 | * This is set if we treat the device as HDMI, instead of DVI. |
69 | */ | 76 | */ |
70 | bool is_hdmi; | 77 | bool is_hdmi; |
78 | |||
71 | /** | 79 | /** |
72 | * This is set if we detect output of sdvo device as LVDS. | 80 | * This is set if we detect output of sdvo device as LVDS. |
73 | */ | 81 | */ |
74 | bool is_lvds; | 82 | bool is_lvds; |
75 | 83 | ||
76 | /** | 84 | /** |
85 | * This is sdvo flags for input timing. | ||
86 | */ | ||
87 | uint8_t sdvo_flags; | ||
88 | |||
89 | /** | ||
90 | * This is sdvo fixed pannel mode pointer | ||
91 | */ | ||
92 | struct drm_display_mode *sdvo_lvds_fixed_mode; | ||
93 | |||
94 | /** | ||
77 | * Returned SDTV resolutions allowed for the current format, if the | 95 | * Returned SDTV resolutions allowed for the current format, if the |
78 | * device reported it. | 96 | * device reported it. |
79 | */ | 97 | */ |
@@ -103,6 +121,9 @@ struct intel_sdvo_priv { | |||
103 | u32 save_SDVOX; | 121 | u32 save_SDVOX; |
104 | }; | 122 | }; |
105 | 123 | ||
124 | static bool | ||
125 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags); | ||
126 | |||
106 | /** | 127 | /** |
107 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 128 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
108 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 129 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
@@ -592,6 +613,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
592 | uint16_t height) | 613 | uint16_t height) |
593 | { | 614 | { |
594 | struct intel_sdvo_preferred_input_timing_args args; | 615 | struct intel_sdvo_preferred_input_timing_args args; |
616 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | ||
595 | uint8_t status; | 617 | uint8_t status; |
596 | 618 | ||
597 | memset(&args, 0, sizeof(args)); | 619 | memset(&args, 0, sizeof(args)); |
@@ -599,7 +621,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
599 | args.width = width; | 621 | args.width = width; |
600 | args.height = height; | 622 | args.height = height; |
601 | args.interlace = 0; | 623 | args.interlace = 0; |
602 | args.scaled = 0; | 624 | |
625 | if (sdvo_priv->is_lvds && | ||
626 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | ||
627 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | ||
628 | args.scaled = 1; | ||
629 | |||
603 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 630 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
604 | &args, sizeof(args)); | 631 | &args, sizeof(args)); |
605 | status = intel_sdvo_read_response(output, NULL, 0); | 632 | status = intel_sdvo_read_response(output, NULL, 0); |
@@ -944,12 +971,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
944 | struct intel_output *output = enc_to_intel_output(encoder); | 971 | struct intel_output *output = enc_to_intel_output(encoder); |
945 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | 972 | struct intel_sdvo_priv *dev_priv = output->dev_priv; |
946 | 973 | ||
947 | if (!dev_priv->is_tv) { | 974 | if (dev_priv->is_tv) { |
948 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
949 | * SDVO device will be told of the multiplier during mode_set. | ||
950 | */ | ||
951 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
952 | } else { | ||
953 | struct intel_sdvo_dtd output_dtd; | 975 | struct intel_sdvo_dtd output_dtd; |
954 | bool success; | 976 | bool success; |
955 | 977 | ||
@@ -980,6 +1002,47 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
980 | intel_sdvo_get_preferred_input_timing(output, | 1002 | intel_sdvo_get_preferred_input_timing(output, |
981 | &input_dtd); | 1003 | &input_dtd); |
982 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1004 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1005 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1006 | |||
1007 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
1008 | |||
1009 | mode->clock = adjusted_mode->clock; | ||
1010 | |||
1011 | adjusted_mode->clock *= | ||
1012 | intel_sdvo_get_pixel_multiplier(mode); | ||
1013 | } else { | ||
1014 | return false; | ||
1015 | } | ||
1016 | } else if (dev_priv->is_lvds) { | ||
1017 | struct intel_sdvo_dtd output_dtd; | ||
1018 | bool success; | ||
1019 | |||
1020 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1021 | /* Set output timings */ | ||
1022 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1023 | dev_priv->sdvo_lvds_fixed_mode); | ||
1024 | |||
1025 | intel_sdvo_set_target_output(output, | ||
1026 | dev_priv->controlled_output); | ||
1027 | intel_sdvo_set_output_timing(output, &output_dtd); | ||
1028 | |||
1029 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1030 | intel_sdvo_set_target_input(output, true, false); | ||
1031 | |||
1032 | |||
1033 | success = intel_sdvo_create_preferred_input_timing( | ||
1034 | output, | ||
1035 | mode->clock / 10, | ||
1036 | mode->hdisplay, | ||
1037 | mode->vdisplay); | ||
1038 | |||
1039 | if (success) { | ||
1040 | struct intel_sdvo_dtd input_dtd; | ||
1041 | |||
1042 | intel_sdvo_get_preferred_input_timing(output, | ||
1043 | &input_dtd); | ||
1044 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1045 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
983 | 1046 | ||
984 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1047 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
985 | 1048 | ||
@@ -990,6 +1053,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
990 | } else { | 1053 | } else { |
991 | return false; | 1054 | return false; |
992 | } | 1055 | } |
1056 | |||
1057 | } else { | ||
1058 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1059 | * SDVO device will be told of the multiplier during mode_set. | ||
1060 | */ | ||
1061 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
993 | } | 1062 | } |
994 | return true; | 1063 | return true; |
995 | } | 1064 | } |
@@ -1033,15 +1102,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1033 | 1102 | ||
1034 | /* We have tried to get input timing in mode_fixup, and filled into | 1103 | /* We have tried to get input timing in mode_fixup, and filled into |
1035 | adjusted_mode */ | 1104 | adjusted_mode */ |
1036 | if (sdvo_priv->is_tv) | 1105 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { |
1037 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1106 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1038 | else | 1107 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; |
1108 | } else | ||
1039 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1109 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
1040 | 1110 | ||
1041 | /* If it's a TV, we already set the output timing in mode_fixup. | 1111 | /* If it's a TV, we already set the output timing in mode_fixup. |
1042 | * Otherwise, the output timing is equal to the input timing. | 1112 | * Otherwise, the output timing is equal to the input timing. |
1043 | */ | 1113 | */ |
1044 | if (!sdvo_priv->is_tv) { | 1114 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1045 | /* Set the output timing to the screen */ | 1115 | /* Set the output timing to the screen */ |
1046 | intel_sdvo_set_target_output(output, | 1116 | intel_sdvo_set_target_output(output, |
1047 | sdvo_priv->controlled_output); | 1117 | sdvo_priv->controlled_output); |
@@ -1116,6 +1186,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1116 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1186 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1117 | } | 1187 | } |
1118 | 1188 | ||
1189 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | ||
1190 | sdvox |= SDVO_STALL_SELECT; | ||
1119 | intel_sdvo_write_sdvox(output, sdvox); | 1191 | intel_sdvo_write_sdvox(output, sdvox); |
1120 | } | 1192 | } |
1121 | 1193 | ||
@@ -1276,6 +1348,17 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1276 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1348 | if (sdvo_priv->pixel_clock_max < mode->clock) |
1277 | return MODE_CLOCK_HIGH; | 1349 | return MODE_CLOCK_HIGH; |
1278 | 1350 | ||
1351 | if (sdvo_priv->is_lvds == true) { | ||
1352 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | ||
1353 | return MODE_PANEL; | ||
1354 | |||
1355 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | ||
1356 | return MODE_PANEL; | ||
1357 | |||
1358 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1359 | return MODE_PANEL; | ||
1360 | } | ||
1361 | |||
1279 | return MODE_OK; | 1362 | return MODE_OK; |
1280 | } | 1363 | } |
1281 | 1364 | ||
@@ -1362,41 +1445,96 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | |||
1362 | intel_sdvo_read_response(intel_output, &response, 2); | 1445 | intel_sdvo_read_response(intel_output, &response, 2); |
1363 | } | 1446 | } |
1364 | 1447 | ||
1365 | static void | 1448 | static bool |
1366 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1449 | intel_sdvo_multifunc_encoder(struct intel_output *intel_output) |
1450 | { | ||
1451 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1452 | int caps = 0; | ||
1453 | |||
1454 | if (sdvo_priv->caps.output_flags & | ||
1455 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | ||
1456 | caps++; | ||
1457 | if (sdvo_priv->caps.output_flags & | ||
1458 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | ||
1459 | caps++; | ||
1460 | if (sdvo_priv->caps.output_flags & | ||
1461 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0)) | ||
1462 | caps++; | ||
1463 | if (sdvo_priv->caps.output_flags & | ||
1464 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | ||
1465 | caps++; | ||
1466 | if (sdvo_priv->caps.output_flags & | ||
1467 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) | ||
1468 | caps++; | ||
1469 | |||
1470 | if (sdvo_priv->caps.output_flags & | ||
1471 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) | ||
1472 | caps++; | ||
1473 | |||
1474 | if (sdvo_priv->caps.output_flags & | ||
1475 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) | ||
1476 | caps++; | ||
1477 | |||
1478 | return (caps > 1); | ||
1479 | } | ||
1480 | |||
1481 | enum drm_connector_status | ||
1482 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | ||
1367 | { | 1483 | { |
1368 | struct intel_output *intel_output = to_intel_output(connector); | 1484 | struct intel_output *intel_output = to_intel_output(connector); |
1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1485 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1486 | enum drm_connector_status status = connector_status_connected; | ||
1370 | struct edid *edid = NULL; | 1487 | struct edid *edid = NULL; |
1371 | 1488 | ||
1372 | edid = drm_get_edid(&intel_output->base, | 1489 | edid = drm_get_edid(&intel_output->base, |
1373 | intel_output->ddc_bus); | 1490 | intel_output->ddc_bus); |
1374 | if (edid != NULL) { | 1491 | if (edid != NULL) { |
1375 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1492 | /* Don't report the output as connected if it's a DVI-I |
1493 | * connector with a non-digital EDID coming out. | ||
1494 | */ | ||
1495 | if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1496 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
1497 | sdvo_priv->is_hdmi = | ||
1498 | drm_detect_hdmi_monitor(edid); | ||
1499 | else | ||
1500 | status = connector_status_disconnected; | ||
1501 | } | ||
1502 | |||
1376 | kfree(edid); | 1503 | kfree(edid); |
1377 | intel_output->base.display_info.raw_edid = NULL; | 1504 | intel_output->base.display_info.raw_edid = NULL; |
1378 | } | 1505 | |
1506 | } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | ||
1507 | status = connector_status_disconnected; | ||
1508 | |||
1509 | return status; | ||
1379 | } | 1510 | } |
1380 | 1511 | ||
1381 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1512 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1382 | { | 1513 | { |
1383 | u8 response[2]; | 1514 | uint16_t response; |
1384 | u8 status; | 1515 | u8 status; |
1385 | struct intel_output *intel_output = to_intel_output(connector); | 1516 | struct intel_output *intel_output = to_intel_output(connector); |
1517 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1386 | 1518 | ||
1387 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1519 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); |
1388 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1520 | status = intel_sdvo_read_response(intel_output, &response, 2); |
1389 | 1521 | ||
1390 | DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); | 1522 | DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8); |
1391 | 1523 | ||
1392 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1524 | if (status != SDVO_CMD_STATUS_SUCCESS) |
1393 | return connector_status_unknown; | 1525 | return connector_status_unknown; |
1394 | 1526 | ||
1395 | if ((response[0] != 0) || (response[1] != 0)) { | 1527 | if (response == 0) |
1396 | intel_sdvo_hdmi_sink_detect(connector); | ||
1397 | return connector_status_connected; | ||
1398 | } else | ||
1399 | return connector_status_disconnected; | 1528 | return connector_status_disconnected; |
1529 | |||
1530 | if (intel_sdvo_multifunc_encoder(intel_output) && | ||
1531 | sdvo_priv->attached_output != response) { | ||
1532 | if (sdvo_priv->controlled_output != response && | ||
1533 | intel_sdvo_output_setup(intel_output, response) != true) | ||
1534 | return connector_status_unknown; | ||
1535 | sdvo_priv->attached_output = response; | ||
1536 | } | ||
1537 | return intel_sdvo_hdmi_sink_detect(connector, response); | ||
1400 | } | 1538 | } |
1401 | 1539 | ||
1402 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1540 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
@@ -1549,6 +1687,8 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1549 | { | 1687 | { |
1550 | struct intel_output *intel_output = to_intel_output(connector); | 1688 | struct intel_output *intel_output = to_intel_output(connector); |
1551 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1689 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1690 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1691 | struct drm_display_mode *newmode; | ||
1552 | 1692 | ||
1553 | /* | 1693 | /* |
1554 | * Attempt to get the mode list from DDC. | 1694 | * Attempt to get the mode list from DDC. |
@@ -1557,11 +1697,10 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1557 | */ | 1697 | */ |
1558 | intel_ddc_get_modes(intel_output); | 1698 | intel_ddc_get_modes(intel_output); |
1559 | if (list_empty(&connector->probed_modes) == false) | 1699 | if (list_empty(&connector->probed_modes) == false) |
1560 | return; | 1700 | goto end; |
1561 | 1701 | ||
1562 | /* Fetch modes from VBT */ | 1702 | /* Fetch modes from VBT */ |
1563 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { | 1703 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
1564 | struct drm_display_mode *newmode; | ||
1565 | newmode = drm_mode_duplicate(connector->dev, | 1704 | newmode = drm_mode_duplicate(connector->dev, |
1566 | dev_priv->sdvo_lvds_vbt_mode); | 1705 | dev_priv->sdvo_lvds_vbt_mode); |
1567 | if (newmode != NULL) { | 1706 | if (newmode != NULL) { |
@@ -1571,6 +1710,16 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1571 | drm_mode_probed_add(connector, newmode); | 1710 | drm_mode_probed_add(connector, newmode); |
1572 | } | 1711 | } |
1573 | } | 1712 | } |
1713 | |||
1714 | end: | ||
1715 | list_for_each_entry(newmode, &connector->probed_modes, head) { | ||
1716 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1717 | sdvo_priv->sdvo_lvds_fixed_mode = | ||
1718 | drm_mode_duplicate(connector->dev, newmode); | ||
1719 | break; | ||
1720 | } | ||
1721 | } | ||
1722 | |||
1574 | } | 1723 | } |
1575 | 1724 | ||
1576 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1725 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
@@ -1593,14 +1742,20 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1593 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1742 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1594 | { | 1743 | { |
1595 | struct intel_output *intel_output = to_intel_output(connector); | 1744 | struct intel_output *intel_output = to_intel_output(connector); |
1745 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1596 | 1746 | ||
1597 | if (intel_output->i2c_bus) | 1747 | if (intel_output->i2c_bus) |
1598 | intel_i2c_destroy(intel_output->i2c_bus); | 1748 | intel_i2c_destroy(intel_output->i2c_bus); |
1599 | if (intel_output->ddc_bus) | 1749 | if (intel_output->ddc_bus) |
1600 | intel_i2c_destroy(intel_output->ddc_bus); | 1750 | intel_i2c_destroy(intel_output->ddc_bus); |
1601 | 1751 | ||
1752 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1753 | drm_mode_destroy(connector->dev, | ||
1754 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1755 | |||
1602 | drm_sysfs_connector_remove(connector); | 1756 | drm_sysfs_connector_remove(connector); |
1603 | drm_connector_cleanup(connector); | 1757 | drm_connector_cleanup(connector); |
1758 | |||
1604 | kfree(intel_output); | 1759 | kfree(intel_output); |
1605 | } | 1760 | } |
1606 | 1761 | ||
@@ -1776,16 +1931,101 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device) | |||
1776 | return 0x72; | 1931 | return 0x72; |
1777 | } | 1932 | } |
1778 | 1933 | ||
1934 | static bool | ||
1935 | intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | ||
1936 | { | ||
1937 | struct drm_connector *connector = &intel_output->base; | ||
1938 | struct drm_encoder *encoder = &intel_output->enc; | ||
1939 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1940 | bool ret = true, registered = false; | ||
1941 | |||
1942 | sdvo_priv->is_tv = false; | ||
1943 | intel_output->needs_tv_clock = false; | ||
1944 | sdvo_priv->is_lvds = false; | ||
1945 | |||
1946 | if (device_is_registered(&connector->kdev)) { | ||
1947 | drm_sysfs_connector_remove(connector); | ||
1948 | registered = true; | ||
1949 | } | ||
1950 | |||
1951 | if (flags & | ||
1952 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | ||
1953 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | ||
1954 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | ||
1955 | else | ||
1956 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | ||
1957 | |||
1958 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | ||
1959 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | ||
1960 | |||
1961 | if (intel_sdvo_get_supp_encode(intel_output, | ||
1962 | &sdvo_priv->encode) && | ||
1963 | intel_sdvo_get_digital_encoding_mode(intel_output) && | ||
1964 | sdvo_priv->is_hdmi) { | ||
1965 | /* enable hdmi encoding mode if supported */ | ||
1966 | intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); | ||
1967 | intel_sdvo_set_colorimetry(intel_output, | ||
1968 | SDVO_COLORIMETRY_RGB256); | ||
1969 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
1970 | } | ||
1971 | } else if (flags & SDVO_OUTPUT_SVID0) { | ||
1972 | |||
1973 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
1974 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
1975 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
1976 | sdvo_priv->is_tv = true; | ||
1977 | intel_output->needs_tv_clock = true; | ||
1978 | } else if (flags & SDVO_OUTPUT_RGB0) { | ||
1979 | |||
1980 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
1981 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
1982 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1983 | } else if (flags & SDVO_OUTPUT_RGB1) { | ||
1984 | |||
1985 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
1986 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | ||
1987 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1988 | } else if (flags & SDVO_OUTPUT_LVDS0) { | ||
1989 | |||
1990 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
1991 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1992 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1993 | sdvo_priv->is_lvds = true; | ||
1994 | } else if (flags & SDVO_OUTPUT_LVDS1) { | ||
1995 | |||
1996 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
1997 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1998 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1999 | sdvo_priv->is_lvds = true; | ||
2000 | } else { | ||
2001 | |||
2002 | unsigned char bytes[2]; | ||
2003 | |||
2004 | sdvo_priv->controlled_output = 0; | ||
2005 | memcpy(bytes, &sdvo_priv->caps.output_flags, 2); | ||
2006 | DRM_DEBUG_KMS(I915_SDVO, | ||
2007 | "%s: Unknown SDVO output type (0x%02x%02x)\n", | ||
2008 | SDVO_NAME(sdvo_priv), | ||
2009 | bytes[0], bytes[1]); | ||
2010 | ret = false; | ||
2011 | } | ||
2012 | |||
2013 | if (ret && registered) | ||
2014 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | ||
2015 | |||
2016 | |||
2017 | return ret; | ||
2018 | |||
2019 | } | ||
2020 | |||
1779 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 2021 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
1780 | { | 2022 | { |
1781 | struct drm_connector *connector; | 2023 | struct drm_connector *connector; |
1782 | struct intel_output *intel_output; | 2024 | struct intel_output *intel_output; |
1783 | struct intel_sdvo_priv *sdvo_priv; | 2025 | struct intel_sdvo_priv *sdvo_priv; |
1784 | 2026 | ||
1785 | int connector_type; | ||
1786 | u8 ch[0x40]; | 2027 | u8 ch[0x40]; |
1787 | int i; | 2028 | int i; |
1788 | int encoder_type; | ||
1789 | 2029 | ||
1790 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2030 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
1791 | if (!intel_output) { | 2031 | if (!intel_output) { |
@@ -1835,88 +2075,28 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1835 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; | 2075 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
1836 | 2076 | ||
1837 | /* In defaut case sdvo lvds is false */ | 2077 | /* In defaut case sdvo lvds is false */ |
1838 | sdvo_priv->is_lvds = false; | ||
1839 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); | 2078 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); |
1840 | 2079 | ||
1841 | if (sdvo_priv->caps.output_flags & | 2080 | if (intel_sdvo_output_setup(intel_output, |
1842 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) { | 2081 | sdvo_priv->caps.output_flags) != true) { |
1843 | if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) | 2082 | DRM_DEBUG("SDVO output failed to setup on SDVO%c\n", |
1844 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0; | 2083 | output_device == SDVOB ? 'B' : 'C'); |
1845 | else | ||
1846 | sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS1; | ||
1847 | |||
1848 | encoder_type = DRM_MODE_ENCODER_TMDS; | ||
1849 | connector_type = DRM_MODE_CONNECTOR_DVID; | ||
1850 | |||
1851 | if (intel_sdvo_get_supp_encode(intel_output, | ||
1852 | &sdvo_priv->encode) && | ||
1853 | intel_sdvo_get_digital_encoding_mode(intel_output) && | ||
1854 | sdvo_priv->is_hdmi) { | ||
1855 | /* enable hdmi encoding mode if supported */ | ||
1856 | intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI); | ||
1857 | intel_sdvo_set_colorimetry(intel_output, | ||
1858 | SDVO_COLORIMETRY_RGB256); | ||
1859 | connector_type = DRM_MODE_CONNECTOR_HDMIA; | ||
1860 | } | ||
1861 | } | ||
1862 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0) | ||
1863 | { | ||
1864 | sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0; | ||
1865 | encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
1866 | connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
1867 | sdvo_priv->is_tv = true; | ||
1868 | intel_output->needs_tv_clock = true; | ||
1869 | } | ||
1870 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) | ||
1871 | { | ||
1872 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | ||
1873 | encoder_type = DRM_MODE_ENCODER_DAC; | ||
1874 | connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1875 | } | ||
1876 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) | ||
1877 | { | ||
1878 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | ||
1879 | encoder_type = DRM_MODE_ENCODER_DAC; | ||
1880 | connector_type = DRM_MODE_CONNECTOR_VGA; | ||
1881 | } | ||
1882 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) | ||
1883 | { | ||
1884 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | ||
1885 | encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1886 | connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1887 | sdvo_priv->is_lvds = true; | ||
1888 | } | ||
1889 | else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) | ||
1890 | { | ||
1891 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | ||
1892 | encoder_type = DRM_MODE_ENCODER_LVDS; | ||
1893 | connector_type = DRM_MODE_CONNECTOR_LVDS; | ||
1894 | sdvo_priv->is_lvds = true; | ||
1895 | } | ||
1896 | else | ||
1897 | { | ||
1898 | unsigned char bytes[2]; | ||
1899 | |||
1900 | sdvo_priv->controlled_output = 0; | ||
1901 | memcpy (bytes, &sdvo_priv->caps.output_flags, 2); | ||
1902 | DRM_DEBUG_KMS(I915_SDVO, | ||
1903 | "%s: Unknown SDVO output type (0x%02x%02x)\n", | ||
1904 | SDVO_NAME(sdvo_priv), | ||
1905 | bytes[0], bytes[1]); | ||
1906 | encoder_type = DRM_MODE_ENCODER_NONE; | ||
1907 | connector_type = DRM_MODE_CONNECTOR_Unknown; | ||
1908 | goto err_i2c; | 2084 | goto err_i2c; |
1909 | } | 2085 | } |
1910 | 2086 | ||
2087 | |||
1911 | connector = &intel_output->base; | 2088 | connector = &intel_output->base; |
1912 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, | 2089 | drm_connector_init(dev, connector, &intel_sdvo_connector_funcs, |
1913 | connector_type); | 2090 | connector->connector_type); |
2091 | |||
1914 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); | 2092 | drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs); |
1915 | connector->interlace_allowed = 0; | 2093 | connector->interlace_allowed = 0; |
1916 | connector->doublescan_allowed = 0; | 2094 | connector->doublescan_allowed = 0; |
1917 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; | 2095 | connector->display_info.subpixel_order = SubPixelHorizontalRGB; |
1918 | 2096 | ||
1919 | drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type); | 2097 | drm_encoder_init(dev, &intel_output->enc, |
2098 | &intel_sdvo_enc_funcs, intel_output->enc.encoder_type); | ||
2099 | |||
1920 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); | 2100 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); |
1921 | 2101 | ||
1922 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 2102 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |