diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 118 |
1 files changed, 101 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 26c12a3fe430..a03c73411a56 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1052,7 +1052,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
1052 | int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); | 1052 | int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); |
1053 | 1053 | ||
1054 | /* pass the actual clock to atombios_crtc_program_pll for DCE5,6 for HDMI */ | 1054 | /* pass the actual clock to atombios_crtc_program_pll for DCE5,6 for HDMI */ |
1055 | if (ASIC_IS_DCE5(rdev) && !ASIC_IS_DCE8(rdev) && | 1055 | if (ASIC_IS_DCE5(rdev) && |
1056 | (encoder_mode == ATOM_ENCODER_MODE_HDMI) && | 1056 | (encoder_mode == ATOM_ENCODER_MODE_HDMI) && |
1057 | (radeon_crtc->bpc > 8)) | 1057 | (radeon_crtc->bpc > 8)) |
1058 | clock = radeon_crtc->adjusted_clock; | 1058 | clock = radeon_crtc->adjusted_clock; |
@@ -1136,6 +1136,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1136 | u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); | 1136 | u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); |
1137 | u32 tmp, viewport_w, viewport_h; | 1137 | u32 tmp, viewport_w, viewport_h; |
1138 | int r; | 1138 | int r; |
1139 | bool bypass_lut = false; | ||
1139 | 1140 | ||
1140 | /* no fb bound */ | 1141 | /* no fb bound */ |
1141 | if (!atomic && !crtc->primary->fb) { | 1142 | if (!atomic && !crtc->primary->fb) { |
@@ -1174,33 +1175,73 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1174 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | 1175 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); |
1175 | radeon_bo_unreserve(rbo); | 1176 | radeon_bo_unreserve(rbo); |
1176 | 1177 | ||
1177 | switch (target_fb->bits_per_pixel) { | 1178 | switch (target_fb->pixel_format) { |
1178 | case 8: | 1179 | case DRM_FORMAT_C8: |
1179 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | | 1180 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | |
1180 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); | 1181 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); |
1181 | break; | 1182 | break; |
1182 | case 15: | 1183 | case DRM_FORMAT_XRGB4444: |
1184 | case DRM_FORMAT_ARGB4444: | ||
1185 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | | ||
1186 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB4444)); | ||
1187 | #ifdef __BIG_ENDIAN | ||
1188 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16); | ||
1189 | #endif | ||
1190 | break; | ||
1191 | case DRM_FORMAT_XRGB1555: | ||
1192 | case DRM_FORMAT_ARGB1555: | ||
1183 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | | 1193 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | |
1184 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555)); | 1194 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555)); |
1195 | #ifdef __BIG_ENDIAN | ||
1196 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16); | ||
1197 | #endif | ||
1198 | break; | ||
1199 | case DRM_FORMAT_BGRX5551: | ||
1200 | case DRM_FORMAT_BGRA5551: | ||
1201 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | | ||
1202 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA5551)); | ||
1203 | #ifdef __BIG_ENDIAN | ||
1204 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16); | ||
1205 | #endif | ||
1185 | break; | 1206 | break; |
1186 | case 16: | 1207 | case DRM_FORMAT_RGB565: |
1187 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | | 1208 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | |
1188 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565)); | 1209 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565)); |
1189 | #ifdef __BIG_ENDIAN | 1210 | #ifdef __BIG_ENDIAN |
1190 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16); | 1211 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16); |
1191 | #endif | 1212 | #endif |
1192 | break; | 1213 | break; |
1193 | case 24: | 1214 | case DRM_FORMAT_XRGB8888: |
1194 | case 32: | 1215 | case DRM_FORMAT_ARGB8888: |
1195 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | | 1216 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | |
1196 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888)); | 1217 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888)); |
1197 | #ifdef __BIG_ENDIAN | 1218 | #ifdef __BIG_ENDIAN |
1198 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); | 1219 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); |
1199 | #endif | 1220 | #endif |
1200 | break; | 1221 | break; |
1222 | case DRM_FORMAT_XRGB2101010: | ||
1223 | case DRM_FORMAT_ARGB2101010: | ||
1224 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | | ||
1225 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB2101010)); | ||
1226 | #ifdef __BIG_ENDIAN | ||
1227 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); | ||
1228 | #endif | ||
1229 | /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */ | ||
1230 | bypass_lut = true; | ||
1231 | break; | ||
1232 | case DRM_FORMAT_BGRX1010102: | ||
1233 | case DRM_FORMAT_BGRA1010102: | ||
1234 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | | ||
1235 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA1010102)); | ||
1236 | #ifdef __BIG_ENDIAN | ||
1237 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); | ||
1238 | #endif | ||
1239 | /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */ | ||
1240 | bypass_lut = true; | ||
1241 | break; | ||
1201 | default: | 1242 | default: |
1202 | DRM_ERROR("Unsupported screen depth %d\n", | 1243 | DRM_ERROR("Unsupported screen format %s\n", |
1203 | target_fb->bits_per_pixel); | 1244 | drm_get_format_name(target_fb->pixel_format)); |
1204 | return -EINVAL; | 1245 | return -EINVAL; |
1205 | } | 1246 | } |
1206 | 1247 | ||
@@ -1329,6 +1370,18 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1329 | WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); | 1370 | WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); |
1330 | WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); | 1371 | WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); |
1331 | 1372 | ||
1373 | /* | ||
1374 | * The LUT only has 256 slots for indexing by a 8 bpc fb. Bypass the LUT | ||
1375 | * for > 8 bpc scanout to avoid truncation of fb indices to 8 msb's, to | ||
1376 | * retain the full precision throughout the pipeline. | ||
1377 | */ | ||
1378 | WREG32_P(EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL + radeon_crtc->crtc_offset, | ||
1379 | (bypass_lut ? EVERGREEN_LUT_10BIT_BYPASS_EN : 0), | ||
1380 | ~EVERGREEN_LUT_10BIT_BYPASS_EN); | ||
1381 | |||
1382 | if (bypass_lut) | ||
1383 | DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n"); | ||
1384 | |||
1332 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); | 1385 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
1333 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1386 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
1334 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); | 1387 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); |
@@ -1396,6 +1449,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1396 | u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; | 1449 | u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; |
1397 | u32 tmp, viewport_w, viewport_h; | 1450 | u32 tmp, viewport_w, viewport_h; |
1398 | int r; | 1451 | int r; |
1452 | bool bypass_lut = false; | ||
1399 | 1453 | ||
1400 | /* no fb bound */ | 1454 | /* no fb bound */ |
1401 | if (!atomic && !crtc->primary->fb) { | 1455 | if (!atomic && !crtc->primary->fb) { |
@@ -1433,18 +1487,30 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1433 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | 1487 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); |
1434 | radeon_bo_unreserve(rbo); | 1488 | radeon_bo_unreserve(rbo); |
1435 | 1489 | ||
1436 | switch (target_fb->bits_per_pixel) { | 1490 | switch (target_fb->pixel_format) { |
1437 | case 8: | 1491 | case DRM_FORMAT_C8: |
1438 | fb_format = | 1492 | fb_format = |
1439 | AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | | 1493 | AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | |
1440 | AVIVO_D1GRPH_CONTROL_8BPP_INDEXED; | 1494 | AVIVO_D1GRPH_CONTROL_8BPP_INDEXED; |
1441 | break; | 1495 | break; |
1442 | case 15: | 1496 | case DRM_FORMAT_XRGB4444: |
1497 | case DRM_FORMAT_ARGB4444: | ||
1498 | fb_format = | ||
1499 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | | ||
1500 | AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444; | ||
1501 | #ifdef __BIG_ENDIAN | ||
1502 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT; | ||
1503 | #endif | ||
1504 | break; | ||
1505 | case DRM_FORMAT_XRGB1555: | ||
1443 | fb_format = | 1506 | fb_format = |
1444 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | | 1507 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | |
1445 | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555; | 1508 | AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555; |
1509 | #ifdef __BIG_ENDIAN | ||
1510 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT; | ||
1511 | #endif | ||
1446 | break; | 1512 | break; |
1447 | case 16: | 1513 | case DRM_FORMAT_RGB565: |
1448 | fb_format = | 1514 | fb_format = |
1449 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | | 1515 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | |
1450 | AVIVO_D1GRPH_CONTROL_16BPP_RGB565; | 1516 | AVIVO_D1GRPH_CONTROL_16BPP_RGB565; |
@@ -1452,8 +1518,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1452 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT; | 1518 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT; |
1453 | #endif | 1519 | #endif |
1454 | break; | 1520 | break; |
1455 | case 24: | 1521 | case DRM_FORMAT_XRGB8888: |
1456 | case 32: | 1522 | case DRM_FORMAT_ARGB8888: |
1457 | fb_format = | 1523 | fb_format = |
1458 | AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | | 1524 | AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | |
1459 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; | 1525 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; |
@@ -1461,9 +1527,20 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1461 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT; | 1527 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT; |
1462 | #endif | 1528 | #endif |
1463 | break; | 1529 | break; |
1530 | case DRM_FORMAT_XRGB2101010: | ||
1531 | case DRM_FORMAT_ARGB2101010: | ||
1532 | fb_format = | ||
1533 | AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | | ||
1534 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010; | ||
1535 | #ifdef __BIG_ENDIAN | ||
1536 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT; | ||
1537 | #endif | ||
1538 | /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */ | ||
1539 | bypass_lut = true; | ||
1540 | break; | ||
1464 | default: | 1541 | default: |
1465 | DRM_ERROR("Unsupported screen depth %d\n", | 1542 | DRM_ERROR("Unsupported screen format %s\n", |
1466 | target_fb->bits_per_pixel); | 1543 | drm_get_format_name(target_fb->pixel_format)); |
1467 | return -EINVAL; | 1544 | return -EINVAL; |
1468 | } | 1545 | } |
1469 | 1546 | ||
@@ -1502,6 +1579,13 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1502 | if (rdev->family >= CHIP_R600) | 1579 | if (rdev->family >= CHIP_R600) |
1503 | WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); | 1580 | WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); |
1504 | 1581 | ||
1582 | /* LUT only has 256 slots for 8 bpc fb. Bypass for > 8 bpc scanout for precision */ | ||
1583 | WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, | ||
1584 | (bypass_lut ? AVIVO_LUT_10BIT_BYPASS_EN : 0), ~AVIVO_LUT_10BIT_BYPASS_EN); | ||
1585 | |||
1586 | if (bypass_lut) | ||
1587 | DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n"); | ||
1588 | |||
1505 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); | 1589 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
1506 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1590 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
1507 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); | 1591 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); |