diff options
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 27 | ||||
| -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, 32 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index b91f79ebbda1..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) { |
| @@ -1225,6 +1226,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1225 | #ifdef __BIG_ENDIAN | 1226 | #ifdef __BIG_ENDIAN |
| 1226 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); | 1227 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); |
| 1227 | #endif | 1228 | #endif |
| 1229 | /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */ | ||
| 1230 | bypass_lut = true; | ||
| 1228 | break; | 1231 | break; |
| 1229 | case DRM_FORMAT_BGRX1010102: | 1232 | case DRM_FORMAT_BGRX1010102: |
| 1230 | case DRM_FORMAT_BGRA1010102: | 1233 | case DRM_FORMAT_BGRA1010102: |
| @@ -1233,6 +1236,8 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1233 | #ifdef __BIG_ENDIAN | 1236 | #ifdef __BIG_ENDIAN |
| 1234 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); | 1237 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); |
| 1235 | #endif | 1238 | #endif |
| 1239 | /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */ | ||
| 1240 | bypass_lut = true; | ||
| 1236 | break; | 1241 | break; |
| 1237 | default: | 1242 | default: |
| 1238 | DRM_ERROR("Unsupported screen format %s\n", | 1243 | DRM_ERROR("Unsupported screen format %s\n", |
| @@ -1365,6 +1370,18 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1365 | WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); | 1370 | WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); |
| 1366 | WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); | 1371 | WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); |
| 1367 | 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 | |||
| 1368 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); | 1385 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
| 1369 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1386 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
| 1370 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); | 1387 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); |
| @@ -1432,6 +1449,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1432 | u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; | 1449 | u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; |
| 1433 | u32 tmp, viewport_w, viewport_h; | 1450 | u32 tmp, viewport_w, viewport_h; |
| 1434 | int r; | 1451 | int r; |
| 1452 | bool bypass_lut = false; | ||
| 1435 | 1453 | ||
| 1436 | /* no fb bound */ | 1454 | /* no fb bound */ |
| 1437 | if (!atomic && !crtc->primary->fb) { | 1455 | if (!atomic && !crtc->primary->fb) { |
| @@ -1517,6 +1535,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1517 | #ifdef __BIG_ENDIAN | 1535 | #ifdef __BIG_ENDIAN |
| 1518 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT; | 1536 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT; |
| 1519 | #endif | 1537 | #endif |
| 1538 | /* Greater 8 bpc fb needs to bypass hw-lut to retain precision */ | ||
| 1539 | bypass_lut = true; | ||
| 1520 | break; | 1540 | break; |
| 1521 | default: | 1541 | default: |
| 1522 | DRM_ERROR("Unsupported screen format %s\n", | 1542 | DRM_ERROR("Unsupported screen format %s\n", |
| @@ -1559,6 +1579,13 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1559 | if (rdev->family >= CHIP_R600) | 1579 | if (rdev->family >= CHIP_R600) |
| 1560 | WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); | 1580 | WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); |
| 1561 | 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 | |||
| 1562 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); | 1589 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
| 1563 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1590 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
| 1564 | 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) |
