linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / video / ffb.c
index 1f76131..9c9b21d 100644 (file)
@@ -37,9 +37,8 @@ static void ffb_imageblit(struct fb_info *, const struct fb_image *);
 static void ffb_fillrect(struct fb_info *, const struct fb_fillrect *);
 static void ffb_copyarea(struct fb_info *, const struct fb_copyarea *);
 static int ffb_sync(struct fb_info *);
-static int ffb_mmap(struct fb_info *, struct file *, struct vm_area_struct *);
-static int ffb_ioctl(struct inode *, struct file *, unsigned int,
-                    unsigned long, struct fb_info *);
+static int ffb_mmap(struct fb_info *, struct vm_area_struct *);
+static int ffb_ioctl(struct fb_info *, unsigned int, unsigned long);
 static int ffb_pan_display(struct fb_var_screeninfo *, struct fb_info *);
 
 /*
@@ -57,9 +56,9 @@ static struct fb_ops ffb_ops = {
        .fb_sync                = ffb_sync,
        .fb_mmap                = ffb_mmap,
        .fb_ioctl               = ffb_ioctl,
-
-       /* XXX Use FFB hw cursor once fb cursor API is better understood... */
-       .fb_cursor              = soft_cursor,
+#ifdef CONFIG_COMPAT
+       .fb_compat_ioctl        = sbusfb_compat_ioctl,
+#endif
 };
 
 /* Register layout and definitions */
@@ -359,64 +358,8 @@ struct ffb_par {
        int                     prom_parent_node;
        int                     dac_rev;
        int                     board_type;
-       struct list_head        list;
 };
 
-#undef FFB_DO_DEBUG_LOG
-
-#ifdef FFB_DO_DEBUG_LOG
-#define FFB_DEBUG_LOG_ENTS     32
-static struct ffb_log {
-       int op;
-#define OP_FILLRECT    1
-#define OP_IMAGEBLIT   2
-
-       int depth, x, y, w, h;
-} ffb_debug_log[FFB_DEBUG_LOG_ENTS];
-static int ffb_debug_log_ent;
-
-static void ffb_do_log(unsigned long unused)
-{
-       int i;
-
-       for (i = 0; i < FFB_DEBUG_LOG_ENTS; i++) {
-               struct ffb_log *p = &ffb_debug_log[i];
-
-               printk("FFB_LOG: OP[%s] depth(%d) x(%d) y(%d) w(%d) h(%d)\n",
-                      (p->op == OP_FILLRECT ? "FILLRECT" : "IMAGEBLIT"),
-                      p->depth, p->x, p->y, p->w, p->h);
-       }
-}
-static struct timer_list ffb_log_timer =
-       TIMER_INITIALIZER(ffb_do_log, 0, 0);
-
-static void ffb_log(int op, int depth, int x, int y, int w, int h)
-{
-       if (ffb_debug_log_ent < FFB_DEBUG_LOG_ENTS) {
-               struct ffb_log *p = &ffb_debug_log[ffb_debug_log_ent];
-
-               if (ffb_debug_log_ent != 0 &&
-                   p[-1].op == op && p[-1].depth == depth)
-                       return;
-               p->op = op;
-               p->depth = depth;
-               p->x = x;
-               p->y = y;
-               p->w = w;
-               p->h = h;
-
-               if (++ffb_debug_log_ent == FFB_DEBUG_LOG_ENTS) {
-                       ffb_log_timer.expires = jiffies + 2;
-                       add_timer(&ffb_log_timer);
-               }
-       }
-}
-#else
-#define ffb_log(a,b,c,d,e,f)   do { } while(0)
-#endif
-
-#undef FORCE_WAIT_EVERY_ROP
-
 static void FFBFifo(struct ffb_par *par, int n)
 {
        struct ffb_fbc *fbc;
@@ -479,7 +422,7 @@ static void ffb_switch_from_graph(struct ffb_par *par)
        upa_writel(0x2000707f, &fbc->fbc);
        upa_writel(par->rop_cache, &fbc->rop);
        upa_writel(0xffffffff, &fbc->pmask);
-       upa_writel((0 << 16) | (32 << 0), &fbc->fontinc);
+       upa_writel((1 << 16) | (0 << 0), &fbc->fontinc);
        upa_writel(par->fg_cache, &fbc->fg);
        upa_writel(par->bg_cache, &fbc->bg);
        FFBWait(par);
@@ -526,8 +469,6 @@ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
        if (rect->rop != ROP_COPY && rect->rop != ROP_XOR)
                BUG();
 
-       ffb_log(OP_FILLRECT, 0, rect->dx, rect->dy, rect->width, rect->height);
-
        fg = ((u32 *)info->pseudo_palette)[rect->color];
 
        spin_lock_irqsave(&par->lock, flags);
@@ -548,9 +489,6 @@ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
        upa_writel(rect->dx, &fbc->bx);
        upa_writel(rect->height, &fbc->bh);
        upa_writel(rect->width, &fbc->bw);
-#ifdef FORCE_WAIT_EVERY_ROP
-       FFBWait(par);
-#endif
 
        spin_unlock_irqrestore(&par->lock, flags);
 }
