diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_tv.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_tv.c | 232 |
1 files changed, 122 insertions, 110 deletions
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 4a117e318a73..113e4e7264cd 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -48,7 +48,7 @@ struct intel_tv { | |||
48 | struct intel_encoder base; | 48 | struct intel_encoder base; |
49 | 49 | ||
50 | int type; | 50 | int type; |
51 | char *tv_format; | 51 | const char *tv_format; |
52 | int margin[4]; | 52 | int margin[4]; |
53 | u32 save_TV_H_CTL_1; | 53 | u32 save_TV_H_CTL_1; |
54 | u32 save_TV_H_CTL_2; | 54 | u32 save_TV_H_CTL_2; |
@@ -350,7 +350,7 @@ static const struct video_levels component_levels = { | |||
350 | 350 | ||
351 | 351 | ||
352 | struct tv_mode { | 352 | struct tv_mode { |
353 | char *name; | 353 | const char *name; |
354 | int clock; | 354 | int clock; |
355 | int refresh; /* in millihertz (for precision) */ | 355 | int refresh; /* in millihertz (for precision) */ |
356 | u32 oversample; | 356 | u32 oversample; |
@@ -900,7 +900,14 @@ static const struct tv_mode tv_modes[] = { | |||
900 | 900 | ||
901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | 901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) |
902 | { | 902 | { |
903 | return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base); | 903 | return container_of(encoder, struct intel_tv, base.base); |
904 | } | ||
905 | |||
906 | static struct intel_tv *intel_attached_tv(struct drm_connector *connector) | ||
907 | { | ||
908 | return container_of(intel_attached_encoder(connector), | ||
909 | struct intel_tv, | ||
910 | base); | ||
904 | } | 911 | } |
905 | 912 | ||
906 | static void | 913 | static void |
@@ -922,7 +929,7 @@ intel_tv_dpms(struct drm_encoder *encoder, int mode) | |||
922 | } | 929 | } |
923 | 930 | ||
924 | static const struct tv_mode * | 931 | static const struct tv_mode * |
925 | intel_tv_mode_lookup (char *tv_format) | 932 | intel_tv_mode_lookup(const char *tv_format) |
926 | { | 933 | { |
927 | int i; | 934 | int i; |
928 | 935 | ||
@@ -936,22 +943,23 @@ intel_tv_mode_lookup (char *tv_format) | |||
936 | } | 943 | } |
937 | 944 | ||
938 | static const struct tv_mode * | 945 | static const struct tv_mode * |
939 | intel_tv_mode_find (struct intel_tv *intel_tv) | 946 | intel_tv_mode_find(struct intel_tv *intel_tv) |
940 | { | 947 | { |
941 | return intel_tv_mode_lookup(intel_tv->tv_format); | 948 | return intel_tv_mode_lookup(intel_tv->tv_format); |
942 | } | 949 | } |
943 | 950 | ||
944 | static enum drm_mode_status | 951 | static enum drm_mode_status |
945 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 952 | intel_tv_mode_valid(struct drm_connector *connector, |
953 | struct drm_display_mode *mode) | ||
946 | { | 954 | { |
947 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 955 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
948 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
949 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 956 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
950 | 957 | ||
951 | /* Ensure TV refresh is close to desired refresh */ | 958 | /* Ensure TV refresh is close to desired refresh */ |
952 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 959 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
953 | < 1000) | 960 | < 1000) |
954 | return MODE_OK; | 961 | return MODE_OK; |
962 | |||
955 | return MODE_CLOCK_RANGE; | 963 | return MODE_CLOCK_RANGE; |
956 | } | 964 | } |
957 | 965 | ||
@@ -998,6 +1006,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
998 | const struct video_levels *video_levels; | 1006 | const struct video_levels *video_levels; |
999 | const struct color_conversion *color_conversion; | 1007 | const struct color_conversion *color_conversion; |
1000 | bool burst_ena; | 1008 | bool burst_ena; |
1009 | int pipe = intel_crtc->pipe; | ||
1001 | 1010 | ||
1002 | if (!tv_mode) | 1011 | if (!tv_mode) |
1003 | return; /* can't happen (mode_prepare prevents this) */ | 1012 | return; /* can't happen (mode_prepare prevents this) */ |
@@ -1131,7 +1140,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1131 | color_conversion->av); | 1140 | color_conversion->av); |
1132 | } | 1141 | } |
1133 | 1142 | ||
1134 | if (IS_I965G(dev)) | 1143 | if (INTEL_INFO(dev)->gen >= 4) |
1135 | I915_WRITE(TV_CLR_KNOBS, 0x00404000); | 1144 | I915_WRITE(TV_CLR_KNOBS, 0x00404000); |
1136 | else | 1145 | else |
1137 | I915_WRITE(TV_CLR_KNOBS, 0x00606000); | 1146 | I915_WRITE(TV_CLR_KNOBS, 0x00606000); |
@@ -1141,14 +1150,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1141 | ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | | 1150 | ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | |
1142 | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); | 1151 | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); |
1143 | { | 1152 | { |
1144 | int pipeconf_reg = (intel_crtc->pipe == 0) ? | 1153 | int pipeconf_reg = PIPECONF(pipe); |
1145 | PIPEACONF : PIPEBCONF; | 1154 | int dspcntr_reg = DSPCNTR(intel_crtc->plane); |
1146 | int dspcntr_reg = (intel_crtc->plane == 0) ? | ||
1147 | DSPACNTR : DSPBCNTR; | ||
1148 | int pipeconf = I915_READ(pipeconf_reg); | 1155 | int pipeconf = I915_READ(pipeconf_reg); |
1149 | int dspcntr = I915_READ(dspcntr_reg); | 1156 | int dspcntr = I915_READ(dspcntr_reg); |
1150 | int dspbase_reg = (intel_crtc->plane == 0) ? | 1157 | int dspbase_reg = DSPADDR(intel_crtc->plane); |
1151 | DSPAADDR : DSPBADDR; | ||
1152 | int xpos = 0x0, ypos = 0x0; | 1158 | int xpos = 0x0, ypos = 0x0; |
1153 | unsigned int xsize, ysize; | 1159 | unsigned int xsize, ysize; |
1154 | /* Pipe must be off here */ | 1160 | /* Pipe must be off here */ |
@@ -1157,12 +1163,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1157 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); | 1163 | I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); |
1158 | 1164 | ||
1159 | /* Wait for vblank for the disable to take effect */ | 1165 | /* Wait for vblank for the disable to take effect */ |
1160 | if (!IS_I9XX(dev)) | 1166 | if (IS_GEN2(dev)) |
1161 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1167 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1162 | 1168 | ||
1163 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | 1169 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE); |
1164 | /* Wait for vblank for the disable to take effect. */ | 1170 | /* Wait for vblank for the disable to take effect. */ |
1165 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1171 | intel_wait_for_pipe_off(dev, intel_crtc->pipe); |
1166 | 1172 | ||
1167 | /* Filter ctl must be set before TV_WIN_SIZE */ | 1173 | /* Filter ctl must be set before TV_WIN_SIZE */ |
1168 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); | 1174 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); |
@@ -1196,7 +1202,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1196 | I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); | 1202 | I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); |
1197 | for (i = 0; i < 43; i++) | 1203 | for (i = 0; i < 43; i++) |
1198 | I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); | 1204 | I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); |
1199 | I915_WRITE(TV_DAC, 0); | 1205 | I915_WRITE(TV_DAC, I915_READ(TV_DAC) & TV_DAC_SAVE); |
1200 | I915_WRITE(TV_CTL, tv_ctl); | 1206 | I915_WRITE(TV_CTL, tv_ctl); |
1201 | } | 1207 | } |
1202 | 1208 | ||
@@ -1226,37 +1232,34 @@ static const struct drm_display_mode reported_modes[] = { | |||
1226 | * \return false if TV is disconnected. | 1232 | * \return false if TV is disconnected. |
1227 | */ | 1233 | */ |
1228 | static int | 1234 | static int |
1229 | intel_tv_detect_type (struct intel_tv *intel_tv) | 1235 | intel_tv_detect_type (struct intel_tv *intel_tv, |
1236 | struct drm_connector *connector) | ||
1230 | { | 1237 | { |
1231 | struct drm_encoder *encoder = &intel_tv->base.enc; | 1238 | struct drm_encoder *encoder = &intel_tv->base.base; |
1232 | struct drm_device *dev = encoder->dev; | 1239 | struct drm_device *dev = encoder->dev; |
1233 | struct drm_i915_private *dev_priv = dev->dev_private; | 1240 | struct drm_i915_private *dev_priv = dev->dev_private; |
1234 | unsigned long irqflags; | 1241 | unsigned long irqflags; |
1235 | u32 tv_ctl, save_tv_ctl; | 1242 | u32 tv_ctl, save_tv_ctl; |
1236 | u32 tv_dac, save_tv_dac; | 1243 | u32 tv_dac, save_tv_dac; |
1237 | int type = DRM_MODE_CONNECTOR_Unknown; | 1244 | int type; |
1238 | |||
1239 | tv_dac = I915_READ(TV_DAC); | ||
1240 | 1245 | ||
1241 | /* Disable TV interrupts around load detect or we'll recurse */ | 1246 | /* Disable TV interrupts around load detect or we'll recurse */ |
1242 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1247 | if (connector->polled & DRM_CONNECTOR_POLL_HPD) { |
1243 | i915_disable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | | 1248 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1244 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | 1249 | i915_disable_pipestat(dev_priv, 0, |
1245 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1250 | PIPE_HOTPLUG_INTERRUPT_ENABLE | |
1251 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | ||
1252 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
1253 | } | ||
1246 | 1254 | ||
1247 | /* | 1255 | save_tv_dac = tv_dac = I915_READ(TV_DAC); |
1248 | * Detect TV by polling) | 1256 | save_tv_ctl = tv_ctl = I915_READ(TV_CTL); |
1249 | */ | 1257 | |
1250 | save_tv_dac = tv_dac; | 1258 | /* Poll for TV detection */ |
1251 | tv_ctl = I915_READ(TV_CTL); | 1259 | tv_ctl &= ~(TV_ENC_ENABLE | TV_TEST_MODE_MASK); |
1252 | save_tv_ctl = tv_ctl; | ||
1253 | tv_ctl &= ~TV_ENC_ENABLE; | ||
1254 | tv_ctl &= ~TV_TEST_MODE_MASK; | ||
1255 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; | 1260 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; |
1256 | tv_dac &= ~TVDAC_SENSE_MASK; | 1261 | |
1257 | tv_dac &= ~DAC_A_MASK; | 1262 | tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK); |
1258 | tv_dac &= ~DAC_B_MASK; | ||
1259 | tv_dac &= ~DAC_C_MASK; | ||
1260 | tv_dac |= (TVDAC_STATE_CHG_EN | | 1263 | tv_dac |= (TVDAC_STATE_CHG_EN | |
1261 | TVDAC_A_SENSE_CTL | | 1264 | TVDAC_A_SENSE_CTL | |
1262 | TVDAC_B_SENSE_CTL | | 1265 | TVDAC_B_SENSE_CTL | |
@@ -1265,42 +1268,48 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1265 | DAC_A_0_7_V | | 1268 | DAC_A_0_7_V | |
1266 | DAC_B_0_7_V | | 1269 | DAC_B_0_7_V | |
1267 | DAC_C_0_7_V); | 1270 | DAC_C_0_7_V); |
1271 | |||
1268 | I915_WRITE(TV_CTL, tv_ctl); | 1272 | I915_WRITE(TV_CTL, tv_ctl); |
1269 | I915_WRITE(TV_DAC, tv_dac); | 1273 | I915_WRITE(TV_DAC, tv_dac); |
1270 | POSTING_READ(TV_DAC); | 1274 | POSTING_READ(TV_DAC); |
1271 | msleep(20); | ||
1272 | 1275 | ||
1273 | tv_dac = I915_READ(TV_DAC); | 1276 | intel_wait_for_vblank(intel_tv->base.base.dev, |
1274 | I915_WRITE(TV_DAC, save_tv_dac); | 1277 | to_intel_crtc(intel_tv->base.base.crtc)->pipe); |
1275 | I915_WRITE(TV_CTL, save_tv_ctl); | ||
1276 | POSTING_READ(TV_CTL); | ||
1277 | msleep(20); | ||
1278 | 1278 | ||
1279 | /* | 1279 | type = -1; |
1280 | * A B C | 1280 | if (wait_for((tv_dac = I915_READ(TV_DAC)) & TVDAC_STATE_CHG, 20) == 0) { |
1281 | * 0 1 1 Composite | 1281 | DRM_DEBUG_KMS("TV detected: %x, %x\n", tv_ctl, tv_dac); |
1282 | * 1 0 X svideo | 1282 | /* |
1283 | * 0 0 0 Component | 1283 | * A B C |
1284 | */ | 1284 | * 0 1 1 Composite |
1285 | if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { | 1285 | * 1 0 X svideo |
1286 | DRM_DEBUG_KMS("Detected Composite TV connection\n"); | 1286 | * 0 0 0 Component |
1287 | type = DRM_MODE_CONNECTOR_Composite; | 1287 | */ |
1288 | } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { | 1288 | if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { |
1289 | DRM_DEBUG_KMS("Detected S-Video TV connection\n"); | 1289 | DRM_DEBUG_KMS("Detected Composite TV connection\n"); |
1290 | type = DRM_MODE_CONNECTOR_SVIDEO; | 1290 | type = DRM_MODE_CONNECTOR_Composite; |
1291 | } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { | 1291 | } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { |
1292 | DRM_DEBUG_KMS("Detected Component TV connection\n"); | 1292 | DRM_DEBUG_KMS("Detected S-Video TV connection\n"); |
1293 | type = DRM_MODE_CONNECTOR_Component; | 1293 | type = DRM_MODE_CONNECTOR_SVIDEO; |
1294 | } else { | 1294 | } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { |
1295 | DRM_DEBUG_KMS("No TV connection detected\n"); | 1295 | DRM_DEBUG_KMS("Detected Component TV connection\n"); |
1296 | type = -1; | 1296 | type = DRM_MODE_CONNECTOR_Component; |
1297 | } else { | ||
1298 | DRM_DEBUG_KMS("Unrecognised TV connection\n"); | ||
1299 | } | ||
1297 | } | 1300 | } |
1298 | 1301 | ||
1302 | I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); | ||
1303 | I915_WRITE(TV_CTL, save_tv_ctl); | ||
1304 | |||
1299 | /* Restore interrupt config */ | 1305 | /* Restore interrupt config */ |
1300 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 1306 | if (connector->polled & DRM_CONNECTOR_POLL_HPD) { |
1301 | i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | | 1307 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
1302 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | 1308 | i915_enable_pipestat(dev_priv, 0, |
1303 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 1309 | PIPE_HOTPLUG_INTERRUPT_ENABLE | |
1310 | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); | ||
1311 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | ||
1312 | } | ||
1304 | 1313 | ||
1305 | return type; | 1314 | return type; |
1306 | } | 1315 | } |
@@ -1311,8 +1320,7 @@ intel_tv_detect_type (struct intel_tv *intel_tv) | |||
1311 | */ | 1320 | */ |
1312 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1321 | static void intel_tv_find_better_format(struct drm_connector *connector) |
1313 | { | 1322 | { |
1314 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1323 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1315 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1316 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 1324 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1317 | int i; | 1325 | int i; |
1318 | 1326 | ||
@@ -1344,25 +1352,23 @@ static enum drm_connector_status | |||
1344 | intel_tv_detect(struct drm_connector *connector, bool force) | 1352 | intel_tv_detect(struct drm_connector *connector, bool force) |
1345 | { | 1353 | { |
1346 | struct drm_display_mode mode; | 1354 | struct drm_display_mode mode; |
1347 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1355 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1348 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1349 | int type; | 1356 | int type; |
1350 | 1357 | ||
1351 | mode = reported_modes[0]; | 1358 | mode = reported_modes[0]; |
1352 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1359 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
1353 | 1360 | ||
1354 | if (encoder->crtc && encoder->crtc->enabled) { | 1361 | if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { |
1355 | type = intel_tv_detect_type(intel_tv); | 1362 | type = intel_tv_detect_type(intel_tv, connector); |
1356 | } else if (force) { | 1363 | } else if (force) { |
1357 | struct drm_crtc *crtc; | 1364 | struct intel_load_detect_pipe tmp; |
1358 | int dpms_mode; | 1365 | |
1359 | 1366 | if (intel_get_load_detect_pipe(&intel_tv->base, connector, | |
1360 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, | 1367 | &mode, &tmp)) { |
1361 | &mode, &dpms_mode); | 1368 | type = intel_tv_detect_type(intel_tv, connector); |
1362 | if (crtc) { | 1369 | intel_release_load_detect_pipe(&intel_tv->base, |
1363 | type = intel_tv_detect_type(intel_tv); | 1370 | connector, |
1364 | intel_release_load_detect_pipe(&intel_tv->base, connector, | 1371 | &tmp); |
1365 | dpms_mode); | ||
1366 | } else | 1372 | } else |
1367 | return connector_status_unknown; | 1373 | return connector_status_unknown; |
1368 | } else | 1374 | } else |
@@ -1371,15 +1377,16 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
1371 | if (type < 0) | 1377 | if (type < 0) |
1372 | return connector_status_disconnected; | 1378 | return connector_status_disconnected; |
1373 | 1379 | ||
1380 | intel_tv->type = type; | ||
1374 | intel_tv_find_better_format(connector); | 1381 | intel_tv_find_better_format(connector); |
1382 | |||
1375 | return connector_status_connected; | 1383 | return connector_status_connected; |
1376 | } | 1384 | } |
1377 | 1385 | ||
1378 | static struct input_res { | 1386 | static const struct input_res { |
1379 | char *name; | 1387 | const char *name; |
1380 | int w, h; | 1388 | int w, h; |
1381 | } input_res_table[] = | 1389 | } input_res_table[] = { |
1382 | { | ||
1383 | {"640x480", 640, 480}, | 1390 | {"640x480", 640, 480}, |
1384 | {"800x600", 800, 600}, | 1391 | {"800x600", 800, 600}, |
1385 | {"1024x768", 1024, 768}, | 1392 | {"1024x768", 1024, 768}, |
@@ -1396,8 +1403,7 @@ static void | |||
1396 | intel_tv_chose_preferred_modes(struct drm_connector *connector, | 1403 | intel_tv_chose_preferred_modes(struct drm_connector *connector, |
1397 | struct drm_display_mode *mode_ptr) | 1404 | struct drm_display_mode *mode_ptr) |
1398 | { | 1405 | { |
1399 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1406 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1400 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1401 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 1407 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1402 | 1408 | ||
1403 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1409 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
@@ -1422,15 +1428,14 @@ static int | |||
1422 | intel_tv_get_modes(struct drm_connector *connector) | 1428 | intel_tv_get_modes(struct drm_connector *connector) |
1423 | { | 1429 | { |
1424 | struct drm_display_mode *mode_ptr; | 1430 | struct drm_display_mode *mode_ptr; |
1425 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1431 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1426 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | ||
1427 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 1432 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1428 | int j, count = 0; | 1433 | int j, count = 0; |
1429 | u64 tmp; | 1434 | u64 tmp; |
1430 | 1435 | ||
1431 | for (j = 0; j < ARRAY_SIZE(input_res_table); | 1436 | for (j = 0; j < ARRAY_SIZE(input_res_table); |
1432 | j++) { | 1437 | j++) { |
1433 | struct input_res *input = &input_res_table[j]; | 1438 | const struct input_res *input = &input_res_table[j]; |
1434 | unsigned int hactive_s = input->w; | 1439 | unsigned int hactive_s = input->w; |
1435 | unsigned int vactive_s = input->h; | 1440 | unsigned int vactive_s = input->h; |
1436 | 1441 | ||
@@ -1488,9 +1493,8 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1488 | uint64_t val) | 1493 | uint64_t val) |
1489 | { | 1494 | { |
1490 | struct drm_device *dev = connector->dev; | 1495 | struct drm_device *dev = connector->dev; |
1491 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1496 | struct intel_tv *intel_tv = intel_attached_tv(connector); |
1492 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | 1497 | struct drm_crtc *crtc = intel_tv->base.base.crtc; |
1493 | struct drm_crtc *crtc = encoder->crtc; | ||
1494 | int ret = 0; | 1498 | int ret = 0; |
1495 | bool changed = false; | 1499 | bool changed = false; |
1496 | 1500 | ||
@@ -1555,7 +1559,7 @@ static const struct drm_connector_funcs intel_tv_connector_funcs = { | |||
1555 | static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { | 1559 | static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = { |
1556 | .mode_valid = intel_tv_mode_valid, | 1560 | .mode_valid = intel_tv_mode_valid, |
1557 | .get_modes = intel_tv_get_modes, | 1561 | .get_modes = intel_tv_get_modes, |
1558 | .best_encoder = intel_attached_encoder, | 1562 | .best_encoder = intel_best_encoder, |
1559 | }; | 1563 | }; |
1560 | 1564 | ||
1561 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1565 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
@@ -1607,7 +1611,7 @@ intel_tv_init(struct drm_device *dev) | |||
1607 | struct intel_encoder *intel_encoder; | 1611 | struct intel_encoder *intel_encoder; |
1608 | struct intel_connector *intel_connector; | 1612 | struct intel_connector *intel_connector; |
1609 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1613 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
1610 | char **tv_format_names; | 1614 | char *tv_format_names[ARRAY_SIZE(tv_modes)]; |
1611 | int i, initial_mode = 0; | 1615 | int i, initial_mode = 0; |
1612 | 1616 | ||
1613 | if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) | 1617 | if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) |
@@ -1658,18 +1662,29 @@ intel_tv_init(struct drm_device *dev) | |||
1658 | intel_encoder = &intel_tv->base; | 1662 | intel_encoder = &intel_tv->base; |
1659 | connector = &intel_connector->base; | 1663 | connector = &intel_connector->base; |
1660 | 1664 | ||
1665 | /* The documentation, for the older chipsets at least, recommend | ||
1666 | * using a polling method rather than hotplug detection for TVs. | ||
1667 | * This is because in order to perform the hotplug detection, the PLLs | ||
1668 | * for the TV must be kept alive increasing power drain and starving | ||
1669 | * bandwidth from other encoders. Notably for instance, it causes | ||
1670 | * pipe underruns on Crestline when this encoder is supposedly idle. | ||
1671 | * | ||
1672 | * More recent chipsets favour HDMI rather than integrated S-Video. | ||
1673 | */ | ||
1674 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
1675 | |||
1661 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1676 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
1662 | DRM_MODE_CONNECTOR_SVIDEO); | 1677 | DRM_MODE_CONNECTOR_SVIDEO); |
1663 | 1678 | ||
1664 | drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs, | 1679 | drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs, |
1665 | DRM_MODE_ENCODER_TVDAC); | 1680 | DRM_MODE_ENCODER_TVDAC); |
1666 | 1681 | ||
1667 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 1682 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
1668 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1683 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
1669 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1684 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1670 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1685 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
1671 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1686 | intel_encoder->base.possible_crtcs = ((1 << 0) | (1 << 1)); |
1672 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1687 | intel_encoder->base.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1673 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; | 1688 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; |
1674 | 1689 | ||
1675 | /* BIOS margin values */ | 1690 | /* BIOS margin values */ |
@@ -1678,21 +1693,19 @@ intel_tv_init(struct drm_device *dev) | |||
1678 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; | 1693 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; |
1679 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; | 1694 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; |
1680 | 1695 | ||
1681 | intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1696 | intel_tv->tv_format = tv_modes[initial_mode].name; |
1682 | 1697 | ||
1683 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); | 1698 | drm_encoder_helper_add(&intel_encoder->base, &intel_tv_helper_funcs); |
1684 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1699 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
1685 | connector->interlace_allowed = false; | 1700 | connector->interlace_allowed = false; |
1686 | connector->doublescan_allowed = false; | 1701 | connector->doublescan_allowed = false; |
1687 | 1702 | ||
1688 | /* Create TV properties then attach current values */ | 1703 | /* Create TV properties then attach current values */ |
1689 | tv_format_names = kmalloc(sizeof(char *) * ARRAY_SIZE(tv_modes), | ||
1690 | GFP_KERNEL); | ||
1691 | if (!tv_format_names) | ||
1692 | goto out; | ||
1693 | for (i = 0; i < ARRAY_SIZE(tv_modes); i++) | 1704 | for (i = 0; i < ARRAY_SIZE(tv_modes); i++) |
1694 | tv_format_names[i] = tv_modes[i].name; | 1705 | tv_format_names[i] = (char *)tv_modes[i].name; |
1695 | drm_mode_create_tv_properties(dev, ARRAY_SIZE(tv_modes), tv_format_names); | 1706 | drm_mode_create_tv_properties(dev, |
1707 | ARRAY_SIZE(tv_modes), | ||
1708 | tv_format_names); | ||
1696 | 1709 | ||
1697 | drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, | 1710 | drm_connector_attach_property(connector, dev->mode_config.tv_mode_property, |
1698 | initial_mode); | 1711 | initial_mode); |
@@ -1708,6 +1721,5 @@ intel_tv_init(struct drm_device *dev) | |||
1708 | drm_connector_attach_property(connector, | 1721 | drm_connector_attach_property(connector, |
1709 | dev->mode_config.tv_bottom_margin_property, | 1722 | dev->mode_config.tv_bottom_margin_property, |
1710 | intel_tv->margin[TV_MARGIN_BOTTOM]); | 1723 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1711 | out: | ||
1712 | drm_sysfs_connector_add(connector); | 1724 | drm_sysfs_connector_add(connector); |
1713 | } | 1725 | } |