diff options
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 116 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_reg.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r500_reg.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 3 |
4 files changed, 105 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 26c12a3fe430..9758f9170fce 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -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); |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index a0f63ff5a5e9..333d143fca2c 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -116,6 +116,8 @@ | |||
116 | # define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 | 116 | # define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 |
117 | # define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1 2 | 117 | # define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1 2 |
118 | # define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1 4 | 118 | # define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1 4 |
119 | #define EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL 0x6808 | ||
120 | # define EVERGREEN_LUT_10BIT_BYPASS_EN (1 << 8) | ||
119 | #define EVERGREEN_GRPH_SWAP_CONTROL 0x680c | 121 | #define EVERGREEN_GRPH_SWAP_CONTROL 0x680c |
120 | # define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) | 122 | # define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0) |
121 | # define EVERGREEN_GRPH_ENDIAN_NONE 0 | 123 | # define EVERGREEN_GRPH_ENDIAN_NONE 0 |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 1dd0d32993d5..136b7bc7cd20 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
@@ -402,6 +402,7 @@ | |||
402 | * block and vice versa. This applies to GRPH, CUR, etc. | 402 | * block and vice versa. This applies to GRPH, CUR, etc. |
403 | */ | 403 | */ |
404 | #define AVIVO_D1GRPH_LUT_SEL 0x6108 | 404 | #define AVIVO_D1GRPH_LUT_SEL 0x6108 |
405 | # define AVIVO_LUT_10BIT_BYPASS_EN (1 << 8) | ||
405 | #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 | 406 | #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 |
406 | #define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 | 407 | #define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 |
407 | #define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 | 408 | #define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 5ed617056b9c..4db26420f38a 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -66,7 +66,8 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc) | |||
66 | (radeon_crtc->lut_b[i] << 0)); | 66 | (radeon_crtc->lut_b[i] << 0)); |
67 | } | 67 | } |
68 | 68 | ||
69 | WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id); | 69 | /* Only change bit 0 of LUT_SEL, other bits are set elsewhere */ |
70 | WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id, ~1); | ||
70 | } | 71 | } |
71 | 72 | ||
72 | static void dce4_crtc_load_lut(struct drm_crtc *crtc) | 73 | static void dce4_crtc_load_lut(struct drm_crtc *crtc) |