mirror of https://gitee.com/openkylin/linux.git
Merge branch 'drm-next-3.16' of git://people.freedesktop.org/~agd5f/linux into drm-next
two fixes for the deep color support in radeon. * 'drm-next-3.16' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: Bypass hw lut's for > 8 bpc framebuffer scanout. drm/radeon: use pixel formats instead of depth/bpp
This commit is contained in:
commit
844f22823e
|
@ -1136,6 +1136,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
|
||||
u32 tmp, viewport_w, viewport_h;
|
||||
int r;
|
||||
bool bypass_lut = false;
|
||||
|
||||
/* no fb bound */
|
||||
if (!atomic && !crtc->primary->fb) {
|
||||
|
@ -1174,33 +1175,73 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
|
||||
radeon_bo_unreserve(rbo);
|
||||
|
||||
switch (target_fb->bits_per_pixel) {
|
||||
case 8:
|
||||
switch (target_fb->pixel_format) {
|
||||
case DRM_FORMAT_C8:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED));
|
||||
break;
|
||||
case 15:
|
||||
case DRM_FORMAT_XRGB4444:
|
||||
case DRM_FORMAT_ARGB4444:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB4444));
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
|
||||
#endif
|
||||
break;
|
||||
case DRM_FORMAT_XRGB1555:
|
||||
case DRM_FORMAT_ARGB1555:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB1555));
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
|
||||
#endif
|
||||
break;
|
||||
case 16:
|
||||
case DRM_FORMAT_BGRX5551:
|
||||
case DRM_FORMAT_BGRA5551:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA5551));
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
|
||||
#endif
|
||||
break;
|
||||
case DRM_FORMAT_RGB565:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
|
||||
#endif
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
|
||||
#endif
|
||||
break;
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
case DRM_FORMAT_ARGB2101010:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB2101010));
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
|
||||
#endif
|
||||
/* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
|
||||
bypass_lut = true;
|
||||
break;
|
||||
case DRM_FORMAT_BGRX1010102:
|
||||
case DRM_FORMAT_BGRA1010102:
|
||||
fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
|
||||
EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_BGRA1010102));
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
|
||||
#endif
|
||||
/* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
|
||||
bypass_lut = true;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unsupported screen depth %d\n",
|
||||
target_fb->bits_per_pixel);
|
||||
DRM_ERROR("Unsupported screen format %s\n",
|
||||
drm_get_format_name(target_fb->pixel_format));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1329,6 +1370,18 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
|
||||
WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
|
||||
|
||||
/*
|
||||
* The LUT only has 256 slots for indexing by a 8 bpc fb. Bypass the LUT
|
||||
* for > 8 bpc scanout to avoid truncation of fb indices to 8 msb's, to
|
||||
* retain the full precision throughout the pipeline.
|
||||
*/
|
||||
WREG32_P(EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL + radeon_crtc->crtc_offset,
|
||||
(bypass_lut ? EVERGREEN_LUT_10BIT_BYPASS_EN : 0),
|
||||
~EVERGREEN_LUT_10BIT_BYPASS_EN);
|
||||
|
||||
if (bypass_lut)
|
||||
DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
|
||||
|
||||
WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
|
||||
WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
|
||||
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,
|
|||
u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
|
||||
u32 tmp, viewport_w, viewport_h;
|
||||
int r;
|
||||
bool bypass_lut = false;
|
||||
|
||||
/* no fb bound */
|
||||
if (!atomic && !crtc->primary->fb) {
|
||||
|
@ -1433,18 +1487,30 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
|
||||
radeon_bo_unreserve(rbo);
|
||||
|
||||
switch (target_fb->bits_per_pixel) {
|
||||
case 8:
|
||||
switch (target_fb->pixel_format) {
|
||||
case DRM_FORMAT_C8:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
|
||||
AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
|
||||
break;
|
||||
case 15:
|
||||
case DRM_FORMAT_XRGB4444:
|
||||
case DRM_FORMAT_ARGB4444:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
|
||||
AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444;
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
|
||||
#endif
|
||||
break;
|
||||
case DRM_FORMAT_XRGB1555:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
|
||||
AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555;
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
|
||||
#endif
|
||||
break;
|
||||
case 16:
|
||||
case DRM_FORMAT_RGB565:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
|
||||
AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
|
||||
|
@ -1452,8 +1518,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
|
||||
#endif
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
|
||||
AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
|
||||
|
@ -1461,9 +1527,20 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
|
||||
#endif
|
||||
break;
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
case DRM_FORMAT_ARGB2101010:
|
||||
fb_format =
|
||||
AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
|
||||
AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010;
|
||||
#ifdef __BIG_ENDIAN
|
||||
fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
|
||||
#endif
|
||||
/* Greater 8 bpc fb needs to bypass hw-lut to retain precision */
|
||||
bypass_lut = true;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unsupported screen depth %d\n",
|
||||
target_fb->bits_per_pixel);
|
||||
DRM_ERROR("Unsupported screen format %s\n",
|
||||
drm_get_format_name(target_fb->pixel_format));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -1502,6 +1579,13 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
|
|||
if (rdev->family >= CHIP_R600)
|
||||
WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
|
||||
|
||||
/* LUT only has 256 slots for 8 bpc fb. Bypass for > 8 bpc scanout for precision */
|
||||
WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset,
|
||||
(bypass_lut ? AVIVO_LUT_10BIT_BYPASS_EN : 0), ~AVIVO_LUT_10BIT_BYPASS_EN);
|
||||
|
||||
if (bypass_lut)
|
||||
DRM_DEBUG_KMS("Bypassing hardware LUT due to 10 bit fb scanout.\n");
|
||||
|
||||
WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
|
||||
WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
|
||||
WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0);
|
||||
|
|
|
@ -116,6 +116,8 @@
|
|||
# define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1
|
||||
# define EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1 2
|
||||
# define EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1 4
|
||||
#define EVERGREEN_GRPH_LUT_10BIT_BYPASS_CONTROL 0x6808
|
||||
# define EVERGREEN_LUT_10BIT_BYPASS_EN (1 << 8)
|
||||
#define EVERGREEN_GRPH_SWAP_CONTROL 0x680c
|
||||
# define EVERGREEN_GRPH_ENDIAN_SWAP(x) (((x) & 0x3) << 0)
|
||||
# define EVERGREEN_GRPH_ENDIAN_NONE 0
|
||||
|
|
|
@ -402,6 +402,7 @@
|
|||
* block and vice versa. This applies to GRPH, CUR, etc.
|
||||
*/
|
||||
#define AVIVO_D1GRPH_LUT_SEL 0x6108
|
||||
# define AVIVO_LUT_10BIT_BYPASS_EN (1 << 8)
|
||||
#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110
|
||||
#define R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914
|
||||
#define R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114
|
||||
|
|
|
@ -66,7 +66,8 @@ static void avivo_crtc_load_lut(struct drm_crtc *crtc)
|
|||
(radeon_crtc->lut_b[i] << 0));
|
||||
}
|
||||
|
||||
WREG32(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id);
|
||||
/* Only change bit 0 of LUT_SEL, other bits are set elsewhere */
|
||||
WREG32_P(AVIVO_D1GRPH_LUT_SEL + radeon_crtc->crtc_offset, radeon_crtc->crtc_id, ~1);
|
||||
}
|
||||
|
||||
static void dce4_crtc_load_lut(struct drm_crtc *crtc)
|
||||
|
|
Loading…
Reference in New Issue