X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fcirrusfb.c;h=2c4bc6205738992f643128a812769859352f20f8;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=8132b3bf262fda5321cbe126200eb8077a47b919;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 8132b3bf2..2c4bc6205 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -36,13 +36,11 @@ #define CIRRUSFB_VERSION "2.0-pre2" -#include #include #include #include #include #include -#include #include #include #include @@ -60,8 +58,8 @@ #include #endif #ifdef CONFIG_PPC_PREP -#include -#define isPReP (_machine == _MACH_prep) +#include +#define isPReP (machine_is(prep)) #else #define isPReP 0 #endif @@ -275,20 +273,20 @@ static const struct cirrusfb_board_info_rec { #ifdef CONFIG_PCI #define CHIP(id, btype) \ - { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } + { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } static struct pci_device_id cirrusfb_pci_table[] = { - CHIP( CIRRUS_5436, BT_ALPINE ), - CHIP( CIRRUS_5434_8, BT_ALPINE ), - CHIP( CIRRUS_5434_4, BT_ALPINE ), - CHIP( CIRRUS_5430, BT_ALPINE ), /* GD-5440 has identical id */ - CHIP( CIRRUS_7543, BT_ALPINE ), - CHIP( CIRRUS_7548, BT_ALPINE ), - CHIP( CIRRUS_5480, BT_GD5480 ), /* MacPicasso probably */ - CHIP( CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is a GD5446 */ - CHIP( CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */ - CHIP( CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */ - CHIP( CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/ + CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */ + CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ), + CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */ + CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */ + CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */ + CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */ + CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/ { 0, } }; MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); @@ -391,9 +389,9 @@ typedef enum { struct cirrusfb_info { struct fb_info *info; - caddr_t fbmem; - caddr_t regbase; - caddr_t mem; + u8 __iomem *fbmem; + u8 __iomem *regbase; + u8 __iomem *mem; unsigned long size; cirrusfb_board_t btype; unsigned char SFR; /* Shadow of special function register */ @@ -404,7 +402,7 @@ struct cirrusfb_info { struct cirrusfb_regs currentmode; int blank_mode; - u32 pseudo_palette[17]; + u32 pseudo_palette[16]; struct { u8 red, green, blue, pad; } palette[256]; #ifdef CONFIG_ZORRO @@ -515,23 +513,25 @@ static const struct { /*--- Interface used by the world ------------------------------------------*/ -int cirrusfb_init (void); -int cirrusfb_setup (char *options); - -int cirrusfb_open (struct fb_info *info, int user); -int cirrusfb_release (struct fb_info *info, int user); -int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info); -int cirrusfb_check_var (struct fb_var_screeninfo *var, - struct fb_info *info); -int cirrusfb_set_par (struct fb_info *info); -int cirrusfb_pan_display (struct fb_var_screeninfo *var, - struct fb_info *info); -int cirrusfb_blank (int blank_mode, struct fb_info *info); -void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region); -void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); -void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image); +static int cirrusfb_init (void); +#ifndef MODULE +static int cirrusfb_setup (char *options); +#endif + +static int cirrusfb_open (struct fb_info *info, int user); +static int cirrusfb_release (struct fb_info *info, int user); +static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info); +static int cirrusfb_check_var (struct fb_var_screeninfo *var, + struct fb_info *info); +static int cirrusfb_set_par (struct fb_info *info); +static int cirrusfb_pan_display (struct fb_var_screeninfo *var, + struct fb_info *info); +static int cirrusfb_blank (int blank_mode, struct fb_info *info); +static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region); +static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); +static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image); /* function table of the above functions */ static struct fb_ops cirrusfb_ops = { @@ -546,7 +546,6 @@ static struct fb_ops cirrusfb_ops = { .fb_fillrect = cirrusfb_fillrect, .fb_copyarea = cirrusfb_copyarea, .fb_imageblit = cirrusfb_imageblit, - .fb_cursor = soft_cursor, }; /*--- Hardware Specific Routines -------------------------------------------*/ @@ -571,13 +570,13 @@ static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned c unsigned char *green, unsigned char *blue); #endif -static void cirrusfb_WaitBLT (caddr_t regbase); -static void cirrusfb_BitBLT (caddr_t regbase, int bits_per_pixel, +static void cirrusfb_WaitBLT (u8 __iomem *regbase); +static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel, u_short curx, u_short cury, u_short destx, u_short desty, u_short width, u_short height, u_short line_length); -static void cirrusfb_RectFill (caddr_t regbase, int bits_per_pixel, +static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel, u_short x, u_short y, u_short width, u_short height, u_char color, u_short line_length); @@ -600,7 +599,7 @@ static void cirrusfb_dbg_print_byte (const char *name, unsigned char val); static int opencount = 0; /*--- Open /dev/fbx ---------------------------------------------------------*/ -int cirrusfb_open (struct fb_info *info, int user) +static int cirrusfb_open (struct fb_info *info, int user) { if (opencount++ == 0) switch_monitor (info->par, 1); @@ -608,7 +607,7 @@ int cirrusfb_open (struct fb_info *info, int user) } /*--- Close /dev/fbx --------------------------------------------------------*/ -int cirrusfb_release (struct fb_info *info, int user) +static int cirrusfb_release (struct fb_info *info, int user) { if (--opencount == 0) switch_monitor (info->par, 0); @@ -660,8 +659,8 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div) return mclk; } -int cirrusfb_check_var(struct fb_var_screeninfo *var, - struct fb_info *info) +static int cirrusfb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; int nom, den; /* translyting from pixels->bytes */ @@ -1016,7 +1015,7 @@ static int cirrusfb_set_par_foo (struct fb_info *info) struct cirrusfb_info *cinfo = info->par; struct fb_var_screeninfo *var = &info->var; struct cirrusfb_regs regs; - caddr_t regbase = cinfo->regbase; + u8 __iomem *regbase = cinfo->regbase; unsigned char tmp; int offset = 0, err; const struct cirrusfb_board_info_rec *bi; @@ -1573,15 +1572,15 @@ static int cirrusfb_set_par_foo (struct fb_info *info) /* for some reason incomprehensible to me, cirrusfb requires that you write * the registers twice for the settings to take..grr. -dte */ -int cirrusfb_set_par (struct fb_info *info) +static int cirrusfb_set_par (struct fb_info *info) { cirrusfb_set_par_foo (info); return cirrusfb_set_par_foo (info); } -int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, - struct fb_info *info) +static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; @@ -1602,14 +1601,14 @@ int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, switch (info->var.bits_per_pixel) { case 8: - ((u8*)(info->pseudo_palette))[regno] = v; + cinfo->pseudo_palette[regno] = v; break; case 16: - ((u16*)(info->pseudo_palette))[regno] = v; + cinfo->pseudo_palette[regno] = v; break; case 24: case 32: - ((u32*)(info->pseudo_palette))[regno] = v; + cinfo->pseudo_palette[regno] = v; break; } return 0; @@ -1632,8 +1631,8 @@ int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, performs display panning - provided hardware permits this **************************************************************************/ -int cirrusfb_pan_display (struct fb_var_screeninfo *var, - struct fb_info *info) +static int cirrusfb_pan_display (struct fb_var_screeninfo *var, + struct fb_info *info) { int xoffset = 0; int yoffset = 0; @@ -1702,7 +1701,7 @@ int cirrusfb_pan_display (struct fb_var_screeninfo *var, } -int cirrusfb_blank (int blank_mode, struct fb_info *info) +static int cirrusfb_blank (int blank_mode, struct fb_info *info) { /* * Blank the screen if blank_mode != 0, else unblank. If blank == NULL @@ -1727,7 +1726,8 @@ int cirrusfb_blank (int blank_mode, struct fb_info *info) } /* Undo current */ - if (current_mode != VESA_NO_BLANKING) { + if (current_mode == FB_BLANK_NORMAL || + current_mode == FB_BLANK_UNBLANK) { /* unblank the screen */ val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE); vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf); /* clear "FullBandwidth" bit */ @@ -1736,22 +1736,23 @@ int cirrusfb_blank (int blank_mode, struct fb_info *info) } /* set new */ - if(blank_mode != VESA_NO_BLANKING) { + if(blank_mode > FB_BLANK_NORMAL) { /* blank the screen */ val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE); vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20); /* set "FullBandwidth" bit */ } switch (blank_mode) { - case VESA_NO_BLANKING: + case FB_BLANK_UNBLANK: + case FB_BLANK_NORMAL: break; - case VESA_VSYNC_SUSPEND: + case FB_BLANK_VSYNC_SUSPEND: vga_wgfx (cinfo->regbase, CL_GRE, 0x04); break; - case VESA_HSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: vga_wgfx (cinfo->regbase, CL_GRE, 0x02); break; - case VESA_POWERDOWN: + case FB_BLANK_POWERDOWN: vga_wgfx (cinfo->regbase, CL_GRE, 0x06); break; default: @@ -1761,7 +1762,9 @@ int cirrusfb_blank (int blank_mode, struct fb_info *info) cinfo->blank_mode = blank_mode; DPRINTK ("EXIT, returning 0\n"); - return 0; + + /* Let fbcon do a soft blank for us */ + return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; } /**** END Hardware specific Routines **************************************/ /****************************************************************************/ @@ -2015,24 +2018,27 @@ static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo, const struct fb_fillrect *region) { int m; /* bytes per pixel */ + u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ? + cinfo->pseudo_palette[region->color] : region->color; + if(cinfo->info->var.bits_per_pixel == 1) { cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel, region->dx / 8, region->dy, region->width / 8, region->height, - region->color, + color, cinfo->currentmode.line_length); } else { m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8; cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel, region->dx * m, region->dy, region->width * m, region->height, - region->color, + color, cinfo->currentmode.line_length); } return; } -void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region) +static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region) { struct cirrusfb_info *cinfo = info->par; struct fb_fillrect modded; @@ -2082,7 +2088,7 @@ static void cirrusfb_prim_copyarea(struct cirrusfb_info *cinfo, } -void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { struct cirrusfb_info *cinfo = info->par; struct fb_copyarea modded; @@ -2117,7 +2123,7 @@ void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) cirrusfb_prim_copyarea(cinfo, &modded); } -void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image) +static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct cirrusfb_info *cinfo = info->par; @@ -2149,7 +2155,7 @@ static int release_io_ports = 0; * based on the DRAM bandwidth bit and DRAM bank switching bit. This * works with 1MB, 2MB and 4MB configurations (which the Motorola boards * seem to have. */ -static unsigned int cirrusfb_get_memsize (caddr_t regbase) +static unsigned int cirrusfb_get_memsize (u8 __iomem *regbase) { unsigned long mem; unsigned char SRF; @@ -2219,7 +2225,6 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo) release_region(0x3C0, 32); pci_release_regions(pdev); framebuffer_release(cinfo->info); - pci_disable_device(pdev); } #endif /* CONFIG_PCI */ @@ -2246,7 +2251,6 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo) struct fb_info *info = cinfo->info; struct fb_var_screeninfo *var = &info->var; - info->currcon = -1; info->par = cinfo; info->pseudo_palette = cinfo->pseudo_palette; info->flags = FBINFO_DEFAULT @@ -2394,7 +2398,7 @@ static int cirrusfb_pci_register (struct pci_dev *pdev, get_prep_addrs (&board_addr, &cinfo->fbregs_phys); #endif /* PReP dies if we ioremap the IO registers, but it works w/out... */ - cinfo->regbase = (char *) cinfo->fbregs_phys; + cinfo->regbase = (char __iomem *) cinfo->fbregs_phys; } else { DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n"); get_pci_addrs (pdev, &board_addr, &cinfo->fbregs_phys); @@ -2438,7 +2442,10 @@ static int cirrusfb_pci_register (struct pci_dev *pdev, printk ("Cirrus Logic chipset on PCI bus\n"); pci_set_drvdata(pdev, info); - return cirrusfb_register(cinfo); + ret = cirrusfb_register(cinfo); + if (ret) + iounmap(cinfo->fbmem); + return ret; err_release_legacy: if (release_io_ports) @@ -2451,12 +2458,11 @@ err_release_regions: err_release_fb: framebuffer_release(info); err_disable: - pci_disable_device(pdev); err_out: return ret; } -void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev) +static void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); DPRINTK ("ENTER\n"); @@ -2571,7 +2577,15 @@ static int cirrusfb_zorro_register(struct zorro_dev *z, printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); zorro_set_drvdata(z, info); - return cirrusfb_register(cinfo); + ret = cirrusfb_register(cinfo); + if (ret) { + if (btype == BT_PICASSO4) { + iounmap(cinfo->fbmem); + iounmap(cinfo->regbase - 0x600000); + } else if (board_addr > 0x01000000) + iounmap(cinfo->fbmem); + } + return ret; err_unmap_regbase: /* Parental advisory: explicit hack */ @@ -2602,7 +2616,7 @@ static struct zorro_driver cirrusfb_zorro_driver = { }; #endif /* CONFIG_ZORRO */ -int __init cirrusfb_init(void) +static int __init cirrusfb_init(void) { int error = 0; @@ -2615,10 +2629,10 @@ int __init cirrusfb_init(void) #endif #ifdef CONFIG_ZORRO - error |= zorro_module_init(&cirrusfb_zorro_driver); + error |= zorro_register_driver(&cirrusfb_zorro_driver); #endif #ifdef CONFIG_PCI - error |= pci_module_init(&cirrusfb_pci_driver); + error |= pci_register_driver(&cirrusfb_pci_driver); #endif return error; } @@ -2626,7 +2640,7 @@ int __init cirrusfb_init(void) #ifndef MODULE -int __init cirrusfb_setup(char *options) { +static int __init cirrusfb_setup(char *options) { char *this_opt, s[32]; int i; @@ -2661,7 +2675,7 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik "); MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); MODULE_LICENSE("GPL"); -void __exit cirrusfb_exit (void) +static void __exit cirrusfb_exit (void) { #ifdef CONFIG_PCI pci_unregister_driver(&cirrusfb_pci_driver); @@ -2865,7 +2879,7 @@ static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned c *********************************************************************/ /* FIXME: use interrupts instead */ -static void cirrusfb_WaitBLT (caddr_t regbase) +static void cirrusfb_WaitBLT (u8 __iomem *regbase) { /* now busy-wait until we're done */ while (vga_rgfx (regbase, CL_GR31) & 0x08) @@ -2878,7 +2892,7 @@ static void cirrusfb_WaitBLT (caddr_t regbase) perform accelerated "scrolling" ********************************************************************/ -static void cirrusfb_BitBLT (caddr_t regbase, int bits_per_pixel, +static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel, u_short curx, u_short cury, u_short destx, u_short desty, u_short width, u_short height, u_short line_length) { @@ -2969,7 +2983,7 @@ static void cirrusfb_BitBLT (caddr_t regbase, int bits_per_pixel, perform accelerated rectangle fill ********************************************************************/ -static void cirrusfb_RectFill (caddr_t regbase, int bits_per_pixel, +static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel, u_short x, u_short y, u_short width, u_short height, u_char color, u_short line_length) {