Blackfin: fix cache Kconfig typo
[safe/jmp/linux-2.6] / drivers / video / atafb.c
index dff3547..37624f7 100644 (file)
@@ -122,7 +122,6 @@ static struct atafb_par {
        void *screen_base;
        int yres_virtual;
        u_long next_line;
-       u_long next_plane;
 #if defined ATAFB_TT || defined ATAFB_STE
        union {
                struct {
@@ -149,6 +148,7 @@ static struct atafb_par {
                        short mono;
                        short ste_mode;
                        short bpp;
+                       u32 pseudo_palette[16];
                } falcon;
 #endif
                /* Nothing needed for external mode */
@@ -329,12 +329,6 @@ extern unsigned char fontdata_8x16[];
  *
  *     * perform fb specific mmap *
  *     int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
- *
- *     * save current hardware state *
- *     void (*fb_save_state)(struct fb_info *info);
- *
- *     * restore saved state *
- *     void (*fb_restore_state)(struct fb_info *info);
  * } ;
  */
 
@@ -614,7 +608,7 @@ static int tt_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
        fix->xpanstep = 0;
        fix->ypanstep = 1;
        fix->ywrapstep = 0;
-       fix->line_length = 0;
+       fix->line_length = par->next_line;
        fix->accel = FB_ACCEL_ATARIBLITT;
        return 0;
 }
@@ -691,6 +685,7 @@ static int tt_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
                return -EINVAL;
        par->yres_virtual = yres_virtual;
        par->screen_base = screen_base + var->yoffset * linelen;
+       par->next_line = linelen;
        return 0;
 }
 
@@ -840,7 +835,7 @@ static int tt_detect(void)
                tt_dmasnd.ctrl = DMASND_CTRL_OFF;
                udelay(20);             /* wait a while for things to settle down */
        }
-       mono_moni = (mfp.par_dt_reg & 0x80) == 0;
+       mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
 
        tt_get_par(&par);
        tt_encode_var(&atafb_predefined[0], &par);
@@ -884,10 +879,6 @@ static int vdl_prescale[4][3] = {
 /* Default hsync timing [mon_type] in picoseconds */
 static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };
 
-#ifdef FBCON_HAS_CFB16
-static u16 fbcon_cfb16_cmap[16];
-#endif
-
 static inline int hxx_prescale(struct falcon_hw *hw)
 {
        return hw->ste_mode ? 16
@@ -918,7 +909,7 @@ static int falcon_encode_fix(struct fb_fix_screeninfo *fix,
                fix->visual = FB_VISUAL_TRUECOLOR;
                fix->xpanstep = 2;
        }
-       fix->line_length = 0;
+       fix->line_length = par->next_line;
        fix->accel = FB_ACCEL_ATARIBLITT;
        return 0;
 }
@@ -1394,14 +1385,7 @@ set_screen_base:
        par->screen_base = screen_base + var->yoffset * linelen;
        par->hw.falcon.xoffset = 0;
 
-       // FIXME!!! sort of works, no crash
-       //par->next_line = linelen;
-       //par->next_plane = yres_virtual * linelen;
        par->next_line = linelen;
-       par->next_plane = 2;
-       // crashes
-       //par->next_plane = linelen;
-       //par->next_line  = yres_virtual * linelen;
 
        return 0;
 }
@@ -1735,10 +1719,10 @@ static int falcon_setcolreg(unsigned int regno, unsigned int red,
                        (((red & 0xe000) >> 13) | ((red & 0x1000) >> 12) << 8) |
                        (((green & 0xe000) >> 13) | ((green & 0x1000) >> 12) << 4) |
                        ((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);
-#ifdef FBCON_HAS_CFB16
-               fbcon_cfb16_cmap[regno] = ((red & 0xf800) |
-                                          ((green & 0xfc00) >> 5) |
-                                          ((blue & 0xf800) >> 11));
+#ifdef ATAFB_FALCON
+               ((u32 *)info->pseudo_palette)[regno] = ((red & 0xf800) |
+                                                      ((green & 0xfc00) >> 5) |
+                                                      ((blue & 0xf800) >> 11));
 #endif
        }
        return 0;
@@ -1852,7 +1836,7 @@ static int stste_encode_fix(struct fb_fix_screeninfo *fix,
                fix->ypanstep = 0;
        }
        fix->ywrapstep = 0;
-       fix->line_length = 0;
+       fix->line_length = par->next_line;
        fix->accel = FB_ACCEL_ATARIBLITT;
        return 0;
 }
