This source file includes following definitions.
- i810_report_error
- wait_for_space
- wait_for_engine_idle
- begin_iring
- end_iring
- source_copy_blit
- color_blit
- mono_src_copy_imm_blit
- load_front
- i810fb_iring_enable
- i810fb_fillrect
- i810fb_copyarea
- i810fb_imageblit
- i810fb_sync
- i810fb_load_front
- i810fb_init_ringbuffer
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  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"
  17 #include "i810_main.h"
  18 
  19 static u32 i810fb_rop[] = {
  20         COLOR_COPY_ROP, 
  21         XOR_ROP         
  22 };
  23 
  24 
  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 
  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 
  52 
  53 
  54 
  55 
  56 
  57 
  58      
  59 static inline int wait_for_space(struct fb_info *info, u32 space)
  60 {
  61         struct i810fb_par *par = info->par;
  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 
  84 
  85 
  86 
  87 
  88 
  89 
  90 static inline int wait_for_engine_idle(struct fb_info *info)
  91 {
  92         struct i810fb_par *par = info->par;
  93         u8 __iomem *mmio = par->mmio_start_virtual;
  94         int count = WAIT_COUNT;
  95 
  96         if (wait_for_space(info, par->iring.size)) 
  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 
 111 
 112 
 113 
 114 
 115 
 116 
 117  
 118 static inline u32 begin_iring(struct fb_info *info, u32 space)
 119 {
 120         struct i810fb_par *par = info->par;
 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 
 129 
 130 
 131 
 132 
 133 
 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 
 144 
 145 
 146 
 147 
 148 
 149 
 150 
 151 
 152 
 153 
 154 
 155 
 156 
 157 
 158 
 159 
 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 {
 165         struct i810fb_par *par = info->par;
 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 
 181 
 182 
 183 
 184 
 185 
 186 
 187 
 188 
 189 
 190 
 191 
 192 
 193 
 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 {
 199         struct i810fb_par *par = info->par;
 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 
 215 
 216 
 217 
 218 
 219 
 220 
 221 
 222 
 223 
 224 
 225 
 226 
 227 
 228 
 229 
 230 
 231 
 232 
 233 
 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 {
 240         struct i810fb_par *par = info->par;
 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 {
 258         struct i810fb_par *par = info->par;
 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 
 277 
 278 
 279 
 280 
 281 
 282 
 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 {
 300         struct i810fb_par *par = info->par;
 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                 cfb_fillrect(info, rect);
 306                 return;
 307         }
 308 
 309         if (par->depth == 1) 
 310                 color = rect->color;
 311         else 
 312                 color = ((u32 *) (info->pseudo_palette))[rect->color];
 313 
 314         rop = i810fb_rop[rect->rop];
 315 
 316         dx = rect->dx * par->depth;
 317         width = rect->width * par->depth;
 318         dy = rect->dy;
 319         height = rect->height;
 320 
 321         dest = info->fix.smem_start + (dy * info->fix.line_length) + dx;
 322         color_blit(width, height, info->fix.line_length, dest, rop, color, 
 323                    par->blit_bpp, info);
 324 }
 325         
 326 void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) 
 327 {
 328         struct i810fb_par *par = info->par;
 329         u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir;
 330 
 331         if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
 332             par->depth == 4) {
 333                 cfb_copyarea(info, region);
 334                 return;
 335         }
 336 
 337         dx = region->dx * par->depth;
 338         sx = region->sx * par->depth;
 339         width = region->width * par->depth;
 340         sy = region->sy;
 341         dy = region->dy;
 342         height = region->height;
 343 
 344         if (dx <= sx) {
 345                 xdir = INCREMENT;
 346         }
 347         else {
 348                 xdir = DECREMENT;
 349                 sx += width - 1;
 350                 dx += width - 1;
 351         }
 352         if (dy <= sy) {
 353                 pitch = info->fix.line_length;
 354         }
 355         else {
 356                 pitch = (-(info->fix.line_length)) & 0xFFFF;
 357                 sy += height - 1;
 358                 dy += height - 1;
 359         }
 360         src = info->fix.smem_start + (sy * info->fix.line_length) + sx;
 361         dest = info->fix.smem_start + (dy * info->fix.line_length) + dx;
 362 
 363         source_copy_blit(width, height, pitch, xdir, src, dest,
 364                          PAT_COPY_ROP, par->blit_bpp, info);
 365 }
 366 
 367 void i810fb_imageblit(struct fb_info *info, const struct fb_image *image)
 368 {
 369         struct i810fb_par *par = info->par;
 370         u32 fg = 0, bg = 0, size, dst;
 371         
 372         if (!info->var.accel_flags || par->dev_flags & LOCKUP ||
 373             par->depth == 4 || image->depth != 1) {
 374                 cfb_imageblit(info, image);
 375                 return;
 376         }
 377 
 378         switch (info->var.bits_per_pixel) {
 379         case 8:
 380                 fg = image->fg_color;
 381                 bg = image->bg_color;
 382                 break;
 383         case 16:
 384         case 24:
 385                 fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
 386                 bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
 387                 break;
 388         }       
 389         
 390         dst = info->fix.smem_start + (image->dy * info->fix.line_length) + 
 391                 (image->dx * par->depth);
 392 
 393         size = (image->width+7)/8 + 1;
 394         size &= ~1;
 395         size *= image->height;
 396         size += 7;
 397         size &= ~7;
 398         mono_src_copy_imm_blit(image->width * par->depth, 
 399                                image->height, info->fix.line_length, 
 400                                size/4, par->blit_bpp,
 401                                PAT_COPY_ROP, dst, (u32 *) image->data, 
 402                                bg, fg, info);
 403 } 
 404 
 405 int i810fb_sync(struct fb_info *info)
 406 {
 407         struct i810fb_par *par = info->par;
 408         
 409         if (!info->var.accel_flags || par->dev_flags & LOCKUP)
 410                 return 0;
 411 
 412         return wait_for_engine_idle(info);
 413 }
 414 
 415 void i810fb_load_front(u32 offset, struct fb_info *info)
 416 {
 417         struct i810fb_par *par = info->par;
 418         u8 __iomem *mmio = par->mmio_start_virtual;
 419 
 420         if (!info->var.accel_flags || par->dev_flags & LOCKUP)
 421                 i810_writel(DPLYBASE, mmio, par->fb.physical + offset);
 422         else 
 423                 load_front(offset, info);
 424 }
 425 
 426 
 427 
 428 
 429 
 430 
 431 
 432 
 433 
 434 
 435 void i810fb_init_ringbuffer(struct fb_info *info)
 436 {
 437         struct i810fb_par *par = info->par;
 438         u32 tmp1, tmp2;
 439         u8 __iomem *mmio = par->mmio_start_virtual;
 440         
 441         wait_for_engine_idle(info);
 442         i810fb_iring_enable(par, OFF);
 443         i810_writel(IRING, mmio, 0);
 444         i810_writel(IRING + 4, mmio, 0);
 445         par->cur_tail = 0;
 446 
 447         tmp2 = i810_readl(IRING + 8, mmio) & ~RBUFFER_START_MASK; 
 448         tmp1 = par->iring.physical;
 449         i810_writel(IRING + 8, mmio, tmp2 | tmp1);
 450 
 451         tmp1 = i810_readl(IRING + 12, mmio);
 452         tmp1 &= ~RBUFFER_SIZE_MASK;
 453         tmp2 = (par->iring.size - I810_PAGESIZE) & RBUFFER_SIZE_MASK;
 454         i810_writel(IRING + 12, mmio, tmp1 | tmp2);
 455         i810fb_iring_enable(par, ON);
 456 }