libata: don't check whether to use DMA or not for no data commands
[pandora-kernel.git] / drivers / video / cirrusfb.c
index ebb8ddb..c14b243 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/init.h>
-#include <linux/selection.h>
 #include <asm/pgtable.h>
 
 #ifdef CONFIG_ZORRO
@@ -64,8 +63,8 @@
 #define isPReP 0
 #endif
 
-#include "video/vga.h"
-#include "video/cirrus.h"
+#include <video/vga.h>
+#include <video/cirrus.h>
 
 /*****************************************************************
  *
@@ -82,7 +81,7 @@
 /* debug output */
 #ifdef CIRRUSFB_DEBUG
 #define DPRINTK(fmt, args...) \
-       printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+       printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
 #else
 #define DPRINTK(fmt, args...)
 #endif
 #define assert(expr) \
        if (!(expr)) { \
                printk("Assertion failed! %s,%s,%s,line=%d\n", \
-               #expr, __FILE__, __FUNCTION__, __LINE__); \
+               #expr, __FILE__, __func__, __LINE__); \
        }
 #else
 #define assert(expr)
 #endif
 
 #define MB_ (1024 * 1024)
-#define KB_ (1024)
-
-#define MAX_NUM_BOARDS 7
 
 /*****************************************************************
  *
@@ -331,10 +327,6 @@ static const struct {
 #endif /* CONFIG_ZORRO */
 
 struct cirrusfb_regs {
-       __u32 line_length;      /* in BYTES! */
-       __u32 visual;
-       __u32 type;
-
        long freq;
        long nom;
        long den;
@@ -525,7 +517,7 @@ static struct fb_ops cirrusfb_ops = {
 /*--- Hardware Specific Routines -------------------------------------------*/
 static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
                                struct cirrusfb_regs *regs,
-                               const struct fb_info *info);
+                               struct fb_info *info);
 /*--- Internal routines ----------------------------------------------------*/
 static void init_vgachip(struct fb_info *info);
 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
@@ -647,31 +639,17 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
          { -1, -1 } };
 
        switch (var->bits_per_pixel) {
-       case 0 ... 1:
-               var->bits_per_pixel = 1;
+       case 1:
                nom = 4;
                den = 8;
                break;          /* 8 pixel per byte, only 1/4th of mem usable */
-       case 2 ... 8:
-               var->bits_per_pixel = 8;
-               nom = 1;
+       case 8:
+       case 16:
+       case 24:
+       case 32:
+               nom = var->bits_per_pixel / 8;
                den = 1;
                break;          /* 1 pixel == 1 byte */
-       case 9 ... 16:
-               var->bits_per_pixel = 16;
-               nom = 2;
-               den = 1;
-               break;          /* 2 bytes per pixel */
-       case 17 ... 24:
-               var->bits_per_pixel = 24;
-               nom = 3;
-               den = 1;
-               break;          /* 3 bytes per pixel */
-       case 25 ... 32:
-               var->bits_per_pixel = 32;
-               nom = 4;
-               den = 1;
-               break;          /* 4 bytes per pixel */
        default:
                printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
                        "color depth not supported.\n",
@@ -732,19 +710,15 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
        case 1:
                var->red.offset = 0;
                var->red.length = 1;
-               var->green.offset = 0;
-               var->green.length = 1;
-               var->blue.offset = 0;
-               var->blue.length = 1;
+               var->green = var->red;
+               var->blue = var->red;
                break;
 
        case 8:
                var->red.offset = 0;
                var->red.length = 6;
-               var->green.offset = 0;
-               var->green.length = 6;
-               var->blue.offset = 0;
-               var->blue.length = 6;
+               var->green = var->red;
+               var->blue = var->red;
                break;
 
        case 16:
@@ -763,20 +737,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
                break;
 
        case 24:
-               if (isPReP) {
-                       var->red.offset = 8;
-                       var->green.offset = 16;
-                       var->blue.offset = 24;
-               } else {
-                       var->red.offset = 16;
-                       var->green.offset = 8;
-                       var->blue.offset = 0;
-               }
-               var->red.length = 8;
-               var->green.length = 8;
-               var->blue.length = 8;
-               break;
-
        case 32:
                if (isPReP) {
                        var->red.offset = 8;
@@ -824,44 +784,31 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
 
 static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
                                struct cirrusfb_regs *regs,
-                               const struct fb_info *info)
+                               struct fb_info *info)
 {
        long freq;
        long maxclock;
-       int maxclockidx = 0;
+       int maxclockidx = var->bits_per_pixel >> 3;
        struct cirrusfb_info *cinfo = info->par;
        int xres, hfront, hsync, hback;
        int yres, vfront, vsync, vback;
 
        switch (var->bits_per_pixel) {
        case 1:
-               regs->line_length = var->xres_virtual / 8;
-               regs->visual = FB_VISUAL_MONO10;
-               maxclockidx = 0;
+               info->fix.line_length = var->xres_virtual / 8;
+               info->fix.visual = FB_VISUAL_MONO10;
                break;
 
        case 8:
-               regs->line_length = var->xres_virtual;
-               regs->visual = FB_VISUAL_PSEUDOCOLOR;
-               maxclockidx = 1;
+               info->fix.line_length = var->xres_virtual;
+               info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
                break;
 
        case 16:
-               regs->line_length = var->xres_virtual * 2;
-               regs->visual = FB_VISUAL_DIRECTCOLOR;
-               maxclockidx = 2;
-               break;
-
        case 24:
-               regs->line_length = var->xres_virtual * 3;
-               regs->visual = FB_VISUAL_DIRECTCOLOR;
-               maxclockidx = 3;
-               break;
-
        case 32:
-               regs->line_length = var->xres_virtual * 4;
-               regs->visual = FB_VISUAL_DIRECTCOLOR;
-               maxclockidx = 4;
+               info->fix.line_length = var->xres_virtual * maxclockidx;
+               info->fix.visual = FB_VISUAL_DIRECTCOLOR;
                break;
 
        default:
@@ -871,10 +818,10 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
                break;
        }
 
-       regs->type = FB_TYPE_PACKED_PIXELS;
+       info->fix.type = FB_TYPE_PACKED_PIXELS;
 
        /* convert from ps to kHz */
-       freq = 1000000000 / var->pixclock;
+       freq = PICOS2KHZ(var->pixclock);
 
        DPRINTK("desired pixclock: %ld kHz\n", freq);
 
@@ -1213,7 +1160,8 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                        break;
 
                case BT_PICCOLO:
-                       DPRINTK("(for Piccolo)\n");
+               case BT_SPECTRUM:
+                       DPRINTK("(for Piccolo/Spectrum)\n");
                        /* ### ueberall 0x22? */
                        /* ##vorher 1c MCLK select */
                        vga_wseq(regbase, CL_SEQR1F, 0x22);
@@ -1229,15 +1177,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                        vga_wseq(regbase, CL_SEQRF, 0xd0);
                        break;
 
-               case BT_SPECTRUM:
-                       DPRINTK("(for Spectrum)\n");
-                       /* ### ueberall 0x22? */
-                       /* ##vorher 1c MCLK select */
-                       vga_wseq(regbase, CL_SEQR1F, 0x22);
-                       /* evtl d0? avoid FIFO underruns..? */
-                       vga_wseq(regbase, CL_SEQRF, 0xb0);
-                       break;
-
                case BT_PICASSO4:
                case BT_ALPINE:
                case BT_GD5480:
@@ -1306,19 +1245,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                        break;
 
                case BT_PICCOLO:
-                       /* ### vorher 1c MCLK select */
-                       vga_wseq(regbase, CL_SEQR1F, 0x22);
-                       /* Fast Page-Mode writes */
-                       vga_wseq(regbase, CL_SEQRF, 0xb0);
-                       break;
-
                case BT_PICASSO:
-                       /* ### vorher 1c MCLK select */
-                       vga_wseq(regbase, CL_SEQR1F, 0x22);
-                       /* Fast Page-Mode writes */
-                       vga_wseq(regbase, CL_SEQRF, 0xb0);
-                       break;
-
                case BT_SPECTRUM:
                        /* ### vorher 1c MCLK select */
                        vga_wseq(regbase, CL_SEQR1F, 0x22);
@@ -1385,6 +1312,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                        break;
 
                case BT_PICCOLO:
+               case BT_SPECTRUM:
                        vga_wseq(regbase, CL_SEQR7, 0x87);
                        /* Fast Page-Mode writes */
                        vga_wseq(regbase, CL_SEQRF, 0xb0);
@@ -1400,14 +1328,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                        vga_wseq(regbase, CL_SEQR1F, 0x22);
                        break;
 
-               case BT_SPECTRUM:
-                       vga_wseq(regbase, CL_SEQR7, 0x87);
-                       /* Fast Page-Mode writes */
-                       vga_wseq(regbase, CL_SEQRF, 0xb0);
-                       /* MCLK select */
-                       vga_wseq(regbase, CL_SEQR1F, 0x22);
-                       break;
-
                case BT_PICASSO4:
                        vga_wseq(regbase, CL_SEQR7, 0x27);
 /*                     vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
@@ -1473,6 +1393,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                        break;
 
                case BT_PICCOLO:
+               case BT_SPECTRUM:
                        vga_wseq(regbase, CL_SEQR7, 0x85);
                        /* Fast Page-Mode writes */
                        vga_wseq(regbase, CL_SEQRF, 0xb0);
@@ -1488,14 +1409,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
                        vga_wseq(regbase, CL_SEQR1F, 0x22);
                        break;
 
-               case BT_SPECTRUM:
-                       vga_wseq(regbase, CL_SEQR7, 0x85);
-                       /* Fast Page-Mode writes */
-                       vga_wseq(regbase, CL_SEQRF, 0xb0);
-                       /* MCLK select */
-                       vga_wseq(regbase, CL_SEQR1F, 0x22);
-                       break;
-
                case BT_PICASSO4:
                        vga_wseq(regbase, CL_SEQR7, 0x25);
 /*                     vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
@@ -1618,9 +1531,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
        DPRINTK("CL_SEQR1: %d\n", tmp);
 
        cinfo->currentmode = regs;
-       info->fix.type = regs.type;
-       info->fix.visual = regs.visual;
-       info->fix.line_length = regs.line_length;
 
        /* pan to requested offset */
        cirrusfb_pan_display(var, info);
@@ -1662,18 +1572,7 @@ static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
                    (green << info->var.green.offset) |
                    (blue << info->var.blue.offset);
 
-               switch (info->var.bits_per_pixel) {
-               case 8:
-                       cinfo->pseudo_palette[regno] = v;
-                       break;
-               case 16:
-                       cinfo->pseudo_palette[regno] = v;
-                       break;
-               case 24:
-               case 32:
-                       cinfo->pseudo_palette[regno] = v;
-                       break;
-               }
+               cinfo->pseudo_palette[regno] = v;
                return 0;
        }
 