@@ -1910,6 +1894,7 @@ static int stste_decode_var(struct fb_var_screeninfo *var,
                return -EINVAL;
        par->yres_virtual = yres_virtual;
        par->screen_base = screen_base + var->yoffset * linelen;
+       par->next_line = linelen;
        return 0;
 }
 
@@ -2044,7 +2029,7 @@ static int stste_detect(void)
                tt_dmasnd.ctrl = DMASND_CTRL_OFF;
                udelay(20);             /* wait a while for things to settle down */
        }
-       mono_moni = (mfp.par_dt_reg & 0x80) == 0;
+       mono_moni = (st_mfp.par_dt_reg & 0x80) == 0;
 
        stste_get_par(&par);
        stste_encode_var(&atafb_predefined[0], &par);
@@ -2095,20 +2080,20 @@ static void st_ovsc_switch(void)
                return;
        local_irq_save(flags);
 
-       mfp.tim_ct_b = 0x10;
-       mfp.active_edge |= 8;
-       mfp.tim_ct_b = 0;
-       mfp.tim_dt_b = 0xf0;
-       mfp.tim_ct_b = 8;
-       while (mfp.tim_dt_b > 1)        /* TOS does it this way, don't ask why */
+       st_mfp.tim_ct_b = 0x10;
+       st_mfp.active_edge |= 8;
+       st_mfp.tim_ct_b = 0;
+       st_mfp.tim_dt_b = 0xf0;
+       st_mfp.tim_ct_b = 8;
+       while (st_mfp.tim_dt_b > 1)     /* TOS does it this way, don't ask why */
                ;
-       new = mfp.tim_dt_b;
+       new = st_mfp.tim_dt_b;
        do {
                udelay(LINE_DELAY);
                old = new;
-               new = mfp.tim_dt_b;
+               new = st_mfp.tim_dt_b;
        } while (old != new);
-       mfp.tim_ct_b = 0x10;
+       st_mfp.tim_ct_b = 0x10;
        udelay(SYNC_DELAY);
 
        if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
@@ -2169,7 +2154,7 @@ static int ext_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
        fix->xpanstep = 0;
        fix->ypanstep = 0;
        fix->ywrapstep = 0;
-       fix->line_length = 0;
+       fix->line_length = par->next_line;
        return 0;
 }
 
@@ -2184,6 +2169,8 @@ static int ext_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
            var->xoffset > 0 ||
            var->yoffset > 0)
                return -EINVAL;
+
+       par->next_line = external_xres_virtual * external_depth / 8;
        return 0;
 }
 
@@ -2412,6 +2399,9 @@ static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
        return 0;
 }
 
+/* fbhw->encode_fix() must be called with fb_info->mm_lock held
+ * if it is called after the register_framebuffer() - not a case here
+ */
 static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
 {
        struct atafb_par par;
@@ -2421,7 +2411,8 @@ static int atafb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
        if (err)
                return err;
        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-       return fbhw->encode_fix(fix, &par);
+       err = fbhw->encode_fix(fix, &par);
+       return err;
 }
 
 static int atafb_get_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -2443,42 +2434,6 @@ static void atafb_set_disp(struct fb_info *info)
        atafb_get_fix(&info->fix, info);
 
        info->screen_base = (void *)info->fix.smem_start;
-
-       switch (info->fix.type) {
-       case FB_TYPE_INTERLEAVED_PLANES:
-               switch (info->var.bits_per_pixel) {
-               case 2:
-                       // display->dispsw = &fbcon_iplan2p2;
-                       break;
-               case 4:
-                       // display->dispsw = &fbcon_iplan2p4;
-                       break;
-               case 8:
-                       // display->dispsw = &fbcon_iplan2p8;
-                       break;
-               }
-               break;
-       case FB_TYPE_PACKED_PIXELS:
-               switch (info->var.bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
-               case 1:
-                       // display->dispsw = &fbcon_mfb;
-                       break;
-#endif
-#ifdef FBCON_HAS_CFB8
-               case 8:
-                       // display->dispsw = &fbcon_cfb8;
-                       break;
-#endif
-#ifdef FBCON_HAS_CFB16
-               case 16:
-                       // display->dispsw = &fbcon_cfb16;
-                       // display->dispsw_data = fbcon_cfb16_cmap;
-                       break;
-#endif
-               }
-               break;
-       }
 }
 
 static int atafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
@@ -2549,6 +2504,13 @@ static void atafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
        if (!rect->width || !rect->height)
                return;
 
