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.c210
1 files changed, 152 insertions, 58 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index d251d9d7a06c..0007a4d9bf6e 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -96,7 +96,7 @@ struct intel_sdvo {
96 /* 96 /*
97 * Hotplug activation bits for this device 97 * Hotplug activation bits for this device
98 */ 98 */
99 uint8_t hotplug_active[2]; 99 uint16_t hotplug_active;
100 100
101 /** 101 /**
102 * This is used to select the color range of RBG outputs in HDMI mode. 102 * This is used to select the color range of RBG outputs in HDMI mode.
@@ -627,6 +627,14 @@ static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo,
627 &outputs, sizeof(outputs)); 627 &outputs, sizeof(outputs));
628} 628}
629 629
630static bool intel_sdvo_get_active_outputs(struct intel_sdvo *intel_sdvo,
631 u16 *outputs)
632{
633 return intel_sdvo_get_value(intel_sdvo,
634 SDVO_CMD_GET_ACTIVE_OUTPUTS,
635 outputs, sizeof(*outputs));
636}
637
630static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, 638static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo,
631 int mode) 639 int mode)
632{ 640{
@@ -1141,51 +1149,132 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
1141 intel_sdvo_write_sdvox(intel_sdvo, sdvox); 1149 intel_sdvo_write_sdvox(intel_sdvo, sdvox);
1142} 1150}
1143 1151
1144static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) 1152static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector)
1145{ 1153{
1146 struct drm_device *dev = encoder->dev; 1154 struct intel_sdvo_connector *intel_sdvo_connector =
1155 to_intel_sdvo_connector(&connector->base);
1156 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base);
1157 u16 active_outputs;
1158
1159 intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
1160
1161 if (active_outputs & intel_sdvo_connector->output_flag)
1162 return true;
1163 else
1164 return false;
1165}
1166
1167static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
1168 enum pipe *pipe)
1169{
1170 struct drm_device *dev = encoder->base.dev;
1147 struct drm_i915_private *dev_priv = dev->dev_private; 1171 struct drm_i915_private *dev_priv = dev->dev_private;
1148 struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); 1172 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
1149 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 1173 u32 tmp;
1174
1175 tmp = I915_READ(intel_sdvo->sdvo_reg);
1176
1177 if (!(tmp & SDVO_ENABLE))
1178 return false;
1179
1180 if (HAS_PCH_CPT(dev))
1181 *pipe = PORT_TO_PIPE_CPT(tmp);
1182 else
1183 *pipe = PORT_TO_PIPE(tmp);
1184
1185 return true;
1186}
1187
1188static void intel_disable_sdvo(struct intel_encoder *encoder)
1189{
1190 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1191 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
1192 u32 temp;
1193
1194 intel_sdvo_set_active_outputs(intel_sdvo, 0);
1195 if (0)
1196 intel_sdvo_set_encoder_power_state(intel_sdvo,
1197 DRM_MODE_DPMS_OFF);
1198
1199 temp = I915_READ(intel_sdvo->sdvo_reg);
1200 if ((temp & SDVO_ENABLE) != 0) {
1201 intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
1202 }
1203}
1204
1205static void intel_enable_sdvo(struct intel_encoder *encoder)
1206{
1207 struct drm_device *dev = encoder->base.dev;
1208 struct drm_i915_private *dev_priv = dev->dev_private;
1209 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
1210 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
1150 u32 temp; 1211 u32 temp;
1212 bool input1, input2;
1213 int i;
1214 u8 status;
1215
1216 temp = I915_READ(intel_sdvo->sdvo_reg);
1217 if ((temp & SDVO_ENABLE) == 0)
1218 intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
1219 for (i = 0; i < 2; i++)
1220 intel_wait_for_vblank(dev, intel_crtc->pipe);
1221
1222 status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
1223 /* Warn if the device reported failure to sync.
1224 * A lot of SDVO devices fail to notify of sync, but it's
1225 * a given it the status is a success, we succeeded.
1226 */
1227 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
1228 DRM_DEBUG_KMS("First %s output reported failure to "
1229 "sync\n", SDVO_NAME(intel_sdvo));
1230 }
1231
1232 if (0)
1233 intel_sdvo_set_encoder_power_state(intel_sdvo,
1234 DRM_MODE_DPMS_ON);
1235 intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
1236}
1237
1238static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
1239{
1240 struct drm_crtc *crtc;
1241 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1242
1243 /* dvo supports only 2 dpms states. */
1244 if (mode != DRM_MODE_DPMS_ON)
1245 mode = DRM_MODE_DPMS_OFF;
1246
1247 if (mode == connector->dpms)
1248 return;
1249
1250 connector->dpms = mode;
1251
1252 /* Only need to change hw state when actually enabled */
1253 crtc = intel_sdvo->base.base.crtc;
1254 if (!crtc) {
1255 intel_sdvo->base.connectors_active = false;
1256 return;
1257 }
1151 1258
1152 if (mode != DRM_MODE_DPMS_ON) { 1259 if (mode != DRM_MODE_DPMS_ON) {
1153 intel_sdvo_set_active_outputs(intel_sdvo, 0); 1260 intel_sdvo_set_active_outputs(intel_sdvo, 0);
1154 if (0) 1261 if (0)
1155 intel_sdvo_set_encoder_power_state(intel_sdvo, mode); 1262 intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
1156 1263
1157 if (mode == DRM_MODE_DPMS_OFF) { 1264 intel_sdvo->base.connectors_active = false;
1158 temp = I915_READ(intel_sdvo->sdvo_reg); 1265
1159 if ((temp & SDVO_ENABLE) != 0) { 1266 intel_crtc_update_dpms(crtc);
1160 intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
1161 }
1162 }
1163 } else { 1267 } else {
1164 bool input1, input2; 1268 intel_sdvo->base.connectors_active = true;
1165 int i; 1269
1166 u8 status; 1270 intel_crtc_update_dpms(crtc);
1167
1168 temp = I915_READ(intel_sdvo->sdvo_reg);
1169 if ((temp & SDVO_ENABLE) == 0)
1170 intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
1171 for (i = 0; i < 2; i++)
1172 intel_wait_for_vblank(dev, intel_crtc->pipe);
1173
1174 status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
1175 /* Warn if the device reported failure to sync.
1176 * A lot of SDVO devices fail to notify of sync, but it's
1177 * a given it the status is a success, we succeeded.
1178 */
1179 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
1180 DRM_DEBUG_KMS("First %s output reported failure to "
1181 "sync\n", SDVO_NAME(intel_sdvo));
1182 }
1183 1271
1184 if (0) 1272 if (0)
1185 intel_sdvo_set_encoder_power_state(intel_sdvo, mode); 1273 intel_sdvo_set_encoder_power_state(intel_sdvo, mode);
1186 intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); 1274 intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
1187 } 1275 }
1188 return; 1276
1277 intel_modeset_check_state(connector->dev);
1189} 1278}
1190 1279
1191static int intel_sdvo_mode_valid(struct drm_connector *connector, 1280static int intel_sdvo_mode_valid(struct drm_connector *connector,
@@ -1250,25 +1339,29 @@ static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct in
1250 return true; 1339 return true;
1251} 1340}
1252 1341
1253static int intel_sdvo_supports_hotplug(struct intel_sdvo *intel_sdvo) 1342static uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo)
1254{ 1343{
1255 struct drm_device *dev = intel_sdvo->base.base.dev; 1344 struct drm_device *dev = intel_sdvo->base.base.dev;
1256 u8 response[2]; 1345 uint16_t hotplug;
1257 1346
1258 /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise 1347 /* HW Erratum: SDVO Hotplug is broken on all i945G chips, there's noise
1259 * on the line. */ 1348 * on the line. */
1260 if (IS_I945G(dev) || IS_I945GM(dev)) 1349 if (IS_I945G(dev) || IS_I945GM(dev))
1261 return false; 1350 return 0;
1262 1351
1263 return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, 1352 if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT,
1264 &response, 2) && response[0]; 1353 &hotplug, sizeof(hotplug)))
1354 return 0;
1355
1356 return hotplug;
1265} 1357}
1266 1358
1267static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder) 1359static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
1268{ 1360{
1269 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); 1361 struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base);
1270 1362
1271 intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &intel_sdvo->hotplug_active, 2); 1363 intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG,
1364 &intel_sdvo->hotplug_active, 2);
1272} 1365}
1273 1366
1274static bool 1367static bool
@@ -1344,7 +1437,6 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector)
1344 } 1437 }
1345 } else 1438 } else
1346 status = connector_status_disconnected; 1439 status = connector_status_disconnected;
1347 connector->display_info.raw_edid = NULL;
1348 kfree(edid); 1440 kfree(edid);
1349 } 1441 }
1350 1442
@@ -1418,7 +1510,6 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
1418 else 1510 else
1419 ret = connector_status_disconnected; 1511 ret = connector_status_disconnected;
1420 1512
1421 connector->display_info.raw_edid = NULL;
1422 kfree(edid); 1513 kfree(edid);
1423 } else 1514 } else
1424 ret = connector_status_connected; 1515 ret = connector_status_connected;
@@ -1464,7 +1555,6 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
1464 drm_add_edid_modes(connector, edid); 1555 drm_add_edid_modes(connector, edid);
1465 } 1556 }
1466 1557
1467 connector->display_info.raw_edid = NULL;
1468 kfree(edid); 1558 kfree(edid);
1469 } 1559 }
1470} 1560}
@@ -1836,8 +1926,8 @@ set_value:
1836done: 1926done:
1837 if (intel_sdvo->base.base.crtc) { 1927 if (intel_sdvo->base.base.crtc) {
1838 struct drm_crtc *crtc = intel_sdvo->base.base.crtc; 1928 struct drm_crtc *crtc = intel_sdvo->base.base.crtc;
1839 drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, 1929 intel_set_mode(crtc, &crtc->mode,
1840 crtc->y, crtc->fb); 1930 crtc->x, crtc->y, crtc->fb);
1841 } 1931 }
1842 1932
1843 return 0; 1933 return 0;
@@ -1845,15 +1935,13 @@ done:
1845} 1935}
1846 1936
1847static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { 1937static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
1848 .dpms = intel_sdvo_dpms,
1849 .mode_fixup = intel_sdvo_mode_fixup, 1938 .mode_fixup = intel_sdvo_mode_fixup,
1850 .prepare = intel_encoder_prepare,
1851 .mode_set = intel_sdvo_mode_set, 1939 .mode_set = intel_sdvo_mode_set,
1852 .commit = intel_encoder_commit, 1940 .disable = intel_encoder_noop,
1853}; 1941};
1854 1942
1855static const struct drm_connector_funcs intel_sdvo_connector_funcs = { 1943static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
1856 .dpms = drm_helper_connector_dpms, 1944 .dpms = intel_sdvo_dpms,
1857 .detect = intel_sdvo_detect, 1945 .detect = intel_sdvo_detect,
1858 .fill_modes = drm_helper_probe_single_connector_modes, 1946 .fill_modes = drm_helper_probe_single_connector_modes,
1859 .set_property = intel_sdvo_set_property, 1947 .set_property = intel_sdvo_set_property,
@@ -2025,6 +2113,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
2025 connector->base.base.interlace_allowed = 1; 2113 connector->base.base.interlace_allowed = 1;
2026 connector->base.base.doublescan_allowed = 0; 2114 connector->base.base.doublescan_allowed = 0;
2027 connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; 2115 connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
2116 connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
2028 2117
2029 intel_connector_attach_encoder(&connector->base, &encoder->base); 2118 intel_connector_attach_encoder(&connector->base, &encoder->base);
2030 drm_sysfs_connector_add(&connector->base.base); 2119 drm_sysfs_connector_add(&connector->base.base);
@@ -2063,17 +2152,18 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2063 2152
2064 intel_connector = &intel_sdvo_connector->base; 2153 intel_connector = &intel_sdvo_connector->base;
2065 connector = &intel_connector->base; 2154 connector = &intel_connector->base;
2066 if (intel_sdvo_supports_hotplug(intel_sdvo) & (1 << device)) { 2155 if (intel_sdvo_get_hotplug_support(intel_sdvo) &
2156 intel_sdvo_connector->output_flag) {
2067 connector->polled = DRM_CONNECTOR_POLL_HPD; 2157 connector->polled = DRM_CONNECTOR_POLL_HPD;
2068 intel_sdvo->hotplug_active[0] |= 1 << device; 2158 intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag;
2069 /* Some SDVO devices have one-shot hotplug interrupts. 2159 /* Some SDVO devices have one-shot hotplug interrupts.
2070 * Ensure that they get re-enabled when an interrupt happens. 2160 * Ensure that they get re-enabled when an interrupt happens.
2071 */ 2161 */
2072 intel_encoder->hot_plug = intel_sdvo_enable_hotplug; 2162 intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
2073 intel_sdvo_enable_hotplug(intel_encoder); 2163 intel_sdvo_enable_hotplug(intel_encoder);
2074 } 2164 } else {
2075 else
2076 connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 2165 connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
2166 }
2077 encoder->encoder_type = DRM_MODE_ENCODER_TMDS; 2167 encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
2078 connector->connector_type = DRM_MODE_CONNECTOR_DVID; 2168 connector->connector_type = DRM_MODE_CONNECTOR_DVID;
2079 2169
@@ -2081,8 +2171,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2081 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; 2171 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
2082 intel_sdvo->is_hdmi = true; 2172 intel_sdvo->is_hdmi = true;
2083 } 2173 }
2084 intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | 2174 intel_sdvo->base.cloneable = true;
2085 (1 << INTEL_ANALOG_CLONE_BIT));
2086 2175
2087 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); 2176 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
2088 if (intel_sdvo->is_hdmi) 2177 if (intel_sdvo->is_hdmi)
@@ -2113,7 +2202,7 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
2113 2202
2114 intel_sdvo->is_tv = true; 2203 intel_sdvo->is_tv = true;
2115 intel_sdvo->base.needs_tv_clock = true; 2204 intel_sdvo->base.needs_tv_clock = true;
2116 intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; 2205 intel_sdvo->base.cloneable = false;
2117 2206
2118 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); 2207 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
2119 2208
@@ -2156,8 +2245,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
2156 intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; 2245 intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
2157 } 2246 }
2158 2247
2159 intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | 2248 intel_sdvo->base.cloneable = true;
2160 (1 << INTEL_ANALOG_CLONE_BIT));
2161 2249
2162 intel_sdvo_connector_init(intel_sdvo_connector, 2250 intel_sdvo_connector_init(intel_sdvo_connector,
2163 intel_sdvo); 2251 intel_sdvo);
@@ -2189,8 +2277,10 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
2189 intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; 2277 intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
2190 } 2278 }
2191 2279
2192 intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | 2280 /* SDVO LVDS is cloneable because the SDVO encoder does the upscaling,
2193 (1 << INTEL_SDVO_LVDS_CLONE_BIT)); 2281 * as opposed to native LVDS, where we upscale with the panel-fitter
2282 * (and hence only the native LVDS resolution could be cloned). */
2283 intel_sdvo->base.cloneable = true;
2194 2284
2195 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); 2285 intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
2196 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) 2286 if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
@@ -2575,6 +2665,10 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
2575 2665
2576 drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); 2666 drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
2577 2667
2668 intel_encoder->disable = intel_disable_sdvo;
2669 intel_encoder->enable = intel_enable_sdvo;
2670 intel_encoder->get_hw_state = intel_sdvo_get_hw_state;
2671
2578 /* In default case sdvo lvds is false */ 2672 /* In default case sdvo lvds is false */
2579 if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) 2673 if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
2580 goto err; 2674 goto err;
@@ -2589,7 +2683,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
2589 /* Only enable the hotplug irq if we need it, to work around noisy 2683 /* Only enable the hotplug irq if we need it, to work around noisy
2590 * hotplug lines. 2684 * hotplug lines.
2591 */ 2685 */
2592 if (intel_sdvo->hotplug_active[0]) 2686 if (intel_sdvo->hotplug_active)
2593 dev_priv->hotplug_supported_mask |= hotplug_mask; 2687 dev_priv->hotplug_supported_mask |= hotplug_mask;
2594 2688
2595 intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); 2689 intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg);