aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyu.z.wang@intel.com>2009-03-24 02:02:43 -0400
committerEric Anholt <eric@anholt.net>2009-04-01 18:22:05 -0400
commit7026d4ac1fc134566c2c946e6c0d849fc03ba7b7 (patch)
tree3845375aa46b8552e6857d5c64982fabd423ef14
parente642c6f1d2ebea41b8d7ccc132734b74b5821034 (diff)
drm/i915: Fix SDVO TV support
This brings SDVO TV support from 2D driver, including origin fix f1ca56e17d0 and later fix 2fcf4fcccfe. Also fix wrong modeline definitions for SDVO TV. Signed-off-by: Zhenyu Wang <zhenyu.z.wang@intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c20
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c140
2 files changed, 108 insertions, 52 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0b33760b04cb..64773ce52964 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1106,6 +1106,26 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
1106 return -EINVAL; 1106 return -EINVAL;
1107 } 1107 }
1108 1108
1109 /* SDVO TV has fixed PLL values depend on its clock range,
1110 this mirrors vbios setting. */
1111 if (is_sdvo && is_tv) {
1112 if (adjusted_mode->clock >= 100000
1113 && adjusted_mode->clock < 140500) {
1114 clock.p1 = 2;
1115 clock.p2 = 10;
1116 clock.n = 3;
1117 clock.m1 = 16;
1118 clock.m2 = 8;
1119 } else if (adjusted_mode->clock >= 140500
1120 && adjusted_mode->clock <= 200000) {
1121 clock.p1 = 1;
1122 clock.p2 = 10;
1123 clock.n = 6;
1124 clock.m1 = 12;
1125 clock.m2 = 8;
1126 }
1127 }
1128
1109 if (IS_IGD(dev)) 1129 if (IS_IGD(dev))
1110 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; 1130 fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
1111 else 1131 else
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index ea311c7241c2..7b31f55f55c8 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -911,6 +911,27 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
911 SDVO_HBUF_TX_VSYNC); 911 SDVO_HBUF_TX_VSYNC);
912} 912}
913 913
914static void intel_sdvo_set_tv_format(struct intel_output *output)
915{
916 struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
917 struct intel_sdvo_tv_format *format, unset;
918 u8 status;
919
920 format = &sdvo_priv->tv_format;
921 memset(&unset, 0, sizeof(unset));
922 if (memcmp(format, &unset, sizeof(*format))) {
923 DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
924 SDVO_NAME(sdvo_priv));
925 format->ntsc_m = 1;
926 intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format,
927 sizeof(*format));
928 status = intel_sdvo_read_response(output, NULL, 0);
929 if (status != SDVO_CMD_STATUS_SUCCESS)
930 DRM_DEBUG("%s: Failed to set TV format\n",
931 SDVO_NAME(sdvo_priv));
932 }
933}
934
914static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, 935static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
915 struct drm_display_mode *mode, 936 struct drm_display_mode *mode,
916 struct drm_display_mode *adjusted_mode) 937 struct drm_display_mode *adjusted_mode)
@@ -955,6 +976,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
955 &input_dtd); 976 &input_dtd);
956 intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); 977 intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
957 978
979 drm_mode_set_crtcinfo(adjusted_mode, 0);
980
981 mode->clock = adjusted_mode->clock;
982
983 adjusted_mode->clock *=
984 intel_sdvo_get_pixel_multiplier(mode);
958 } else { 985 } else {
959 return false; 986 return false;
960 } 987 }
@@ -999,7 +1026,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
999 sdvox |= SDVO_AUDIO_ENABLE; 1026 sdvox |= SDVO_AUDIO_ENABLE;
1000 } 1027 }
1001 1028
1002 intel_sdvo_get_dtd_from_mode(&input_dtd, mode); 1029 /* We have tried to get input timing in mode_fixup, and filled into
1030 adjusted_mode */
1031 if (sdvo_priv->is_tv)
1032 intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
1033 else
1034 intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
1003 1035
1004 /* If it's a TV, we already set the output timing in mode_fixup. 1036 /* If it's a TV, we already set the output timing in mode_fixup.
1005 * Otherwise, the output timing is equal to the input timing. 1037 * Otherwise, the output timing is equal to the input timing.
@@ -1014,6 +1046,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
1014 /* Set the input timing to the screen. Assume always input 0. */ 1046 /* Set the input timing to the screen. Assume always input 0. */
1015 intel_sdvo_set_target_input(output, true, false); 1047 intel_sdvo_set_target_input(output, true, false);
1016 1048
1049 if (sdvo_priv->is_tv)
1050 intel_sdvo_set_tv_format(output);
1051
1017 /* We would like to use intel_sdvo_create_preferred_input_timing() to 1052 /* We would like to use intel_sdvo_create_preferred_input_timing() to
1018 * provide the device with a timing it can support, if it supports that 1053 * provide the device with a timing it can support, if it supports that
1019 * feature. However, presumably we would need to adjust the CRTC to 1054 * feature. However, presumably we would need to adjust the CRTC to
@@ -1382,7 +1417,7 @@ static void
1382intel_sdvo_check_tv_format(struct intel_output *output) 1417intel_sdvo_check_tv_format(struct intel_output *output)
1383{ 1418{
1384 struct intel_sdvo_priv *dev_priv = output->dev_priv; 1419 struct intel_sdvo_priv *dev_priv = output->dev_priv;
1385 struct intel_sdvo_tv_format format, unset; 1420 struct intel_sdvo_tv_format format;
1386 uint8_t status; 1421 uint8_t status;
1387 1422
1388 intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); 1423 intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
@@ -1390,15 +1425,7 @@ intel_sdvo_check_tv_format(struct intel_output *output)
1390 if (status != SDVO_CMD_STATUS_SUCCESS) 1425 if (status != SDVO_CMD_STATUS_SUCCESS)
1391 return; 1426 return;
1392 1427
1393 memset(&unset, 0, sizeof(unset)); 1428 memcpy(&dev_priv->tv_format, &format, sizeof(format));
1394 if (memcmp(&format, &unset, sizeof(format))) {
1395 DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
1396 SDVO_NAME(dev_priv));
1397
1398 format.ntsc_m = true;
1399 intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
1400 status = intel_sdvo_read_response(output, NULL, 0);
1401 }
1402} 1429}
1403 1430
1404/* 1431/*
@@ -1407,68 +1434,70 @@ intel_sdvo_check_tv_format(struct intel_output *output)
1407 * XXX: all 60Hz refresh? 1434 * XXX: all 60Hz refresh?
1408 */ 1435 */
1409struct drm_display_mode sdvo_tv_modes[] = { 1436struct drm_display_mode sdvo_tv_modes[] = {
1410 { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416, 1437 { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384,
1411 200, 0, 232, 201, 233, 4196112, 0, 1438 416, 0, 200, 201, 232, 233, 0,
1412 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1439 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1413 { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416, 1440 { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384,
1414 240, 0, 272, 241, 273, 4196112, 0, 1441 416, 0, 240, 241, 272, 273, 0,
1415 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1442 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1416 { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496, 1443 { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464,
1417 300, 0, 332, 301, 333, 4196112, 0, 1444 496, 0, 300, 301, 332, 333, 0,
1418 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1445 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1419 { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736, 1446 { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704,
1420 350, 0, 382, 351, 383, 4196112, 0, 1447 736, 0, 350, 351, 382, 383, 0,
1421 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1448 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1422 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, 1449 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704,
1423 400, 0, 432, 401, 433, 4196112, 0, 1450 736, 0, 400, 401, 432, 433, 0,
1424 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1451 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1425 { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736, 1452 { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704,
1426 400, 0, 432, 401, 433, 4196112, 0, 1453 736, 0, 480, 481, 512, 513, 0,
1427 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1454 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1428 { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800, 1455 { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768,
1429 480, 0, 512, 481, 513, 4196112, 0, 1456 800, 0, 480, 481, 512, 513, 0,
1430 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1457 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1431 { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800, 1458 { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768,
1432 576, 0, 608, 577, 609, 4196112, 0, 1459 800, 0, 576, 577, 608, 609, 0,
1433 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1460 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1434 { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816, 1461 { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784,
1435 350, 0, 382, 351, 383, 4196112, 0, 1462 816, 0, 350, 351, 382, 383, 0,
1436 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1463 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1437 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816, 1464 { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784,
1438 400, 0, 432, 401, 433, 4196112, 0, 1465 816, 0, 400, 401, 432, 433, 0,
1439 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1466 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1440 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816, 1467 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784,
1441 480, 0, 512, 481, 513, 4196112, 0, 1468 816, 0, 480, 481, 512, 513, 0,
1442 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1469 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1443 { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816, 1470 { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784,
1444 540, 0, 572, 541, 573, 4196112, 0, 1471 816, 0, 540, 541, 572, 573, 0,
1445 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1472 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1446 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816, 1473 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784,
1447 576, 0, 608, 577, 609, 4196112, 0, 1474 816, 0, 576, 577, 608, 609, 0,
1448 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1475 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1449 { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864, 1476 { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832,
1450 576, 0, 608, 577, 609, 4196112, 0, 1477 864, 0, 576, 577, 608, 609, 0,
1451 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1478 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1452 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896, 1479 { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864,
1453 600, 0, 632, 601, 633, 4196112, 0, 1480 896, 0, 600, 601, 632, 633, 0,
1454 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1481 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1455 { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928, 1482 { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896,
1456 624, 0, 656, 625, 657, 4196112, 0, 1483 928, 0, 624, 625, 656, 657, 0,
1457 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1484 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1458 { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016, 1485 { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984,
1459 766, 0, 798, 767, 799, 4196112, 0, 1486 1016, 0, 766, 767, 798, 799, 0,
1460 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1487 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1461 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120, 1488 { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088,
1462 768, 0, 800, 769, 801, 4196112, 0, 1489 1120, 0, 768, 769, 800, 801, 0,
1463 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1490 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1464 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376, 1491 { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344,
1465 1024, 0, 1056, 1025, 1057, 4196112, 0, 1492 1376, 0, 1024, 1025, 1056, 1057, 0,
1466 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1493 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
1467}; 1494};
1468 1495
1469static void intel_sdvo_get_tv_modes(struct drm_connector *connector) 1496static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
1470{ 1497{
1471 struct intel_output *output = to_intel_output(connector); 1498 struct intel_output *output = to_intel_output(connector);
1499 struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
1500 struct intel_sdvo_sdtv_resolution_request tv_res;
1472 uint32_t reply = 0; 1501 uint32_t reply = 0;
1473 uint8_t status; 1502 uint8_t status;
1474 int i = 0; 1503 int i = 0;
@@ -1478,15 +1507,22 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
1478 /* Read the list of supported input resolutions for the selected TV 1507 /* Read the list of supported input resolutions for the selected TV
1479 * format. 1508 * format.
1480 */ 1509 */
1510 memset(&tv_res, 0, sizeof(tv_res));
1511 memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res));
1481 intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, 1512 intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
1482 NULL, 0); 1513 &tv_res, sizeof(tv_res));
1483 status = intel_sdvo_read_response(output, &reply, 3); 1514 status = intel_sdvo_read_response(output, &reply, 3);
1484 if (status != SDVO_CMD_STATUS_SUCCESS) 1515 if (status != SDVO_CMD_STATUS_SUCCESS)
1485 return; 1516 return;
1486 1517
1487 for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) 1518 for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
1488 if (reply & (1 << i)) 1519 if (reply & (1 << i)) {
1489 drm_mode_probed_add(connector, &sdvo_tv_modes[i]); 1520 struct drm_display_mode *nmode;
1521 nmode = drm_mode_duplicate(connector->dev,
1522 &sdvo_tv_modes[i]);
1523 if (nmode)
1524 drm_mode_probed_add(connector, nmode);
1525 }
1490} 1526}
1491 1527
1492static int intel_sdvo_get_modes(struct drm_connector *connector) 1528static int intel_sdvo_get_modes(struct drm_connector *connector)