aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/aty/radeon_accel.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-16 01:03:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 14:21:44 -0400
commitb1ee26bab14886350ba12a5c10cbc0696ac679bf (patch)
tree18fff332492d5a989dde01864cfb3c524976209d /drivers/video/aty/radeon_accel.c
parenta6c0c37db654444dfce91cd75ad8a56bb15a0d25 (diff)
radeonfb: accelerate imageblit and other improvements
Implement support for HW color expansion of 1bpp images, along with some improvements to the FIFO handling and other accel operations. The offset fixup code is now unnecessary as the fbcon core will call our set_par upon switch back from KD_GRAPHICS before anything else happens. I removed it as it would slow down accel operations. The fifo wait has been improved to avoid hitting the HW register as often, and the various accel ops are now performing better caching of register values. Overall, this improve accel performances. The imageblit acceleration does result in a small overall regression in performances on some machines (on the order of 5% on some x86), probably becaus the SW path provides a better bus utilisation, but I decided to ingnore that as the performances is still very good, and on the other hand, some machines such as some sparc64 get a 3 fold performance improvement. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: David S. Miller <davem@davemloft.net> Cc: Krzysztof Halasa <khc@pm.waw.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/aty/radeon_accel.c')
-rw-r--r--drivers/video/aty/radeon_accel.c291
1 files changed, 205 insertions, 86 deletions
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
index a469a3d6edcb..8718f7349d6b 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/aty/radeon_accel.c
@@ -5,61 +5,61 @@
5 * --dte 5 * --dte
6 */ 6 */
7 7
8static void radeon_fixup_offset(struct radeonfb_info *rinfo) 8#define FLUSH_CACHE_WORKAROUND 1
9
10void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries)
9{ 11{
10 u32 local_base; 12 int i;
11
12 /* *** Ugly workaround *** */
13 /*
14 * On some platforms, the video memory is mapped at 0 in radeon chip space
15 * (like PPCs) by the firmware. X will always move it up so that it's seen
16 * by the chip to be at the same address as the PCI BAR.
17 * That means that when switching back from X, there is a mismatch between
18 * the offsets programmed into the engine. This means that potentially,
19 * accel operations done before radeonfb has a chance to re-init the engine
20 * will have incorrect offsets, and potentially trash system memory !
21 *
22 * The correct fix is for fbcon to never call any accel op before the engine
23 * has properly been re-initialized (by a call to set_var), but this is a
24 * complex fix. This workaround in the meantime, called before every accel
25 * operation, makes sure the offsets are in sync.
26 */
27 13
28 radeon_fifo_wait (1); 14 for (i=0; i<2000000; i++) {
29 local_base = INREG(MC_FB_LOCATION) << 16; 15 rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f;
30 if (local_base == rinfo->fb_local_base) 16 if (rinfo->fifo_free >= entries)
31 return; 17 return;
18 udelay(10);
19 }
20 printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
21 /* XXX Todo: attempt to reset the engine */
22}
32 23
33 rinfo->fb_local_base = local_base; 24static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
25{
26 if (entries <= rinfo->fifo_free)
27 rinfo->fifo_free -= entries;
28 else
29 radeon_fifo_update_and_wait(rinfo, entries);
30}
34 31
35 radeon_fifo_wait (3); 32static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg,
36 OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) | 33 u32 *cache, u32 new_val)
37 (rinfo->fb_local_base >> 10)); 34{
38 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 35 if (new_val == *cache)
39 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 36 return;
37 *cache = new_val;
38 radeon_fifo_wait(rinfo, 1);
39 OUTREG(reg, new_val);
40} 40}
41 41
42static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, 42static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
43 const struct fb_fillrect *region) 43 const struct fb_fillrect *region)
44{ 44{
45 radeon_fifo_wait(4); 45 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
46 46 rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P);
47 OUTREG(DP_GUI_MASTER_CNTL, 47 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
48 rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */ 48 DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
49 | GMC_BRUSH_SOLID_COLOR 49 radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache,
50 | ROP3_P); 50 region->color);
51 if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP) 51
52 OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]); 52 /* Ensure the dst cache is flushed and the engine idle before
53 else 53 * issuing the operation.
54 OUTREG(DP_BRUSH_FRGD_CLR, region->color); 54 *
55 OUTREG(DP_WRITE_MSK, 0xffffffff); 55 * This works around engine lockups on some cards
56 OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); 56 */
57 57#if FLUSH_CACHE_WORKAROUND
58 radeon_fifo_wait(2); 58 radeon_fifo_wait(rinfo, 2);
59 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); 59 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
60 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); 60 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
61 61#endif
62 radeon_fifo_wait(2); 62 radeon_fifo_wait(rinfo, 2);
63 OUTREG(DST_Y_X, (region->dy << 16) | region->dx); 63 OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
64 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); 64 OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
65} 65}
@@ -70,15 +70,14 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
70 struct fb_fillrect modded; 70 struct fb_fillrect modded;
71 int vxres, vyres; 71 int vxres, vyres;
72 72
73 if (info->state != FBINFO_STATE_RUNNING) 73 WARN_ON(rinfo->gfx_mode);
74 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
74 return; 75 return;
75 if (info->flags & FBINFO_HWACCEL_DISABLED) { 76 if (info->flags & FBINFO_HWACCEL_DISABLED) {
76 cfb_fillrect(info, region); 77 cfb_fillrect(info, region);
77 return; 78 return;
78 } 79 }
79 80
80 radeon_fixup_offset(rinfo);
81
82 vxres = info->var.xres_virtual; 81 vxres = info->var.xres_virtual;
83 vyres = info->var.yres_virtual; 82 vyres = info->var.yres_virtual;
84 83
@@ -91,6 +90,10 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
91 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; 90 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
92 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; 91 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
93 92
93 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
94 info->fix.visual == FB_VISUAL_DIRECTCOLOR )
95 modded.color = ((u32 *) (info->pseudo_palette))[region->color];
96
94 radeonfb_prim_fillrect(rinfo, &modded); 97 radeonfb_prim_fillrect(rinfo, &modded);
95} 98}
96 99
@@ -109,22 +112,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
109 if ( xdir < 0 ) { sx += w-1; dx += w-1; } 112 if ( xdir < 0 ) { sx += w-1; dx += w-1; }
110 if ( ydir < 0 ) { sy += h-1; dy += h-1; } 113 if ( ydir < 0 ) { sy += h-1; dy += h-1; }
111 114
112 radeon_fifo_wait(3); 115 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
113 OUTREG(DP_GUI_MASTER_CNTL, 116 rinfo->dp_gui_mc_base |
114 rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */ 117 GMC_BRUSH_NONE |
115 | GMC_BRUSH_NONE 118 GMC_SRC_DATATYPE_COLOR |
116 | GMC_SRC_DSTCOLOR 119 ROP3_S |
117 | ROP3_S 120 DP_SRC_SOURCE_MEMORY);
118 | DP_SRC_SOURCE_MEMORY ); 121 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
119 OUTREG(DP_WRITE_MSK, 0xffffffff); 122 (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) |
120 OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) 123 (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
121 | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); 124
122 125#if FLUSH_CACHE_WORKAROUND
123 radeon_fifo_wait(2); 126 radeon_fifo_wait(rinfo, 2);
124 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); 127 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
125 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); 128 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
126 129#endif
127 radeon_fifo_wait(3); 130 radeon_fifo_wait(rinfo, 3);
128 OUTREG(SRC_Y_X, (sy << 16) | sx); 131 OUTREG(SRC_Y_X, (sy << 16) | sx);
129 OUTREG(DST_Y_X, (dy << 16) | dx); 132 OUTREG(DST_Y_X, (dy << 16) | dx);
130 OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); 133 OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w);
@@ -143,15 +146,14 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
143 modded.width = area->width; 146 modded.width = area->width;
144 modded.height = area->height; 147 modded.height = area->height;
145 148
146 if (info->state != FBINFO_STATE_RUNNING) 149 WARN_ON(rinfo->gfx_mode);
150 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
147 return; 151 return;
148 if (info->flags & FBINFO_HWACCEL_DISABLED) { 152 if (info->flags & FBINFO_HWACCEL_DISABLED) {
149 cfb_copyarea(info, area); 153 cfb_copyarea(info, area);
150 return; 154 return;
151 } 155 }
152 156
153 radeon_fixup_offset(rinfo);
154
155 vxres = info->var.xres_virtual; 157 vxres = info->var.xres_virtual;
156 vyres = info->var.yres_virtual; 158 vyres = info->var.yres_virtual;
157 159
@@ -168,13 +170,112 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
168 radeonfb_prim_copyarea(rinfo, &modded); 170 radeonfb_prim_copyarea(rinfo, &modded);
169} 171}
170 172
173static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
174 const struct fb_image *image,
175 u32 fg, u32 bg)
176{
177 unsigned int src_bytes, dwords;
178 u32 *bits;
179
180 radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
181 rinfo->dp_gui_mc_base |
182 GMC_BRUSH_NONE |
183 GMC_SRC_DATATYPE_MONO_FG_BG |
184 ROP3_S |
185 GMC_BYTE_ORDER_MSB_TO_LSB |
186 DP_SRC_SOURCE_HOST_DATA);
187 radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
188 DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
189 radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg);
190 radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg);
191
192 radeon_fifo_wait(rinfo, 1);
193 OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
194
195 /* Ensure the dst cache is flushed and the engine idle before
196 * issuing the operation.
197 *
198 * This works around engine lockups on some cards
199 */
200#if FLUSH_CACHE_WORKAROUND
201 radeon_fifo_wait(rinfo, 2);
202 OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
203 OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
204#endif
205
206 /* X here pads width to a multiple of 32 and uses the clipper to
207 * adjust the result. Is that really necessary ? Things seem to
208 * work ok for me without that and the doco doesn't seem to imply
209 * there is such a restriction.
210 */
211 OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height);
212
213 src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;
214 dwords = (src_bytes + 3) / 4;
215 bits = (u32*)(image->data);
216
217 while(dwords >= 8) {
218 radeon_fifo_wait(rinfo, 8);
219#if BITS_PER_LONG == 64
220 __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0);
221 __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2);
222 __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4);
223 __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6);
224 bits += 8;
225#else
226 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
227 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1);
228 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2);
229 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3);
230 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4);
231 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5);
232 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6);
233 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7);
234#endif
235 dwords -= 8;
236 }
237 while(dwords--) {
238 radeon_fifo_wait(rinfo, 1);
239 __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
240 }
241}
242
171void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) 243void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
172{ 244{
173 struct radeonfb_info *rinfo = info->par; 245 struct radeonfb_info *rinfo = info->par;
246 u32 fg, bg;
174 247
175 if (info->state != FBINFO_STATE_RUNNING) 248 WARN_ON(rinfo->gfx_mode);
249 if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
250 return;
251
252 if (!image->width || !image->height)
176 return; 253 return;
177 radeon_engine_idle(); 254
255 /* We only do 1 bpp color expansion for now */
256 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
257 goto fallback;
258
259 /* Fallback if running out of the screen. We may do clipping
260 * in the future */
261 if ((image->dx + image->width) > info->var.xres_virtual ||
262 (image->dy + image->height) > info->var.yres_virtual)
263 goto fallback;
264
265 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
266 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
267 fg = ((u32*)(info->pseudo_palette))[image->fg_color];
268 bg = ((u32*)(info->pseudo_palette))[image->bg_color];
269 } else {
270 fg = image->fg_color;
271 bg = image->bg_color;
272 }
273
274 radeonfb_prim_imageblit(rinfo, image, fg, bg);
275 return;
276
277 fallback:
278 radeon_engine_idle(rinfo);
178 279
179 cfb_imageblit(info, image); 280 cfb_imageblit(info, image);
180} 281}
@@ -185,7 +286,8 @@ int radeonfb_sync(struct fb_info *info)
185 286
186 if (info->state != FBINFO_STATE_RUNNING) 287 if (info->state != FBINFO_STATE_RUNNING)
187 return 0; 288 return 0;
188 radeon_engine_idle(); 289
290 radeon_engine_idle(rinfo);
189 291
190 return 0; 292 return 0;
191} 293}
@@ -261,9 +363,10 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
261 /* disable 3D engine */ 363 /* disable 3D engine */
262 OUTREG(RB3D_CNTL, 0); 364 OUTREG(RB3D_CNTL, 0);
263 365
366 rinfo->fifo_free = 0;
264 radeonfb_engine_reset(rinfo); 367 radeonfb_engine_reset(rinfo);
265 368
266 radeon_fifo_wait (1); 369 radeon_fifo_wait(rinfo, 1);
267 if (IS_R300_VARIANT(rinfo)) { 370 if (IS_R300_VARIANT(rinfo)) {
268 OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) | 371 OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) |
269 RB2D_DC_AUTOFLUSH_ENABLE | 372 RB2D_DC_AUTOFLUSH_ENABLE |
@@ -277,7 +380,7 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
277 OUTREG(RB2D_DSTCACHE_MODE, 0); 380 OUTREG(RB2D_DSTCACHE_MODE, 0);
278 } 381 }
279 382
280 radeon_fifo_wait (3); 383 radeon_fifo_wait(rinfo, 3);
281 /* We re-read MC_FB_LOCATION from card as it can have been 384 /* We re-read MC_FB_LOCATION from card as it can have been
282 * modified by XFree drivers (ouch !) 385 * modified by XFree drivers (ouch !)
283 */ 386 */
@@ -288,41 +391,57 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
288 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 391 OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
289 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); 392 OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
290 393
291 radeon_fifo_wait (1); 394 radeon_fifo_wait(rinfo, 1);
292#if defined(__BIG_ENDIAN) 395#ifdef __BIG_ENDIAN
293 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); 396 OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
294#else 397#else
295 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); 398 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
296#endif 399#endif
297 radeon_fifo_wait (2); 400 radeon_fifo_wait(rinfo, 2);
298 OUTREG(DEFAULT_SC_TOP_LEFT, 0); 401 OUTREG(DEFAULT_SC_TOP_LEFT, 0);
299 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | 402 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
300 DEFAULT_SC_BOTTOM_MAX)); 403 DEFAULT_SC_BOTTOM_MAX));
301 404
405 /* set default DP_GUI_MASTER_CNTL */
302 temp = radeon_get_dstbpp(rinfo->depth); 406 temp = radeon_get_dstbpp(rinfo->depth);
303 rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); 407 rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
304 408
305 radeon_fifo_wait (1); 409 rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base |
306 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | 410 GMC_BRUSH_SOLID_COLOR |
307 GMC_BRUSH_SOLID_COLOR | 411 GMC_SRC_DATATYPE_COLOR;
308 GMC_SRC_DATATYPE_COLOR)); 412 radeon_fifo_wait(rinfo, 1);
413 OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache);
309 414
310 radeon_fifo_wait (7);
311 415
312 /* clear line drawing regs */ 416 /* clear line drawing regs */
417 radeon_fifo_wait(rinfo, 2);
313 OUTREG(DST_LINE_START, 0); 418 OUTREG(DST_LINE_START, 0);
314 OUTREG(DST_LINE_END, 0); 419 OUTREG(DST_LINE_END, 0);
315 420
316 /* set brush color regs */ 421 /* set brush and source color regs */
317 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); 422 rinfo->dp_brush_fg_cache = 0xffffffff;
318 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); 423 rinfo->dp_brush_bg_cache = 0x00000000;
319 424 rinfo->dp_src_fg_cache = 0xffffffff;
320 /* set source color regs */ 425 rinfo->dp_src_bg_cache = 0x00000000;
321 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); 426 radeon_fifo_wait(rinfo, 4);
322 OUTREG(DP_SRC_BKGD_CLR, 0x00000000); 427 OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache);
428 OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache);
429 OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache);
430 OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache);
431
432 /* Default direction */
433 rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM;
434 radeon_fifo_wait(rinfo, 1);
435 OUTREG(DP_CNTL, rinfo->dp_cntl_cache);
323 436
324 /* default write mask */ 437 /* default write mask */
438 radeon_fifo_wait(rinfo, 1);
325 OUTREG(DP_WRITE_MSK, 0xffffffff); 439 OUTREG(DP_WRITE_MSK, 0xffffffff);
326 440
327 radeon_engine_idle (); 441 /* Default to no swapping of host data */
442 radeon_fifo_wait(rinfo, 1);
443 OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE);
444
445 /* Make sure it's settled */
446 radeon_engine_idle(rinfo);
328} 447}