@@ -572,7 +510,7 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        unsigned long flags;
 
        if (area->dx != area->sx ||
-           area->dy == area->dy) {
+           area->dy == area->sy) {
                cfb_copyarea(info, area);
                return;
        }
@@ -609,10 +547,7 @@ static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
        unsigned long flags;
        u32 fg, bg, xy;
        u64 fgbg;
-       int i, width;
-
-       ffb_log(OP_IMAGEBLIT, image->depth,
-               image->dx, image->dy, image->width, image->height);
+       int i, width, stride;
 
        if (image->depth > 1) {
                cfb_imageblit(info, image);
@@ -623,6 +558,8 @@ static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
        bg = ((u32 *)info->pseudo_palette)[image->bg_color];
        fgbg = ((u64) fg << 32) | (u64) bg;
        xy = (image->dy << 16) | image->dx;
+       width = image->width;
+       stride = ((width + 7) >> 3);
 
        spin_lock_irqsave(&par->lock, flags);
 
@@ -632,55 +569,49 @@ static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
                *(u64 *)&par->fg_cache = fgbg;
        }
 
-       ffb_rop(par, FFB_ROP_NEW);
+       if (width >= 32) {
+               FFBFifo(par, 1);
+               upa_writel(32, &fbc->fontw);
+       }
 
