diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-01-25 11:55:50 -0500 |
---|---|---|
committer | Dave Airlie <airlied@gmail.com> | 2011-01-26 22:54:13 -0500 |
commit | fa6bee46a655a750afb9a78a7ddf9a3bcda97db8 (patch) | |
tree | 899ff04db8e6ab05b2179037645c762117b9355c | |
parent | d75ee3be44380040b9d2c7925298dc52e049768d (diff) |
drm/radeon/kms: fix r6xx+ scanout on BE systems
R6xx+ have per-block swappers. BE content in the
framebuffer will now be swapped properly during scanout.
Untested, however, the same code is reported working in
the UMS ddx.
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@gmail.com>
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_reg.h | 6 |
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index d3ca17080df7..842954fe74c5 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -994,6 +994,7 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, | |||
994 | struct radeon_bo *rbo; | 994 | struct radeon_bo *rbo; |
995 | uint64_t fb_location; | 995 | uint64_t fb_location; |
996 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; | 996 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
997 | u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); | ||
997 | int r; | 998 | int r; |
998 | 999 | ||
999 | /* no fb bound */ | 1000 | /* no fb bound */ |
@@ -1045,11 +1046,17 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, | |||
1045 | case 16: | 1046 | case 16: |
1046 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | | 1047 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) | |
1047 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565)); | 1048 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565)); |
1049 | #ifdef __BIG_ENDIAN | ||
1050 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16); | ||
1051 | #endif | ||
1048 | break; | 1052 | break; |
1049 | case 24: | 1053 | case 24: |
1050 | case 32: | 1054 | case 32: |
1051 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | | 1055 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) | |
1052 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888)); | 1056 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888)); |
1057 | #ifdef __BIG_ENDIAN | ||
1058 | fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32); | ||
1059 | #endif | ||
1053 | break; | 1060 | break; |
1054 | default: | 1061 | default: |
1055 | DRM_ERROR("Unsupported screen depth %d\n", | 1062 | DRM_ERROR("Unsupported screen depth %d\n", |
@@ -1094,6 +1101,7 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, | |||
1094 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | 1101 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, |
1095 | (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); | 1102 | (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK); |
1096 | WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); | 1103 | WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); |
1104 | WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); | ||
1097 | 1105 | ||
1098 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); | 1106 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
1099 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1107 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
@@ -1150,6 +1158,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1150 | struct drm_framebuffer *target_fb; | 1158 | struct drm_framebuffer *target_fb; |
1151 | uint64_t fb_location; | 1159 | uint64_t fb_location; |
1152 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; | 1160 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
1161 | u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; | ||
1153 | int r; | 1162 | int r; |
1154 | 1163 | ||
1155 | /* no fb bound */ | 1164 | /* no fb bound */ |
@@ -1203,12 +1212,18 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1203 | fb_format = | 1212 | fb_format = |
1204 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | | 1213 | AVIVO_D1GRPH_CONTROL_DEPTH_16BPP | |
1205 | AVIVO_D1GRPH_CONTROL_16BPP_RGB565; | 1214 | AVIVO_D1GRPH_CONTROL_16BPP_RGB565; |
1215 | #ifdef __BIG_ENDIAN | ||
1216 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT; | ||
1217 | #endif | ||
1206 | break; | 1218 | break; |
1207 | case 24: | 1219 | case 24: |
1208 | case 32: | 1220 | case 32: |
1209 | fb_format = | 1221 | fb_format = |
1210 | AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | | 1222 | AVIVO_D1GRPH_CONTROL_DEPTH_32BPP | |
1211 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; | 1223 | AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888; |
1224 | #ifdef __BIG_ENDIAN | ||
1225 | fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT; | ||
1226 | #endif | ||
1212 | break; | 1227 | break; |
1213 | default: | 1228 | default: |
1214 | DRM_ERROR("Unsupported screen depth %d\n", | 1229 | DRM_ERROR("Unsupported screen depth %d\n", |
@@ -1248,6 +1263,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
1248 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + | 1263 | WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + |
1249 | radeon_crtc->crtc_offset, (u32) fb_location); | 1264 | radeon_crtc->crtc_offset, (u32) fb_location); |
1250 | WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); | 1265 | WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format); |
1266 | if (rdev->family >= CHIP_R600) | ||
1267 | WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap); | ||
1251 | 1268 | ||
1252 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); | 1269 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0); |
1253 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1270 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h index 33cda016b083..f869897c7456 100644 --- a/drivers/gpu/drm/radeon/r600_reg.h +++ b/drivers/gpu/drm/radeon/r600_reg.h | |||
@@ -81,7 +81,11 @@ | |||
81 | #define R600_MEDIUM_VID_LOWER_GPIO_CNTL 0x720 | 81 | #define R600_MEDIUM_VID_LOWER_GPIO_CNTL 0x720 |
82 | #define R600_LOW_VID_LOWER_GPIO_CNTL 0x724 | 82 | #define R600_LOW_VID_LOWER_GPIO_CNTL 0x724 |
83 | 83 | ||
84 | 84 | #define R600_D1GRPH_SWAP_CONTROL 0x610C | |
85 | # define R600_D1GRPH_SWAP_ENDIAN_NONE (0 << 0) | ||
86 | # define R600_D1GRPH_SWAP_ENDIAN_16BIT (1 << 0) | ||
87 | # define R600_D1GRPH_SWAP_ENDIAN_32BIT (2 << 0) | ||
88 | # define R600_D1GRPH_SWAP_ENDIAN_64BIT (3 << 0) | ||
85 | 89 | ||
86 | #define R600_HDP_NONSURFACE_BASE 0x2c04 | 90 | #define R600_HDP_NONSURFACE_BASE 0x2c04 |
87 | 91 | ||