diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_tv.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_tv.c | 159 |
1 files changed, 76 insertions, 83 deletions
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index cc3726a4a1c..d2029efee98 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -44,7 +44,9 @@ enum tv_margin { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | /** Private structure for the integrated TV support */ | 46 | /** Private structure for the integrated TV support */ |
47 | struct intel_tv_priv { | 47 | struct intel_tv { |
48 | struct intel_encoder base; | ||
49 | |||
48 | int type; | 50 | int type; |
49 | char *tv_format; | 51 | char *tv_format; |
50 | int margin[4]; | 52 | int margin[4]; |
@@ -896,6 +898,11 @@ static const struct tv_mode tv_modes[] = { | |||
896 | }, | 898 | }, |
897 | }; | 899 | }; |
898 | 900 | ||
901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | ||
902 | { | ||
903 | return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base); | ||
904 | } | ||
905 | |||
899 | static void | 906 | static void |
900 | intel_tv_dpms(struct drm_encoder *encoder, int mode) | 907 | intel_tv_dpms(struct drm_encoder *encoder, int mode) |
901 | { | 908 | { |
@@ -929,19 +936,17 @@ intel_tv_mode_lookup (char *tv_format) | |||
929 | } | 936 | } |
930 | 937 | ||
931 | static const struct tv_mode * | 938 | static const struct tv_mode * |
932 | intel_tv_mode_find (struct intel_encoder *intel_encoder) | 939 | intel_tv_mode_find (struct intel_tv *intel_tv) |
933 | { | 940 | { |
934 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 941 | return intel_tv_mode_lookup(intel_tv->tv_format); |
935 | |||
936 | return intel_tv_mode_lookup(tv_priv->tv_format); | ||
937 | } | 942 | } |
938 | 943 | ||
939 | static enum drm_mode_status | 944 | static enum drm_mode_status |
940 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 945 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) |
941 | { | 946 | { |
942 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 947 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
943 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 948 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
944 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 949 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
945 | 950 | ||
946 | /* Ensure TV refresh is close to desired refresh */ | 951 | /* Ensure TV refresh is close to desired refresh */ |
947 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 952 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
@@ -957,8 +962,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
957 | { | 962 | { |
958 | struct drm_device *dev = encoder->dev; | 963 | struct drm_device *dev = encoder->dev; |
959 | struct drm_mode_config *drm_config = &dev->mode_config; | 964 | struct drm_mode_config *drm_config = &dev->mode_config; |
960 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 965 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
961 | const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); | 966 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
962 | struct drm_encoder *other_encoder; | 967 | struct drm_encoder *other_encoder; |
963 | 968 | ||
964 | if (!tv_mode) | 969 | if (!tv_mode) |
@@ -983,9 +988,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
983 | struct drm_i915_private *dev_priv = dev->dev_private; | 988 | struct drm_i915_private *dev_priv = dev->dev_private; |
984 | struct drm_crtc *crtc = encoder->crtc; | 989 | struct drm_crtc *crtc = encoder->crtc; |
985 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 990 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
986 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 991 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
987 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 992 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
988 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
989 | u32 tv_ctl; | 993 | u32 tv_ctl; |
990 | u32 hctl1, hctl2, hctl3; | 994 | u32 hctl1, hctl2, hctl3; |
991 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; | 995 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; |
@@ -1001,7 +1005,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1001 | tv_ctl = I915_READ(TV_CTL); | 1005 | tv_ctl = I915_READ(TV_CTL); |
1002 | tv_ctl &= TV_CTL_SAVE; | 1006 | tv_ctl &= TV_CTL_SAVE; |
1003 | 1007 | ||
1004 | switch (tv_priv->type) { | 1008 | switch (intel_tv->type) { |
1005 | default: | 1009 | default: |
1006 | case DRM_MODE_CONNECTOR_Unknown: | 1010 | case DRM_MODE_CONNECTOR_Unknown: |
1007 | case DRM_MODE_CONNECTOR_Composite: | 1011 | case DRM_MODE_CONNECTOR_Composite: |
@@ -1154,11 +1158,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1154 | 1158 | ||
1155 | /* Wait for vblank for the disable to take effect */ | 1159 | /* Wait for vblank for the disable to take effect */ |
1156 | if (!IS_I9XX(dev)) | 1160 | if (!IS_I9XX(dev)) |
1157 | intel_wait_for_vblank(dev); | 1161 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1158 | 1162 | ||
1159 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | 1163 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); |
1160 | /* Wait for vblank for the disable to take effect. */ | 1164 | /* Wait for vblank for the disable to take effect. */ |
1161 | intel_wait_for_vblank(dev); | 1165 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1162 | 1166 | ||
1163 | /* Filter ctl must be set before TV_WIN_SIZE */ | 1167 | /* Filter ctl must be set before TV_WIN_SIZE */ |
1164 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); | 1168 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); |
@@ -1168,12 +1172,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1168 | else | 1172 | else |
1169 | ysize = 2*tv_mode->nbr_end + 1; | 1173 | ysize = 2*tv_mode->nbr_end + 1; |
1170 | 1174 | ||
1171 | xpos += tv_priv->margin[TV_MARGIN_LEFT]; | 1175 | xpos += intel_tv->margin[TV_MARGIN_LEFT]; |
1172 | ypos += tv_priv->margin[TV_MARGIN_TOP]; | 1176 | ypos += intel_tv->margin[TV_MARGIN_TOP]; |
1173 | xsize -= (tv_priv->margin[TV_MARGIN_LEFT] + | 1177 | xsize -= (intel_tv->margin[TV_MARGIN_LEFT] + |
1174 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1178 | intel_tv->margin[TV_MARGIN_RIGHT]); |
1175 | ysize -= (tv_priv->margin[TV_MARGIN_TOP] + | 1179 | ysize -= (intel_tv->margin[TV_MARGIN_TOP] + |
1176 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1180 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1177 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); | 1181 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); |
1178 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); | 1182 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); |
1179 | 1183 | ||
@@ -1222,11 +1226,12 @@ static const struct drm_display_mode reported_modes[] = { | |||
1222 | * \return false if TV is disconnected. | 1226 | * \return false if TV is disconnected. |
1223 | */ | 1227 | */ |
1224 | static int | 1228 | static int |
1225 | intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) | 1229 | intel_tv_detect_type (struct intel_tv *intel_tv) |
1226 | { | 1230 | { |
1227 | struct drm_encoder *encoder = &intel_encoder->enc; | 1231 | struct drm_encoder *encoder = &intel_tv->base.enc; |
1228 | struct drm_device *dev = encoder->dev; | 1232 | struct drm_device *dev = encoder->dev; |
1229 | struct drm_i915_private *dev_priv = dev->dev_private; | 1233 | struct drm_i915_private *dev_priv = dev->dev_private; |
1234 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
1230 | unsigned long irqflags; | 1235 | unsigned long irqflags; |
1231 | u32 tv_ctl, save_tv_ctl; | 1236 | u32 tv_ctl, save_tv_ctl; |
1232 | u32 tv_dac, save_tv_dac; | 1237 | u32 tv_dac, save_tv_dac; |
@@ -1263,11 +1268,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
1263 | DAC_C_0_7_V); | 1268 | DAC_C_0_7_V); |
1264 | I915_WRITE(TV_CTL, tv_ctl); | 1269 | I915_WRITE(TV_CTL, tv_ctl); |
1265 | I915_WRITE(TV_DAC, tv_dac); | 1270 | I915_WRITE(TV_DAC, tv_dac); |
1266 | intel_wait_for_vblank(dev); | 1271 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1267 | tv_dac = I915_READ(TV_DAC); | 1272 | tv_dac = I915_READ(TV_DAC); |
1268 | I915_WRITE(TV_DAC, save_tv_dac); | 1273 | I915_WRITE(TV_DAC, save_tv_dac); |
1269 | I915_WRITE(TV_CTL, save_tv_ctl); | 1274 | I915_WRITE(TV_CTL, save_tv_ctl); |
1270 | intel_wait_for_vblank(dev); | 1275 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1271 | /* | 1276 | /* |
1272 | * A B C | 1277 | * A B C |
1273 | * 0 1 1 Composite | 1278 | * 0 1 1 Composite |
@@ -1304,12 +1309,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
1304 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1309 | static void intel_tv_find_better_format(struct drm_connector *connector) |
1305 | { | 1310 | { |
1306 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1311 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1307 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1312 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1308 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1313 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1309 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
1310 | int i; | 1314 | int i; |
1311 | 1315 | ||
1312 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1316 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
1313 | tv_mode->component_only) | 1317 | tv_mode->component_only) |
1314 | return; | 1318 | return; |
1315 | 1319 | ||
@@ -1317,12 +1321,12 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1317 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { | 1321 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { |
1318 | tv_mode = tv_modes + i; | 1322 | tv_mode = tv_modes + i; |
1319 | 1323 | ||
1320 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1324 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
1321 | tv_mode->component_only) | 1325 | tv_mode->component_only) |
1322 | break; | 1326 | break; |
1323 | } | 1327 | } |
1324 | 1328 | ||
1325 | tv_priv->tv_format = tv_mode->name; | 1329 | intel_tv->tv_format = tv_mode->name; |
1326 | drm_connector_property_set_value(connector, | 1330 | drm_connector_property_set_value(connector, |
1327 | connector->dev->mode_config.tv_mode_property, i); | 1331 | connector->dev->mode_config.tv_mode_property, i); |
1328 | } | 1332 | } |
@@ -1336,31 +1340,31 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1336 | static enum drm_connector_status | 1340 | static enum drm_connector_status |
1337 | intel_tv_detect(struct drm_connector *connector) | 1341 | intel_tv_detect(struct drm_connector *connector) |
1338 | { | 1342 | { |
1339 | struct drm_crtc *crtc; | ||
1340 | struct drm_display_mode mode; | 1343 | struct drm_display_mode mode; |
1341 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1344 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1342 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1345 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1343 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1346 | int type; |
1344 | int dpms_mode; | ||
1345 | int type = tv_priv->type; | ||
1346 | 1347 | ||
1347 | mode = reported_modes[0]; | 1348 | mode = reported_modes[0]; |
1348 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1349 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
1349 | 1350 | ||
1350 | if (encoder->crtc && encoder->crtc->enabled) { | 1351 | if (encoder->crtc && encoder->crtc->enabled) { |
1351 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); | 1352 | type = intel_tv_detect_type(intel_tv); |
1352 | } else { | 1353 | } else { |
1353 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, | 1354 | struct drm_crtc *crtc; |
1355 | int dpms_mode; | ||
1356 | |||
1357 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, | ||
1354 | &mode, &dpms_mode); | 1358 | &mode, &dpms_mode); |
1355 | if (crtc) { | 1359 | if (crtc) { |
1356 | type = intel_tv_detect_type(crtc, intel_encoder); | 1360 | type = intel_tv_detect_type(intel_tv); |
1357 | intel_release_load_detect_pipe(intel_encoder, connector, | 1361 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
1358 | dpms_mode); | 1362 | dpms_mode); |
1359 | } else | 1363 | } else |
1360 | type = -1; | 1364 | type = -1; |
1361 | } | 1365 | } |
1362 | 1366 | ||
1363 | tv_priv->type = type; | 1367 | intel_tv->type = type; |
1364 | 1368 | ||
1365 | if (type < 0) | 1369 | if (type < 0) |
1366 | return connector_status_disconnected; | 1370 | return connector_status_disconnected; |
@@ -1391,8 +1395,8 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector, | |||
1391 | struct drm_display_mode *mode_ptr) | 1395 | struct drm_display_mode *mode_ptr) |
1392 | { | 1396 | { |
1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1397 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1394 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1398 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1395 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1399 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1396 | 1400 | ||
1397 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1401 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
1398 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | 1402 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; |
@@ -1417,8 +1421,8 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
1417 | { | 1421 | { |
1418 | struct drm_display_mode *mode_ptr; | 1422 | struct drm_display_mode *mode_ptr; |
1419 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1423 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1420 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1424 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1421 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1425 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1422 | int j, count = 0; | 1426 | int j, count = 0; |
1423 | u64 tmp; | 1427 | u64 tmp; |
1424 | 1428 | ||
@@ -1483,8 +1487,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1483 | { | 1487 | { |
1484 | struct drm_device *dev = connector->dev; | 1488 | struct drm_device *dev = connector->dev; |
1485 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1489 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1486 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1490 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1487 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | ||
1488 | struct drm_crtc *crtc = encoder->crtc; | 1491 | struct drm_crtc *crtc = encoder->crtc; |
1489 | int ret = 0; | 1492 | int ret = 0; |
1490 | bool changed = false; | 1493 | bool changed = false; |
@@ -1494,30 +1497,30 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1494 | goto out; | 1497 | goto out; |
1495 | 1498 | ||
1496 | if (property == dev->mode_config.tv_left_margin_property && | 1499 | if (property == dev->mode_config.tv_left_margin_property && |
1497 | tv_priv->margin[TV_MARGIN_LEFT] != val) { | 1500 | intel_tv->margin[TV_MARGIN_LEFT] != val) { |
1498 | tv_priv->margin[TV_MARGIN_LEFT] = val; | 1501 | intel_tv->margin[TV_MARGIN_LEFT] = val; |
1499 | changed = true; | 1502 | changed = true; |
1500 | } else if (property == dev->mode_config.tv_right_margin_property && | 1503 | } else if (property == dev->mode_config.tv_right_margin_property && |
1501 | tv_priv->margin[TV_MARGIN_RIGHT] != val) { | 1504 | intel_tv->margin[TV_MARGIN_RIGHT] != val) { |
1502 | tv_priv->margin[TV_MARGIN_RIGHT] = val; | 1505 | intel_tv->margin[TV_MARGIN_RIGHT] = val; |
1503 | changed = true; | 1506 | changed = true; |
1504 | } else if (property == dev->mode_config.tv_top_margin_property && | 1507 | } else if (property == dev->mode_config.tv_top_margin_property && |
1505 | tv_priv->margin[TV_MARGIN_TOP] != val) { | 1508 | intel_tv->margin[TV_MARGIN_TOP] != val) { |
1506 | tv_priv->margin[TV_MARGIN_TOP] = val; | 1509 | intel_tv->margin[TV_MARGIN_TOP] = val; |
1507 | changed = true; | 1510 | changed = true; |
1508 | } else if (property == dev->mode_config.tv_bottom_margin_property && | 1511 | } else if (property == dev->mode_config.tv_bottom_margin_property && |
1509 | tv_priv->margin[TV_MARGIN_BOTTOM] != val) { | 1512 | intel_tv->margin[TV_MARGIN_BOTTOM] != val) { |
1510 | tv_priv->margin[TV_MARGIN_BOTTOM] = val; | 1513 | intel_tv->margin[TV_MARGIN_BOTTOM] = val; |
1511 | changed = true; | 1514 | changed = true; |
1512 | } else if (property == dev->mode_config.tv_mode_property) { | 1515 | } else if (property == dev->mode_config.tv_mode_property) { |
1513 | if (val >= ARRAY_SIZE(tv_modes)) { | 1516 | if (val >= ARRAY_SIZE(tv_modes)) { |
1514 | ret = -EINVAL; | 1517 | ret = -EINVAL; |
1515 | goto out; | 1518 | goto out; |
1516 | } | 1519 | } |
1517 | if (!strcmp(tv_priv->tv_format, tv_modes[val].name)) | 1520 | if (!strcmp(intel_tv->tv_format, tv_modes[val].name)) |
1518 | goto out; | 1521 | goto out; |
1519 | 1522 | ||
1520 | tv_priv->tv_format = tv_modes[val].name; | 1523 | intel_tv->tv_format = tv_modes[val].name; |
1521 | changed = true; | 1524 | changed = true; |
1522 | } else { | 1525 | } else { |
1523 | ret = -EINVAL; | 1526 | ret = -EINVAL; |
@@ -1553,16 +1556,8 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = | |||
1553 | .best_encoder = intel_attached_encoder, | 1556 | .best_encoder = intel_attached_encoder, |
1554 | }; | 1557 | }; |
1555 | 1558 | ||
1556 | static void intel_tv_enc_destroy(struct drm_encoder *encoder) | ||
1557 | { | ||
1558 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1559 | |||
1560 | drm_encoder_cleanup(encoder); | ||
1561 | kfree(intel_encoder); | ||
1562 | } | ||
1563 | |||
1564 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1559 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
1565 | .destroy = intel_tv_enc_destroy, | 1560 | .destroy = intel_encoder_destroy, |
1566 | }; | 1561 | }; |
1567 | 1562 | ||
1568 | /* | 1563 | /* |
@@ -1606,9 +1601,9 @@ intel_tv_init(struct drm_device *dev) | |||
1606 | { | 1601 | { |
1607 | struct drm_i915_private *dev_priv = dev->dev_private; | 1602 | struct drm_i915_private *dev_priv = dev->dev_private; |
1608 | struct drm_connector *connector; | 1603 | struct drm_connector *connector; |
1604 | struct intel_tv *intel_tv; | ||
1609 | struct intel_encoder *intel_encoder; | 1605 | struct intel_encoder *intel_encoder; |
1610 | struct intel_connector *intel_connector; | 1606 | struct intel_connector *intel_connector; |
1611 | struct intel_tv_priv *tv_priv; | ||
1612 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1607 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
1613 | char **tv_format_names; | 1608 | char **tv_format_names; |
1614 | int i, initial_mode = 0; | 1609 | int i, initial_mode = 0; |
@@ -1647,18 +1642,18 @@ intel_tv_init(struct drm_device *dev) | |||
1647 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) | 1642 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) |
1648 | return; | 1643 | return; |
1649 | 1644 | ||
1650 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 1645 | intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL); |
1651 | sizeof(struct intel_tv_priv), GFP_KERNEL); | 1646 | if (!intel_tv) { |
1652 | if (!intel_encoder) { | ||
1653 | return; | 1647 | return; |
1654 | } | 1648 | } |
1655 | 1649 | ||
1656 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1650 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1657 | if (!intel_connector) { | 1651 | if (!intel_connector) { |
1658 | kfree(intel_encoder); | 1652 | kfree(intel_tv); |
1659 | return; | 1653 | return; |
1660 | } | 1654 | } |
1661 | 1655 | ||
1656 | intel_encoder = &intel_tv->base; | ||
1662 | connector = &intel_connector->base; | 1657 | connector = &intel_connector->base; |
1663 | 1658 | ||
1664 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1659 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
@@ -1668,22 +1663,20 @@ intel_tv_init(struct drm_device *dev) | |||
1668 | DRM_MODE_ENCODER_TVDAC); | 1663 | DRM_MODE_ENCODER_TVDAC); |
1669 | 1664 | ||
1670 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 1665 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); |
1671 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); | ||
1672 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1666 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
1673 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1667 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1674 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1668 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
1675 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1669 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
1676 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1670 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1677 | intel_encoder->dev_priv = tv_priv; | 1671 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; |
1678 | tv_priv->type = DRM_MODE_CONNECTOR_Unknown; | ||
1679 | 1672 | ||
1680 | /* BIOS margin values */ | 1673 | /* BIOS margin values */ |
1681 | tv_priv->margin[TV_MARGIN_LEFT] = 54; | 1674 | intel_tv->margin[TV_MARGIN_LEFT] = 54; |
1682 | tv_priv->margin[TV_MARGIN_TOP] = 36; | 1675 | intel_tv->margin[TV_MARGIN_TOP] = 36; |
1683 | tv_priv->margin[TV_MARGIN_RIGHT] = 46; | 1676 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; |
1684 | tv_priv->margin[TV_MARGIN_BOTTOM] = 37; | 1677 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; |
1685 | 1678 | ||
1686 | tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1679 | intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); |
1687 | 1680 | ||
1688 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); | 1681 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); |
1689 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1682 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
@@ -1703,16 +1696,16 @@ intel_tv_init(struct drm_device *dev) | |||
1703 | initial_mode); | 1696 | initial_mode); |
1704 | drm_connector_attach_property(connector, | 1697 | drm_connector_attach_property(connector, |
1705 | dev->mode_config.tv_left_margin_property, | 1698 | dev->mode_config.tv_left_margin_property, |
1706 | tv_priv->margin[TV_MARGIN_LEFT]); | 1699 | intel_tv->margin[TV_MARGIN_LEFT]); |
1707 | drm_connector_attach_property(connector, | 1700 | drm_connector_attach_property(connector, |
1708 | dev->mode_config.tv_top_margin_property, | 1701 | dev->mode_config.tv_top_margin_property, |
1709 | tv_priv->margin[TV_MARGIN_TOP]); | 1702 | intel_tv->margin[TV_MARGIN_TOP]); |
1710 | drm_connector_attach_property(connector, | 1703 | drm_connector_attach_property(connector, |
1711 | dev->mode_config.tv_right_margin_property, | 1704 | dev->mode_config.tv_right_margin_property, |
1712 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1705 | intel_tv->margin[TV_MARGIN_RIGHT]); |
1713 | drm_connector_attach_property(connector, | 1706 | drm_connector_attach_property(connector, |
1714 | dev->mode_config.tv_bottom_margin_property, | 1707 | dev->mode_config.tv_bottom_margin_property, |
1715 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1708 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1716 | out: | 1709 | out: |
1717 | drm_sysfs_connector_add(connector); | 1710 | drm_sysfs_connector_add(connector); |
1718 | } | 1711 | } |