-       for (i = 0; i < image->height; i++) {
-               width = image->width;
+       while (width >= 32) {
+               const u8 *next_data = data + 4;
 
                FFBFifo(par, 1);
                upa_writel(xy, &fbc->fontxy);
-               xy += (1 << 16);
-
-               while (width >= 32) {
-                       u32 val;
-
-                       FFBFifo(par, 2);
-                       upa_writel(32, &fbc->fontw);
-
-                       val = ((u32)data[0] << 24) |
-                             ((u32)data[1] << 16) |
-                             ((u32)data[2] <<  8) |
-                             ((u32)data[3] <<  0);
+               xy += (32 << 0);
+
+               for (i = 0; i < image->height; i++) {
+                       u32 val = (((u32)data[0] << 24) |
+                                  ((u32)data[1] << 16) |
+                                  ((u32)data[2] <<  8) |
+                                  ((u32)data[3] <<  0));
+                       FFBFifo(par, 1);
                        upa_writel(val, &fbc->font);
 
-                       data += 4;
-                       width -= 32;
+                       data += stride;
                }
 
-               if (width) {
-                       u32 val;
-
-                       FFBFifo(par, 2);
-                       upa_writel(width, &fbc->fontw);
-                       if (width <= 8) {
-                               val = (u32) data[0] << 24;
-                               data += 1;
-                       } else if (width <= 16) {
-                               val = ((u32) data[0] << 24) |
-                                     ((u32) data[1] << 16);
-                               data += 2;
-                       } else {
-                               val = ((u32) data[0] << 24) |
-                                     ((u32) data[1] << 16) |
-                                     ((u32) data[2] <<  8);
-                               data += 3;
-                       }
+               data = next_data;
+               width -= 32;
+       }
+
+       if (width) {
+               FFBFifo(par, 2);
+               upa_writel(width, &fbc->fontw);
+               upa_writel(xy, &fbc->fontxy);
+
+               for (i = 0; i < image->height; i++) {
+                       u32 val = (((u32)data[0] << 24) |
+                                  ((u32)data[1] << 16) |
+                                  ((u32)data[2] <<  8) |
+                                  ((u32)data[3] <<  0));
+                       FFBFifo(par, 1);
                        upa_writel(val, &fbc->font);
+
+                       data += stride;
                }
        }
-#ifdef FORCE_WAIT_EVERY_ROP
-       FFBWait(par);
-#endif
 
        spin_unlock_irqrestore(&par->lock, flags);
 }
@@ -743,7 +674,7 @@ ffb_blank(int blank, struct fb_info *info)
        FFBWait(par);
 
        switch (blank) {
-       case 0: /* Unblanking */
+       case FB_BLANK_UNBLANK: /* Unblanking */
                upa_writel(0x6000, &dac->type);
                tmp = (upa_readl(&dac->value) | 0x1);
                upa_writel(0x6000, &dac->type);
@@ -751,10 +682,10 @@ ffb_blank(int blank, struct fb_info *info)
                par->flags &= ~FFB_FLAG_BLANKED;
                break;
 
-       case 1: /* Normal blanking */
-       case 2: /* VESA blank (vsync off) */
-       case 3: /* VESA blank (hsync off) */
-       case 4: /* Poweroff */
+       case FB_BLANK_NORMAL: /* Normal blanking */
+       case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */
+       case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */
+       case FB_BLANK_POWERDOWN: /* Poweroff */
                upa_writel(0x6000, &dac->type);
                tmp = (upa_readl(&dac->value) & ~0x1);
                upa_writel(0x6000, &dac->type);
@@ -907,7 +838,7 @@ static struct sbus_mmap_map ffb_mmap_map[] = {
        { .size = 0 }
 };
 
-static int ffb_mmap(struct fb_info *info, struct file *file, struct vm_area_struct *vma)
+static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        struct ffb_par *par = (struct ffb_par *)info->par;
 
@@ -916,8 +847,7 @@ static int ffb_mmap(struct fb_info *info, struct file *file, struct vm_area_stru
                                  0, vma);
 }
 
-static int ffb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-                    unsigned long arg, struct fb_info *info)
+static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 {
        struct ffb_par *par = (struct ffb_par *) info->par;
 
@@ -1027,10 +957,15 @@ static void ffb_init_one(int node, int parent)
        all->par.prom_node = node;
        all->par.prom_parent_node = parent;
 
-       all->info.flags = FBINFO_FLAG_DEFAULT;
+       /* Don't mention copyarea, so SCROLL_REDRAW is always
+        * used.  It is the fastest on this chip.
+        */
+       all->info.flags = (FBINFO_DEFAULT |
+                          /* FBINFO_HWACCEL_COPYAREA | */
+                          FBINFO_HWACCEL_FILLRECT |
+                          FBINFO_HWACCEL_IMAGEBLIT);
        all->info.fbops = &ffb_ops;
        all->info.screen_base = (char *) all->par.physbase + FFB_DFB24_POFF;
-       all->info.currcon = -1;
        all->info.par = &all->par;
        all->info.pseudo_palette = all->pseudo_palette;
 
@@ -1110,6 +1045,9 @@ int __init ffb_init(void)
 {
        int root;
 
+       if (fb_get_options("ffb", NULL))
+               return -ENODEV;
+
        ffb_scan_siblings(prom_root_node);
 
        root = prom_getchild(prom_root_node);
@@ -1140,8 +1078,9 @@ ffb_setup(char *arg)
        return 0;
 }
 
-#ifdef MODULE
 module_init(ffb_init);
+
+#ifdef MODULE
 module_exit(ffb_exit);
 #endif