| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /*-*- linux-c -*- | 
 | 2 |  *  linux/drivers/video/i810_accel.c -- Hardware Acceleration | 
 | 3 |  * | 
 | 4 |  *      Copyright (C) 2001 Antonino Daplas<adaplas@pol.net> | 
 | 5 |  *      All Rights Reserved       | 
 | 6 |  * | 
 | 7 |  *  This file is subject to the terms and conditions of the GNU General Public | 
 | 8 |  *  License. See the file COPYING in the main directory of this archive for | 
 | 9 |  *  more details. | 
 | 10 |  */ | 
 | 11 | #include <linux/kernel.h> | 
 | 12 | #include <linux/string.h> | 
 | 13 | #include <linux/fb.h> | 
 | 14 |  | 
 | 15 | #include "i810_regs.h" | 
 | 16 | #include "i810.h" | 
| Adrian Bunk | a0aa7d0 | 2006-01-09 20:54:04 -0800 | [diff] [blame] | 17 | #include "i810_main.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 18 |  | 
 | 19 | static u32 i810fb_rop[] = { | 
 | 20 | 	COLOR_COPY_ROP, /* ROP_COPY */ | 
 | 21 | 	XOR_ROP         /* ROP_XOR  */ | 
 | 22 | }; | 
 | 23 |  | 
 | 24 | /* Macros */ | 
 | 25 | #define PUT_RING(n) {                                        \ | 
 | 26 | 	i810_writel(par->cur_tail, par->iring.virtual, n);   \ | 
 | 27 |         par->cur_tail += 4;                                  \ | 
 | 28 |         par->cur_tail &= RING_SIZE_MASK;                     \ | 
 | 29 | }                                                                       | 
 | 30 |  | 
 | 31 | extern void flush_cache(void); | 
 | 32 |  | 
 | 33 | /************************************************************/ | 
 | 34 |  | 
 | 35 | /* BLT Engine Routines */ | 
 | 36 | static inline void i810_report_error(u8 __iomem *mmio) | 
 | 37 | { | 
 | 38 | 	printk("IIR     : 0x%04x\n" | 
 | 39 | 	       "EIR     : 0x%04x\n" | 
 | 40 | 	       "PGTBL_ER: 0x%04x\n" | 
 | 41 | 	       "IPEIR   : 0x%04x\n" | 
 | 42 | 	       "IPEHR   : 0x%04x\n", | 
 | 43 | 	       i810_readw(IIR, mmio), | 
 | 44 | 	       i810_readb(EIR, mmio), | 
 | 45 | 	       i810_readl(PGTBL_ER, mmio), | 
 | 46 | 	       i810_readl(IPEIR, mmio),  | 
 | 47 | 	       i810_readl(IPEHR, mmio)); | 
 | 48 | } | 
 | 49 |  | 
 | 50 | /** | 
 | 51 |  * wait_for_space - check ring buffer free space | 
 | 52 |  * @space: amount of ringbuffer space needed in bytes | 
 | 53 |  * @par: pointer to i810fb_par structure | 
 | 54 |  * | 
 | 55 |  * DESCRIPTION: | 
 | 56 |  * The function waits until a free space from the ringbuffer | 
 | 57 |  * is available  | 
 | 58 |  */	 | 
 | 59 | static inline int wait_for_space(struct fb_info *info, u32 space) | 
 | 60 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 61 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 62 | 	u32 head, count = WAIT_COUNT, tail; | 
 | 63 | 	u8 __iomem *mmio = par->mmio_start_virtual; | 
 | 64 |  | 
 | 65 | 	tail = par->cur_tail; | 
 | 66 | 	while (count--) { | 
 | 67 | 		head = i810_readl(IRING + 4, mmio) & RBUFFER_HEAD_MASK;	 | 
 | 68 | 		if ((tail == head) ||  | 
 | 69 | 		    (tail > head &&  | 
 | 70 | 		     (par->iring.size - tail + head) >= space) ||  | 
 | 71 | 		    (tail < head && (head - tail) >= space)) { | 
 | 72 | 			return 0;	 | 
 | 73 | 		} | 
 | 74 | 	} | 
 | 75 | 	printk("ringbuffer lockup!!!\n"); | 
 | 76 | 	i810_report_error(mmio);  | 
 | 77 | 	par->dev_flags |= LOCKUP; | 
 | 78 | 	info->pixmap.scan_align = 1; | 
 | 79 | 	return 1; | 
 | 80 | } | 
 | 81 |  | 
 | 82 | /**  | 
 | 83 |  * wait_for_engine_idle - waits for all hardware engines to finish | 
 | 84 |  * @par: pointer to i810fb_par structure | 
 | 85 |  * | 
 | 86 |  * DESCRIPTION: | 
 | 87 |  * This waits for lring(0), iring(1), and batch(3), etc to finish and | 
 | 88 |  * waits until ringbuffer is empty. | 
 | 89 |  */ | 
 | 90 | static inline int wait_for_engine_idle(struct fb_info *info) | 
 | 91 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 92 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 93 | 	u8 __iomem *mmio = par->mmio_start_virtual; | 
 | 94 | 	int count = WAIT_COUNT; | 
 | 95 |  | 
 | 96 | 	if (wait_for_space(info, par->iring.size)) /* flush */ | 
 | 97 | 		return 1; | 
 | 98 |  | 
 | 99 | 	while((i810_readw(INSTDONE, mmio) & 0x7B) != 0x7B && --count);  | 
 | 100 | 	if (count) return 0; | 
 | 101 |  | 
 | 102 | 	printk("accel engine lockup!!!\n"); | 
 | 103 | 	printk("INSTDONE: 0x%04x\n", i810_readl(INSTDONE, mmio)); | 
 | 104 | 	i810_report_error(mmio);  | 
 | 105 | 	par->dev_flags |= LOCKUP; | 
 | 106 | 	info->pixmap.scan_align = 1; | 
 | 107 | 	return 1; | 
 | 108 | } | 
 | 109 |  | 
 | 110 | /* begin_iring - prepares the ringbuffer  | 
 | 111 |  * @space: length of sequence in dwords | 
 | 112 |  * @par: pointer to i810fb_par structure | 
 | 113 |  * | 
 | 114 |  * DESCRIPTION: | 
 | 115 |  * Checks/waits for sufficent space in ringbuffer of size | 
 | 116 |  * space.  Returns the tail of the buffer | 
 | 117 |  */  | 
 | 118 | static inline u32 begin_iring(struct fb_info *info, u32 space) | 
 | 119 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 120 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 |  | 
 | 122 | 	if (par->dev_flags & ALWAYS_SYNC)  | 
 | 123 | 		wait_for_engine_idle(info); | 
 | 124 | 	return wait_for_space(info, space); | 
 | 125 | } | 
 | 126 |  | 
 | 127 | /** | 
 | 128 |  * end_iring - advances the buffer | 
 | 129 |  * @par: pointer to i810fb_par structure | 
 | 130 |  * | 
 | 131 |  * DESCRIPTION: | 
 | 132 |  * This advances the tail of the ringbuffer, effectively | 
 | 133 |  * beginning the execution of the graphics instruction sequence. | 
 | 134 |  */ | 
 | 135 | static inline void end_iring(struct i810fb_par *par) | 
 | 136 | { | 
 | 137 | 	u8 __iomem *mmio = par->mmio_start_virtual; | 
 | 138 |  | 
 | 139 | 	i810_writel(IRING, mmio, par->cur_tail); | 
 | 140 | } | 
 | 141 |  | 
 | 142 | /** | 
 | 143 |  * source_copy_blit - BLIT transfer operation | 
 | 144 |  * @dwidth: width of rectangular graphics data | 
 | 145 |  * @dheight: height of rectangular graphics data | 
 | 146 |  * @dpitch: bytes per line of destination buffer | 
 | 147 |  * @xdir: direction of copy (left to right or right to left) | 
 | 148 |  * @src: address of first pixel to read from | 
 | 149 |  * @dest: address of first pixel to write to | 
 | 150 |  * @from: source address | 
 | 151 |  * @where: destination address | 
 | 152 |  * @rop: raster operation | 
 | 153 |  * @blit_bpp: pixel format which can be different from the  | 
 | 154 |  *            framebuffer's pixelformat | 
 | 155 |  * @par: pointer to i810fb_par structure | 
 | 156 |  * | 
 | 157 |  * DESCRIPTION: | 
 | 158 |  * This is a BLIT operation typically used when doing | 
 | 159 |  * a 'Copy and Paste' | 
 | 160 |  */ | 
 | 161 | static inline void source_copy_blit(int dwidth, int dheight, int dpitch,  | 
 | 162 | 				    int xdir, int src, int dest, int rop,  | 
 | 163 | 				    int blit_bpp, struct fb_info *info) | 
 | 164 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 165 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 166 |  | 
 | 167 | 	if (begin_iring(info, 24 + IRING_PAD)) return; | 
 | 168 |  | 
 | 169 | 	PUT_RING(BLIT | SOURCE_COPY_BLIT | 4); | 
 | 170 | 	PUT_RING(xdir | rop << 16 | dpitch | DYN_COLOR_EN | blit_bpp); | 
 | 171 | 	PUT_RING(dheight << 16 | dwidth); | 
 | 172 | 	PUT_RING(dest); | 
 | 173 | 	PUT_RING(dpitch); | 
 | 174 | 	PUT_RING(src); | 
 | 175 |  | 
 | 176 | 	end_iring(par); | 
 | 177 | }	 | 
 | 178 |  | 
 | 179 | /** | 
 | 180 |  * color_blit - solid color BLIT operation | 
 | 181 |  * @width: width of destination | 
 | 182 |  * @height: height of destination | 
 | 183 |  * @pitch: pixels per line of the buffer | 
 | 184 |  * @dest: address of first pixel to write to | 
 | 185 |  * @where: destination | 
 | 186 |  * @rop: raster operation | 
 | 187 |  * @what: color to transfer | 
 | 188 |  * @blit_bpp: pixel format which can be different from the  | 
 | 189 |  *            framebuffer's pixelformat | 
 | 190 |  * @par: pointer to i810fb_par structure | 
 | 191 |  * | 
 | 192 |  * DESCRIPTION: | 
 | 193 |  * A BLIT operation which can be used for  color fill/rectangular fill | 
 | 194 |  */ | 
 | 195 | static inline void color_blit(int width, int height, int pitch,  int dest,  | 
 | 196 | 			      int rop, int what, int blit_bpp,  | 
 | 197 | 			      struct fb_info *info) | 
 | 198 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 199 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 200 |  | 
 | 201 | 	if (begin_iring(info, 24 + IRING_PAD)) return; | 
 | 202 |  | 
 | 203 | 	PUT_RING(BLIT | COLOR_BLT | 3); | 
 | 204 | 	PUT_RING(rop << 16 | pitch | SOLIDPATTERN | DYN_COLOR_EN | blit_bpp); | 
 | 205 | 	PUT_RING(height << 16 | width); | 
 | 206 | 	PUT_RING(dest); | 
 | 207 | 	PUT_RING(what); | 
 | 208 | 	PUT_RING(NOP); | 
 | 209 |  | 
 | 210 | 	end_iring(par); | 
 | 211 | } | 
 | 212 |   | 
 | 213 | /** | 
 | 214 |  * mono_src_copy_imm_blit - color expand from system memory to framebuffer | 
 | 215 |  * @dwidth: width of destination | 
 | 216 |  * @dheight: height of destination | 
 | 217 |  * @dpitch: pixels per line of the buffer | 
 | 218 |  * @dsize: size of bitmap in double words | 
 | 219 |  * @dest: address of first byte of pixel; | 
 | 220 |  * @rop: raster operation | 
 | 221 |  * @blit_bpp: pixelformat to use which can be different from the  | 
 | 222 |  *            framebuffer's pixelformat | 
 | 223 |  * @src: address of image data | 
 | 224 |  * @bg: backgound color | 
 | 225 |  * @fg: forground color | 
 | 226 |  * @par: pointer to i810fb_par structure | 
 | 227 |  * | 
 | 228 |  * DESCRIPTION: | 
 | 229 |  * A color expand operation where the  source data is placed in the  | 
 | 230 |  * ringbuffer itself. Useful for drawing text.  | 
 | 231 |  * | 
 | 232 |  * REQUIREMENT: | 
 | 233 |  * The end of a scanline must be padded to the next word. | 
 | 234 |  */ | 
 | 235 | static inline void mono_src_copy_imm_blit(int dwidth, int dheight, int dpitch, | 
 | 236 | 					  int dsize, int blit_bpp, int rop, | 
 | 237 | 					  int dest, const u32 *src, int bg, | 
 | 238 | 					  int fg, struct fb_info *info) | 
 | 239 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 240 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 241 |  | 
 | 242 | 	if (begin_iring(info, 24 + (dsize << 2) + IRING_PAD)) return; | 
 | 243 |  | 
 | 244 | 	PUT_RING(BLIT | MONO_SOURCE_COPY_IMMEDIATE | (4 + dsize)); | 
 | 245 | 	PUT_RING(DYN_COLOR_EN | blit_bpp | rop << 16 | dpitch); | 
 | 246 | 	PUT_RING(dheight << 16 | dwidth); | 
 | 247 | 	PUT_RING(dest); | 
 | 248 | 	PUT_RING(bg); | 
 | 249 | 	PUT_RING(fg); | 
 | 250 | 	while (dsize--)  | 
 | 251 | 		PUT_RING(*src++); | 
 | 252 |  | 
 | 253 | 	end_iring(par); | 
 | 254 | } | 
 | 255 |  | 
 | 256 | static inline void load_front(int offset, struct fb_info *info) | 
 | 257 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 258 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 259 |  | 
 | 260 | 	if (begin_iring(info, 8 + IRING_PAD)) return; | 
 | 261 |  | 
 | 262 | 	PUT_RING(PARSER | FLUSH); | 
 | 263 | 	PUT_RING(NOP); | 
 | 264 |  | 
 | 265 | 	end_iring(par); | 
 | 266 |  | 
 | 267 | 	if (begin_iring(info, 8 + IRING_PAD)) return; | 
 | 268 |  | 
 | 269 | 	PUT_RING(PARSER | FRONT_BUFFER | ((par->pitch >> 3) << 8)); | 
 | 270 | 	PUT_RING((par->fb.offset << 12) + offset); | 
 | 271 |  | 
 | 272 | 	end_iring(par); | 
 | 273 | } | 
 | 274 |  | 
 | 275 | /** | 
 | 276 |  * i810fb_iring_enable - enables/disables the ringbuffer | 
 | 277 |  * @mode: enable or disable | 
 | 278 |  * @par: pointer to i810fb_par structure | 
 | 279 |  * | 
 | 280 |  * DESCRIPTION: | 
 | 281 |  * Enables or disables the ringbuffer, effectively enabling or | 
 | 282 |  * disabling the instruction/acceleration engine. | 
 | 283 |  */ | 
 | 284 | static inline void i810fb_iring_enable(struct i810fb_par *par, u32 mode) | 
 | 285 | { | 
 | 286 | 	u32 tmp; | 
 | 287 | 	u8 __iomem *mmio = par->mmio_start_virtual; | 
 | 288 |  | 
 | 289 | 	tmp = i810_readl(IRING + 12, mmio); | 
 | 290 | 	if (mode == OFF)  | 
 | 291 | 		tmp &= ~1; | 
 | 292 | 	else  | 
 | 293 | 		tmp |= 1; | 
 | 294 | 	flush_cache(); | 
 | 295 | 	i810_writel(IRING + 12, mmio, tmp); | 
 | 296 | }        | 
 | 297 |  | 
 | 298 | void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 
 | 299 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 300 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 301 | 	u32 dx, dy, width, height, dest, rop = 0, color = 0; | 
 | 302 |  | 
 | 303 | 	if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 
 | 304 | 	    par->depth == 4)  | 
 | 305 | 		return cfb_fillrect(info, rect); | 
 | 306 |  | 
 | 307 | 	if (par->depth == 1)  | 
 | 308 | 		color = rect->color; | 
 | 309 | 	else  | 
 | 310 | 		color = ((u32 *) (info->pseudo_palette))[rect->color]; | 
 | 311 |  | 
 | 312 | 	rop = i810fb_rop[rect->rop]; | 
 | 313 |  | 
 | 314 | 	dx = rect->dx * par->depth; | 
 | 315 | 	width = rect->width * par->depth; | 
 | 316 | 	dy = rect->dy; | 
 | 317 | 	height = rect->height; | 
 | 318 |  | 
 | 319 | 	dest = info->fix.smem_start + (dy * info->fix.line_length) + dx; | 
 | 320 | 	color_blit(width, height, info->fix.line_length, dest, rop, color,  | 
 | 321 | 		   par->blit_bpp, info); | 
 | 322 | } | 
 | 323 | 	 | 
 | 324 | void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)  | 
 | 325 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 326 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 327 | 	u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir; | 
 | 328 |  | 
 | 329 | 	if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 
 | 330 | 	    par->depth == 4) | 
 | 331 | 		return cfb_copyarea(info, region); | 
 | 332 |  | 
 | 333 | 	dx = region->dx * par->depth; | 
 | 334 | 	sx = region->sx * par->depth; | 
 | 335 | 	width = region->width * par->depth; | 
 | 336 | 	sy = region->sy; | 
 | 337 | 	dy = region->dy; | 
 | 338 | 	height = region->height; | 
 | 339 |  | 
 | 340 | 	if (dx <= sx) { | 
 | 341 | 		xdir = INCREMENT; | 
 | 342 | 	} | 
 | 343 | 	else { | 
 | 344 | 		xdir = DECREMENT; | 
 | 345 | 		sx += width - 1; | 
 | 346 | 		dx += width - 1; | 
 | 347 | 	} | 
 | 348 | 	if (dy <= sy) { | 
 | 349 | 		pitch = info->fix.line_length; | 
 | 350 | 	} | 
 | 351 | 	else { | 
 | 352 | 		pitch = (-(info->fix.line_length)) & 0xFFFF; | 
 | 353 | 		sy += height - 1; | 
 | 354 | 		dy += height - 1; | 
 | 355 | 	} | 
 | 356 | 	src = info->fix.smem_start + (sy * info->fix.line_length) + sx; | 
 | 357 | 	dest = info->fix.smem_start + (dy * info->fix.line_length) + dx; | 
 | 358 |  | 
 | 359 | 	source_copy_blit(width, height, pitch, xdir, src, dest, | 
 | 360 | 			 PAT_COPY_ROP, par->blit_bpp, info); | 
 | 361 | } | 
 | 362 |  | 
 | 363 | void i810fb_imageblit(struct fb_info *info, const struct fb_image *image) | 
 | 364 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 365 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 366 | 	u32 fg = 0, bg = 0, size, dst; | 
 | 367 | 	 | 
 | 368 | 	if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 
 | 369 | 	    par->depth == 4 || image->depth != 1)  | 
 | 370 | 		return cfb_imageblit(info, image); | 
 | 371 |  | 
 | 372 | 	switch (info->var.bits_per_pixel) { | 
 | 373 | 	case 8: | 
 | 374 | 		fg = image->fg_color; | 
 | 375 | 		bg = image->bg_color; | 
 | 376 | 		break; | 
 | 377 | 	case 16: | 
 | 378 | 	case 24: | 
 | 379 | 		fg = ((u32 *)(info->pseudo_palette))[image->fg_color]; | 
 | 380 | 		bg = ((u32 *)(info->pseudo_palette))[image->bg_color]; | 
 | 381 | 		break; | 
 | 382 | 	}	 | 
 | 383 | 	 | 
 | 384 | 	dst = info->fix.smem_start + (image->dy * info->fix.line_length) +  | 
 | 385 | 		(image->dx * par->depth); | 
 | 386 |  | 
 | 387 | 	size = (image->width+7)/8 + 1; | 
 | 388 | 	size &= ~1; | 
 | 389 | 	size *= image->height; | 
 | 390 | 	size += 7; | 
 | 391 | 	size &= ~7; | 
 | 392 | 	mono_src_copy_imm_blit(image->width * par->depth,  | 
 | 393 | 			       image->height, info->fix.line_length,  | 
 | 394 | 			       size/4, par->blit_bpp, | 
 | 395 | 			       PAT_COPY_ROP, dst, (u32 *) image->data,  | 
 | 396 | 			       bg, fg, info); | 
 | 397 | }  | 
 | 398 |  | 
 | 399 | int i810fb_sync(struct fb_info *info) | 
 | 400 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 401 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 402 | 	 | 
 | 403 | 	if (!info->var.accel_flags || par->dev_flags & LOCKUP) | 
 | 404 | 		return 0; | 
 | 405 |  | 
 | 406 | 	return wait_for_engine_idle(info); | 
 | 407 | } | 
 | 408 |  | 
 | 409 | void i810fb_load_front(u32 offset, struct fb_info *info) | 
 | 410 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 411 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 412 | 	u8 __iomem *mmio = par->mmio_start_virtual; | 
 | 413 |  | 
 | 414 | 	if (!info->var.accel_flags || par->dev_flags & LOCKUP) | 
 | 415 | 		i810_writel(DPLYBASE, mmio, par->fb.physical + offset); | 
 | 416 | 	else  | 
 | 417 | 		load_front(offset, info); | 
 | 418 | } | 
 | 419 |  | 
 | 420 | /** | 
 | 421 |  * i810fb_init_ringbuffer - initialize the ringbuffer | 
 | 422 |  * @par: pointer to i810fb_par structure | 
 | 423 |  * | 
 | 424 |  * DESCRIPTION: | 
 | 425 |  * Initializes the ringbuffer by telling the device the | 
 | 426 |  * size and location of the ringbuffer.  It also sets  | 
 | 427 |  * the head and tail pointers = 0 | 
 | 428 |  */ | 
 | 429 | void i810fb_init_ringbuffer(struct fb_info *info) | 
 | 430 | { | 
| Antonino A. Daplas | c019c0e | 2006-01-09 20:53:03 -0800 | [diff] [blame] | 431 | 	struct i810fb_par *par = info->par; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 432 | 	u32 tmp1, tmp2; | 
 | 433 | 	u8 __iomem *mmio = par->mmio_start_virtual; | 
 | 434 | 	 | 
 | 435 | 	wait_for_engine_idle(info); | 
 | 436 | 	i810fb_iring_enable(par, OFF); | 
 | 437 | 	i810_writel(IRING, mmio, 0); | 
 | 438 | 	i810_writel(IRING + 4, mmio, 0); | 
 | 439 | 	par->cur_tail = 0; | 
 | 440 |  | 
 | 441 | 	tmp2 = i810_readl(IRING + 8, mmio) & ~RBUFFER_START_MASK;  | 
 | 442 | 	tmp1 = par->iring.physical; | 
 | 443 | 	i810_writel(IRING + 8, mmio, tmp2 | tmp1); | 
 | 444 |  | 
 | 445 | 	tmp1 = i810_readl(IRING + 12, mmio); | 
 | 446 | 	tmp1 &= ~RBUFFER_SIZE_MASK; | 
 | 447 | 	tmp2 = (par->iring.size - I810_PAGESIZE) & RBUFFER_SIZE_MASK; | 
 | 448 | 	i810_writel(IRING + 12, mmio, tmp1 | tmp2); | 
 | 449 | 	i810fb_iring_enable(par, ON); | 
 | 450 | } |