+#ifdef ATAFB_FALCON
+       if (info->var.bits_per_pixel == 16) {
+               cfb_fillrect(info, rect);
+               return;
+       }
+#endif
+
        /*
         * We could use hardware clipping but on many cards you get around
         * hardware clipping by writing to framebuffer directly.
@@ -2583,6 +2545,13 @@ static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        u32 dx, dy, sx, sy, width, height;
        int rev_copy = 0;
 
+#ifdef ATAFB_FALCON
+       if (info->var.bits_per_pixel == 16) {
+               cfb_copyarea(info, area);
+               return;
+       }
+#endif
+
        /* clip the destination */
        x2 = area->dx + area->width;
        y2 = area->dy + area->height;
@@ -2593,13 +2562,16 @@ static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        width = x2 - dx;
        height = y2 - dy;
 
+       if (area->sx + dx < area->dx || area->sy + dy < area->dy)
+               return;
+
        /* update sx,sy */
        sx = area->sx + (dx - area->dx);
        sy = area->sy + (dy - area->dy);
 
        /* the source must be completely inside the virtual screen */
-       if (sx < 0 || sy < 0 || (sx + width) > info->var.xres_virtual ||
-           (sy + height) > info->var.yres_virtual)
+       if (sx + width > info->var.xres_virtual ||
+                       sy + height > info->var.yres_virtual)
                return;
 
        if (dy > sy || (dy == sy && dx > sx)) {
@@ -2629,6 +2601,13 @@ static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
        const char *src;
        u32 dx, dy, width, height, pitch;
 
+#ifdef ATAFB_FALCON
+       if (info->var.bits_per_pixel == 16) {
+               cfb_imageblit(info, image);
+               return;
+       }
+#endif
+
        /*
         * We could use hardware clipping but on many cards you get around
         * hardware clipping by writing to framebuffer directly like we are
@@ -2673,10 +2652,9 @@ static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
                        src += pitch;
                }
        } else {
-               // only used for logo; broken
-               c2p(info->screen_base, image->data, dx, dy, width, height,
-                   par->next_line, par->next_plane, image->width,
-                   info->var.bits_per_pixel);
+               c2p_iplan2(info->screen_base, image->data, dx, dy, width,
+                          height, par->next_line, image->width,
+                          info->var.bits_per_pixel);
        }
 }
 
@@ -2763,7 +2741,9 @@ static int atafb_set_par(struct fb_info *info)
 
        /* Decode wanted screen parameters */
        fbhw->decode_var(&info->var, par);
+       mutex_lock(&info->mm_lock);
        fbhw->encode_fix(&info->fix, par);
+       mutex_unlock(&info->mm_lock);
 
        /* Set new videomode */
        ata_set_par(par);
@@ -3095,8 +3075,7 @@ int __init atafb_setup(char *options)
 
 int __init atafb_init(void)
 {
-       int pad;
-       int detected_mode;
+       int pad, detected_mode, error;
        unsigned int defmode = 0;
        unsigned long mem_req;
 
@@ -3110,7 +3089,7 @@ int __init atafb_init(void)
        printk("atafb_init: start\n");
 
        if (!MACH_IS_ATARI)
-               return -ENXIO;
+               return -ENODEV;
 
        do {
 #ifdef ATAFB_EXT
@@ -3136,8 +3115,12 @@ int __init atafb_init(void)
                        printk("atafb_init: initializing Falcon hw\n");
                        fbhw = &falcon_switch;
                        atafb_ops.fb_setcolreg = &falcon_setcolreg;
-                       request_irq(IRQ_AUTO_4, falcon_vbl_switcher, IRQ_TYPE_PRIO,
-                                   "framebuffer/modeswitch", falcon_vbl_switcher);
+                       error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher,
+                                           IRQ_TYPE_PRIO,
+                                           "framebuffer/modeswitch",
+                                           falcon_vbl_switcher);
+                       if (error)
+                               return error;
                        defmode = DEFMODE_F30;
                        break;
                }
@@ -3222,6 +3205,10 @@ int __init atafb_init(void)
        // tries to read from HW which may not be initialized yet
        // so set sane var first, then call atafb_set_par
        atafb_get_var(&fb_info.var, &fb_info);
+
+#ifdef ATAFB_FALCON
+       fb_info.pseudo_palette = current_par.hw.falcon.pseudo_palette;
+#endif
        fb_info.flags = FBINFO_FLAG_DEFAULT;
 
        if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, atafb_modedb,
@@ -3230,6 +3217,9 @@ int __init atafb_init(void)
                return -EINVAL;
        }
 
+       fb_videomode_to_modelist(atafb_modedb, NUM_TOTAL_MODES,
+                                &fb_info.modelist);
+
        atafb_set_disp(&fb_info);
 
        fb_alloc_cmap(&(fb_info.cmap), 1 << fb_info.var.bits_per_pixel, 0);