aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c168
1 files changed, 133 insertions, 35 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index d4ea6c265ce1..2628d5622449 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -80,7 +80,7 @@ struct intel_sdvo {
80 80
81 /* 81 /*
82 * Capabilities of the SDVO device returned by 82 * Capabilities of the SDVO device returned by
83 * i830_sdvo_get_capabilities() 83 * intel_sdvo_get_capabilities()
84 */ 84 */
85 struct intel_sdvo_caps caps; 85 struct intel_sdvo_caps caps;
86 86
@@ -712,6 +712,13 @@ static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
712 intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); 712 intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
713} 713}
714 714
715static bool intel_sdvo_get_timing(struct intel_sdvo *intel_sdvo, u8 cmd,
716 struct intel_sdvo_dtd *dtd)
717{
718 return intel_sdvo_get_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) &&
719 intel_sdvo_get_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2));
720}
721
715static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, 722static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo,
716 struct intel_sdvo_dtd *dtd) 723 struct intel_sdvo_dtd *dtd)
717{ 724{
@@ -726,6 +733,13 @@ static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo,
726 SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); 733 SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
727} 734}
728 735
736static bool intel_sdvo_get_input_timing(struct intel_sdvo *intel_sdvo,
737 struct intel_sdvo_dtd *dtd)
738{
739 return intel_sdvo_get_timing(intel_sdvo,
740 SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
741}
742
729static bool 743static bool
730intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, 744intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo,
731 uint16_t clock, 745 uint16_t clock,
@@ -1041,6 +1055,32 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
1041 return true; 1055 return true;
1042} 1056}
1043 1057
1058static void i9xx_adjust_sdvo_tv_clock(struct intel_crtc_config *pipe_config)
1059{
1060 unsigned dotclock = pipe_config->adjusted_mode.clock;
1061 struct dpll *clock = &pipe_config->dpll;
1062
1063 /* SDVO TV has fixed PLL values depend on its clock range,
1064 this mirrors vbios setting. */
1065 if (dotclock >= 100000 && dotclock < 140500) {
1066 clock->p1 = 2;
1067 clock->p2 = 10;
1068 clock->n = 3;
1069 clock->m1 = 16;
1070 clock->m2 = 8;
1071 } else if (dotclock >= 140500 && dotclock <= 200000) {
1072 clock->p1 = 1;
1073 clock->p2 = 10;
1074 clock->n = 6;
1075 clock->m1 = 12;
1076 clock->m2 = 8;
1077 } else {
1078 WARN(1, "SDVO TV clock out of range: %i\n", dotclock);
1079 }
1080
1081 pipe_config->clock_set = true;
1082}
1083
1044static bool intel_sdvo_compute_config(struct intel_encoder *encoder, 1084static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1045 struct intel_crtc_config *pipe_config) 1085 struct intel_crtc_config *pipe_config)
1046{ 1086{
@@ -1066,6 +1106,7 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1066 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo, 1106 (void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
1067 mode, 1107 mode,
1068 adjusted_mode); 1108 adjusted_mode);
1109 pipe_config->sdvo_tv_clock = true;
1069 } else if (intel_sdvo->is_lvds) { 1110 } else if (intel_sdvo->is_lvds) {
1070 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, 1111 if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
1071 intel_sdvo->sdvo_lvds_fixed_mode)) 1112 intel_sdvo->sdvo_lvds_fixed_mode))
@@ -1097,6 +1138,10 @@ static bool intel_sdvo_compute_config(struct intel_encoder *encoder,
1097 if (intel_sdvo->color_range) 1138 if (intel_sdvo->color_range)
1098 pipe_config->limited_color_range = true; 1139 pipe_config->limited_color_range = true;
1099 1140
1141 /* Clock computation needs to happen after pixel multiplier. */
1142 if (intel_sdvo->is_tv)
1143 i9xx_adjust_sdvo_tv_clock(pipe_config);
1144
1100 return true; 1145 return true;
1101} 1146}
1102 1147
@@ -1174,6 +1219,7 @@ static void intel_sdvo_mode_set(struct intel_encoder *intel_encoder)
1174 1219
1175 switch (intel_crtc->config.pixel_multiplier) { 1220 switch (intel_crtc->config.pixel_multiplier) {
1176 default: 1221 default:
1222 WARN(1, "unknown pixel mutlipler specified\n");
1177 case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; 1223 case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
1178 case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; 1224 case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
1179 case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; 1225 case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
@@ -1231,7 +1277,7 @@ static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector)
1231 struct intel_sdvo_connector *intel_sdvo_connector = 1277 struct intel_sdvo_connector *intel_sdvo_connector =
1232 to_intel_sdvo_connector(&connector->base); 1278 to_intel_sdvo_connector(&connector->base);
1233 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base); 1279 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base);
1234 u16 active_outputs; 1280 u16 active_outputs = 0;
1235 1281
1236 intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs); 1282 intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
1237 1283
@@ -1247,7 +1293,7 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
1247 struct drm_device *dev = encoder->base.dev; 1293 struct drm_device *dev = encoder->base.dev;
1248 struct drm_i915_private *dev_priv = dev->dev_private; 1294 struct drm_i915_private *dev_priv = dev->dev_private;
1249 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); 1295 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
1250 u16 active_outputs; 1296 u16 active_outputs = 0;
1251 u32 tmp; 1297 u32 tmp;
1252 1298
1253 tmp = I915_READ(intel_sdvo->sdvo_reg); 1299 tmp = I915_READ(intel_sdvo->sdvo_reg);
@@ -1264,6 +1310,74 @@ static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
1264 return true; 1310 return true;
1265} 1311}
1266 1312
1313static void intel_sdvo_get_config(struct intel_encoder *encoder,
1314 struct intel_crtc_config *pipe_config)
1315{
1316 struct drm_device *dev = encoder->base.dev;
1317 struct drm_i915_private *dev_priv = dev->dev_private;
1318 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
1319 struct intel_sdvo_dtd dtd;
1320 int encoder_pixel_multiplier = 0;
1321 u32 flags = 0, sdvox;
1322 u8 val;
1323 bool ret;
1324
1325 ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd);
1326 if (!ret) {
1327 /* Some sdvo encoders are not spec compliant and don't
1328 * implement the mandatory get_timings function. */
1329 DRM_DEBUG_DRIVER("failed to retrieve SDVO DTD\n");
1330 pipe_config->quirks |= PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS;
1331 } else {
1332 if (dtd.part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE)
1333 flags |= DRM_MODE_FLAG_PHSYNC;
1334 else
1335 flags |= DRM_MODE_FLAG_NHSYNC;
1336
1337 if (dtd.part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE)
1338 flags |= DRM_MODE_FLAG_PVSYNC;
1339 else
1340 flags |= DRM_MODE_FLAG_NVSYNC;
1341 }
1342
1343 pipe_config->adjusted_mode.flags |= flags;
1344
1345 /*
1346 * pixel multiplier readout is tricky: Only on i915g/gm it is stored in
1347 * the sdvo port register, on all other platforms it is part of the dpll
1348 * state. Since the general pipe state readout happens before the
1349 * encoder->get_config we so already have a valid pixel multplier on all
1350 * other platfroms.
1351 */
1352 if (IS_I915G(dev) || IS_I915GM(dev)) {
1353 sdvox = I915_READ(intel_sdvo->sdvo_reg);
1354 pipe_config->pixel_multiplier =
1355 ((sdvox & SDVO_PORT_MULTIPLY_MASK)
1356 >> SDVO_PORT_MULTIPLY_SHIFT) + 1;
1357 }
1358
1359 /* Cross check the port pixel multiplier with the sdvo encoder state. */
1360 intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT, &val, 1);
1361 switch (val) {
1362 case SDVO_CLOCK_RATE_MULT_1X:
1363 encoder_pixel_multiplier = 1;
1364 break;
1365 case SDVO_CLOCK_RATE_MULT_2X:
1366 encoder_pixel_multiplier = 2;
1367 break;
1368 case SDVO_CLOCK_RATE_MULT_4X:
1369 encoder_pixel_multiplier = 4;
1370 break;
1371 }
1372
1373 if(HAS_PCH_SPLIT(dev))
1374 return; /* no pixel multiplier readout support yet */
1375
1376 WARN(encoder_pixel_multiplier != pipe_config->pixel_multiplier,
1377 "SDVO pixel multiplier mismatch, port: %i, encoder: %i\n",
1378 pipe_config->pixel_multiplier, encoder_pixel_multiplier);
1379}
1380
1267static void intel_disable_sdvo(struct intel_encoder *encoder) 1381static void intel_disable_sdvo(struct intel_encoder *encoder)
1268{ 1382{
1269 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; 1383 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
@@ -1344,6 +1458,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
1344 intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); 1458 intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
1345} 1459}
1346 1460
1461/* Special dpms function to support cloning between dvo/sdvo/crt. */
1347static void intel_sdvo_dpms(struct drm_connector *connector, int mode) 1462static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
1348{ 1463{
1349 struct drm_crtc *crtc; 1464 struct drm_crtc *crtc;
@@ -1365,6 +1480,8 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
1365 return; 1480 return;
1366 } 1481 }
1367 1482
1483 /* We set active outputs manually below in case pipe dpms doesn't change
1484 * due to cloning. */
1368 if (mode != DRM_MODE_DPMS_ON) { 1485 if (mode != DRM_MODE_DPMS_ON) {
1369 intel_sdvo_set_active_outputs(intel_sdvo, 0); 1486 intel_sdvo_set_active_outputs(intel_sdvo, 0);
1370 if (0) 1487 if (0)
@@ -1495,7 +1612,7 @@ intel_sdvo_get_analog_edid(struct drm_connector *connector)
1495 1612
1496 return drm_get_edid(connector, 1613 return drm_get_edid(connector,
1497 intel_gmbus_get_adapter(dev_priv, 1614 intel_gmbus_get_adapter(dev_priv,
1498 dev_priv->crt_ddc_pin)); 1615 dev_priv->vbt.crt_ddc_pin));
1499} 1616}
1500 1617
1501static enum drm_connector_status 1618static enum drm_connector_status
@@ -1625,12 +1742,9 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
1625 if (ret == connector_status_connected) { 1742 if (ret == connector_status_connected) {
1626 intel_sdvo->is_tv = false; 1743 intel_sdvo->is_tv = false;
1627 intel_sdvo->is_lvds = false; 1744 intel_sdvo->is_lvds = false;
1628 intel_sdvo->base.needs_tv_clock = false;
1629 1745
1630 if (response & SDVO_TV_MASK) { 1746 if (response & SDVO_TV_MASK)
1631 intel_sdvo->is_tv = true; 1747 intel_sdvo->is_tv = true;
1632 intel_sdvo->base.needs_tv_clock = true;
1633 }
1634 if (response & SDVO_LVDS_MASK) 1748 if (response & SDVO_LVDS_MASK)
1635 intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; 1749 intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL;
1636 } 1750 }
@@ -1772,21 +1886,12 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
1772 struct drm_display_mode *newmode; 1886 struct drm_display_mode *newmode;
1773 1887
1774 /* 1888 /*
1775 * Attempt to get the mode list from DDC.
1776 * Assume that the preferred modes are
1777 * arranged in priority order.
1778 */
1779 intel_ddc_get_modes(connector, &intel_sdvo->ddc);
1780
1781 /*
1782 * Fetch modes from VBT. For SDVO prefer the VBT mode since some 1889 * Fetch modes from VBT. For SDVO prefer the VBT mode since some
1783 * SDVO->LVDS transcoders can't cope with the EDID mode. Since 1890 * SDVO->LVDS transcoders can't cope with the EDID mode.
1784 * drm_mode_probed_add adds the mode at the head of the list we add it
1785 * last.
1786 */ 1891 */
1787 if (dev_priv->sdvo_lvds_vbt_mode != NULL) { 1892 if (dev_priv->vbt.sdvo_lvds_vbt_mode != NULL) {
1788 newmode = drm_mode_duplicate(connector->dev, 1893 newmode = drm_mode_duplicate(connector->dev,
1789 dev_priv->sdvo_lvds_vbt_mode); 1894 dev_priv->vbt.sdvo_lvds_vbt_mode);
1790 if (newmode != NULL) { 1895 if (newmode != NULL) {
1791 /* Guarantee the mode is preferred */ 1896 /* Guarantee the mode is preferred */
1792 newmode->type = (DRM_MODE_TYPE_PREFERRED | 1897 newmode->type = (DRM_MODE_TYPE_PREFERRED |
@@ -1795,6 +1900,13 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
1795 } 1900 }
1796 } 1901 }
1797 1902
1903 /*
1904 * Attempt to get the mode list from DDC.
1905 * Assume that the preferred modes are
1906 * arranged in priority order.
1907 */
1908 intel_ddc_get_modes(connector, &intel_sdvo->ddc);
1909
1798 list_for_each_entry(newmode, &connector->probed_modes, head) { 1910 list_for_each_entry(newmode, &connector->probed_modes, head) {
1799 if (newmode->type & DRM_MODE_TYPE_PREFERRED) { 1911 if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
1800 intel_sdvo->sdvo_lvds_fixed_mode = 1912 intel_sdvo->sdvo_lvds_fixed_mode =
@@ -2329,7 +2441,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
2329 intel_sdvo_connector->output_flag = type; 2441 intel_sdvo_connector->output_flag = type;
2330 2442
2331 intel_sdvo->is_tv = true; 2443 intel_sdvo->is_tv = true;
2332 intel_sdvo->base.needs_tv_clock = true;
2333 2444
2334 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); 2445 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
2335 2446
@@ -2417,7 +2528,6 @@ static bool
2417intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) 2528intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags)
2418{ 2529{
2419 intel_sdvo->is_tv = false; 2530 intel_sdvo->is_tv = false;
2420 intel_sdvo->base.needs_tv_clock = false;
2421 intel_sdvo->is_lvds = false; 2531 intel_sdvo->is_lvds = false;
2422 2532
2423 /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ 2533 /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
@@ -2751,7 +2861,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
2751 struct drm_i915_private *dev_priv = dev->dev_private; 2861 struct drm_i915_private *dev_priv = dev->dev_private;
2752 struct intel_encoder *intel_encoder; 2862 struct intel_encoder *intel_encoder;
2753 struct intel_sdvo *intel_sdvo; 2863 struct intel_sdvo *intel_sdvo;
2754 u32 hotplug_mask;
2755 int i; 2864 int i;
2756 intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); 2865 intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
2757 if (!intel_sdvo) 2866 if (!intel_sdvo)
@@ -2780,23 +2889,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
2780 } 2889 }
2781 } 2890 }
2782 2891
2783 hotplug_mask = 0;
2784 if (IS_G4X(dev)) {
2785 hotplug_mask = intel_sdvo->is_sdvob ?
2786 SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X;
2787 } else if (IS_GEN4(dev)) {
2788 hotplug_mask = intel_sdvo->is_sdvob ?
2789 SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965;
2790 } else {
2791 hotplug_mask = intel_sdvo->is_sdvob ?
2792 SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
2793 }
2794
2795 intel_encoder->compute_config = intel_sdvo_compute_config; 2892 intel_encoder->compute_config = intel_sdvo_compute_config;
2796 intel_encoder->disable = intel_disable_sdvo; 2893 intel_encoder->disable = intel_disable_sdvo;
2797 intel_encoder->mode_set = intel_sdvo_mode_set; 2894 intel_encoder->mode_set = intel_sdvo_mode_set;
2798 intel_encoder->enable = intel_enable_sdvo; 2895 intel_encoder->enable = intel_enable_sdvo;
2799 intel_encoder->get_hw_state = intel_sdvo_get_hw_state; 2896 intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
2897 intel_encoder->get_config = intel_sdvo_get_config;
2800 2898
2801 /* In default case sdvo lvds is false */ 2899 /* In default case sdvo lvds is false */
2802 if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) 2900 if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))