aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorMichel Dänzer <daenzer@vmware.com>2009-09-15 11:09:30 -0400
committerDave Airlie <airlied@redhat.com>2009-09-18 02:01:59 -0400
commitc88f9f0c91de55efaece6d9bd9ec920b90244776 (patch)
treeb171eada095c88ad432ec3cc320426771829ce8d /drivers/gpu/drm
parent733289c2656c556d5cf36eafa1c8ec77222c359f (diff)
drm/radeon/kms: Use surfaces for scanout / cursor byte swapping on big endian.
Signed-off-by: Michel Dänzer <daenzer@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/r100.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c121
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c2
3 files changed, 25 insertions, 103 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index fa0fdc1e3457..737970b43aef 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2235,6 +2235,11 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
2235 flags |= R300_SURF_TILE_MICRO; 2235 flags |= R300_SURF_TILE_MICRO;
2236 } 2236 }
2237 2237
2238 if (tiling_flags & RADEON_TILING_SWAP_16BIT)
2239 flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP;
2240 if (tiling_flags & RADEON_TILING_SWAP_32BIT)
2241 flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
2242
2238 DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); 2243 DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
2239 WREG32(RADEON_SURFACE0_INFO + surf_index, flags); 2244 WREG32(RADEON_SURFACE0_INFO + surf_index, flags);
2240 WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); 2245 WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 19e244a512ba..944e4fa78db5 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -45,71 +45,9 @@ struct radeon_fb_device {
45 struct radeon_device *rdev; 45 struct radeon_device *rdev;
46}; 46};
47 47
48static int radeon_fb_check_var(struct fb_var_screeninfo *var,
49 struct fb_info *info)
50{
51 int ret;
52 ret = drm_fb_helper_check_var(var, info);
53 if (ret)
54 return ret;
55
56 /* big endian override for radeon endian workaround */
57#ifdef __BIG_ENDIAN
58 {
59 int depth;
60 switch (var->bits_per_pixel) {
61 case 16:
62 depth = (var->green.length == 6) ? 16 : 15;
63 break;
64 case 32:
65 depth = (var->transp.length > 0) ? 32 : 24;
66 break;
67 default:
68 depth = var->bits_per_pixel;
69 break;
70 }
71 switch (depth) {
72 case 8:
73 var->red.offset = 0;
74 var->green.offset = 0;
75 var->blue.offset = 0;
76 var->red.length = 8;
77 var->green.length = 8;
78 var->blue.length = 8;
79 var->transp.length = 0;
80 var->transp.offset = 0;
81 break;
82 case 24:
83 var->red.offset = 8;
84 var->green.offset = 16;
85 var->blue.offset = 24;
86 var->red.length = 8;
87 var->green.length = 8;
88 var->blue.length = 8;
89 var->transp.length = 0;
90 var->transp.offset = 0;
91 break;
92 case 32:
93 var->red.offset = 8;
94 var->green.offset = 16;
95 var->blue.offset = 24;
96 var->red.length = 8;
97 var->green.length = 8;
98 var->blue.length = 8;
99 var->transp.length = 8;
100 var->transp.offset = 0;
101 break;
102 default:
103 return -EINVAL;
104 }
105 }
106#endif
107 return 0;
108}
109
110static struct fb_ops radeonfb_ops = { 48static struct fb_ops radeonfb_ops = {
111 .owner = THIS_MODULE, 49 .owner = THIS_MODULE,
112 .fb_check_var = radeon_fb_check_var, 50 .fb_check_var = drm_fb_helper_check_var,
113 .fb_set_par = drm_fb_helper_set_par, 51 .fb_set_par = drm_fb_helper_set_par,
114 .fb_setcolreg = drm_fb_helper_setcolreg, 52 .fb_setcolreg = drm_fb_helper_setcolreg,
115 .fb_fillrect = cfb_fillrect, 53 .fb_fillrect = cfb_fillrect,
@@ -206,6 +144,7 @@ int radeonfb_create(struct drm_device *dev,
206 void *fbptr = NULL; 144 void *fbptr = NULL;
207 unsigned long tmp; 145 unsigned long tmp;
208 bool fb_tiled = false; /* useful for testing */ 146 bool fb_tiled = false; /* useful for testing */
147 u32 tiling_flags = 0;
209 148
210 mode_cmd.width = surface_width; 149 mode_cmd.width = surface_width;
211 mode_cmd.height = surface_height; 150 mode_cmd.height = surface_height;
@@ -230,7 +169,22 @@ int radeonfb_create(struct drm_device *dev,
230 robj = gobj->driver_private; 169 robj = gobj->driver_private;
231 170
232 if (fb_tiled) 171 if (fb_tiled)
233 radeon_object_set_tiling_flags(robj, RADEON_TILING_MACRO|RADEON_TILING_SURFACE, mode_cmd.pitch); 172 tiling_flags = RADEON_TILING_MACRO;
173
174#ifdef __BIG_ENDIAN
175 switch (mode_cmd.bpp) {
176 case 32:
177 tiling_flags |= RADEON_TILING_SWAP_32BIT;
178 break;
179 case 16:
180 tiling_flags |= RADEON_TILING_SWAP_16BIT;
181 default:
182 break;
183 }
184#endif
185
186 if (tiling_flags)
187 radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch);
234 mutex_lock(&rdev->ddev->struct_mutex); 188 mutex_lock(&rdev->ddev->struct_mutex);
235 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); 189 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
236 if (fb == NULL) { 190 if (fb == NULL) {
@@ -313,45 +267,6 @@ int radeonfb_create(struct drm_device *dev,
313 DRM_INFO("fb depth is %d\n", fb->depth); 267 DRM_INFO("fb depth is %d\n", fb->depth);
314 DRM_INFO(" pitch is %d\n", fb->pitch); 268 DRM_INFO(" pitch is %d\n", fb->pitch);
315 269
316#ifdef __BIG_ENDIAN
317 /* fill var sets defaults for this stuff - override
318 on big endian */
319 switch (fb->depth) {
320 case 8:
321 info->var.red.offset = 0;
322 info->var.green.offset = 0;
323 info->var.blue.offset = 0;
324 info->var.red.length = 8; /* 8bit DAC */
325 info->var.green.length = 8;
326 info->var.blue.length = 8;
327 info->var.transp.offset = 0;
328 info->var.transp.length = 0;
329 break;
330 case 24:
331 info->var.red.offset = 8;
332 info->var.green.offset = 16;
333 info->var.blue.offset = 24;
334 info->var.red.length = 8;
335 info->var.green.length = 8;
336 info->var.blue.length = 8;
337 info->var.transp.offset = 0;
338 info->var.transp.length = 0;
339 break;
340 case 32:
341 info->var.red.offset = 8;
342 info->var.green.offset = 16;
343 info->var.blue.offset = 24;
344 info->var.red.length = 8;
345 info->var.green.length = 8;
346 info->var.blue.length = 8;
347 info->var.transp.offset = 0;
348 info->var.transp.length = 8;
349 break;
350 default:
351 break;
352 }
353#endif
354
355 fb->fbdev = info; 270 fb->fbdev = info;
356 rfbdev->rfb = rfb; 271 rfbdev->rfb = rfb;
357 rfbdev->rdev = rdev; 272 rfbdev->rdev = rdev;
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 1500d5bc7af5..73af463b7a59 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -188,6 +188,7 @@ int radeon_object_kmap(struct radeon_object *robj, void **ptr)
188 if (ptr) { 188 if (ptr) {
189 *ptr = robj->kptr; 189 *ptr = robj->kptr;
190 } 190 }
191 radeon_object_check_tiling(robj, 0, 0);
191 return 0; 192 return 0;
192} 193}
193 194
@@ -200,6 +201,7 @@ void radeon_object_kunmap(struct radeon_object *robj)
200 } 201 }
201 robj->kptr = NULL; 202 robj->kptr = NULL;
202 spin_unlock(&robj->tobj.lock); 203 spin_unlock(&robj->tobj.lock);
204 radeon_object_check_tiling(robj, 0, 0);
203 ttm_bo_kunmap(&robj->kmap); 205 ttm_bo_kunmap(&robj->kmap);
204} 206}
205 207