@@ -1712,7 +1611,7 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
        xoffset = var->xoffset * info->var.bits_per_pixel / 8;
        yoffset = var->yoffset;
 
-       base = yoffset * cinfo->currentmode.line_length + xoffset;
+       base = yoffset * info->fix.line_length + xoffset;
 
        if (info->var.bits_per_pixel == 1) {
                /* base is already correct */
@@ -1743,12 +1642,8 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
        vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
 
        /* construct bit 19 of screen start address */
-       if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
-               tmp2 = 0;
-               if (base & 0x80000)
-                       tmp2 = 0x80;
-               vga_wcrt(cinfo->regbase, CL_CRT1D, tmp2);
-       }
+       if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
+               vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
 
        /* write pixel panning value to AR33; this does not quite work in 8bpp
         *
@@ -2139,38 +2034,15 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
 /* Linux 2.6-style  accelerated functions */
 /******************************************/
 
-static void cirrusfb_prim_fillrect(struct fb_info *info,
-                                  const struct fb_fillrect *region)
-{
-       struct cirrusfb_info *cinfo = info->par;
-       int m; /* bytes per pixel */
-       u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
-               cinfo->pseudo_palette[region->color] : region->color;
-
-       if (info->var.bits_per_pixel == 1) {
-               cirrusfb_RectFill(cinfo->regbase,
-                                 info->var.bits_per_pixel,
-                                 region->dx / 8, region->dy,
-                                 region->width / 8, region->height,
-                                 color,
-                                 cinfo->currentmode.line_length);
-       } else {
-               m = (info->var.bits_per_pixel + 7) / 8;
-               cirrusfb_RectFill(cinfo->regbase,
-                                 info->var.bits_per_pixel,
-                                 region->dx * m, region->dy,
-                                 region->width * m, region->height,
-                                 color,
-                                 cinfo->currentmode.line_length);
-       }
-       return;
-}
-
 static void cirrusfb_fillrect(struct fb_info *info,
                              const struct fb_fillrect *region)
 {
        struct fb_fillrect modded;
        int vxres, vyres;
+       struct cirrusfb_info *cinfo = info->par;
+       int m = info->var.bits_per_pixel;
+       u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+               cinfo->pseudo_palette[region->color] : region->color;
 
        if (info->state != FBINFO_STATE_RUNNING)
                return;
@@ -2193,30 +2065,12 @@ static void cirrusfb_fillrect(struct fb_info *info,
        if (modded.dy + modded.height > vyres)
                modded.height = vyres - modded.dy;
 
-       cirrusfb_prim_fillrect(info, &modded);
-}
-
-static void cirrusfb_prim_copyarea(struct fb_info *info,
-                                  const struct fb_copyarea *area)
-{
-       struct cirrusfb_info *cinfo = info->par;
-       int m; /* bytes per pixel */
-
-       if (info->var.bits_per_pixel == 1) {
-               cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
-                               area->sx / 8, area->sy,
-                               area->dx / 8, area->dy,
-                               area->width / 8, area->height,
-                               cinfo->currentmode.line_length);
-       } else {
-               m = (info->var.bits_per_pixel + 7) / 8;
-               cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
-                               area->sx * m, area->sy,
-                               area->dx * m, area->dy,
-                               area->width * m, area->height,
-                               cinfo->currentmode.line_length);
-       }
-       return;
+       cirrusfb_RectFill(cinfo->regbase,
+                         info->var.bits_per_pixel,
+                         (region->dx * m) / 8, region->dy,
+                         (region->width * m) / 8, region->height,
+                         color,
+                         info->fix.line_length);
 }
 
 static void cirrusfb_copyarea(struct fb_info *info,
@@ -2224,13 +2078,8 @@ static void cirrusfb_copyarea(struct fb_info *info,
 {
        struct fb_copyarea modded;
        u32 vxres, vyres;
-
-       modded.sx = area->sx;
-       modded.sy = area->sy;
-       modded.dx = area->dx;
-       modded.dy = area->dy;
-       modded.width  = area->width;
-       modded.height = area->height;
+       struct cirrusfb_info *cinfo = info->par;
+       int m = info->var.bits_per_pixel;
 
        if (info->state != FBINFO_STATE_RUNNING)
                return;
@@ -2241,6 +2090,7 @@ static void cirrusfb_copyarea(struct fb_info *info,
 
        vxres = info->var.xres_virtual;
        vyres = info->var.yres_virtual;
+       memcpy(&modded, area, sizeof(struct fb_copyarea));
 
        if (!modded.width || !modded.height ||
           modded.sx >= vxres || modded.sy >= vyres ||
@@ -2256,7 +2106,12 @@ static void cirrusfb_copyarea(struct fb_info *info,
        if (modded.dy + modded.height > vyres)
                modded.height = vyres - modded.dy;
 
-       cirrusfb_prim_copyarea(info, &modded);
+       cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
+                       (area->sx * m) / 8, area->sy,
+                       (area->dx * m) / 8, area->dy,
+                       (area->width * m) / 8, area->height,
+                       info->fix.line_length);
+
 }
 
 static void cirrusfb_imageblit(struct fb_info *info,
@@ -2366,13 +2221,13 @@ static void cirrusfb_pci_unmap(struct fb_info *info)
        if (release_io_ports)
                release_region(0x3C0, 32);
        pci_release_regions(pdev);
-       framebuffer_release(info);
 }
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_ZORRO
-static void __devexit cirrusfb_zorro_unmap(struct cirrusfb_info *cinfo)
+static void __devexit cirrusfb_zorro_unmap(struct fb_info *info)
 {
+       struct cirrusfb_info *cinfo = info->par;
        zorro_release_device(cinfo->zdev);
 
        if (cinfo->btype == BT_PICASSO4) {
@@ -2383,7 +2238,6 @@ static void __devexit cirrusfb_zorro_unmap(struct cirrusfb_info *cinfo)
                if (zorro_resource_start(cinfo->zdev) > 0x01000000)
                        iounmap(info->screen_base);
        }
-       framebuffer_release(cinfo->info);
 }
 #endif /* CONFIG_ZORRO */
 
@@ -2417,13 +2271,10 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
        info->fix.smem_len   = info->screen_size;
        if (var->bits_per_pixel == 1)
                info->fix.smem_len /= 4;
-       info->fix.type       = cinfo->currentmode.type;
        info->fix.type_aux   = 0;
-       info->fix.visual     = cinfo->currentmode.visual;
        info->fix.xpanstep   = 1;
        info->fix.ypanstep   = 1;
        info->fix.ywrapstep  = 0;
-       info->fix.line_length = cinfo->currentmode.line_length;
 
        /* FIXME: map region at 0xB8000 if available, fill in here */
        info->fix.mmio_len   = 0;
@@ -2481,6 +2332,7 @@ err_dealloc_cmap:
        fb_dealloc_cmap(&info->cmap);
 err_unmap_cirrusfb:
        cinfo->unmap(info);
+       framebuffer_release(info);
        return err;
 }
 
@@ -2495,6 +2347,7 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info)
        fb_dealloc_cmap(&info->cmap);
        printk("Framebuffer unregistered\n");
        cinfo->unmap(info);
+       framebuffer_release(info);
 
        DPRINTK("EXIT\n");
 }
@@ -2579,9 +2432,9 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
        info->screen_size = board_size;
        cinfo->unmap = cirrusfb_pci_unmap;
 
-       printk(KERN_INFO " RAM (%lu kB) at 0xx%lx, ",
-               info->screen_size / KB_, board_addr);
-       printk(KERN_INFO "Cirrus Logic chipset on PCI bus\n");
+       printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus "
+                       "Logic chipset on PCI bus\n",
+                       info->screen_size >> 10, board_addr);
        pci_set_drvdata(pdev, info);
 
        ret = cirrusfb_register(info);
@@ -2654,11 +2507,9 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
        }
 
        cinfo = info->par;
-       cinfo->info = info;
        cinfo->btype = btype;
 
-       assert(z > 0);
-       assert(z2 >= 0);
+       assert(z);
        assert(btype != BT_NONE);
 
        cinfo->zdev = z;
@@ -2722,7 +2573,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
        printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
        zorro_set_drvdata(z, info);
 
-       ret = cirrusfb_register(cinfo);
+       ret = cirrusfb_register(info);
        if (ret) {
                if (btype == BT_PICASSO4) {
                        iounmap(info->screen_base);
@@ -3266,7 +3117,7 @@ static void bestclock(long freq, long *best, long *nom,
                                }
                        }
                }
-               d = ((143181 * n) + f - 1) / f;
+               d = DIV_ROUND_UP(143181 * n, f);
                if ((d >= 7) && (d <= 63)) {
                        if (d > 31)
                                d = (d / 2) * 2;