diff options
Diffstat (limited to 'drivers/video')
58 files changed, 1404 insertions, 1394 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3f04427c902..3e153d313bb 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -993,12 +993,6 @@ config FB_ATY_GENERIC_LCD Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, Rage XC, or Rage XL chipset. -config FB_ATY_XL_INIT - bool "Rage XL No-BIOS Init support" - depends on FB_ATY_CT - help - Say Y here to support booting a Rage XL without BIOS support. - config FB_ATY_GX bool "Mach64 GX support" if PCI depends on FB_ATY @@ -1376,7 +1370,7 @@ config FB_PXA This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called vfb. If you want to compile it as a module, + module will be called pxafb. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. If unsure, say N. @@ -1409,7 +1403,7 @@ config FB_W100 This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The - module will be called vfb. If you want to compile it as a module, + module will be called w100fb. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. If unsure, say N. diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index d549e215f3c..2c42a812655 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -590,6 +590,8 @@ static u_short maxfmode, chipset; #define highw(x) ((u_long)(x)>>16 & 0xffff) #define loww(x) ((u_long)(x) & 0xffff) +#define custom amiga_custom + #define VBlankOn() custom.intena = IF_SETCLR|IF_COPER #define VBlankOff() custom.intena = IF_COPER @@ -1164,8 +1166,8 @@ static void ami_update_display(void); static void ami_init_display(void); static void ami_do_blank(void); static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix); -static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data); -static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data); +static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data); +static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data); static int ami_get_cursorstate(struct fb_cursorstate *state); static int ami_set_cursorstate(struct fb_cursorstate *state); static void ami_set_sprite(void); @@ -2179,6 +2181,7 @@ static int amifb_ioctl(struct inode *inode, struct file *file, struct fb_var_cursorinfo var; struct fb_cursorstate state; } crsr; + void __user *argp = (void __user *)arg; int i; switch (cmd) { @@ -2186,33 +2189,32 @@ static int amifb_ioctl(struct inode *inode, struct file *file, i = ami_get_fix_cursorinfo(&crsr.fix); if (i) return i; - return copy_to_user((void *)arg, &crsr.fix, + return copy_to_user(argp, &crsr.fix, sizeof(crsr.fix)) ? -EFAULT : 0; case FBIOGET_VCURSORINFO: i = ami_get_var_cursorinfo(&crsr.var, - ((struct fb_var_cursorinfo *)arg)->data); + ((struct fb_var_cursorinfo __user *)arg)->data); if (i) return i; - return copy_to_user((void *)arg, &crsr.var, + return copy_to_user(argp, &crsr.var, sizeof(crsr.var)) ? -EFAULT : 0; case FBIOPUT_VCURSORINFO: - if (copy_from_user(&crsr.var, (void *)arg, - sizeof(crsr.var))) + if (copy_from_user(&crsr.var, argp, sizeof(crsr.var))) return -EFAULT; return ami_set_var_cursorinfo(&crsr.var, - ((struct fb_var_cursorinfo *)arg)->data); + ((struct fb_var_cursorinfo __user *)arg)->data); case FBIOGET_CURSORSTATE: i = ami_get_cursorstate(&crsr.state); if (i) return i; - return copy_to_user((void *)arg, &crsr.state, + return copy_to_user(argp, &crsr.state, sizeof(crsr.state)) ? -EFAULT : 0; case FBIOPUT_CURSORSTATE: - if (copy_from_user(&crsr.state, (void *)arg, + if (copy_from_user(&crsr.state, argp, sizeof(crsr.state))) return -EFAULT; return ami_set_cursorstate(&crsr.state); @@ -3325,7 +3327,7 @@ static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix) return 0; } -static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) +static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data) { struct amifb_par *par = ¤tpar; register u_short *lspr, *sspr; @@ -3347,14 +3349,14 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) var->yspot = par->crsr.spot_y; if (size > var->height*var->width) return -ENAMETOOLONG; - if (!access_ok(VERIFY_WRITE, (void *)data, size)) + if (!access_ok(VERIFY_WRITE, data, size)) return -EFAULT; delta = 1<<par->crsr.fmode; lspr = lofsprite + (delta<<1); if (par->bplcon0 & BPC0_LACE) sspr = shfsprite + (delta<<1); else - sspr = 0; + sspr = NULL; for (height = (short)var->height-1; height >= 0; height--) { bits = 0; words = delta; datawords = 0; for (width = (short)var->width-1; width >= 0; width--) { @@ -3400,7 +3402,7 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) return 0; } -static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) +static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data) { struct amifb_par *par = ¤tpar; register u_short *lspr, *sspr; @@ -3427,7 +3429,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) return -EINVAL; if (!var->height) return -EINVAL; - if (!access_ok(VERIFY_READ, (void *)data, var->width*var->height)) + if (!access_ok(VERIFY_READ, data, var->width*var->height)) return -EFAULT; delta = 1<<fmode; lofsprite = shfsprite = (u_short *)spritememory; @@ -3442,13 +3444,13 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char *data) if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE) return -EINVAL; memset(lspr, 0, (var->height+2)<<fmode<<2); - sspr = 0; + sspr = NULL; } for (height = (short)var->height-1; height >= 0; height--) { bits = 16; words = delta; datawords = 0; for (width = (short)var->width-1; width >= 0; width--) { unsigned long tdata = 0; - get_user(tdata, (char *)data); + get_user(tdata, data); data++; #ifdef __mc68000__ asm volatile ( diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c index 2784f0a9d69..89060b2db8e 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/arcfb.c @@ -366,7 +366,8 @@ static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx, } } -void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +static void arcfb_fillrect(struct fb_info *info, + const struct fb_fillrect *rect) { struct arcfb_par *par = info->par; @@ -376,7 +377,8 @@ void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); } -void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) +static void arcfb_copyarea(struct fb_info *info, + const struct fb_copyarea *area) { struct arcfb_par *par = info->par; @@ -386,7 +388,7 @@ void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); } -void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) +static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct arcfb_par *par = info->par; diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c index c64de59398f..69f75547865 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/asiliantfb.c @@ -549,7 +549,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) if (!request_mem_region(addr, size, "asiliantfb")) return -EBUSY; - p = framebuffer_alloc(sizeof(u32) * 256, &dp->dev); + p = framebuffer_alloc(sizeof(u32) * 16, &dp->dev); if (!p) { release_mem_region(addr, size); return -ENOMEM; diff --git a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile index 9dec96249ff..18521397a6e 100644 --- a/drivers/video/aty/Makefile +++ b/drivers/video/aty/Makefile @@ -5,7 +5,6 @@ obj-$(CONFIG_FB_RADEON) += radeonfb.o atyfb-y := atyfb_base.o mach64_accel.o mach64_cursor.o atyfb-$(CONFIG_FB_ATY_GX) += mach64_gx.o atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o -atyfb-$(CONFIG_FB_ATY_XL_INIT) += xlinit.o atyfb-objs := $(atyfb-y) diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h index 09de173c116..e9b7a64c1ac 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/aty/atyfb.h @@ -50,6 +50,7 @@ struct pll_info { int sclk, mclk, mclk_pm, xclk; int ref_div; int ref_clk; + int ecp_max; }; typedef struct { @@ -354,6 +355,5 @@ static inline void wait_for_idle(struct atyfb_par *par) extern void aty_reset_engine(const struct atyfb_par *par); extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); -extern int atyfb_xl_init(struct fb_info *info); extern void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par); extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 3fefdb0cbf0..ed81005cbdb 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -109,9 +109,18 @@ #define GUI_RESERVE (1 * PAGE_SIZE) /* FIXME: remove the FAIL definition */ -#define FAIL(msg) do { printk(KERN_CRIT "atyfb: " msg "\n"); return -EINVAL; } while (0) -#define FAIL_MAX(msg, x, _max_) do { if(x > _max_) { printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); return -EINVAL; } } while (0) - +#define FAIL(msg) do { \ + if (!(var->activate & FB_ACTIVATE_TEST)) \ + printk(KERN_CRIT "atyfb: " msg "\n"); \ + return -EINVAL; \ +} while (0) +#define FAIL_MAX(msg, x, _max_) do { \ + if (x > _max_) { \ + if (!(var->activate & FB_ACTIVATE_TEST)) \ + printk(KERN_CRIT "atyfb: " msg " %x(%x)\n", x, _max_); \ + return -EINVAL; \ + } \ +} while (0) #ifdef DEBUG #define DPRINTK(fmt, args...) printk(KERN_DEBUG "atyfb: " fmt, ## args) #else @@ -340,6 +349,7 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; #define ATI_CHIP_264VT3 (M64F_VT | M64F_INTEGRATED | M64F_VT_BUS | M64F_GTB_DSP | M64F_SDRAM_MAGIC_PLL) #define ATI_CHIP_264VT4 (M64F_VT | M64F_INTEGRATED | M64F_GTB_DSP) +/* FIXME what is this chip? */ #define ATI_CHIP_264LT (M64F_GT | M64F_INTEGRATED | M64F_GTB_DSP) /* make sets shorter */ @@ -359,58 +369,60 @@ static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; static struct { u16 pci_id; const char *name; - int pll, mclk, xclk; + int pll, mclk, xclk, ecp_max; u32 features; } aty_chips[] __devinitdata = { #ifdef CONFIG_FB_ATY_GX /* Mach64 GX */ - { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, ATI_CHIP_88800GX }, - { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, ATI_CHIP_88800CX }, + { PCI_CHIP_MACH64GX, "ATI888GX00 (Mach64 GX)", 135, 50, 50, 0, ATI_CHIP_88800GX }, + { PCI_CHIP_MACH64CX, "ATI888CX00 (Mach64 CX)", 135, 50, 50, 0, ATI_CHIP_88800CX }, #endif /* CONFIG_FB_ATY_GX */ #ifdef CONFIG_FB_ATY_CT - { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, ATI_CHIP_264CT }, - { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, ATI_CHIP_264ET }, - { PCI_CHIP_MACH64VT, "ATI264VT? (Mach64 VT)", 170, 67, 67, ATI_CHIP_264VT }, - { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, ATI_CHIP_264GT }, - /* FIXME { ...ATI_264GU, maybe ATI_CHIP_264GTDVD }, */ - { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GTB)", 200, 67, 67, ATI_CHIP_264GTB }, - { PCI_CHIP_MACH64VU, "ATI264VTB (Mach64 VU)", 200, 67, 67, ATI_CHIP_264VT3 }, - - { PCI_CHIP_MACH64LT, "3D RAGE LT (Mach64 LT)", 135, 63, 63, ATI_CHIP_264LT }, - /* FIXME chipset maybe ATI_CHIP_264LTPRO ? */ - { PCI_CHIP_MACH64LG, "3D RAGE LT-G (Mach64 LG)", 230, 63, 63, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 }, - - { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, ATI_CHIP_264VT4 }, - - { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, ATI_CHIP_264GT2C }, - { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, ATI_CHIP_264GT2C }, - { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, ATI_CHIP_264GT2C }, - { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, ATI_CHIP_264GT2C }, - - { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, ATI_CHIP_264GTPRO }, - { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, ATI_CHIP_264GTPRO }, - { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE }, - { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, ATI_CHIP_264GTPRO }, - { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, ATI_CHIP_264GTPRO }, - - { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, ATI_CHIP_264LTPRO }, - { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, ATI_CHIP_264LTPRO }, - { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, - { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO }, - { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, ATI_CHIP_264LTPRO }, - - { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL }, - { PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL }, - { PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL }, - - { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY }, - { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, ATI_CHIP_MOBILITY }, - { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY }, - { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64CT, "ATI264CT (Mach64 CT)", 135, 60, 60, 0, ATI_CHIP_264CT }, + { PCI_CHIP_MACH64ET, "ATI264ET (Mach64 ET)", 135, 60, 60, 0, ATI_CHIP_264ET }, + + /* FIXME what is this chip? */ + { PCI_CHIP_MACH64LT, "ATI264LT (Mach64 LT)", 135, 63, 63, 0, ATI_CHIP_264LT }, + + { PCI_CHIP_MACH64VT, "ATI264VT (Mach64 VT)", 170, 67, 67, 80, ATI_CHIP_264VT }, + { PCI_CHIP_MACH64GT, "3D RAGE (Mach64 GT)", 135, 63, 63, 80, ATI_CHIP_264GT }, + + { PCI_CHIP_MACH64VU, "ATI264VT3 (Mach64 VU)", 200, 67, 67, 80, ATI_CHIP_264VT3 }, + { PCI_CHIP_MACH64GU, "3D RAGE II+ (Mach64 GU)", 200, 67, 67, 100, ATI_CHIP_264GTB }, + + { PCI_CHIP_MACH64LG, "3D RAGE LT (Mach64 LG)", 230, 63, 63, 100, ATI_CHIP_264LTG | M64F_LT_LCD_REGS | M64F_G3_PB_1024x768 }, + + { PCI_CHIP_MACH64VV, "ATI264VT4 (Mach64 VV)", 230, 83, 83, 100, ATI_CHIP_264VT4 }, + + { PCI_CHIP_MACH64GV, "3D RAGE IIC (Mach64 GV, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + { PCI_CHIP_MACH64GW, "3D RAGE IIC (Mach64 GW, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + { PCI_CHIP_MACH64GY, "3D RAGE IIC (Mach64 GY, PCI)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + { PCI_CHIP_MACH64GZ, "3D RAGE IIC (Mach64 GZ, AGP)", 230, 83, 83, 100, ATI_CHIP_264GT2C }, + + { PCI_CHIP_MACH64GB, "3D RAGE PRO (Mach64 GB, BGA, AGP)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + { PCI_CHIP_MACH64GD, "3D RAGE PRO (Mach64 GD, BGA, AGP 1x)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + { PCI_CHIP_MACH64GI, "3D RAGE PRO (Mach64 GI, BGA, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO | M64F_MAGIC_VRAM_SIZE }, + { PCI_CHIP_MACH64GP, "3D RAGE PRO (Mach64 GP, PQFP, PCI)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + { PCI_CHIP_MACH64GQ, "3D RAGE PRO (Mach64 GQ, PQFP, PCI, limited 3D)", 230, 100, 100, 125, ATI_CHIP_264GTPRO }, + + { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, + { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, + { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, + { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, + { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, + + { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GN, "3D RAGE XC (Mach64 GN, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GL, "3D RAGE XC (Mach64 GL, PCI-66)", 230, 83, 63, 135, ATI_CHIP_264XL }, + { PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL }, + { PCI_CHIP_MACH64GS, "3D RAGE XC (Mach64 GS, PCI-33)", 230, 83, 63, 135, ATI_CHIP_264XL }, + + { PCI_CHIP_MACH64LM, "3D RAGE Mobility P/M (Mach64 LM, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64LN, "3D RAGE Mobility L (Mach64 LN, AGP 2x)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64LR, "3D RAGE Mobility P/M (Mach64 LR, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, + { PCI_CHIP_MACH64LS, "3D RAGE Mobility L (Mach64 LS, PCI)", 230, 83, 125, 135, ATI_CHIP_MOBILITY }, #endif /* CONFIG_FB_ATY_CT */ }; @@ -431,6 +443,7 @@ static int __devinit correct_chipset(struct atyfb_par *par) par->pll_limits.pll_max = aty_chips[i].pll; par->pll_limits.mclk = aty_chips[i].mclk; par->pll_limits.xclk = aty_chips[i].xclk; + par->pll_limits.ecp_max = aty_chips[i].ecp_max; par->features = aty_chips[i].features; chip_id = aty_ld_le32(CONFIG_CHIP_ID, par); @@ -450,39 +463,63 @@ static int __devinit correct_chipset(struct atyfb_par *par) #endif #ifdef CONFIG_FB_ATY_CT case PCI_CHIP_MACH64VT: - rev &= 0xc7; - if(rev == 0x00) { - name = "ATI264VTA3 (Mach64 VT)"; - par->pll_limits.pll_max = 170; - par->pll_limits.mclk = 67; - par->pll_limits.xclk = 67; - par->features = ATI_CHIP_264VT; - } else if(rev == 0x40) { - name = "ATI264VTA4 (Mach64 VT)"; + switch (rev & 0x07) { + case 0x00: + switch (rev & 0xc0) { + case 0x00: + name = "ATI264VT (A3) (Mach64 VT)"; + par->pll_limits.pll_max = 170; + par->pll_limits.mclk = 67; + par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VT; + break; + case 0x40: + name = "ATI264VT2 (A4) (Mach64 VT)"; + par->pll_limits.pll_max = 200; + par->pll_limits.mclk = 67; + par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV; + break; + } + break; + case 0x01: + name = "ATI264VT3 (B1) (Mach64 VT)"; par->pll_limits.pll_max = 200; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; - par->features = ATI_CHIP_264VT | M64F_MAGIC_POSTDIV; - } else { - name = "ATI264VTB (Mach64 VT)"; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VTB; + break; + case 0x02: + name = "ATI264VT3 (B2) (Mach64 VT)"; par->pll_limits.pll_max = 200; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; - par->features = ATI_CHIP_264VTB; + par->pll_limits.ecp_max = 80; + par->features = ATI_CHIP_264VT3; + break; } break; case PCI_CHIP_MACH64GT: - rev &= 0x07; - if(rev == 0x01) { + switch (rev & 0x07) { + case 0x01: + name = "3D RAGE II (Mach64 GT)"; par->pll_limits.pll_max = 170; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 80; par->features = ATI_CHIP_264GTB; - } else if(rev == 0x02) { + break; + case 0x02: + name = "3D RAGE II+ (Mach64 GT)"; par->pll_limits.pll_max = 200; par->pll_limits.mclk = 67; par->pll_limits.xclk = 67; + par->pll_limits.ecp_max = 100; par->features = ATI_CHIP_264GTB; + break; } break; #endif @@ -692,7 +729,7 @@ static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc) aty_st_lcd(LCD_GEN_CNTL, (crtc->lcd_gen_cntl & ~CRTC_RW_SELECT) | (SHADOW_EN | SHADOW_RW_EN), par); - DPRINTK("set secondary CRT to %ix%i %c%c\n", + DPRINTK("set shadow CRT to %ix%i %c%c\n", ((((crtc->shadow_h_tot_disp>>16) & 0xff) + 1)<<3), (((crtc->shadow_v_tot_disp>>16) & 0x7ff) + 1), (crtc->shadow_h_sync_strt_wid & 0x200000)?'N':'P', (crtc->shadow_v_sync_strt_wid & 0x200000)?'N':'P'); @@ -840,11 +877,14 @@ static int aty_var_to_crtc(const struct fb_info *info, know if one is connected. So it's better to fail then. */ if (crtc->lcd_gen_cntl & CRT_ON) { - PRINTKI("Disable lcd panel, because video mode does not fit.\n"); + if (!(var->activate & FB_ACTIVATE_TEST)) + PRINTKI("Disable LCD panel, because video mode does not fit.\n"); crtc->lcd_gen_cntl &= ~LCD_ON; /*aty_st_lcd(LCD_GEN_CNTL, crtc->lcd_gen_cntl, par);*/ } else { - FAIL("Video mode exceeds size of lcd panel.\nConnect this computer to a conventional monitor if you really need this mode."); + if (!(var->activate & FB_ACTIVATE_TEST)) + PRINTKE("Video mode exceeds size of LCD panel.\nConnect this computer to a conventional monitor if you really need this mode.\n"); + return -EINVAL; } } } @@ -858,9 +898,9 @@ static int aty_var_to_crtc(const struct fb_info *info, vmode &= ~(FB_VMODE_DOUBLE | FB_VMODE_INTERLACED); /* This is horror! When we simulate, say 640x480 on an 800x600 - lcd monitor, the CRTC should be programmed 800x600 values for + LCD monitor, the CRTC should be programmed 800x600 values for the non visible part, but 640x480 for the visible part. - This code has been tested on a laptop with it's 1400x1050 lcd + This code has been tested on a laptop with it's 1400x1050 LCD monitor and a conventional monitor both switched on. Tested modes: 1280x1024, 1152x864, 1024x768, 800x600, works with little glitches also with DOUBLESCAN modes @@ -955,16 +995,6 @@ static int aty_var_to_crtc(const struct fb_info *info, vdisplay = yres; if(vmode & FB_VMODE_DOUBLE) vdisplay <<= 1; - if(vmode & FB_VMODE_INTERLACED) { - vdisplay >>= 1; - - /* The prefered mode for the lcd is not interlaced, so disable it if - it was enabled. For doublescan there is no problem, because we can - compensate for it in the hardware stretching (we stretch half as much) - */ - vmode &= ~FB_VMODE_INTERLACED; - /*crtc->gen_cntl &= ~CRTC_INTERLACE_EN;*/ - } crtc->gen_cntl &= ~(CRTC2_EN | CRTC2_PIX_WIDTH); crtc->lcd_gen_cntl &= ~(HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 | /*TVCLK_PM_EN | VCLK_DAC_PM_EN |*/ @@ -980,7 +1010,7 @@ static int aty_var_to_crtc(const struct fb_info *info, crtc->horz_stretching &= ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | AUTO_HORZ_RATIO | HORZ_STRETCH_MODE | HORZ_STRETCH_EN); - if (xres < par->lcd_width) { + if (xres < par->lcd_width && crtc->lcd_gen_cntl & LCD_ON) { do { /* * The horizontal blender misbehaves when HDisplay is less than a @@ -1042,7 +1072,7 @@ static int aty_var_to_crtc(const struct fb_info *info, } while (0); } - if (vdisplay < par->lcd_height) { + if (vdisplay < par->lcd_height && crtc->lcd_gen_cntl & LCD_ON) { crtc->vert_stretching = (VERT_STRETCH_USE0 | VERT_STRETCH_EN | (((vdisplay * (VERT_STRETCH_RATIO0 + 1)) / par->lcd_height) & VERT_STRETCH_RATIO0)); @@ -1065,9 +1095,8 @@ static int aty_var_to_crtc(const struct fb_info *info, #endif /* CONFIG_FB_ATY_GENERIC_LCD */ if (M64_HAS(MAGIC_FIFO)) { - /* Not VTB/GTB */ - /* FIXME: magic FIFO values */ - crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC2_PIX_WIDTH); + /* FIXME: display FIFO low watermark values */ + crtc->gen_cntl |= (aty_ld_le32(CRTC_GEN_CNTL, par) & CRTC_FIFO_LWM); } crtc->dp_pix_width = dp_pix_width; crtc->dp_chain_mask = dp_chain_mask; @@ -1184,7 +1213,8 @@ static int aty_crtc_to_var(const struct crtc *crtc, struct fb_var_screeninfo *va var->transp.length = 8; break; default: - FAIL("Invalid pixel width"); + PRINTKE("Invalid pixel width\n"); + return -EINVAL; } /* output */ @@ -1241,7 +1271,8 @@ static int atyfb_set_par(struct fb_info *info) pixclock = atyfb_get_pixclock(var, par); if (pixclock == 0) { - FAIL("Invalid pixclock"); + PRINTKE("Invalid pixclock\n"); + return -EINVAL; } else { if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &par->pll))) return err; @@ -1446,7 +1477,9 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) pixclock = atyfb_get_pixclock(var, par); if (pixclock == 0) { - FAIL("Invalid pixclock"); + if (!(var->activate & FB_ACTIVATE_TEST)) + PRINTKE("Invalid pixclock\n"); + return -EINVAL; } else { if((err = par->pll_ops->var_to_pll(info, pixclock, var->bits_per_pixel, &pll))) return err; @@ -2291,10 +2324,6 @@ static int __init aty_init(struct fb_info *info, const char *name) par->dac_ops = &aty_dac_ct; par->pll_ops = &aty_pll_ct; par->bus_type = PCI; -#ifdef CONFIG_FB_ATY_XL_INIT - if (IS_XL(par->pci_id)) - atyfb_xl_init(info); -#endif par->ram_type = (aty_ld_le32(CONFIG_STAT0, par) & 0x07); ramname = aty_ct_ram[par->ram_type]; /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ @@ -2638,16 +2667,16 @@ static int __init store_video_par(char *video_str, unsigned char m64_num) static int atyfb_blank(int blank, struct fb_info *info) { struct atyfb_par *par = (struct atyfb_par *) info->par; - u8 gen_cntl; + u32 gen_cntl; if (par->lock_blank || par->asleep) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if ((_machine == _MACH_Pmac) && blank) + if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL) set_backlight_enable(0); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) - if (par->lcd_table && blank && + if (par->lcd_table && blank > FB_BLANK_NORMAL && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); pm &= ~PWR_BLON; @@ -2655,31 +2684,31 @@ static int atyfb_blank(int blank, struct fb_info *info) } #endif - gen_cntl = aty_ld_8(CRTC_GEN_CNTL, par); + gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); switch (blank) { case FB_BLANK_UNBLANK: - gen_cntl &= ~(0x4c); + gen_cntl &= ~0x400004c; break; case FB_BLANK_NORMAL: - gen_cntl |= 0x40; + gen_cntl |= 0x4000040; break; case FB_BLANK_VSYNC_SUSPEND: - gen_cntl |= 0x8; + gen_cntl |= 0x4000048; break; case FB_BLANK_HSYNC_SUSPEND: - gen_cntl |= 0x4; + gen_cntl |= 0x4000044; break; case FB_BLANK_POWERDOWN: - gen_cntl |= 0x4c; + gen_cntl |= 0x400004c; break; } - aty_st_8(CRTC_GEN_CNTL, gen_cntl, par); + aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); #ifdef CONFIG_PMAC_BACKLIGHT - if ((_machine == _MACH_Pmac) && !blank) + if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL) set_backlight_enable(1); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) - if (par->lcd_table && !blank && + if (par->lcd_table && blank <= FB_BLANK_NORMAL && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); pm |= PWR_BLON; @@ -3157,15 +3186,15 @@ static void aty_init_lcd(struct atyfb_par *par, u32 bios_base) refresh_rates_buf, lcd_refresh_rates[default_refresh_rate]); par->lcd_refreshrate = lcd_refresh_rates[default_refresh_rate]; /* We now need to determine the crtc parameters for the - * lcd monitor. This is tricky, because they are not stored + * LCD monitor. This is tricky, because they are not stored * individually in the BIOS. Instead, the BIOS contains a * table of display modes that work for this monitor. * * The idea is that we search for a mode of the same dimensions - * as the dimensions of the lcd monitor. Say our lcd monitor + * as the dimensions of the LCD monitor. Say our LCD monitor * is 800x600 pixels, we search for a 800x600 monitor. * The CRTC parameters we find here are the ones that we need - * to use to simulate other resolutions on the lcd screen. + * to use to simulate other resolutions on the LCD screen. */ lcdmodeptr = (u16 *)(par->lcd_table + 64); while (*lcdmodeptr != 0) { @@ -3472,7 +3501,7 @@ err_release_mem: static int __devinit atyfb_atari_probe(void) { - struct aty_par *par; + struct atyfb_par *par; struct fb_info *info; int m64_num; u32 clock_r; @@ -3692,9 +3721,7 @@ static int __init atyfb_init(void) atyfb_setup(option); #endif -#ifdef CONFIG_PCI pci_register_driver(&atyfb_driver); -#endif #ifdef CONFIG_ATARI atyfb_atari_probe(); #endif @@ -3703,9 +3730,7 @@ static int __init atyfb_init(void) static void __exit atyfb_exit(void) { -#ifdef CONFIG_PCI pci_unregister_driver(&atyfb_driver); -#endif } module_init(atyfb_init); diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c index 9bdb2aab01a..e7056934c6a 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/aty/mach64_ct.c @@ -206,9 +206,7 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll { u32 q; struct atyfb_par *par = (struct atyfb_par *) info->par; -#ifdef DEBUG int pllvclk; -#endif /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */ q = par->ref_clk_per * pll->pll_ref_div * 4 / vclk_per; @@ -223,13 +221,26 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll pll->vclk_post_div_real = postdividers[pll->vclk_post_div]; // pll->vclk_post_div <<= 6; pll->vclk_fb_div = q * pll->vclk_post_div_real / 8; -#ifdef DEBUG pllvclk = (1000000 * 2 * pll->vclk_fb_div) / (par->ref_clk_per * pll->pll_ref_div); +#ifdef DEBUG printk("atyfb(%s): pllvclk=%d MHz, vclk=%d MHz\n", __FUNCTION__, pllvclk, pllvclk / pll->vclk_post_div_real); #endif pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */ + + /* Set ECP (scaler/overlay clock) divider */ + if (par->pll_limits.ecp_max) { + int ecp = pllvclk / pll->vclk_post_div_real; + int ecp_div = 0; + + while (ecp > par->pll_limits.ecp_max && ecp_div < 2) { + ecp >>= 1; + ecp_div++; + } + pll->pll_vclk_cntl |= ecp_div << 4; + } + return 0; } diff --git a/drivers/video/aty/xlinit.c b/drivers/video/aty/xlinit.c deleted file mode 100644 index a085cbf74ec..00000000000 --- a/drivers/video/aty/xlinit.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * ATI Rage XL Initialization. Support for Xpert98 and Victoria - * PCI cards. - * - * Copyright (C) 2002 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * stevel@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <asm/io.h> -#include <video/mach64.h> -#include "atyfb.h" - -#define MPLL_GAIN 0xad -#define VPLL_GAIN 0xd5 - -enum { - VICTORIA = 0, - XPERT98, - NUM_XL_CARDS -}; - -extern const struct aty_pll_ops aty_pll_ct; - -#define DEFAULT_CARD XPERT98 -static int xl_card = DEFAULT_CARD; - -static const struct xl_card_cfg_t { - int ref_crystal; // 10^4 Hz - int mem_type; - int mem_size; - u32 mem_cntl; - u32 ext_mem_cntl; - u32 mem_addr_config; - u32 bus_cntl; - u32 dac_cntl; - u32 hw_debug; - u32 custom_macro_cntl; - u8 dll2_cntl; - u8 pll_yclk_cntl; -} card_cfg[NUM_XL_CARDS] = { - // VICTORIA - { 2700, SDRAM, 0x800000, - 0x10757A3B, 0x64000C81, 0x00110202, 0x7b33A040, - 0x82010102, 0x48803800, 0x005E0179, - 0x50, 0x25 - }, - // XPERT98 - { 1432, WRAM, 0x800000, - 0x00165A2B, 0xE0000CF1, 0x00200213, 0x7333A001, - 0x8000000A, 0x48833800, 0x007F0779, - 0x10, 0x19 - } -}; - -typedef struct { - u8 lcd_reg; - u32 val; -} lcd_tbl_t; - -static const lcd_tbl_t lcd_tbl[] = { - { 0x01, 0x000520C0 }, - { 0x08, 0x02000408 }, - { 0x03, 0x00000F00 }, - { 0x00, 0x00000000 }, - { 0x02, 0x00000000 }, - { 0x04, 0x00000000 }, - { 0x05, 0x00000000 }, - { 0x06, 0x00000000 }, - { 0x33, 0x00000000 }, - { 0x34, 0x00000000 }, - { 0x35, 0x00000000 }, - { 0x36, 0x00000000 }, - { 0x37, 0x00000000 } -}; - -static void reset_gui(struct atyfb_par *par) -{ - aty_st_8(GEN_TEST_CNTL+1, 0x01, par); - aty_st_8(GEN_TEST_CNTL+1, 0x00, par); - aty_st_8(GEN_TEST_CNTL+1, 0x02, par); - mdelay(5); -} - -static void reset_sdram(struct atyfb_par *par) -{ - u8 temp; - - temp = aty_ld_8(EXT_MEM_CNTL, par); - temp |= 0x02; - aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_RESET = 1b - temp |= 0x08; - aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST = 10b - temp |= 0x0c; - aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST = 11b - mdelay(5); - temp &= 0xf3; - aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_CYC_TEST = 00b - temp &= 0xfd; - aty_st_8(EXT_MEM_CNTL, temp, par); // MEM_SDRAM_REST = 0b - mdelay(5); -} - -static void init_dll(struct atyfb_par *par) -{ - // enable DLL - aty_st_pll_ct(PLL_GEN_CNTL, - aty_ld_pll_ct(PLL_GEN_CNTL, par) & 0x7f, - par); - - // reset DLL - aty_st_pll_ct(DLL_CNTL, 0x82, par); - aty_st_pll_ct(DLL_CNTL, 0xE2, par); - mdelay(5); - aty_st_pll_ct(DLL_CNTL, 0x82, par); - mdelay(6); -} - -static void reset_clocks(struct atyfb_par *par, struct pll_ct *pll, - int hsync_enb) -{ - reset_gui(par); - aty_st_pll_ct(MCLK_FB_DIV, pll->mclk_fb_div, par); - aty_st_pll_ct(SCLK_FB_DIV, pll->sclk_fb_div, par); - - mdelay(15); - init_dll(par); - aty_st_8(GEN_TEST_CNTL+1, 0x00, par); - mdelay(5); - aty_st_8(CRTC_GEN_CNTL+3, 0x04, par); - mdelay(6); - reset_sdram(par); - aty_st_8(CRTC_GEN_CNTL+3, - hsync_enb ? 0x00 : 0x04, par); - - aty_st_pll_ct(SPLL_CNTL2, pll->spll_cntl2, par); - aty_st_pll_ct(PLL_GEN_CNTL, pll->pll_gen_cntl, par); - aty_st_pll_ct(PLL_VCLK_CNTL, pll->pll_vclk_cntl, par); -} - -int atyfb_xl_init(struct fb_info *info) -{ - const struct xl_card_cfg_t * card = &card_cfg[xl_card]; - struct atyfb_par *par = (struct atyfb_par *) info->par; - union aty_pll pll; - int err; - u32 temp; - - aty_st_8(CONFIG_STAT0, 0x85, par); - mdelay(10); - - /* - * The following needs to be set before the call - * to var_to_pll() below. They'll be re-set again - * to the same values in aty_init(). - */ - par->ref_clk_per = 100000000UL/card->ref_crystal; - par->ram_type = card->mem_type; - info->fix.smem_len = card->mem_size; - if (xl_card == VICTORIA) { - // the MCLK, XCLK are 120MHz on victoria card - par->mclk_per = 1000000/120; - par->xclk_per = 1000000/120; - par->features &= ~M64F_MFB_FORCE_4; - } - - /* - * Calculate mclk and xclk dividers, etc. The passed - * pixclock and bpp values don't matter yet, the vclk - * isn't programmed until later. - */ - if ((err = aty_pll_ct.var_to_pll(info, 39726, 8, &pll))) - return err; - - aty_st_pll_ct(LVDS_CNTL0, 0x00, par); - aty_st_pll_ct(DLL2_CNTL, card->dll2_cntl, par); - aty_st_pll_ct(V2PLL_CNTL, 0x10, par); - aty_st_pll_ct(MPLL_CNTL, MPLL_GAIN, par); - aty_st_pll_ct(VPLL_CNTL, VPLL_GAIN, par); - aty_st_pll_ct(PLL_VCLK_CNTL, 0x00, par); - aty_st_pll_ct(VFC_CNTL, 0x1B, par); - aty_st_pll_ct(PLL_REF_DIV, pll.ct.pll_ref_div, par); - aty_st_pll_ct(PLL_EXT_CNTL, pll.ct.pll_ext_cntl, par); - aty_st_pll_ct(SPLL_CNTL2, 0x03, par); - aty_st_pll_ct(PLL_GEN_CNTL, 0x44, par); - - reset_clocks(par, &pll.ct, 0); - mdelay(10); - - aty_st_pll_ct(VCLK_POST_DIV, 0x03, par); - aty_st_pll_ct(VCLK0_FB_DIV, 0xDA, par); - aty_st_pll_ct(VCLK_POST_DIV, 0x0F, par); - aty_st_pll_ct(VCLK1_FB_DIV, 0xF5, par); - aty_st_pll_ct(VCLK_POST_DIV, 0x3F, par); - aty_st_pll_ct(PLL_EXT_CNTL, 0x40 | pll.ct.pll_ext_cntl, par); - aty_st_pll_ct(VCLK2_FB_DIV, 0x00, par); - aty_st_pll_ct(VCLK_POST_DIV, 0xFF, par); - aty_st_pll_ct(PLL_EXT_CNTL, 0xC0 | pll.ct.pll_ext_cntl, par); - aty_st_pll_ct(VCLK3_FB_DIV, 0x00, par); - - aty_st_8(BUS_CNTL, 0x01, par); - aty_st_le32(BUS_CNTL, card->bus_cntl | 0x08000000, par); - - aty_st_le32(CRTC_GEN_CNTL, 0x04000200, par); - aty_st_le16(CONFIG_STAT0, 0x0020, par); - aty_st_le32(MEM_CNTL, 0x10151A33, par); - aty_st_le32(EXT_MEM_CNTL, 0xE0000C01, par); - aty_st_le16(CRTC_GEN_CNTL+2, 0x0000, par); - aty_st_le32(DAC_CNTL, card->dac_cntl, par); - aty_st_le16(GEN_TEST_CNTL, 0x0100, par); - aty_st_le32(CUSTOM_MACRO_CNTL, 0x003C0171, par); - aty_st_le32(MEM_BUF_CNTL, 0x00382848, par); - - aty_st_le32(HW_DEBUG, card->hw_debug, par); - aty_st_le16(MEM_ADDR_CONFIG, 0x0000, par); - aty_st_le16(GP_IO+2, 0x0000, par); - aty_st_le16(GEN_TEST_CNTL, 0x0000, par); - aty_st_le16(EXT_DAC_REGS+2, 0x0000, par); - aty_st_le32(CRTC_INT_CNTL, 0x00000000, par); - aty_st_le32(TIMER_CONFIG, 0x00000000, par); - aty_st_le32(0xEC, 0x00000000, par); - aty_st_le32(0xFC, 0x00000000, par); - -#if defined (CONFIG_FB_ATY_GENERIC_LCD) - { - int i; - - for (i = 0; i < ARRAY_SIZE(lcd_tbl); i++) - aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par); - } -#endif - - aty_st_le16(CONFIG_STAT0, 0x00A4, par); - mdelay(10); - - aty_st_8(BUS_CNTL+1, 0xA0, par); - mdelay(10); - - reset_clocks(par, &pll.ct, 1); - mdelay(10); - - // something about power management - aty_st_8(LCD_INDEX, 0x08, par); - aty_st_8(LCD_DATA, 0x0A, par); - aty_st_8(LCD_INDEX, 0x08, par); - aty_st_8(LCD_DATA+3, 0x02, par); - aty_st_8(LCD_INDEX, 0x08, par); - aty_st_8(LCD_DATA, 0x0B, par); - mdelay(2); - - // enable display requests, enable CRTC - aty_st_8(CRTC_GEN_CNTL+3, 0x02, par); - // disable display - aty_st_8(CRTC_GEN_CNTL, 0x40, par); - // disable display requests, disable CRTC - aty_st_8(CRTC_GEN_CNTL+3, 0x04, par); - mdelay(10); - - aty_st_pll_ct(PLL_YCLK_CNTL, 0x25, par); - - aty_st_le16(CUSTOM_MACRO_CNTL, 0x0179, par); - aty_st_le16(CUSTOM_MACRO_CNTL+2, 0x005E, par); - aty_st_le16(CUSTOM_MACRO_CNTL+2, card->custom_macro_cntl>>16, par); - aty_st_8(CUSTOM_MACRO_CNTL+1, - (card->custom_macro_cntl>>8) & 0xff, par); - - aty_st_le32(MEM_ADDR_CONFIG, card->mem_addr_config, par); - aty_st_le32(MEM_CNTL, card->mem_cntl, par); - aty_st_le32(EXT_MEM_CNTL, card->ext_mem_cntl, par); - - aty_st_8(CONFIG_STAT0, 0xA0 | card->mem_type, par); - - aty_st_pll_ct(PLL_YCLK_CNTL, 0x01, par); - mdelay(15); - aty_st_pll_ct(PLL_YCLK_CNTL, card->pll_yclk_cntl, par); - mdelay(1); - - reset_clocks(par, &pll.ct, 0); - mdelay(50); - reset_clocks(par, &pll.ct, 0); - mdelay(50); - - // enable extended register block - aty_st_8(BUS_CNTL+3, 0x7B, par); - mdelay(1); - // disable extended register block - aty_st_8(BUS_CNTL+3, 0x73, par); - - aty_st_8(CONFIG_STAT0, 0x80 | card->mem_type, par); - - // disable display requests, disable CRTC - aty_st_8(CRTC_GEN_CNTL+3, 0x04, par); - // disable mapping registers in VGA aperture - aty_st_8(CONFIG_CNTL, aty_ld_8(CONFIG_CNTL, par) & ~0x04, par); - mdelay(50); - // enable display requests, enable CRTC - aty_st_8(CRTC_GEN_CNTL+3, 0x02, par); - - // make GPIO's 14,15,16 all inputs - aty_st_8(LCD_INDEX, 0x07, par); - aty_st_8(LCD_DATA+3, 0x00, par); - - // enable the display - aty_st_8(CRTC_GEN_CNTL, 0x00, par); - mdelay(17); - // reset the memory controller - aty_st_8(GEN_TEST_CNTL+1, 0x02, par); - mdelay(15); - aty_st_8(GEN_TEST_CNTL+1, 0x00, par); - mdelay(30); - - // enable extended register block - aty_st_8(BUS_CNTL+3, - (u8)(aty_ld_8(BUS_CNTL+3, par) | 0x08), - par); - // set FIFO size to 512 (PIO) - aty_st_le32(GUI_CNTL, - aty_ld_le32(GUI_CNTL, par) & ~0x3, - par); - - // enable CRT and disable lcd - aty_st_8(LCD_INDEX, 0x01, par); - temp = aty_ld_le32(LCD_DATA, par); - temp = (temp | 0x01) & ~0x02; - aty_st_le32(LCD_DATA, temp, par); - return 0; -} - diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index e65fc3ef763..eea422eb1ab 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c @@ -234,14 +234,14 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, } } -static void bit_cursor(struct vc_data *vc, struct fb_info *info, - struct display *p, int mode, int softback_lines, int fg, int bg) +static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int softback_lines, int fg, int bg) { struct fb_cursor cursor; - struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + struct fbcon_ops *ops = info->fbcon_par; unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; int w = (vc->vc_font.width + 7) >> 3, c; - int y = real_y(p, vc->vc_y); + int y = real_y(ops->p, vc->vc_y); int attribute, use_sw = (vc->vc_cursor_type & 0x10); int err = 1; char *src; @@ -310,7 +310,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, } if (cursor.set & FB_CUR_SETSIZE || - vc->vc_cursor_type != p->cursor_shape || + vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); @@ -323,10 +323,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, kfree(ops->cursor_state.mask); ops->cursor_state.mask = mask; - p->cursor_shape = vc->vc_cursor_type; + ops->p->cursor_shape = vc->vc_cursor_type; cursor.set |= FB_CUR_SETSHAPE; - switch (p->cursor_shape & CUR_HWMASK) { + switch (ops->p->cursor_shape & CUR_HWMASK) { case CUR_NONE: cur_height = 0; break; diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 50e4c4eb491..041d0698786 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -209,13 +209,13 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) #endif #ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION -static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) +static inline void fbcon_set_rotation(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; if (!(info->flags & FBINFO_MISC_TILEBLITTING) && - p->con_rotate < 4) - ops->rotate = p->con_rotate; + ops->p->con_rotate < 4) + ops->rotate = ops->p->con_rotate; else ops->rotate = 0; } @@ -265,7 +265,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) fbcon_set_all_vcs(info); } #else -static inline void fbcon_set_rotation(struct fb_info *info, struct display *p) +static inline void fbcon_set_rotation(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; @@ -402,7 +402,7 @@ static void fb_flashcursor(void *private) c = scr_readw((u16 *) vc->vc_pos); mode = (!ops->cursor_flash || ops->cursor_state.enable) ? CM_ERASE : CM_DRAW; - ops->cursor(vc, info, p, mode, softback_lines, get_color(vc, info, c, 1), + ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1), get_color(vc, info, c, 0)); release_console_sem(); } @@ -647,29 +647,27 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, } #ifdef CONFIG_FB_TILEBLITTING -static void set_blitting_type(struct vc_data *vc, struct fb_info *info, - struct display *p) +static void set_blitting_type(struct vc_data *vc, struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; - ops->p = (p) ? p : &fb_display[vc->vc_num]; + ops->p = &fb_display[vc->vc_num]; if ((info->flags & FBINFO_MISC_TILEBLITTING)) - fbcon_set_tileops(vc, info, p, ops); + fbcon_set_tileops(vc, info); else { - fbcon_set_rotation(info, ops->p); + fbcon_set_rotation(info); fbcon_set_bitops(ops); } } #else -static void set_blitting_type(struct vc_data *vc, struct fb_info *info, - struct display *p) +static void set_blitting_type(struct vc_data *vc, struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; info->flags &= ~FBINFO_MISC_TILEBLITTING; - ops->p = (p) ? p : &fb_display[vc->vc_num]; - fbcon_set_rotation(info, ops->p); + ops->p = &fb_display[vc->vc_num]; + fbcon_set_rotation(info); fbcon_set_bitops(ops); } #endif /* CONFIG_MISC_TILEBLITTING */ @@ -689,15 +687,14 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, err = -ENODEV; if (!err) { - ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL); + ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); if (!ops) err = -ENOMEM; } if (!err) { - memset(ops, 0, sizeof(struct fbcon_ops)); info->fbcon_par = ops; - set_blitting_type(vc, info, NULL); + set_blitting_type(vc, info); } if (err) { @@ -921,19 +918,18 @@ static const char *fbcon_startup(void) return NULL; } - ops = kmalloc(sizeof(struct fbcon_ops), GFP_KERNEL); + ops = kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL); if (!ops) { module_put(owner); return NULL; } - memset(ops, 0, sizeof(struct fbcon_ops)); ops->currcon = -1; ops->graphics = 1; ops->cur_rotate = -1; info->fbcon_par = ops; p->con_rotate = rotate; - set_blitting_type(vc, info, NULL); + set_blitting_type(vc, info); if (info->fix.type != FB_TYPE_TEXT) { if (fbcon_softback_size) { @@ -1093,7 +1089,7 @@ static void fbcon_init(struct vc_data *vc, int init) ops = info->fbcon_par; p->con_rotate = rotate; - set_blitting_type(vc, info, NULL); + set_blitting_type(vc, info); cols = vc->vc_cols; rows = vc->vc_rows; @@ -1141,9 +1137,9 @@ static void fbcon_init(struct vc_data *vc, int init) if (vc == svc && softback_buf) fbcon_update_softback(vc); - if (ops->rotate_font && ops->rotate_font(info, vc, p)) { + if (ops->rotate_font && ops->rotate_font(info, vc)) { ops->rotate = FB_ROTATE_UR; - set_blitting_type(vc, info, p); + set_blitting_type(vc, info); } } @@ -1243,7 +1239,6 @@ static void fbcon_cursor(struct vc_data *vc, int mode) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; int y; int c = scr_readw((u16 *) vc->vc_pos); @@ -1260,7 +1255,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode) y = 0; } - ops->cursor(vc, info, p, mode, y, get_color(vc, info, c, 1), + ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1), get_color(vc, info, c, 0)); vbl_cursor_cnt = CURSOR_DRAW_DELAY; } @@ -1411,16 +1406,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; - int redraw = 0; p->yscroll += count; + if (p->yscroll > p->vrows - vc->vc_rows) { p->yscroll -= p->vrows - vc->vc_rows; - redraw = 1; - } - - if (redraw) fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); + } ops->var.xoffset = 0; ops->var.yoffset = p->yscroll * vc->vc_font.height; @@ -1462,16 +1454,13 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; - int redraw = 0; p->yscroll -= count; + if (p->yscroll < 0) { p->yscroll += p->vrows - vc->vc_rows; - redraw = 1; - } - - if (redraw) fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); + } ops->var.xoffset = 0; ops->var.yoffset = p->yscroll * vc->vc_font.height; @@ -1968,7 +1957,8 @@ static __inline__ void updatescrollmode(struct display *p, divides(ypan, vc->vc_font.height) && vyres > yres; int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) && divides(ywrap, vc->vc_font.height) && - divides(vc->vc_font.height, vyres); + divides(vc->vc_font.height, vyres) && + divides(vc->vc_font.height, yres); int reading_fast = cap & FBINFO_READS_FAST; int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED); @@ -2107,16 +2097,19 @@ static int fbcon_switch(struct vc_data *vc) info->flags & FBINFO_MISC_ALWAYS_SETPAR)) { if (info->fbops->fb_set_par) info->fbops->fb_set_par(info); - fbcon_del_cursor_timer(old_info); - fbcon_add_cursor_timer(info); + + if (old_info != info) { + fbcon_del_cursor_timer(old_info); + fbcon_add_cursor_timer(info); + } } - set_blitting_type(vc, info, p); + set_blitting_type(vc, info); ops->cursor_reset = 1; - if (ops->rotate_font && ops->rotate_font(info, vc, p)) { + if (ops->rotate_font && ops->rotate_font(info, vc)) { ops->rotate = FB_ROTATE_UR; - set_blitting_type(vc, info, p); + set_blitting_type(vc, info); } vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); @@ -2739,7 +2732,7 @@ static void fbcon_modechanged(struct fb_info *info) return; p = &fb_display[vc->vc_num]; - set_blitting_type(vc, info, p); + set_blitting_type(vc, info); if (CON_IS_VISIBLE(vc)) { var_to_display(p, &info->var, info); @@ -2781,7 +2774,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) continue; p = &fb_display[vc->vc_num]; - set_blitting_type(vc, info, p); + set_blitting_type(vc, info); var_to_display(p, &info->var, info); cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); @@ -2806,6 +2799,8 @@ static void fbcon_set_all_vcs(struct fb_info *info) fbcon_update_softback(vc); } } + + ops->p = &fb_display[ops->currcon]; } static int fbcon_mode_deleted(struct fb_info *info, diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index 6892e7ff34d..c38c3d8e7a7 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -62,12 +62,10 @@ struct fbcon_ops { int fg, int bg); void (*clear_margins)(struct vc_data *vc, struct fb_info *info, int bottom_only); - void (*cursor)(struct vc_data *vc, struct fb_info *info, - struct display *p, int mode, int softback_lines, - int fg, int bg); + void (*cursor)(struct vc_data *vc, struct fb_info *info, int mode, + int softback_lines, int fg, int bg); int (*update_start)(struct fb_info *info); - int (*rotate_font)(struct fb_info *info, struct vc_data *vc, - struct display *p); + int (*rotate_font)(struct fb_info *info, struct vc_data *vc); struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ struct timer_list cursor_timer; /* Cursor timer */ struct fb_cursor cursor_state; @@ -173,8 +171,7 @@ struct fbcon_ops { #define SCROLL_PAN_REDRAW 0x005 #ifdef CONFIG_FB_TILEBLITTING -extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, - struct display *p, struct fbcon_ops *ops); +extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info); #endif extern void fbcon_set_bitops(struct fbcon_ops *ops); extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 4952b66ae20..990289a69b7 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c @@ -219,19 +219,18 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, } } -static void ccw_cursor(struct vc_data *vc, struct fb_info *info, - struct display *p, int mode, int softback_lines, - int fg, int bg) +static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int softback_lines, int fg, int bg) { struct fb_cursor cursor; - struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + struct fbcon_ops *ops = info->fbcon_par; unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; int w = (vc->vc_font.height + 7) >> 3, c; - int y = real_y(p, vc->vc_y); + int y = real_y(ops->p, vc->vc_y); int attribute, use_sw = (vc->vc_cursor_type & 0x10); int err = 1, dx, dy; char *src; - u32 vyres = GETVYRES(p->scrollmode, info); + u32 vyres = GETVYRES(ops->p->scrollmode, info); if (!ops->fontbuffer) return; @@ -303,7 +302,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, } if (cursor.set & FB_CUR_SETSIZE || - vc->vc_cursor_type != p->cursor_shape || + vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); @@ -323,10 +322,10 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, kfree(ops->cursor_state.mask); ops->cursor_state.mask = mask; - p->cursor_shape = vc->vc_cursor_type; + ops->p->cursor_shape = vc->vc_cursor_type; cursor.set |= FB_CUR_SETSHAPE; - switch (p->cursor_shape & CUR_HWMASK) { + switch (ops->p->cursor_shape & CUR_HWMASK) { case CUR_NONE: cur_height = 0; break; diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index 6d92b845620..d44c5fa515f 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c @@ -203,19 +203,18 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, } } -static void cw_cursor(struct vc_data *vc, struct fb_info *info, - struct display *p, int mode, int softback_lines, - int fg, int bg) +static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int softback_lines, int fg, int bg) { struct fb_cursor cursor; - struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + struct fbcon_ops *ops = info->fbcon_par; unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; int w = (vc->vc_font.height + 7) >> 3, c; - int y = real_y(p, vc->vc_y); + int y = real_y(ops->p, vc->vc_y); int attribute, use_sw = (vc->vc_cursor_type & 0x10); int err = 1, dx, dy; char *src; - u32 vxres = GETVXRES(p->scrollmode, info); + u32 vxres = GETVXRES(ops->p->scrollmode, info); if (!ops->fontbuffer) return; @@ -287,7 +286,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, } if (cursor.set & FB_CUR_SETSIZE || - vc->vc_cursor_type != p->cursor_shape || + vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC); @@ -307,10 +306,10 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, kfree(ops->cursor_state.mask); ops->cursor_state.mask = mask; - p->cursor_shape = vc->vc_cursor_type; + ops->p->cursor_shape = vc->vc_cursor_type; cursor.set |= FB_CUR_SETSHAPE; - switch (p->cursor_shape & CUR_HWMASK) { + switch (ops->p->cursor_shape & CUR_HWMASK) { case CUR_NONE: cur_height = 0; break; diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c index ec0dd8fe241..2dc091fbd5c 100644 --- a/drivers/video/console/fbcon_rotate.c +++ b/drivers/video/console/fbcon_rotate.c @@ -18,8 +18,7 @@ #include "fbcon.h" #include "fbcon_rotate.h" -static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc, - struct display *p) +static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) { struct fbcon_ops *ops = info->fbcon_par; int len, err = 0; @@ -28,12 +27,12 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc, u8 *dst; if (vc->vc_font.data == ops->fontdata && - p->con_rotate == ops->cur_rotate) + ops->p->con_rotate == ops->cur_rotate) goto finished; src = ops->fontdata = vc->vc_font.data; - ops->cur_rotate = p->con_rotate; - len = (!p->userfont) ? 256 : FNTCHARCNT(src); + ops->cur_rotate = ops->p->con_rotate; + len = (!ops->p->userfont) ? 256 : FNTCHARCNT(src); s_cellsize = ((vc->vc_font.width + 7)/8) * vc->vc_font.height; d_cellsize = s_cellsize; diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h index 1b8f92fdc6a..75be5ce53dc 100644 --- a/drivers/video/console/fbcon_rotate.h +++ b/drivers/video/console/fbcon_rotate.h @@ -11,8 +11,6 @@ #ifndef _FBCON_ROTATE_H #define _FBCON_ROTATE_H -#define FNTCHARCNT(fd) (((int *)(fd))[-3]) - #define GETVYRES(s,i) ({ \ (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \ (i)->var.yres : (i)->var.yres_virtual; }) diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index 9dd059e8b64..f56ed068a5b 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c @@ -249,20 +249,19 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, } } -static void ud_cursor(struct vc_data *vc, struct fb_info *info, - struct display *p, int mode, int softback_lines, - int fg, int bg) +static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int softback_lines, int fg, int bg) { struct fb_cursor cursor; - struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + struct fbcon_ops *ops = info->fbcon_par; unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; int w = (vc->vc_font.width + 7) >> 3, c; - int y = real_y(p, vc->vc_y); + int y = real_y(ops->p, vc->vc_y); int attribute, use_sw = (vc->vc_cursor_type & 0x10); int err = 1, dx, dy; char *src; - u32 vyres = GETVYRES(p->scrollmode, info); - u32 vxres = GETVXRES(p->scrollmode, info); + u32 vyres = GETVYRES(ops->p->scrollmode, info); + u32 vxres = GETVXRES(ops->p->scrollmode, info); if (!ops->fontbuffer) return; @@ -334,7 +333,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, } if (cursor.set & FB_CUR_SETSIZE || - vc->vc_cursor_type != p->cursor_shape || + vc->vc_cursor_type != ops->p->cursor_shape || ops->cursor_state.mask == NULL || ops->cursor_reset) { char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC); @@ -347,10 +346,10 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, kfree(ops->cursor_state.mask); ops->cursor_state.mask = mask; - p->cursor_shape = vc->vc_cursor_type; + ops->p->cursor_shape = vc->vc_cursor_type; cursor.set |= FB_CUR_SETSHAPE; - switch (p->cursor_shape & CUR_HWMASK) { + switch (ops->p->cursor_shape & CUR_HWMASK) { case CUR_NONE: cur_height = 0; break; diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 8529bf08db2..3957fc7523e 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c @@ -17,6 +17,8 @@ #include <asm/uaccess.h> #include <asm/io.h> +#include "fbcon.h" + int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) { unsigned int scan_align = info->pixmap.scan_align - 1; diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c index cb25324a563..153352ca946 100644 --- a/drivers/video/console/tileblit.c +++ b/drivers/video/console/tileblit.c @@ -80,9 +80,8 @@ static void tile_clear_margins(struct vc_data *vc, struct fb_info *info, return; } -static void tile_cursor(struct vc_data *vc, struct fb_info *info, - struct display *p, int mode, int softback_lines, - int fg, int bg) +static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode, + int softback_lines, int fg, int bg) { struct fb_tilecursor cursor; int use_sw = (vc->vc_cursor_type & 0x01); @@ -130,10 +129,10 @@ static int tile_update_start(struct fb_info *info) return err; } -void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, - struct display *p, struct fbcon_ops *ops) +void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info) { struct fb_tilemap map; + struct fbcon_ops *ops = info->fbcon_par; ops->bmove = tile_bmove; ops->clear = tile_clear; @@ -142,13 +141,13 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, ops->cursor = tile_cursor; ops->update_start = tile_update_start; - if (p) { + if (ops->p) { map.width = vc->vc_font.width; map.height = vc->vc_font.height; map.depth = 1; - map.length = (p->userfont) ? - FNTCHARCNT(p->fontdata) : 256; - map.data = p->fontdata; + map.length = (ops->p->userfont) ? + FNTCHARCNT(ops->p->fontdata) : 256; + map.data = ops->p->fontdata; info->tileops->fb_settile(info, &map); } } diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c index 0b6af00d197..ac90883dc3a 100644 --- a/drivers/video/fbcvt.c +++ b/drivers/video/fbcvt.c @@ -214,12 +214,11 @@ static void fb_cvt_print_name(struct fb_cvt_data *cvt) { u32 pixcount, pixcount_mod; int cnt = 255, offset = 0, read = 0; - u8 *buf = kmalloc(256, GFP_KERNEL); + u8 *buf = kzalloc(256, GFP_KERNEL); if (!buf) return; - memset(buf, 0, 256); pixcount = (cvt->xres * (cvt->yres/cvt->interlace))/1000000; pixcount_mod = (cvt->xres * (cvt->yres/cvt->interlace)) % 1000000; pixcount_mod /= 1000; diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 10dfdf03526..32a9b69becc 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -589,17 +589,19 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) return info->fbops->fb_read(file, buf, count, ppos); total_size = info->screen_size; + if (total_size == 0) total_size = info->fix.smem_len; if (p >= total_size) - return 0; + return 0; + if (count >= total_size) - count = total_size; + count = total_size; + if (count + p > total_size) count = total_size - p; - cnt = 0; buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); if (!buffer) @@ -636,6 +638,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) } kfree(buffer); + return (err) ? err : cnt; } @@ -648,7 +651,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) struct fb_info *info = registered_fb[fbidx]; u32 *buffer, *src; u32 __iomem *dst; - int c, i, cnt = 0, err; + int c, i, cnt = 0, err = 0; unsigned long total_size; if (!info || !info->screen_base) @@ -661,19 +664,19 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) return info->fbops->fb_write(file, buf, count, ppos); total_size = info->screen_size; + if (total_size == 0) total_size = info->fix.smem_len; if (p > total_size) - return -ENOSPC; + return 0; + if (count >= total_size) - count = total_size; - err = 0; - if (count + p > total_size) { - count = total_size - p; - err = -ENOSPC; - } - cnt = 0; + count = total_size; + + if (count + p > total_size) + count = total_size - p; + buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL); if (!buffer) @@ -687,12 +690,15 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) while (count) { c = (count > PAGE_SIZE) ? PAGE_SIZE : count; src = buffer; + if (copy_from_user(src, buf, c)) { err = -EFAULT; break; } + for (i = c >> 2; i--; ) fb_writel(*src++, dst++); + if (c & 3) { u8 *src8 = (u8 *) src; u8 __iomem *dst8 = (u8 __iomem *) dst; @@ -702,11 +708,13 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) dst = (u32 __iomem *) dst8; } + *ppos += c; buf += c; cnt += c; count -= c; } + kfree(buffer); return (err) ? err : cnt; @@ -1226,6 +1234,7 @@ fb_open(struct inode *inode, struct file *file) return -ENODEV; if (!try_module_get(info->fbops->owner)) return -ENODEV; + file->private_data = info; if (info->fbops->fb_open) { res = info->fbops->fb_open(info,1); if (res) @@ -1237,11 +1246,9 @@ fb_open(struct inode *inode, struct file *file) static int fb_release(struct inode *inode, struct file *file) { - int fbidx = iminor(inode); - struct fb_info *info; + struct fb_info * const info = file->private_data; lock_kernel(); - info = registered_fb[fbidx]; if (info->fbops->fb_release) info->fbops->fb_release(info,1); module_put(info->fbops->owner); diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index fc7965b6677..7c74e7325d9 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -317,26 +317,29 @@ static int edid_is_monitor_block(unsigned char *block) static void calc_mode_timings(int xres, int yres, int refresh, struct fb_videomode *mode) { - struct fb_var_screeninfo var; - struct fb_info info; + struct fb_var_screeninfo *var; - memset(&var, 0, sizeof(struct fb_var_screeninfo)); - var.xres = xres; - var.yres = yres; - fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, - refresh, &var, &info); - mode->xres = xres; - mode->yres = yres; - mode->pixclock = var.pixclock; - mode->refresh = refresh; - mode->left_margin = var.left_margin; - mode->right_margin = var.right_margin; - mode->upper_margin = var.upper_margin; - mode->lower_margin = var.lower_margin; - mode->hsync_len = var.hsync_len; - mode->vsync_len = var.vsync_len; - mode->vmode = 0; - mode->sync = 0; + var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); + + if (var) { + var->xres = xres; + var->yres = yres; + fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, + refresh, var, NULL); + mode->xres = xres; + mode->yres = yres; + mode->pixclock = var->pixclock; + mode->refresh = refresh; + mode->left_margin = var->left_margin; + mode->right_margin = var->right_margin; + mode->upper_margin = var->upper_margin; + mode->lower_margin = var->lower_margin; + mode->hsync_len = var->hsync_len; + mode->vsync_len = var->vsync_len; + mode->vmode = 0; + mode->sync = 0; + kfree(var); + } } static int get_est_timing(unsigned char *block, struct fb_videomode *mode) @@ -525,10 +528,9 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) unsigned char *block; int num = 0, i; - mode = kmalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); + mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); if (mode == NULL) return NULL; - memset(mode, 0, 50 * sizeof(struct fb_videomode)); if (edid == NULL || !edid_checksum(edid) || !edid_check_header(edid)) { @@ -1105,15 +1107,21 @@ static void fb_timings_dclk(struct __fb_timings *timings) */ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) { - struct __fb_timings timings; + struct __fb_timings *timings; u32 interlace = 1, dscan = 1; - u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; + u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax, err = 0; + + + timings = kzalloc(sizeof(struct __fb_timings), GFP_KERNEL); + + if (!timings) + return -ENOMEM; /* * If monspecs are invalid, use values that are enough * for 640x480@60 */ - if (!info->monspecs.hfmax || !info->monspecs.vfmax || + if (!info || !info->monspecs.hfmax || !info->monspecs.vfmax || !info->monspecs.dclkmax || info->monspecs.hfmax < info->monspecs.hfmin || info->monspecs.vfmax < info->monspecs.vfmin || @@ -1130,65 +1138,66 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf dclkmax = info->monspecs.dclkmax; } - memset(&timings, 0, sizeof(struct __fb_timings)); - timings.hactive = var->xres; - timings.vactive = var->yres; + timings->hactive = var->xres; + timings->vactive = var->yres; if (var->vmode & FB_VMODE_INTERLACED) { - timings.vactive /= 2; + timings->vactive /= 2; interlace = 2; } if (var->vmode & FB_VMODE_DOUBLE) { - timings.vactive *= 2; + timings->vactive *= 2; dscan = 2; } switch (flags & ~FB_IGNOREMON) { case FB_MAXTIMINGS: /* maximize refresh rate */ - timings.hfreq = hfmax; - fb_timings_hfreq(&timings); - if (timings.vfreq > vfmax) { - timings.vfreq = vfmax; - fb_timings_vfreq(&timings); + timings->hfreq = hfmax; + fb_timings_hfreq(timings); + if (timings->vfreq > vfmax) { + timings->vfreq = vfmax; + fb_timings_vfreq(timings); } - if (timings.dclk > dclkmax) { - timings.dclk = dclkmax; - fb_timings_dclk(&timings); + if (timings->dclk > dclkmax) { + timings->dclk = dclkmax; + fb_timings_dclk(timings); } break; case FB_VSYNCTIMINGS: /* vrefresh driven */ - timings.vfreq = val; - fb_timings_vfreq(&timings); + timings->vfreq = val; + fb_timings_vfreq(timings); break; case FB_HSYNCTIMINGS: /* hsync driven */ - timings.hfreq = val; - fb_timings_hfreq(&timings); + timings->hfreq = val; + fb_timings_hfreq(timings); break; case FB_DCLKTIMINGS: /* pixelclock driven */ - timings.dclk = PICOS2KHZ(val) * 1000; - fb_timings_dclk(&timings); + timings->dclk = PICOS2KHZ(val) * 1000; + fb_timings_dclk(timings); break; default: - return -EINVAL; + err = -EINVAL; } - if (!(flags & FB_IGNOREMON) && - (timings.vfreq < vfmin || timings.vfreq > vfmax || - timings.hfreq < hfmin || timings.hfreq > hfmax || - timings.dclk < dclkmin || timings.dclk > dclkmax)) - return -EINVAL; - - var->pixclock = KHZ2PICOS(timings.dclk/1000); - var->hsync_len = (timings.htotal * 8)/100; - var->right_margin = (timings.hblank/2) - var->hsync_len; - var->left_margin = timings.hblank - var->right_margin - var->hsync_len; - - var->vsync_len = (3 * interlace)/dscan; - var->lower_margin = (1 * interlace)/dscan; - var->upper_margin = (timings.vblank * interlace)/dscan - - (var->vsync_len + var->lower_margin); + if (err || (!(flags & FB_IGNOREMON) && + (timings->vfreq < vfmin || timings->vfreq > vfmax || + timings->hfreq < hfmin || timings->hfreq > hfmax || + timings->dclk < dclkmin || timings->dclk > dclkmax))) { + err = -EINVAL; + } else { + var->pixclock = KHZ2PICOS(timings->dclk/1000); + var->hsync_len = (timings->htotal * 8)/100; + var->right_margin = (timings->hblank/2) - var->hsync_len; + var->left_margin = timings->hblank - var->right_margin - + var->hsync_len; + var->vsync_len = (3 * interlace)/dscan; + var->lower_margin = (1 * interlace)/dscan; + var->upper_margin = (timings->vblank * interlace)/dscan - + (var->vsync_len + var->lower_margin); + } - return 0; + kfree(timings); + return err; } #else int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 08dac9580d1..6d26057337e 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -43,10 +43,11 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev) if (size) fb_info_size += PADDING; - p = kmalloc(fb_info_size + size, GFP_KERNEL); + p = kzalloc(fb_info_size + size, GFP_KERNEL); + if (!p) return NULL; - memset(p, 0, fb_info_size + size); + info = (struct fb_info *) p; if (size) @@ -106,8 +107,7 @@ static int mode_string(char *buf, unsigned int offset, static ssize_t store_mode(struct class_device *class_device, const char * buf, size_t count) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); char mstr[100]; struct fb_var_screeninfo var; struct fb_modelist *modelist; @@ -137,8 +137,7 @@ static ssize_t store_mode(struct class_device *class_device, const char * buf, static ssize_t show_mode(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); if (!fb_info->mode) return 0; @@ -149,8 +148,7 @@ static ssize_t show_mode(struct class_device *class_device, char *buf) static ssize_t store_modes(struct class_device *class_device, const char * buf, size_t count) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); LIST_HEAD(old_list); int i = count / sizeof(struct fb_videomode); @@ -174,8 +172,7 @@ static ssize_t store_modes(struct class_device *class_device, const char * buf, static ssize_t show_modes(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); unsigned int i; struct list_head *pos; struct fb_modelist *modelist; @@ -193,8 +190,7 @@ static ssize_t show_modes(struct class_device *class_device, char *buf) static ssize_t store_bpp(struct class_device *class_device, const char * buf, size_t count) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); struct fb_var_screeninfo var; char ** last = NULL; int err; @@ -208,8 +204,7 @@ static ssize_t store_bpp(struct class_device *class_device, const char * buf, static ssize_t show_bpp(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); } @@ -280,8 +275,7 @@ static ssize_t show_con_rotate(struct class_device *class_device, char *buf) static ssize_t store_virtual(struct class_device *class_device, const char * buf, size_t count) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); struct fb_var_screeninfo var; char *last = NULL; int err; @@ -300,16 +294,14 @@ static ssize_t store_virtual(struct class_device *class_device, static ssize_t show_virtual(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, fb_info->var.yres_virtual); } static ssize_t show_stride(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); } @@ -320,7 +312,7 @@ static ssize_t show_stride(struct class_device *class_device, char *buf) static ssize_t store_cmap(struct class_device *class_device, const char *buf, size_t count) { - struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); int rc, i, start, length, transp = 0; if ((count > PAGE_SIZE) || ((count % 16) != 0)) @@ -380,8 +372,7 @@ static ssize_t store_cmap(struct class_device *class_device, const char *buf, static ssize_t show_cmap(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); unsigned int i; if (!fb_info->cmap.red || !fb_info->cmap.blue || @@ -405,8 +396,7 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf) static ssize_t store_blank(struct class_device *class_device, const char * buf, size_t count) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); char *last = NULL; int err; @@ -422,41 +412,40 @@ static ssize_t store_blank(struct class_device *class_device, const char * buf, static ssize_t show_blank(struct class_device *class_device, char *buf) { -// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } static ssize_t store_console(struct class_device *class_device, const char * buf, size_t count) { -// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } static ssize_t show_console(struct class_device *class_device, char *buf) { -// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } static ssize_t store_cursor(struct class_device *class_device, const char * buf, size_t count) { -// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } static ssize_t show_cursor(struct class_device *class_device, char *buf) { -// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); +// struct fb_info *fb_info = class_get_devdata(class_device); return 0; } static ssize_t store_pan(struct class_device *class_device, const char * buf, size_t count) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); struct fb_var_screeninfo var; char *last = NULL; int err; @@ -479,19 +468,40 @@ static ssize_t store_pan(struct class_device *class_device, const char * buf, static ssize_t show_pan(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = - (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, fb_info->var.xoffset); } static ssize_t show_name(struct class_device *class_device, char *buf) { - struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); } +static ssize_t store_fbstate(struct class_device *class_device, + const char *buf, size_t count) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + u32 state; + char *last = NULL; + + state = simple_strtoul(buf, &last, 0); + + acquire_console_sem(); + fb_set_suspend(fb_info, (int)state); + release_console_sem(); + + return count; +} + +static ssize_t show_fbstate(struct class_device *class_device, char *buf) +{ + struct fb_info *fb_info = class_get_devdata(class_device); + return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); +} + static struct class_device_attribute class_device_attrs[] = { __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), @@ -507,6 +517,7 @@ static struct class_device_attribute class_device_attrs[] = { __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate), __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all), + __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate), }; int fb_init_class_device(struct fb_info *fb_info) diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index b37cea7d109..4e39035cf33 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c @@ -42,6 +42,7 @@ #include <linux/fb.h> #include <linux/init.h> #include <linux/ioport.h> +#include <linux/platform_device.h> #include <asm/io.h> #include <asm/vga.h> @@ -107,7 +108,7 @@ static DEFINE_SPINLOCK(hga_reg_lock); /* Framebuffer driver structures */ -static struct fb_var_screeninfo hga_default_var = { +static struct fb_var_screeninfo __initdata hga_default_var = { .xres = 720, .yres = 348, .xres_virtual = 720, @@ -121,7 +122,7 @@ static struct fb_var_screeninfo hga_default_var = { .width = -1, }; -static struct fb_fix_screeninfo hga_fix = { +static struct fb_fix_screeninfo __initdata hga_fix = { .id = "HGA", .type = FB_TYPE_PACKED_PIXELS, /* (not sure) */ .visual = FB_VISUAL_MONO10, @@ -131,8 +132,6 @@ static struct fb_fix_screeninfo hga_fix = { .accel = FB_ACCEL_NONE }; -static struct fb_info fb_info; - /* Don't assume that tty1 will be the initial current console. */ static int release_io_port = 0; static int release_io_ports = 0; @@ -549,10 +548,9 @@ static struct fb_ops hgafb_ops = { * Initialization */ -static int __init hgafb_init(void) +static int __init hgafb_probe(struct device *device) { - if (fb_get_options("hgafb", NULL)) - return -ENODEV; + struct fb_info *info; if (! hga_card_detect()) { printk(KERN_INFO "hgafb: HGA card not detected.\n"); @@ -564,41 +562,95 @@ static int __init hgafb_init(void) printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n", hga_type_name, hga_vram_len/1024); + info = framebuffer_alloc(0, NULL); + if (!info) { + iounmap(hga_vram); + return -ENOMEM; + } + hga_fix.smem_start = (unsigned long)hga_vram; hga_fix.smem_len = hga_vram_len; - fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; - fb_info.var = hga_default_var; - fb_info.fix = hga_fix; - fb_info.monspecs.hfmin = 0; - fb_info.monspecs.hfmax = 0; - fb_info.monspecs.vfmin = 10000; - fb_info.monspecs.vfmax = 10000; - fb_info.monspecs.dpms = 0; - fb_info.fbops = &hgafb_ops; - fb_info.screen_base = hga_vram; - - if (register_framebuffer(&fb_info) < 0) { + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; + info->var = hga_default_var; + info->fix = hga_fix; + info->monspecs.hfmin = 0; + info->monspecs.hfmax = 0; + info->monspecs.vfmin = 10000; + info->monspecs.vfmax = 10000; + info->monspecs.dpms = 0; + info->fbops = &hgafb_ops; + info->screen_base = hga_vram; + + if (register_framebuffer(info) < 0) { + framebuffer_release(info); iounmap(hga_vram); return -EINVAL; } printk(KERN_INFO "fb%d: %s frame buffer device\n", - fb_info.node, fb_info.fix.id); + info->node, info->fix.id); + dev_set_drvdata(device, info); return 0; } -#ifdef MODULE -static void __exit hgafb_exit(void) +static int hgafb_remove(struct device *device) { + struct fb_info *info = dev_get_drvdata(device); + hga_txt_mode(); hga_clear_screen(); - unregister_framebuffer(&fb_info); + + if (info) { + unregister_framebuffer(info); + framebuffer_release(info); + } + iounmap(hga_vram); - if (release_io_ports) release_region(0x3b0, 12); - if (release_io_port) release_region(0x3bf, 1); + + if (release_io_ports) + release_region(0x3b0, 12); + + if (release_io_port) + release_region(0x3bf, 1); + + return 0; +} + +static struct device_driver hgafb_driver = { + .name = "hgafb", + .bus = &platform_bus_type, + .probe = hgafb_probe, + .remove = hgafb_remove, +}; + +static struct platform_device hgafb_device = { + .name = "hgafb", +}; + +static int __init hgafb_init(void) +{ + int ret; + + if (fb_get_options("hgafb", NULL)) + return -ENODEV; + + ret = driver_register(&hgafb_driver); + + if (!ret) { + ret = platform_device_register(&hgafb_device); + if (ret) + driver_unregister(&hgafb_driver); + } + + return ret; +} + +static void __exit hgafb_exit(void) +{ + platform_device_unregister(&hgafb_device); + driver_unregister(&hgafb_driver); } -#endif /* ------------------------------------------------------------------------- * @@ -613,7 +665,4 @@ MODULE_LICENSE("GPL"); module_param(nologo, bool, 0); MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)"); module_init(hgafb_init); - -#ifdef MODULE module_exit(hgafb_exit); -#endif diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c index c61bad0da20..bd410e06db7 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/i810/i810-i2c.c @@ -17,6 +17,7 @@ #include <linux/fb.h> #include "i810.h" #include "i810_regs.h" +#include "i810_main.h" #include "../edid.h" #define I810_DDC 0x50 @@ -42,7 +43,7 @@ static void i810i2c_setscl(void *data, int state) { - struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; + struct i810fb_i2c_chan *chan = data; struct i810fb_par *par = chan->par; u8 __iomem *mmio = par->mmio_start_virtual; diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c index 64cd1c827cf..76764ea3486 100644 --- a/drivers/video/i810/i810_accel.c +++ b/drivers/video/i810/i810_accel.c @@ -14,6 +14,7 @@ #include "i810_regs.h" #include "i810.h" +#include "i810_main.h" static u32 i810fb_rop[] = { COLOR_COPY_ROP, /* ROP_COPY */ @@ -57,7 +58,7 @@ static inline void i810_report_error(u8 __iomem *mmio) */ static inline int wait_for_space(struct fb_info *info, u32 space) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 head, count = WAIT_COUNT, tail; u8 __iomem *mmio = par->mmio_start_virtual; @@ -88,7 +89,7 @@ static inline int wait_for_space(struct fb_info *info, u32 space) */ static inline int wait_for_engine_idle(struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u8 __iomem *mmio = par->mmio_start_virtual; int count = WAIT_COUNT; @@ -116,7 +117,7 @@ static inline int wait_for_engine_idle(struct fb_info *info) */ static inline u32 begin_iring(struct fb_info *info, u32 space) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; if (par->dev_flags & ALWAYS_SYNC) wait_for_engine_idle(info); @@ -161,7 +162,7 @@ static inline void source_copy_blit(int dwidth, int dheight, int dpitch, int xdir, int src, int dest, int rop, int blit_bpp, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; if (begin_iring(info, 24 + IRING_PAD)) return; @@ -195,7 +196,7 @@ static inline void color_blit(int width, int height, int pitch, int dest, int rop, int what, int blit_bpp, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; if (begin_iring(info, 24 + IRING_PAD)) return; @@ -236,7 +237,7 @@ static inline void mono_src_copy_imm_blit(int dwidth, int dheight, int dpitch, int dest, const u32 *src, int bg, int fg, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; if (begin_iring(info, 24 + (dsize << 2) + IRING_PAD)) return; @@ -254,7 +255,7 @@ static inline void mono_src_copy_imm_blit(int dwidth, int dheight, int dpitch, static inline void load_front(int offset, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; if (begin_iring(info, 8 + IRING_PAD)) return; @@ -296,7 +297,7 @@ static inline void i810fb_iring_enable(struct i810fb_par *par, u32 mode) void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 dx, dy, width, height, dest, rop = 0, color = 0; if (!info->var.accel_flags || par->dev_flags & LOCKUP || @@ -322,7 +323,7 @@ void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir; if (!info->var.accel_flags || par->dev_flags & LOCKUP || @@ -361,7 +362,7 @@ void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) void i810fb_imageblit(struct fb_info *info, const struct fb_image *image) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 fg = 0, bg = 0, size, dst; if (!info->var.accel_flags || par->dev_flags & LOCKUP || @@ -397,7 +398,7 @@ void i810fb_imageblit(struct fb_info *info, const struct fb_image *image) int i810fb_sync(struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; if (!info->var.accel_flags || par->dev_flags & LOCKUP) return 0; @@ -407,7 +408,7 @@ int i810fb_sync(struct fb_info *info) void i810fb_load_front(u32 offset, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u8 __iomem *mmio = par->mmio_start_virtual; if (!info->var.accel_flags || par->dev_flags & LOCKUP) @@ -427,7 +428,7 @@ void i810fb_load_front(u32 offset, struct fb_info *info) */ void i810fb_init_ringbuffer(struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 tmp1, tmp2; u8 __iomem *mmio = par->mmio_start_virtual; diff --git a/drivers/video/i810/i810_gtf.c b/drivers/video/i810/i810_gtf.c index 64f087a4466..9743d51e7f8 100644 --- a/drivers/video/i810/i810_gtf.c +++ b/drivers/video/i810/i810_gtf.c @@ -14,6 +14,7 @@ #include "i810_regs.h" #include "i810.h" +#include "i810_main.h" /* * FIFO and Watermark tables - based almost wholly on i810_wmark.c in diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index c0c974b1afa..266d0ab9266 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -42,20 +42,62 @@ #include <linux/pci_ids.h> #include <linux/resource.h> #include <linux/unistd.h> +#include <linux/console.h> #include <asm/io.h> #include <asm/div64.h> - -#ifdef CONFIG_MTRR -#include <asm/mtrr.h> -#endif - #include <asm/page.h> #include "i810_regs.h" #include "i810.h" #include "i810_main.h" +/* + * voffset - framebuffer offset in MiB from aperture start address. In order for + * the driver to work with X, we must try to use memory holes left untouched by X. The + * following table lists where X's different surfaces start at. + * + * --------------------------------------------- + * : : 64 MiB : 32 MiB : + * ---------------------------------------------- + * : FrontBuffer : 0 : 0 : + * : DepthBuffer : 48 : 16 : + * : BackBuffer : 56 : 24 : + * ---------------------------------------------- + * + * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to + * 15 + 1 MiB of Framebuffer memory. For 32 MiB Aperture sizes, a v_offset of 8 MiB should + * work, allowing 7 + 1 MiB of Framebuffer memory. + * Note, the size of the hole may change depending on how much memory you allocate to X, + * and how the memory is split up between these surfaces. + * + * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with + * DRI disabled. But if the Frontbuffer is overlapped, X will fail to load. + * + * Experiment with v_offset to find out which works best for you. + */ +static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */ +static u32 voffset __initdata = 0; + +static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor); +static int __devinit i810fb_init_pci (struct pci_dev *dev, + const struct pci_device_id *entry); +static void __exit i810fb_remove_pci(struct pci_dev *dev); +static int i810fb_resume(struct pci_dev *dev); +static int i810fb_suspend(struct pci_dev *dev, pm_message_t state); + +/* Chipset Specific Functions */ +static int i810fb_set_par (struct fb_info *info); +static int i810fb_getcolreg (u8 regno, u8 *red, u8 *green, u8 *blue, + u8 *transp, struct fb_info *info); +static int i810fb_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue, + unsigned transp, struct fb_info *info); +static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); +static int i810fb_blank (int blank_mode, struct fb_info *info); + +/* Initialization */ +static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par); + /* PCI */ static const char *i810_pci_list[] __devinitdata = { "Intel(R) 810 Framebuffer Device" , @@ -776,7 +818,7 @@ static void i810_load_cursor_image(int width, int height, u8 *data, static void i810_load_cursor_colors(int fg, int bg, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u8 __iomem *mmio = par->mmio_start_virtual; u8 red, green, blue, trans, temp; @@ -949,7 +991,7 @@ static void set_color_bitfields(struct fb_var_screeninfo *var) static int i810_check_params(struct fb_var_screeninfo *var, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; int line_length, vidmem, mode_valid = 0, retval = 0; u32 vyres = var->yres_virtual, vxres = var->xres_virtual; /* @@ -1043,7 +1085,7 @@ static int i810_check_params(struct fb_var_screeninfo *var, */ static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; memset(fix, 0, sizeof(struct fb_fix_screeninfo)); @@ -1154,7 +1196,7 @@ static void decode_var(const struct fb_var_screeninfo *var, static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue, u8 *transp, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u8 __iomem *mmio = par->mmio_start_virtual; u8 temp; @@ -1193,7 +1235,7 @@ static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue, static int i810fb_open(struct fb_info *info, int user) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 count = atomic_read(&par->use_count); if (count == 0) { @@ -1212,7 +1254,7 @@ static int i810fb_open(struct fb_info *info, int user) static int i810fb_release(struct fb_info *info, int user) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 count; count = atomic_read(&par->use_count); @@ -1234,7 +1276,7 @@ static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u8 __iomem *mmio = par->mmio_start_virtual; u8 temp; int i; @@ -1328,7 +1370,7 @@ static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green, static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u32 total; total = var->xoffset * par->depth + @@ -1340,7 +1382,7 @@ static int i810fb_pan_display(struct fb_var_screeninfo *var, static int i810fb_blank (int blank_mode, struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; u8 __iomem *mmio = par->mmio_start_virtual; int mode = 0, pwr, scr_off = 0; @@ -1385,7 +1427,7 @@ static int i810fb_blank (int blank_mode, struct fb_info *info) static int i810fb_set_par(struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; decode_var(&info->var, par); i810_load_regs(par); @@ -1429,7 +1471,7 @@ static int i810fb_check_var(struct fb_var_screeninfo *var, static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor) { - struct i810fb_par *par = (struct i810fb_par *)info->par; + struct i810fb_par *par = info->par; u8 __iomem *mmio = par->mmio_start_virtual; if (!par->dev_flags & LOCKUP) @@ -1516,36 +1558,29 @@ static struct fb_ops i810fb_ops __devinitdata = { static int i810fb_suspend(struct pci_dev *dev, pm_message_t state) { struct fb_info *info = pci_get_drvdata(dev); - struct i810fb_par *par = (struct i810fb_par *) info->par; - int blank = 0, prev_state = par->cur_state; - - if (state.event == prev_state) - return 0; + struct i810fb_par *par = info->par; par->cur_state = state.event; - switch (state.event) { - case 1: - blank = VESA_VSYNC_SUSPEND; - break; - case 2: - blank = VESA_HSYNC_SUSPEND; - break; - case 3: - blank = VESA_POWERDOWN; - break; - default: - return -EINVAL; + if (state.event == PM_EVENT_FREEZE) { + dev->dev.power.power_state = state; + return 0; } - info->fbops->fb_blank(blank, info); - if (!prev_state) { - agp_unbind_memory(par->i810_gtt.i810_fb_memory); - agp_unbind_memory(par->i810_gtt.i810_cursor_memory); - pci_disable_device(dev); - } + acquire_console_sem(); + fb_set_suspend(info, 1); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + i810fb_blank(FB_BLANK_POWERDOWN, info); + agp_unbind_memory(par->i810_gtt.i810_fb_memory); + agp_unbind_memory(par->i810_gtt.i810_cursor_memory); + pci_save_state(dev); + pci_disable_device(dev); pci_set_power_state(dev, pci_choose_state(dev, state)); + release_console_sem(); return 0; } @@ -1553,23 +1588,29 @@ static int i810fb_suspend(struct pci_dev *dev, pm_message_t state) static int i810fb_resume(struct pci_dev *dev) { struct fb_info *info = pci_get_drvdata(dev); - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; + int cur_state = par->cur_state; + + par->cur_state = PM_EVENT_ON; - if (par->cur_state == 0) + if (cur_state == PM_EVENT_FREEZE) { + pci_set_power_state(dev, PCI_D0); return 0; + } - pci_restore_state(dev); + acquire_console_sem(); pci_set_power_state(dev, PCI_D0); + pci_restore_state(dev); pci_enable_device(dev); + pci_set_master(dev); agp_bind_memory(par->i810_gtt.i810_fb_memory, par->fb.offset); agp_bind_memory(par->i810_gtt.i810_cursor_memory, par->cursor_heap.offset); - + i810fb_set_par(info); + fb_set_suspend (info, 0); info->fbops->fb_blank(VESA_NO_BLANKING, info); - - par->cur_state = 0; - + release_console_sem(); return 0; } /*********************************************************************** @@ -1610,7 +1651,7 @@ static void __devinit i810_fix_offsets(struct i810fb_par *par) static int __devinit i810_alloc_agp_mem(struct fb_info *info) { - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; int size; struct agp_bridge_data *bridge; @@ -2074,7 +2115,7 @@ static void i810fb_release_resource(struct fb_info *info, static void __exit i810fb_remove_pci(struct pci_dev *dev) { struct fb_info *info = pci_get_drvdata(dev); - struct i810fb_par *par = (struct i810fb_par *) info->par; + struct i810fb_par *par = info->par; unregister_framebuffer(info); i810fb_release_resource(info, par); diff --git a/drivers/video/i810/i810_main.h b/drivers/video/i810/i810_main.h index 06072a6466f..51d4f3d4116 100644 --- a/drivers/video/i810/i810_main.h +++ b/drivers/video/i810/i810_main.h @@ -14,55 +14,6 @@ #ifndef __I810_MAIN_H__ #define __I810_MAIN_H__ -static int __devinit i810fb_init_pci (struct pci_dev *dev, - const struct pci_device_id *entry); -static void __exit i810fb_remove_pci(struct pci_dev *dev); -static int i810fb_resume(struct pci_dev *dev); -static int i810fb_suspend(struct pci_dev *dev, pm_message_t state); - -/* - * voffset - framebuffer offset in MiB from aperture start address. In order for - * the driver to work with X, we must try to use memory holes left untouched by X. The - * following table lists where X's different surfaces start at. - * - * --------------------------------------------- - * : : 64 MiB : 32 MiB : - * ---------------------------------------------- - * : FrontBuffer : 0 : 0 : - * : DepthBuffer : 48 : 16 : - * : BackBuffer : 56 : 24 : - * ---------------------------------------------- - * - * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to - * 15 + 1 MiB of Framebuffer memory. For 32 MiB Aperture sizes, a v_offset of 8 MiB should - * work, allowing 7 + 1 MiB of Framebuffer memory. - * Note, the size of the hole may change depending on how much memory you allocate to X, - * and how the memory is split up between these surfaces. - * - * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with - * DRI disabled. But if the Frontbuffer is overlapped, X will fail to load. - * - * Experiment with v_offset to find out which works best for you. - */ -static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */ -static u32 voffset __initdata = 0; - -static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor); - -/* Chipset Specific Functions */ -static int i810fb_set_par (struct fb_info *info); -static int i810fb_getcolreg (u8 regno, u8 *red, u8 *green, u8 *blue, - u8 *transp, struct fb_info *info); -static int i810fb_setcolreg (unsigned regno, unsigned red, unsigned green, unsigned blue, - unsigned transp, struct fb_info *info); -static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); -static int i810fb_blank (int blank_mode, struct fb_info *info); - -/* Initialization */ -static void i810fb_release_resource (struct fb_info *info, struct i810fb_par *par); -extern int __init agp_intel_init(void); - - /* Video Timings */ extern void round_off_xres (u32 *xres); extern void round_off_yres (u32 *xres, u32 *yres); @@ -101,7 +52,7 @@ static inline void i810_delete_i2c_busses(struct i810fb_par *par) { } /* Conditionals */ #ifdef CONFIG_X86 -inline void flush_cache(void) +static inline void flush_cache(void) { asm volatile ("wbinvd":::"memory"); } @@ -110,7 +61,9 @@ inline void flush_cache(void) #endif #ifdef CONFIG_MTRR -#define KERNEL_HAS_MTRR 1 + +#include <asm/mtrr.h> + static inline void __devinit set_mtrr(struct i810fb_par *par) { par->mtrr_reg = mtrr_add((u32) par->aperture.physical, @@ -128,7 +81,6 @@ static inline void unset_mtrr(struct i810fb_par *par) par->aperture.size); } #else -#define KERNEL_HAS_MTRR 0 #define set_mtrr(x) printk("set_mtrr: MTRR is disabled in the kernel\n") #define unset_mtrr(x) do { } while (0) diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index 7fbe24206b1..a5d813050db 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -323,6 +323,7 @@ struct imstt_par { unsigned long cmap_regs_phys; __u8 *cmap_regs; __u32 ramdac; + __u32 palette[16]; }; enum { @@ -657,7 +658,7 @@ set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp) static void set_imstt_regvals (struct fb_info *info, u_int bpp) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; struct imstt_regvals *init = &par->init; __u32 ctl, pitch, byteswap, scr; @@ -749,7 +750,7 @@ set_imstt_regvals (struct fb_info *info, u_int bpp) static inline void set_offset (struct fb_var_screeninfo *var, struct fb_info *info) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; __u32 off = var->yoffset * (info->fix.line_length >> 3) + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3); write_reg_le32(par->dc_regs, SSR, off); @@ -863,7 +864,7 @@ imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int imsttfb_set_par(struct fb_info *info) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; if (!compute_imstt_regvals(par, info->var.xres, info->var.yres)) return -EINVAL; @@ -881,7 +882,7 @@ static int imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; u_int bpp = info->var.bits_per_pixel; if (regno > 255) @@ -905,14 +906,17 @@ imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue, if (regno < 16) switch (bpp) { case 16: - ((u16 *)info->pseudo_palette)[regno] = (regno << (info->var.green.length == 5 ? 10 : 11)) | (regno << 5) | regno; + par->palette[regno] = + (regno << (info->var.green.length == + 5 ? 10 : 11)) | (regno << 5) | regno; break; case 24: - ((u32 *)info->pseudo_palette)[regno] = (regno << 16) | (regno << 8) | regno; + par->palette[regno] = + (regno << 16) | (regno << 8) | regno; break; case 32: { int i = (regno << 8) | regno; - ((u32 *)info->pseudo_palette)[regno] = (i << 16) | i; + par->palette[regno] = (i << 16) |i; break; } } @@ -935,7 +939,7 @@ imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) static int imsttfb_blank(int blank, struct fb_info *info) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; __u32 ctrl; ctrl = read_reg_le32(par->dc_regs, STGCTL); @@ -989,7 +993,7 @@ imsttfb_blank(int blank, struct fb_info *info) static void imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; __u32 Bpp, line_pitch, bgc, dx, dy, width, height; bgc = rect->color; @@ -1033,7 +1037,7 @@ imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) static void imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl; __u32 cnt, bltctl, sx, sy, dx, dy, height, width; @@ -1195,7 +1199,7 @@ imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on) static int imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; u32 flags = cursor->set, fg, bg, xx, yy; if (cursor->dest == NULL && cursor->rop == ROP_XOR) @@ -1266,7 +1270,7 @@ static int imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg, struct fb_info *info) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; void __user *argp = (void __user *)arg; __u32 reg[2]; __u8 idx[2]; @@ -1350,7 +1354,7 @@ static struct fb_ops imsttfb_ops = { static void __devinit init_imstt(struct fb_info *info) { - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; __u32 i, tmp, *ip, *end; tmp = read_reg_le32(par->dc_regs, PRC); @@ -1413,7 +1417,7 @@ init_imstt(struct fb_info *info) if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) { printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); - kfree(info); + framebuffer_release(info); return; } @@ -1449,7 +1453,7 @@ init_imstt(struct fb_info *info) fb_alloc_cmap(&info->cmap, 0, 0); if (register_framebuffer(info) < 0) { - kfree(info); + framebuffer_release(info); return; } @@ -1474,26 +1478,21 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) printk(KERN_ERR "imsttfb: no OF node for pci device\n"); #endif /* CONFIG_PPC_OF */ - size = sizeof(struct fb_info) + sizeof(struct imstt_par) + - sizeof(u32) * 16; - - info = kmalloc(size, GFP_KERNEL); + info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev); if (!info) { printk(KERN_ERR "imsttfb: Can't allocate memory\n"); return -ENOMEM; } - memset(info, 0, size); - - par = (struct imstt_par *) (info + 1); + par = info->par; addr = pci_resource_start (pdev, 0); size = pci_resource_len (pdev, 0); if (!request_mem_region(addr, size, "imsttfb")) { printk(KERN_ERR "imsttfb: Can't reserve memory region\n"); - kfree(info); + framebuffer_release(info); return -ENODEV; } @@ -1516,14 +1515,13 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } info->fix.smem_start = addr; - info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000); + info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? + 0x400000 : 0x800000); info->fix.mmio_start = addr + 0x800000; par->dc_regs = ioremap(addr + 0x800000, 0x1000); par->cmap_regs_phys = addr + 0x840000; par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000); - info->par = par; - info->pseudo_palette = (void *) (par + 1); - info->device = &pdev->dev; + info->pseudo_palette = par->palette; init_imstt(info); pci_set_drvdata(pdev, info); @@ -1534,7 +1532,7 @@ static void __devexit imsttfb_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); - struct imstt_par *par = (struct imstt_par *) info->par; + struct imstt_par *par = info->par; int size = pci_resource_len(pdev, 0); unregister_framebuffer(info); @@ -1542,7 +1540,7 @@ imsttfb_remove(struct pci_dev *pdev) iounmap(par->dc_regs); iounmap(info->screen_base); release_mem_region(info->fix.smem_start, size); - kfree(info); + framebuffer_release(info); } #ifndef MODULE diff --git a/drivers/video/kyro/STG4000InitDevice.c b/drivers/video/kyro/STG4000InitDevice.c index 7e33cd307d4..ab5285a7f1d 100644 --- a/drivers/video/kyro/STG4000InitDevice.c +++ b/drivers/video/kyro/STG4000InitDevice.c @@ -15,6 +15,7 @@ #include <linux/pci.h> #include "STG4000Reg.h" +#include "STG4000Interface.h" /* SDRAM fixed settings */ #define SDRAM_CFG_0 0x49A1 diff --git a/drivers/video/kyro/STG4000Interface.h b/drivers/video/kyro/STG4000Interface.h index e75b3b4a4aa..b7c83d5dfb1 100644 --- a/drivers/video/kyro/STG4000Interface.h +++ b/drivers/video/kyro/STG4000Interface.h @@ -11,7 +11,8 @@ #ifndef _STG4000INTERFACE_H #define _STG4000INTERFACE_H -struct pci_dev; +#include <linux/pci.h> +#include <video/kyro.h> /* * Ramdac Setup diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/kyro/STG4000OverlayDevice.c index 2ae9bafacdd..a8c9713413e 100644 --- a/drivers/video/kyro/STG4000OverlayDevice.c +++ b/drivers/video/kyro/STG4000OverlayDevice.c @@ -14,6 +14,7 @@ #include <linux/types.h> #include "STG4000Reg.h" +#include "STG4000Interface.h" /* HW Defines */ diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c index 5eb4d5c177b..bcd359b6d4f 100644 --- a/drivers/video/kyro/fbdev.c +++ b/drivers/video/kyro/fbdev.c @@ -73,8 +73,6 @@ static struct fb_var_screeninfo kyro_var __devinitdata = { .vmode = FB_VMODE_NONINTERLACED, }; -static struct kyrofb_info *currentpar; - typedef struct { STG4000REG __iomem *pSTGReg; /* Virtual address of PCI register region */ u32 ulNextFreeVidMem; /* Offset from start of vid mem to next free region */ @@ -309,7 +307,7 @@ enum { /* Accessors */ static int kyro_dev_video_mode_set(struct fb_info *info) { - struct kyrofb_info *par = (struct kyrofb_info *)info->par; + struct kyrofb_info *par = info->par; /* Turn off display */ StopVTG(deviceInfo.pSTGReg); @@ -402,7 +400,7 @@ static inline unsigned long get_line_length(int x, int bpp) static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct kyrofb_info *par = (struct kyrofb_info *)info->par; + struct kyrofb_info *par = info->par; if (var->bits_per_pixel != 16 && var->bits_per_pixel != 32) { printk(KERN_WARNING "kyrofb: depth not supported: %u\n", var->bits_per_pixel); @@ -478,7 +476,7 @@ static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int kyrofb_set_par(struct fb_info *info) { - struct kyrofb_info *par = (struct kyrofb_info *)info->par; + struct kyrofb_info *par = info->par; unsigned long lineclock; unsigned long frameclock; @@ -536,20 +534,22 @@ static int kyrofb_set_par(struct fb_info *info) static int kyrofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { + struct kyrofb_info *par = info->par; + if (regno > 255) return 1; /* Invalid register */ if (regno < 16) { switch (info->var.bits_per_pixel) { case 16: - ((u16*)(info->pseudo_palette))[regno] = + par->palette[regno] = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); break; case 32: red >>= 8; green >>= 8; blue >>= 8; transp >>= 8; - ((u32*)(info->pseudo_palette))[regno] = + par->palette[regno] = (transp << 24) | (red << 16) | (green << 8) | blue; break; } @@ -675,6 +675,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct fb_info *info; + struct kyrofb_info *currentpar; unsigned long size; int err; @@ -683,14 +684,11 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, return err; } - size = sizeof(struct fb_info) + sizeof(struct kyrofb_info) + 16 * sizeof(u32); - info = kmalloc(size, GFP_KERNEL); + info = framebuffer_alloc(sizeof(struct kyrofb_info), &pdev->dev); if (!info) return -ENOMEM; - memset(info, 0, size); - - currentpar = (struct kyrofb_info *)(info + 1); + currentpar = info->par; kyro_fix.smem_start = pci_resource_start(pdev, 0); kyro_fix.smem_len = pci_resource_len(pdev, 0); @@ -716,8 +714,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, info->fbops = &kyrofb_ops; info->fix = kyro_fix; - info->par = currentpar; - info->pseudo_palette = (void *)(currentpar + 1); + info->pseudo_palette = currentpar->palette; info->flags = FBINFO_DEFAULT; SetCoreClockPLL(deviceInfo.pSTGReg, pdev); @@ -741,7 +738,6 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, fb_memset(info->screen_base, 0, size); - info->device = &pdev->dev; if (register_framebuffer(info) < 0) goto out_unmap; @@ -757,7 +753,7 @@ static int __devinit kyrofb_probe(struct pci_dev *pdev, out_unmap: iounmap(currentpar->regbase); iounmap(info->screen_base); - kfree(info); + framebuffer_release(info); return -EINVAL; } @@ -765,7 +761,7 @@ out_unmap: static void __devexit kyrofb_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); - struct kyrofb_info *par = (struct kyrofb_info *)info->par; + struct kyrofb_info *par = info->par; /* Reset the board */ StopVTG(deviceInfo.pSTGReg); @@ -789,7 +785,7 @@ static void __devexit kyrofb_remove(struct pci_dev *pdev) unregister_framebuffer(info); pci_set_drvdata(pdev, NULL); - kfree(info); + framebuffer_release(info); } static int __init kyrofb_init(void) diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c index cfc748e9427..e6cbd9de944 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/macfb.c @@ -609,18 +609,19 @@ void __init macfb_setup(char *options) } } -void __init macfb_init(void) +static int __init macfb_init(void) { int video_cmap_len, video_is_nubus = 0; struct nubus_dev* ndev = NULL; char *option = NULL; + int err; if (fb_get_options("macfb", &option)) return -ENODEV; macfb_setup(option); if (!MACH_IS_MAC) - return; + return -ENODEV; /* There can only be one internal video controller anyway so we're not too worried about this */ @@ -958,11 +959,11 @@ void __init macfb_init(void) fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0); - if (register_framebuffer(&fb_info) < 0) - return; - - printk("fb%d: %s frame buffer device\n", - fb_info.node, fb_info.fix.id); + err = register_framebuffer(&fb_info); + if (!err) + printk("fb%d: %s frame buffer device\n", + fb_info.node, fb_info.fix.id); + return err; } module_init(macfb_init); diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index a8c47ad2cdb..3a3e1804c56 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -50,8 +50,6 @@ #include <asm/mtrr.h> #endif -#include "../console/fbcon.h" - #if defined(CONFIG_PPC_PMAC) #include <asm/prom.h> #include <asm/pci-bridge.h> @@ -351,8 +349,6 @@ struct matrox_bios { } output; }; -extern struct display fb_display[]; - struct matrox_switch; struct matroxfb_driver; struct matroxfb_dh_fb_info; diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c index 35008af7db7..c122d8743dd 100644 --- a/drivers/video/matrox/matroxfb_g450.c +++ b/drivers/video/matrox/matroxfb_g450.c @@ -20,6 +20,8 @@ #include <asm/uaccess.h> #include <asm/div64.h> +#include "matroxfb_g450.h" + /* Definition of the various controls */ struct mctl { struct v4l2_queryctrl desc; diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c index d9d3e9f6c08..455a46ce840 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/matrox/matroxfb_misc.c @@ -192,11 +192,8 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { unsigned int wd; unsigned int divider; int i; - int fwidth; struct matrox_hw_state * const hw = &ACCESS_FBINFO(hw); - fwidth = 8; - DBG(__FUNCTION__) hw->SEQ[0] = 0x00; @@ -235,10 +232,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) { hw->ATTR[16] = 0x41; hw->ATTR[17] = 0xFF; hw->ATTR[18] = 0x0F; - if (fwidth == 9) - hw->ATTR[19] = 0x08; - else - hw->ATTR[19] = 0x00; + hw->ATTR[19] = 0x00; hw->ATTR[20] = 0x00; hd = m->HDisplay >> 3; diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 8486e77872d..e18c9f98a40 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -485,7 +485,7 @@ static void vgaHWRestore(const struct fb_info *info, */ static inline int neo2200_sync(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int waitcycles; while (readl(&par->neo2200->bltStat) & 1) @@ -525,7 +525,7 @@ static inline void neo2200_wait_fifo(struct fb_info *info, static inline void neo2200_accel_init(struct fb_info *info, struct fb_var_screeninfo *var) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; Neo2200 __iomem *neo2200 = par->neo2200; u32 bltMod, pitch; @@ -560,7 +560,7 @@ static inline void neo2200_accel_init(struct fb_info *info, static int neofb_open(struct fb_info *info, int user) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int cnt = atomic_read(&par->ref_count); if (!cnt) { @@ -575,7 +575,7 @@ neofb_open(struct fb_info *info, int user) static int neofb_release(struct fb_info *info, int user) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int cnt = atomic_read(&par->ref_count); if (!cnt) @@ -590,7 +590,7 @@ neofb_release(struct fb_info *info, int user) static int neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; unsigned int pixclock = var->pixclock; struct xtimings timings; int memlen, vramlen; @@ -757,7 +757,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int neofb_set_par(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; struct xtimings timings; unsigned char temp; int i, clock_hi = 0; @@ -1216,7 +1216,7 @@ static int neofb_set_par(struct fb_info *info) static void neofb_update_start(struct fb_info *info, struct fb_var_screeninfo *var) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; struct vgastate *state = &par->state; int oldExtCRTDispAddr; int Base; @@ -1331,7 +1331,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info) * wms...Enable VESA DPMS compatible powerdown mode * run "setterm -powersave powerdown" to take advantage */ - struct neofb_par *par = (struct neofb_par *)info->par; + struct neofb_par *par = info->par; int seqflags, lcdflags, dpmsflags, reg; switch (blank_mode) { @@ -1404,7 +1404,7 @@ static int neofb_blank(int blank_mode, struct fb_info *info) static void neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; u_long dst, rop; dst = rect->dx + rect->dy * info->var.xres_virtual; @@ -1440,7 +1440,7 @@ static void neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) { u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; u_long src, dst, bltCntl; bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000; @@ -1472,7 +1472,7 @@ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) static void neo2200_imageblit(struct fb_info *info, const struct fb_image *image) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int s_pitch = (image->width * image->depth + 7) >> 3; int scan_align = info->pixmap.scan_align - 1; int buf_align = info->pixmap.buf_align - 1; @@ -1686,7 +1686,7 @@ static struct fb_videomode __devinitdata mode800x480 = { static int __devinit neo_map_mmio(struct fb_info *info, struct pci_dev *dev) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; DBG("neo_map_mmio"); @@ -1733,7 +1733,7 @@ static int __devinit neo_map_mmio(struct fb_info *info, static void neo_unmap_mmio(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; DBG("neo_unmap_mmio"); @@ -1796,7 +1796,7 @@ static void neo_unmap_video(struct fb_info *info) #ifdef CONFIG_MTRR { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; mtrr_del(par->mtrr, info->fix.smem_start, info->fix.smem_len); @@ -1811,7 +1811,7 @@ static void neo_unmap_video(struct fb_info *info) static int __devinit neo_scan_monitor(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; unsigned char type, display; int w; @@ -1890,7 +1890,7 @@ static int __devinit neo_scan_monitor(struct fb_info *info) static int __devinit neo_init_hw(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int videoRam = 896; int maxClock = 65000; int CursorMem = 1024; @@ -2014,7 +2014,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st struct fb_info *info; struct neofb_par *par; - info = framebuffer_alloc(sizeof(struct neofb_par) + sizeof(u32) * 256, &dev->dev); + info = framebuffer_alloc(sizeof(struct neofb_par), &dev->dev); if (!info) return NULL; @@ -2081,7 +2081,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st info->fix.accel = id->driver_data; info->fbops = &neofb_ops; - info->pseudo_palette = (void *) (par + 1); + info->pseudo_palette = par->palette; return info; } diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index b989358437b..99c3a8e6a23 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c @@ -52,6 +52,7 @@ #include <linux/pci.h> #include "nv_type.h" #include "nv_local.h" +#include "nv_proto.h" void NVLockUnlock(struct nvidia_par *par, int Lock) { @@ -848,7 +849,7 @@ void NVCalcStateExt(struct nvidia_par *par, int width, int hDisplaySize, int height, int dotClock, int flags) { - int pixelDepth, VClk; + int pixelDepth, VClk = 0; /* * Save mode parameters. */ @@ -938,15 +939,24 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) if (par->Architecture == NV_ARCH_04) { NV_WR32(par->PFB, 0x0200, state->config); - } else if ((par->Chipset & 0xfff0) == 0x0090) { - for (i = 0; i < 15; i++) { - NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0); - NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1); - } - } else { + } else if ((par->Architecture < NV_ARCH_40) || + (par->Chipset & 0xfff0) == 0x0040) { for (i = 0; i < 8; i++) { NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0); - NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1); + NV_WR32(par->PFB, 0x0244 + (i * 0x10), + par->FbMapSize - 1); + } + } else { + int regions = 12; + + if (((par->Chipset & 0xfff0) == 0x0090) || + ((par->Chipset & 0xfff0) == 0x01D0) || + ((par->Chipset & 0xfff0) == 0x0290)) + regions = 15; + for(i = 0; i < regions; i++) { + NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0); + NV_WR32(par->PFB, 0x0604 + (i * 0x10), + par->FbMapSize - 1); } } @@ -1182,11 +1192,17 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) NV_WR32(par->PGRAPH, 0x0608, 0xFFFFFFFF); } else { if (par->Architecture >= NV_ARCH_40) { + u32 tmp; + NV_WR32(par->PGRAPH, 0x0084, 0x401287c0); NV_WR32(par->PGRAPH, 0x008C, 0x60de8051); NV_WR32(par->PGRAPH, 0x0090, 0x00008000); NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f); + tmp = NV_RD32(par->REGS, 0x1540) & 0xff; + for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++); + NV_WR32(par->PGRAPH, 0x5000, i); + if ((par->Chipset & 0xfff0) == 0x0040) { NV_WR32(par->PGRAPH, 0x09b0, 0x83280fff); @@ -1211,6 +1227,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) 0xffff7fff); break; case 0x00C0: + case 0x0120: NV_WR32(par->PGRAPH, 0x0828, 0x007596ff); NV_WR32(par->PGRAPH, 0x082C, @@ -1245,6 +1262,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) 0x00100000); break; case 0x0090: + case 0x0290: NV_WR32(par->PRAMDAC, 0x0608, NV_RD32(par->PRAMDAC, 0x0608) | 0x00100000); @@ -1310,14 +1328,44 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) } } - if ((par->Chipset & 0xfff0) == 0x0090) { - for (i = 0; i < 60; i++) - NV_WR32(par->PGRAPH, 0x0D00 + i, - NV_RD32(par->PFB, 0x0600 + i)); + if ((par->Architecture < NV_ARCH_40) || + ((par->Chipset & 0xfff0) == 0x0040)) { + for (i = 0; i < 32; i++) { + NV_WR32(par->PGRAPH, 0x0900 + i*4, + NV_RD32(par->PFB, 0x0240 +i*4)); + NV_WR32(par->PGRAPH, 0x6900 + i*4, + NV_RD32(par->PFB, 0x0240 +i*4)); + } } else { - for (i = 0; i < 32; i++) - NV_WR32(par->PGRAPH, 0x0900 + i, - NV_RD32(par->PFB, 0x0240 + i)); + if (((par->Chipset & 0xfff0) == 0x0090) || + ((par->Chipset & 0xfff0) == 0x01D0) || + ((par->Chipset & 0xfff0) == 0x0290)) { + for (i = 0; i < 60; i++) { + NV_WR32(par->PGRAPH, + 0x0D00 + i*4, + NV_RD32(par->PFB, + 0x0600 + i*4)); + NV_WR32(par->PGRAPH, + 0x6900 + i*4, + NV_RD32(par->PFB, + 0x0600 + i*4)); + } + } else { + for (i = 0; i < 48; i++) { + NV_WR32(par->PGRAPH, + 0x0900 + i*4, + NV_RD32(par->PFB, + 0x0600 + i*4)); + if(((par->Chipset & 0xfff0) + != 0x0160) && + ((par->Chipset & 0xfff0) + != 0x0220)) + NV_WR32(par->PGRAPH, + 0x6900 + i*4, + NV_RD32(par->PFB, + 0x0600 + i*4)); + } + } } if (par->Architecture >= NV_ARCH_40) { @@ -1338,7 +1386,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) NV_WR32(par->PGRAPH, 0x0868, par->FbMapSize - 1); } else { - if((par->Chipset & 0xfff0) == 0x0090) { + if ((par->Chipset & 0xfff0) == 0x0090 || + (par->Chipset & 0xfff0) == 0x01D0 || + (par->Chipset & 0xfff0) == 0x0290) { NV_WR32(par->PGRAPH, 0x0DF0, NV_RD32(par->PFB, 0x0200)); NV_WR32(par->PGRAPH, 0x0DF4, diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 12f2884d3f0..bd9eca05e14 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c @@ -46,7 +46,7 @@ static void nvidia_gpio_setscl(void *data, int state) static void nvidia_gpio_setsda(void *data, int state) { - struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; + struct nvidia_i2c_chan *chan = data; struct nvidia_par *par = chan->par; u32 val; @@ -64,7 +64,7 @@ static void nvidia_gpio_setsda(void *data, int state) static int nvidia_gpio_getscl(void *data) { - struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; + struct nvidia_i2c_chan *chan = data; struct nvidia_par *par = chan->par; u32 val = 0; @@ -79,7 +79,7 @@ static int nvidia_gpio_getscl(void *data) static int nvidia_gpio_getsda(void *data) { - struct nvidia_i2c_chan *chan = (struct nvidia_i2c_chan *)data; + struct nvidia_i2c_chan *chan = data; struct nvidia_par *par = chan->par; u32 val = 0; @@ -136,13 +136,13 @@ void nvidia_create_i2c_busses(struct nvidia_par *par) par->chan[2].par = par; par->chan[0].ddc_base = 0x3e; - nvidia_setup_i2c_bus(&par->chan[0], "BUS1"); + nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0"); par->chan[1].ddc_base = 0x36; - nvidia_setup_i2c_bus(&par->chan[1], "BUS2"); + nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1"); par->chan[2].ddc_base = 0x50; - nvidia_setup_i2c_bus(&par->chan[2], "BUS3"); + nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2"); } void nvidia_delete_i2c_busses(struct nvidia_par *par) diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h index 3353103e8b0..b149a690ee0 100644 --- a/drivers/video/nvidia/nv_proto.h +++ b/drivers/video/nvidia/nv_proto.h @@ -4,7 +4,7 @@ #define __NV_PROTO_H__ /* in nv_setup.c */ -void NVCommonSetup(struct fb_info *info); +int NVCommonSetup(struct fb_info *info); void NVWriteCrtc(struct nvidia_par *par, u8 index, u8 value); u8 NVReadCrtc(struct nvidia_par *par, u8 index); void NVWriteGr(struct nvidia_par *par, u8 index, u8 value); diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c index 1f06a9f1bd0..a18a9aebf05 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/nvidia/nv_setup.c @@ -285,28 +285,34 @@ static void nv10GetConfig(struct nvidia_par *par) par->CrystalFreqKHz = 27000; } - par->CursorStart = (par->RamAmountKBytes - 96) * 1024; par->CURSOR = NULL; /* can't set this here */ par->MinVClockFreqKHz = 12000; par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000; } -void NVCommonSetup(struct fb_info *info) +int NVCommonSetup(struct fb_info *info) { struct nvidia_par *par = info->par; - struct fb_var_screeninfo var; + struct fb_var_screeninfo *var; u16 implementation = par->Chipset & 0x0ff0; u8 *edidA = NULL, *edidB = NULL; - struct fb_monspecs monitorA, monitorB; + struct fb_monspecs *monitorA, *monitorB; struct fb_monspecs *monA = NULL, *monB = NULL; int mobile = 0; int tvA = 0; int tvB = 0; int FlatPanel = -1; /* really means the CRTC is slaved */ int Television = 0; + int err = 0; - memset(&monitorA, 0, sizeof(struct fb_monspecs)); - memset(&monitorB, 0, sizeof(struct fb_monspecs)); + var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); + monitorA = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); + monitorB = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); + + if (!var || !monitorA || !monitorB) { + err = -ENOMEM; + goto done; + } par->PRAMIN = par->REGS + (0x00710000 / 4); par->PCRTC0 = par->REGS + (0x00600000 / 4); @@ -382,6 +388,8 @@ void NVCommonSetup(struct fb_info *info) case 0x0146: case 0x0147: case 0x0148: + case 0x0098: + case 0x0099: mobile = 1; break; default: @@ -406,9 +414,9 @@ void NVCommonSetup(struct fb_info *info) par->CRTCnumber = 0; if (nvidia_probe_i2c_connector(info, 1, &edidA)) nvidia_probe_of_connector(info, 1, &edidA); - if (edidA && !fb_parse_edid(edidA, &var)) { + if (edidA && !fb_parse_edid(edidA, var)) { printk("nvidiafb: EDID found from BUS1\n"); - monA = &monitorA; + monA = monitorA; fb_edid_to_monspecs(edidA, monA); FlatPanel = (monA->input & FB_DISP_DDI) ? 1 : 0; @@ -494,17 +502,17 @@ void NVCommonSetup(struct fb_info *info) if (nvidia_probe_i2c_connector(info, 1, &edidA)) nvidia_probe_of_connector(info, 1, &edidA); - if (edidA && !fb_parse_edid(edidA, &var)) { + if (edidA && !fb_parse_edid(edidA, var)) { printk("nvidiafb: EDID found from BUS1\n"); - monA = &monitorA; + monA = monitorA; fb_edid_to_monspecs(edidA, monA); } if (nvidia_probe_i2c_connector(info, 2, &edidB)) nvidia_probe_of_connector(info, 2, &edidB); - if (edidB && !fb_parse_edid(edidB, &var)) { + if (edidB && !fb_parse_edid(edidB, var)) { printk("nvidiafb: EDID found from BUS2\n"); - monB = &monitorB; + monB = monitorB; fb_edid_to_monspecs(edidB, monB); } @@ -639,4 +647,9 @@ void NVCommonSetup(struct fb_info *info) kfree(edidA); kfree(edidB); +done: + kfree(var); + kfree(monitorA); + kfree(monitorB); + return err; } diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index bee09c6e48f..dbcb8962e57 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -284,6 +284,16 @@ static struct pci_device_id nvidiafb_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {PCI_VENDOR_ID_NVIDIA, PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NVIDIA, 0x0252, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_NVIDIA, 0x0313, @@ -418,6 +428,7 @@ static int noaccel __devinitdata = 0; static int noscale __devinitdata = 0; static int paneltweak __devinitdata = 0; static int vram __devinitdata = 0; +static int bpp __devinitdata = 8; #ifdef CONFIG_MTRR static int nomtrr __devinitdata = 0; #endif @@ -485,7 +496,7 @@ static int nvidia_backlight_levels[] = { static int nvidia_set_backlight_enable(int on, int level, void *data) { - struct nvidia_par *par = (struct nvidia_par *)data; + struct nvidia_par *par = data; u32 tmp_pcrt, tmp_pmc, fpcontrol; tmp_pmc = NV_RD32(par->PMC, 0x10F0) & 0x0000FFFF; @@ -1382,24 +1393,36 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) info->monspecs.modedb_len, &info->modelist); fb_var_to_videomode(&modedb, &nvidiafb_default_var); + switch (bpp) { + case 0 ... 8: + bpp = 8; + break; + case 9 ... 16: + bpp = 16; + break; + default: + bpp = 32; + break; + } + if (specs->modedb != NULL) { struct fb_videomode *modedb; modedb = fb_find_best_display(specs, &info->modelist); fb_videomode_to_var(&nvidiafb_default_var, modedb); - nvidiafb_default_var.bits_per_pixel = 8; + nvidiafb_default_var.bits_per_pixel = bpp; } else if (par->fpWidth && par->fpHeight) { char buf[16]; memset(buf, 0, 16); snprintf(buf, 15, "%dx%dMR", par->fpWidth, par->fpHeight); fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, - specs->modedb_len, &modedb, 8); + specs->modedb_len, &modedb, bpp); } if (mode_option) fb_find_mode(&nvidiafb_default_var, info, mode_option, - specs->modedb, specs->modedb_len, &modedb, 8); + specs->modedb, specs->modedb_len, &modedb, bpp); info->var = nvidiafb_default_var; info->fix.visual = (info->var.bits_per_pixel == 8) ? @@ -1448,11 +1471,34 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) return nvidiafb_check_var(&info->var, info); } -static u32 __devinit nvidia_get_arch(struct pci_dev *pd) +static u32 __devinit nvidia_get_chipset(struct fb_info *info) { + struct nvidia_par *par = info->par; + u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device; + + printk("nvidiafb: PCI id - %x\n", id); + if ((id & 0xfff0) == 0x00f0) { + /* pci-e */ + printk("nvidiafb: PCI-E card\n"); + id = NV_RD32(par->REGS, 0x1800); + + if ((id & 0x0000ffff) == 0x000010DE) + id = 0x10DE0000 | (id >> 16); + else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */ + id = 0x10DE0000 | ((id << 8) & 0x0000ff00) | + ((id >> 8) & 0x000000ff); + } + + printk("nvidiafb: Actual id - %x\n", id); + return id; +} + +static u32 __devinit nvidia_get_arch(struct fb_info *info) +{ + struct nvidia_par *par = info->par; u32 arch = 0; - switch (pd->device & 0x0ff0) { + switch (par->Chipset & 0x0ff0) { case 0x0100: /* GeForce 256 */ case 0x0110: /* GeForce2 MX */ case 0x0150: /* GeForce2 */ @@ -1485,6 +1531,8 @@ static u32 __devinit nvidia_get_arch(struct pci_dev *pd) case 0x0210: case 0x0220: case 0x0230: + case 0x0290: + case 0x0390: arch = NV_ARCH_40; break; case 0x0020: /* TNT, TNT2 */ @@ -1513,7 +1561,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, if (!info) goto err_out; - par = (struct nvidia_par *)info->par; + par = info->par; par->pci_dev = pd; info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); @@ -1533,18 +1581,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, goto err_out_request; } - par->Architecture = nvidia_get_arch(pd); - - par->Chipset = (pd->vendor << 16) | pd->device; - printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); - - if (par->Architecture == 0) { - printk(KERN_ERR PFX "unknown NV_ARCH\n"); - goto err_out_free_base0; - } - - sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); - par->FlatPanel = flatpanel; if (flatpanel == 1) printk(KERN_INFO PFX "flatpanel support enabled\n"); @@ -1570,7 +1606,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, goto err_out_free_base0; } - NVCommonSetup(info); + par->Chipset = nvidia_get_chipset(info); + printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset); + par->Architecture = nvidia_get_arch(info); + + if (par->Architecture == 0) { + printk(KERN_ERR PFX "unknown NV_ARCH\n"); + goto err_out_arch; + } + + sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); + + if (NVCommonSetup(info)) + goto err_out_arch; par->FbAddress = nvidiafb_fix.smem_start; par->FbMapSize = par->RamAmountKBytes * 1024; @@ -1581,10 +1629,15 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, if (par->FbMapSize > 64 * 1024 * 1024) par->FbMapSize = 64 * 1024 * 1024; - par->FbUsableSize = par->FbMapSize - (128 * 1024); + if(par->Architecture >= NV_ARCH_40) + par->FbUsableSize = par->FbMapSize - (560 * 1024); + else + par->FbUsableSize = par->FbMapSize - (128 * 1024); par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 : 16 * 1024; par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize; + par->CursorStart = par->FbUsableSize + (32 * 1024); + info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize); info->screen_size = par->FbUsableSize; nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024; @@ -1640,21 +1693,22 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, NVTRACE_LEAVE(); return 0; - err_out_iounmap_fb: +err_out_iounmap_fb: iounmap(info->screen_base); - err_out_free_base1: +err_out_free_base1: fb_destroy_modedb(info->monspecs.modedb); nvidia_delete_i2c_busses(par); +err_out_arch: iounmap(par->REGS); - err_out_free_base0: +err_out_free_base0: pci_release_regions(pd); - err_out_request: +err_out_request: pci_disable_device(pd); - err_out_enable: +err_out_enable: kfree(info->pixmap.addr); - err_out_kfree: +err_out_kfree: framebuffer_release(info); - err_out: +err_out: return -ENODEV; } @@ -1729,6 +1783,8 @@ static int __devinit nvidiafb_setup(char *options) #endif } else if (!strncmp(this_opt, "fpdither:", 9)) { fpdither = simple_strtol(this_opt+9, NULL, 0); + } else if (!strncmp(this_opt, "bpp:", 4)) { + bpp = simple_strtoul(this_opt+4, NULL, 0); } else mode_option = this_opt; } @@ -1804,6 +1860,11 @@ module_param(vram, int, 0); MODULE_PARM_DESC(vram, "amount of framebuffer memory to remap in MiB" "(default=0 - remap entire memory)"); +module_param(mode_option, charp, 0); +MODULE_PARM_DESC(mode_option, "Specify initial video mode"); +module_param(bpp, int, 0); +MODULE_PARM_DESC(bpp, "pixel width in bits" + "(default=8)"); #ifdef CONFIG_MTRR module_param(nomtrr, bool, 0); MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 0277ce031e5..5fe197943de 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -91,6 +91,7 @@ struct pm2fb_par u32 mem_config; /* MemConfig reg at probe */ u32 mem_control; /* MemControl reg at probe */ u32 boot_address; /* BootAddress reg at probe */ + u32 palette[16]; }; /* @@ -674,7 +675,7 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) */ static int pm2fb_set_par(struct fb_info *info) { - struct pm2fb_par *par = (struct pm2fb_par *) info->par; + struct pm2fb_par *par = info->par; u32 pixclock; u32 width, height, depth; u32 hsstart, hsend, hbend, htotal; @@ -854,7 +855,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct pm2fb_par *par = (struct pm2fb_par *) info->par; + struct pm2fb_par *par = info->par; if (regno >= info->cmap.len) /* no. of hw registers */ return 1; @@ -929,7 +930,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green, case 16: case 24: case 32: - ((u32*)(info->pseudo_palette))[regno] = v; + par->palette[regno] = v; break; } return 0; @@ -955,7 +956,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green, static int pm2fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct pm2fb_par *p = (struct pm2fb_par *) info->par; + struct pm2fb_par *p = info->par; u32 base; u32 depth; u32 xres; @@ -987,7 +988,7 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var, */ static int pm2fb_blank(int blank_mode, struct fb_info *info) { - struct pm2fb_par *par = (struct pm2fb_par *) info->par; + struct pm2fb_par *par = info->par; u32 video = par->video; DPRINTK("blank_mode %d\n", blank_mode); @@ -1054,8 +1055,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, { struct pm2fb_par *default_par; struct fb_info *info; - int size, err; - int err_retval = -ENXIO; + int err, err_retval = -ENXIO; err = pci_enable_device(pdev); if ( err ) { @@ -1063,11 +1063,10 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, return err; } - size = sizeof(struct pm2fb_par) + 256 * sizeof(u32); - info = framebuffer_alloc(size, &pdev->dev); + info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev); if ( !info ) return -ENOMEM; - default_par = (struct pm2fb_par *) info->par; + default_par = info->par; switch (pdev->device) { case PCI_DEVICE_ID_TI_TVP4020: @@ -1171,7 +1170,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev, info->fbops = &pm2fb_ops; info->fix = pm2fb_fix; - info->pseudo_palette = (void *)(default_par + 1); + info->pseudo_palette = default_par->palette; info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 3e9f96e9237..6c19ab6afb0 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -630,7 +630,7 @@ static void riva_load_video_mode(struct fb_info *info) int bpp, width, hDisplaySize, hDisplay, hStart, hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock; int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd; - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; struct riva_regs newmode; NVTRACE_ENTER(); @@ -925,7 +925,7 @@ riva_set_rop_solid(struct riva_par *par, int rop) static void riva_setup_accel(struct fb_info *info) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; RIVA_FIFO_FREE(par->riva, Clip, 2); NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0); @@ -979,7 +979,7 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var) #ifdef CONFIG_PMAC_BACKLIGHT static int riva_set_backlight_enable(int on, int level, void *data) { - struct riva_par *par = (struct riva_par *)data; + struct riva_par *par = data; U032 tmp_pcrt, tmp_pmc; tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; @@ -1008,7 +1008,7 @@ static int riva_set_backlight_level(int level, void *data) static int rivafb_open(struct fb_info *info, int user) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; int cnt = atomic_read(&par->ref_count); NVTRACE_ENTER(); @@ -1034,7 +1034,7 @@ static int rivafb_open(struct fb_info *info, int user) static int rivafb_release(struct fb_info *info, int user) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; int cnt = atomic_read(&par->ref_count); NVTRACE_ENTER(); @@ -1057,7 +1057,7 @@ static int rivafb_release(struct fb_info *info, int user) static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct fb_videomode *mode; - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; int nom, den; /* translating from pixels->bytes */ int mode_valid = 0; @@ -1166,7 +1166,7 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int rivafb_set_par(struct fb_info *info) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; NVTRACE_ENTER(); /* vgaHWunlock() + riva unlock (0x7F) */ @@ -1205,43 +1205,19 @@ static int rivafb_set_par(struct fb_info *info) static int rivafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct riva_par *par = (struct riva_par *)info->par; + struct riva_par *par = info->par; unsigned int base; NVTRACE_ENTER(); - if (var->xoffset > (var->xres_virtual - var->xres)) - return -EINVAL; - if (var->yoffset > (var->yres_virtual - var->yres)) - return -EINVAL; - - if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset < 0 - || var->yoffset >= info->var.yres_virtual - || var->xoffset) return -EINVAL; - } else { - if (var->xoffset + info->var.xres > info->var.xres_virtual || - var->yoffset + info->var.yres > info->var.yres_virtual) - return -EINVAL; - } - base = var->yoffset * info->fix.line_length + var->xoffset; - par->riva.SetStartAddress(&par->riva, base); - - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - - if (var->vmode & FB_VMODE_YWRAP) - info->var.vmode |= FB_VMODE_YWRAP; - else - info->var.vmode &= ~FB_VMODE_YWRAP; NVTRACE_LEAVE(); return 0; } static int rivafb_blank(int blank, struct fb_info *info) { - struct riva_par *par= (struct riva_par *)info->par; + struct riva_par *par= info->par; unsigned char tmp, vesa; tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */ @@ -1304,7 +1280,7 @@ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { - struct riva_par *par = (struct riva_par *)info->par; + struct riva_par *par = info->par; RIVA_HW_INST *chip = &par->riva; int i; @@ -1393,7 +1369,7 @@ static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green, */ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; u_int color, rop = 0; if ((info->flags & FBINFO_HWACCEL_DISABLED)) { @@ -1449,7 +1425,7 @@ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect */ static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; if ((info->flags & FBINFO_HWACCEL_DISABLED)) { cfb_copyarea(info, region); @@ -1495,7 +1471,7 @@ static inline void convert_bgcolor_16(u32 *col) static void rivafb_imageblit(struct fb_info *info, const struct fb_image *image) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; u32 fgx = 0, bgx = 0, width, tmp; u8 *cdat = (u8 *) image->data; volatile u32 __iomem *d; @@ -1580,7 +1556,7 @@ static void rivafb_imageblit(struct fb_info *info, */ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; u8 data[MAX_CURS * MAX_CURS/8]; int i, set = cursor->set; u16 fg, bg; @@ -1664,7 +1640,7 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) static int rivafb_sync(struct fb_info *info) { - struct riva_par *par = (struct riva_par *)info->par; + struct riva_par *par = info->par; wait_for_idle(par); return 0; @@ -1696,7 +1672,7 @@ static struct fb_ops riva_fb_ops = { static int __devinit riva_set_fbinfo(struct fb_info *info) { unsigned int cmap_len; - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; NVTRACE_ENTER(); info->flags = FBINFO_DEFAULT @@ -1733,7 +1709,7 @@ static int __devinit riva_set_fbinfo(struct fb_info *info) #ifdef CONFIG_PPC_OF static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; struct device_node *dp; unsigned char *pedid = NULL; unsigned char *disptype = NULL; @@ -1767,7 +1743,7 @@ static int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd) #if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF) static int __devinit riva_get_EDID_i2c(struct fb_info *info) { - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; struct fb_var_screeninfo var; int i; @@ -1837,7 +1813,7 @@ static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev) static void __devinit riva_get_edidinfo(struct fb_info *info) { struct fb_var_screeninfo *var = &rivafb_default_var; - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; fb_edid_to_monspecs(par->EDID, &info->monspecs); fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len, @@ -1909,7 +1885,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd, ret = -ENOMEM; goto err_ret; } - default_par = (struct riva_par *) info->par; + default_par = info->par; default_par->pdev = pd; info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL); @@ -2070,7 +2046,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd, err_iounmap_screen_base: #ifdef CONFIG_FB_RIVA_I2C - riva_delete_i2c_busses((struct riva_par *) info->par); + riva_delete_i2c_busses(info->par); #endif iounmap(info->screen_base); err_iounmap_pramin: @@ -2093,7 +2069,7 @@ err_ret: static void __exit rivafb_remove(struct pci_dev *pd) { struct fb_info *info = pci_get_drvdata(pd); - struct riva_par *par = (struct riva_par *) info->par; + struct riva_par *par = info->par; NVTRACE_ENTER(); if (!info) diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index 77151d8e076..8b1967fc116 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c @@ -30,7 +30,7 @@ static void riva_gpio_setscl(void* data, int state) { - struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; + struct riva_i2c_chan *chan = data; struct riva_par *par = chan->par; u32 val; @@ -48,7 +48,7 @@ static void riva_gpio_setscl(void* data, int state) static void riva_gpio_setsda(void* data, int state) { - struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; + struct riva_i2c_chan *chan = data; struct riva_par *par = chan->par; u32 val; @@ -66,7 +66,7 @@ static void riva_gpio_setsda(void* data, int state) static int riva_gpio_getscl(void* data) { - struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; + struct riva_i2c_chan *chan = data; struct riva_par *par = chan->par; u32 val = 0; @@ -81,7 +81,7 @@ static int riva_gpio_getscl(void* data) static int riva_gpio_getsda(void* data) { - struct riva_i2c_chan *chan = (struct riva_i2c_chan *)data; + struct riva_i2c_chan *chan = data; struct riva_par *par = chan->par; u32 val = 0; diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index fe99d17a21d..d574dd3c9c8 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -552,7 +552,7 @@ static inline void modify_gpio(void __iomem *reg, * s3c2410fb_init_registers - Initialise all LCD-related registers */ -int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) +static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) { unsigned long flags; @@ -634,7 +634,7 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id, struct pt_regs *r) static char driver_name[]="s3c2410fb"; -int __init s3c2410fb_probe(struct platform_device *pdev) +static int __init s3c2410fb_probe(struct platform_device *pdev) { struct s3c2410fb_info *info; struct fb_info *fbinfo; @@ -667,8 +667,6 @@ int __init s3c2410fb_probe(struct platform_device *pdev) info->fb = fbinfo; platform_set_drvdata(pdev, fbinfo); - s3c2410fb_init_registers(info); - dprintk("devinit\n"); strcpy(fbinfo->fix.id, driver_name); @@ -701,8 +699,8 @@ int __init s3c2410fb_probe(struct platform_device *pdev) fbinfo->var.yres_virtual = mach_info->yres.defval; fbinfo->var.bits_per_pixel = mach_info->bpp.defval; - fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) +1; - fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) +1; + fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1; + fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1; fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1; fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1; diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index 3c98457783c..00719a91479 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c @@ -49,7 +49,7 @@ static void savage4_gpio_setscl(void *data, int val) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; unsigned int r; r = readl(chan->ioaddr + chan->reg); @@ -63,7 +63,7 @@ static void savage4_gpio_setscl(void *data, int val) static void savage4_gpio_setsda(void *data, int val) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; unsigned int r; r = readl(chan->ioaddr + chan->reg); @@ -77,21 +77,21 @@ static void savage4_gpio_setsda(void *data, int val) static int savage4_gpio_getscl(void *data) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SCL_IN)); } static int savage4_gpio_getsda(void *data) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; return (0 != (readl(chan->ioaddr + chan->reg) & SAVAGE4_I2C_SDA_IN)); } static void prosavage_gpio_setscl(void* data, int val) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; u32 r; SET_CR_IX(chan->ioaddr, chan->reg); @@ -107,7 +107,7 @@ static void prosavage_gpio_setscl(void* data, int val) static void prosavage_gpio_setsda(void* data, int val) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; unsigned int r; SET_CR_IX(chan->ioaddr, chan->reg); @@ -123,7 +123,7 @@ static void prosavage_gpio_setsda(void* data, int val) static int prosavage_gpio_getscl(void* data) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; SET_CR_IX(chan->ioaddr, chan->reg); return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN)); @@ -131,7 +131,7 @@ static int prosavage_gpio_getscl(void* data) static int prosavage_gpio_getsda(void* data) { - struct savagefb_i2c_chan *chan = (struct savagefb_i2c_chan *)data; + struct savagefb_i2c_chan *chan = data; SET_CR_IX(chan->ioaddr, chan->reg); return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN)); @@ -140,10 +140,9 @@ static int prosavage_gpio_getsda(void* data) static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, const char *name) { - int (*add_bus)(struct i2c_adapter *) = symbol_get(i2c_bit_add_bus); int rc = 0; - if (add_bus && chan->par) { + if (chan->par) { strcpy(chan->adapter.name, name); chan->adapter.owner = THIS_MODULE; chan->adapter.id = I2C_HW_B_SAVAGE; @@ -161,7 +160,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, chan->algo.setscl(chan, 1); udelay(20); - rc = add_bus(&chan->adapter); + rc = i2c_bit_add_bus(&chan->adapter); if (rc == 0) dev_dbg(&chan->par->pcidev->dev, @@ -169,8 +168,6 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, else dev_warn(&chan->par->pcidev->dev, "Failed to register I2C bus %s.\n", name); - - symbol_put(i2c_bit_add_bus); } else chan->par = NULL; @@ -179,7 +176,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, void savagefb_create_i2c_busses(struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; par->chan.par = par; switch(info->fix.accel) { @@ -193,6 +190,7 @@ void savagefb_create_i2c_busses(struct fb_info *info) par->chan.algo.getscl = prosavage_gpio_getscl; break; case FB_ACCEL_SAVAGE4: + case FB_ACCEL_SAVAGE2000: par->chan.reg = 0xff20; par->chan.ioaddr = par->mmio.vbase; par->chan.algo.setsda = savage4_gpio_setsda; @@ -209,14 +207,10 @@ void savagefb_create_i2c_busses(struct fb_info *info) void savagefb_delete_i2c_busses(struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; - int (*del_bus)(struct i2c_adapter *) = - symbol_get(i2c_bit_del_bus); + struct savagefb_par *par = info->par; - if (del_bus && par->chan.par) { - del_bus(&par->chan.adapter); - symbol_put(i2c_bit_del_bus); - } + if (par->chan.par) + i2c_bit_del_bus(&par->chan.adapter); par->chan.par = NULL; } @@ -224,8 +218,6 @@ void savagefb_delete_i2c_busses(struct fb_info *info) static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan) { u8 start = 0x0; - int (*transfer)(struct i2c_adapter *, struct i2c_msg *, int) = - symbol_get(i2c_transfer); struct i2c_msg msgs[] = { { .addr = SAVAGE_DDC, @@ -239,21 +231,19 @@ static u8 *savage_do_probe_i2c_edid(struct savagefb_i2c_chan *chan) }; u8 *buf = NULL; - if (transfer && chan->par) { + if (chan->par) { buf = kmalloc(EDID_LENGTH, GFP_KERNEL); if (buf) { msgs[1].buf = buf; - if (transfer(&chan->adapter, msgs, 2) != 2) { + if (i2c_transfer(&chan->adapter, msgs, 2) != 2) { dev_dbg(&chan->par->pcidev->dev, "Unable to read EDID block.\n"); kfree(buf); buf = NULL; } } - - symbol_put(i2c_transfer); } return buf; diff --git a/drivers/video/savage/savagefb_accel.c b/drivers/video/savage/savagefb_accel.c index bac8ea3a010..bbcc055d3bb 100644 --- a/drivers/video/savage/savagefb_accel.c +++ b/drivers/video/savage/savagefb_accel.c @@ -21,7 +21,7 @@ static u32 savagefb_rop[] = { int savagefb_sync(struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; par->SavageWaitIdle(par); return 0; @@ -29,7 +29,7 @@ int savagefb_sync(struct fb_info *info) void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; int sx = region->sx, dx = region->dx; int sy = region->sy, dy = region->dy; int cmd; @@ -63,7 +63,7 @@ void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region) void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; int cmd, color; if (!rect->width || !rect->height) @@ -90,7 +90,7 @@ void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) void savagefb_imageblit(struct fb_info *info, const struct fb_image *image) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; int fg, bg, size, i, width; int cmd; u32 *src = (u32 *) image->data; diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 09e2f284190..ab727eaa7f4 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -686,7 +686,7 @@ static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode static int savagefb_check_var (struct fb_var_screeninfo *var, struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; int memlen, vramlen, mode_valid = 0; DBG("savagefb_check_var"); @@ -1025,7 +1025,7 @@ static int savagefb_setcolreg(unsigned regno, unsigned transp, struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; if (regno >= NR_PALETTE) return -EINVAL; @@ -1328,7 +1328,7 @@ static void savagefb_set_fix(struct fb_info *info) #if defined(CONFIG_FB_SAVAGE_ACCEL) static void savagefb_set_clip(struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; int cmd; cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; @@ -1342,7 +1342,7 @@ static void savagefb_set_clip(struct fb_info *info) static int savagefb_set_par (struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; struct fb_var_screeninfo *var = &info->var; int err; @@ -1381,29 +1381,9 @@ static int savagefb_set_par (struct fb_info *info) static int savagefb_pan_display (struct fb_var_screeninfo *var, struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; - u_int y_bottom; - - y_bottom = var->yoffset; - - if (!(var->vmode & FB_VMODE_YWRAP)) - y_bottom += var->yres; - - if (var->xoffset > (var->xres_virtual - var->xres)) - return -EINVAL; - if (y_bottom > info->var.yres_virtual) - return -EINVAL; + struct savagefb_par *par = info->par; savagefb_update_start (par, var); - - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - - if (var->vmode & FB_VMODE_YWRAP) - info->var.vmode |= FB_VMODE_YWRAP; - else - info->var.vmode &= ~FB_VMODE_YWRAP; - return 0; } @@ -1534,7 +1514,7 @@ static void savage_disable_mmio (struct savagefb_par *par) static int __devinit savage_map_mmio (struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; DBG ("savage_map_mmio"); if (S3_SAVAGE3D_SERIES (par->chip)) @@ -1567,7 +1547,7 @@ static int __devinit savage_map_mmio (struct fb_info *info) static void __devinit savage_unmap_mmio (struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; DBG ("savage_unmap_mmio"); savage_disable_mmio(par); @@ -1581,7 +1561,7 @@ static void __devinit savage_unmap_mmio (struct fb_info *info) static int __devinit savage_map_video (struct fb_info *info, int video_len) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; int resource; DBG("savage_map_video"); @@ -1619,7 +1599,7 @@ static int __devinit savage_map_video (struct fb_info *info, static void __devinit savage_unmap_video (struct fb_info *info) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; DBG("savage_unmap_video"); @@ -1869,7 +1849,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info, struct pci_dev *dev, const struct pci_device_id *id) { - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct savagefb_par *par = info->par; int err = 0; par->pcidev = dev; @@ -2139,8 +2119,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev, static void __devexit savagefb_remove (struct pci_dev *dev) { - struct fb_info *info = - (struct fb_info *)pci_get_drvdata(dev); + struct fb_info *info = pci_get_drvdata(dev); DBG("savagefb_remove"); @@ -2174,9 +2153,8 @@ static void __devexit savagefb_remove (struct pci_dev *dev) static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) { - struct fb_info *info = - (struct fb_info *)pci_get_drvdata(dev); - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct fb_info *info = pci_get_drvdata(dev); + struct savagefb_par *par = info->par; DBG("savagefb_suspend"); @@ -2210,9 +2188,8 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) static int savagefb_resume (struct pci_dev* dev) { - struct fb_info *info = - (struct fb_info *)pci_get_drvdata(dev); - struct savagefb_par *par = (struct savagefb_par *)info->par; + struct fb_info *info = pci_get_drvdata(dev); + struct savagefb_par *par = info->par; int cur_state = par->pm_state; DBG("savage_resume"); diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index a01e7ecc15e..9b707771d75 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c @@ -115,7 +115,8 @@ static struct fb_fix_screeninfo xxxfb_fix __initdata = { /* * If your driver supports multiple boards or it supports multiple * framebuffers, you should make these arrays, or allocate them - * dynamically (using kmalloc()). + * dynamically using framebuffer_alloc() and free them with + * framebuffer_release(). */ static struct fb_info info; @@ -179,18 +180,31 @@ static int xxxfb_release(const struct fb_info *info, int user) * intent to only test a mode and not actually set it. The stuff in * modedb.c is a example of this. If the var passed in is slightly * off by what the hardware can support then we alter the var PASSED in - * to what we can do. If the hardware doesn't support mode change - * a -EINVAL will be returned by the upper layers. You don't need to - * implement this function then. If you hardware doesn't support - * changing the resolution then this function is not needed. In this - * case the driver woudl just provide a var that represents the static - * state the screen is in. + * to what we can do. + * + * For values that are off, this function must round them _up_ to the + * next value that is supported by the hardware. If the value is + * greater than the highest value supported by the hardware, then this + * function must return -EINVAL. + * + * Exception to the above rule: Some drivers have a fixed mode, ie, + * the hardware is already set at boot up, and cannot be changed. In + * this case, it is more acceptable that this function just return + * a copy of the currently working var (info->var). Better is to not + * implement this function, as the upper layer will do the copying + * of the current var for you. + * + * Note: This is the only function where the contents of var can be + * freely adjusted after the driver has been registered. If you find + * that you have code outside of this function that alters the content + * of var, then you are doing something wrong. Note also that the + * contents of info->var must be left untouched at all times after + * driver registration. * * Returns negative errno on error, or zero on success. */ static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - const struct xxx_par *par = (const struct xxx_par *) info->par; /* ... */ return 0; } @@ -204,14 +218,39 @@ static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in * fb_info since we are using that data. This means we depend on the * data in var inside fb_info to be supported by the hardware. - * xxxfb_check_var is always called before xxxfb_set_par to ensure this. + * + * This function is also used to recover/restore the hardware to a + * known working state. + * + * xxxfb_check_var is always called before xxxfb_set_par to ensure that + * the contents of var is always valid. + * * Again if you can't change the resolution you don't need this function. * + * However, even if your hardware does not support mode changing, + * a set_par might be needed to at least initialize the hardware to + * a known working state, especially if it came back from another + * process that also modifies the same hardware, such as X. + * + * If this is the case, a combination such as the following should work: + * + * static int xxxfb_check_var(struct fb_var_screeninfo *var, + * struct fb_info *info) + * { + * *var = info->var; + * return 0; + * } + * + * static int xxxfb_set_par(struct fb_info *info) + * { + * init your hardware here + * } + * * Returns negative errno on error, or zero on success. */ static int xxxfb_set_par(struct fb_info *info) { - struct xxx_par *par = (struct xxx_par *) info->par; + struct xxx_par *par = info->par; /* ... */ return 0; } @@ -258,70 +297,110 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, * var->{color}.offset contains start of bitfield * var->{color}.length contains length of bitfield * {hardwarespecific} contains width of DAC - * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) + * pseudo_palette[X] is programmed to (X << red.offset) | + * (X << green.offset) | + * (X << blue.offset) * RAMDAC[X] is programmed to (red, green, blue) + * color depth = SUM(var->{color}.length) * * Pseudocolor: - * uses offset = 0 && length = DAC register width. * var->{color}.offset is 0 - * var->{color}.length contains widht of DAC - * cmap is not used - * DAC[X] is programmed to (red, green, blue) + * var->{color}.length contains width of DAC or the number of unique + * colors available (color depth) + * pseudo_palette is not used + * RAMDAC[X] is programmed to (red, green, blue) + * color depth = var->{color}.length + * + * Static pseudocolor: + * same as Pseudocolor, but the RAMDAC is not programmed (read-only) + * + * Mono01/Mono10: + * Has only 2 values, black on white or white on black (fg on bg), + * var->{color}.offset is 0 + * white = (1 << var->{color}.length) - 1, black = 0 + * pseudo_palette is not used + * RAMDAC does not exist + * color depth is always 2 + * * Truecolor: * does not use RAMDAC (usually has 3 of them). * var->{color}.offset contains start of bitfield * var->{color}.length contains length of bitfield - * cmap is programmed to (red << red.offset) | (green << green.offset) | - * (blue << blue.offset) | (transp << transp.offset) + * pseudo_palette is programmed to (red << red.offset) | + * (green << green.offset) | + * (blue << blue.offset) | + * (transp << transp.offset) * RAMDAC does not exist + * color depth = SUM(var->{color}.length}) + * + * The color depth is used by fbcon for choosing the logo and also + * for color palette transformation if color depth < 4 + * + * As can be seen from the above, the field bits_per_pixel is _NOT_ + * a criteria for describing the color visual. + * + * A common mistake is assuming that bits_per_pixel <= 8 is pseudocolor, + * and higher than that, true/directcolor. This is incorrect, one needs + * to look at the fix->visual. + * + * Another common mistake is using bits_per_pixel to calculate the color + * depth. The bits_per_pixel field does not directly translate to color + * depth. You have to compute for the color depth (using the color + * bitfields) and fix->visual as seen above. + */ + + /* + * This is the point where the color is converted to something that + * is acceptable by the hardware. */ #define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) - switch (info->fix.visual) { - case FB_VISUAL_TRUECOLOR: - case FB_VISUAL_PSEUDOCOLOR: - red = CNVT_TOHW(red, info->var.red.length); - green = CNVT_TOHW(green, info->var.green.length); - blue = CNVT_TOHW(blue, info->var.blue.length); - transp = CNVT_TOHW(transp, info->var.transp.length); - break; - case FB_VISUAL_DIRECTCOLOR: - /* example here assumes 8 bit DAC. Might be different - * for your hardware */ - red = CNVT_TOHW(red, 8); - green = CNVT_TOHW(green, 8); - blue = CNVT_TOHW(blue, 8); - /* hey, there is bug in transp handling... */ - transp = CNVT_TOHW(transp, 8); - break; - } + red = CNVT_TOHW(red, info->var.red.length); + green = CNVT_TOHW(green, info->var.green.length); + blue = CNVT_TOHW(blue, info->var.blue.length); + transp = CNVT_TOHW(transp, info->var.transp.length); #undef CNVT_TOHW - /* Truecolor has hardware independent palette */ - if (info->fix.visual == FB_VISUAL_TRUECOLOR) { - u32 v; - - if (regno >= 16) - return -EINVAL; - - v = (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset) | - (transp << info->var.transp.offset); - - switch (info->var.bits_per_pixel) { - case 8: - /* Yes some hand held devices have this. */ - ((u8*)(info->pseudo_palette))[regno] = v; - break; - case 16: - ((u16*)(info->pseudo_palette))[regno] = v; - break; - case 24: - case 32: - ((u32*)(info->pseudo_palette))[regno] = v; - break; - } - return 0; + /* + * This is the point where the function feeds the color to the hardware + * palette after converting the colors to something acceptable by + * the hardware. Note, only FB_VISUAL_DIRECTCOLOR and + * FB_VISUAL_PSEUDOCOLOR visuals need to write to the hardware palette. + * If you have code that writes to the hardware CLUT, and it's not + * any of the above visuals, then you are doing something wrong. + */ + if (info->fix.visual == FB_VISUAL_DIRECTCOLOR || + info->fix.visual == FB_VISUAL_TRUECOLOR) + write_{red|green|blue|transp}_to_clut(); + + /* This is the point were you need to fill up the contents of + * info->pseudo_palette. This structure is used _only_ by fbcon, thus + * it only contains 16 entries to match the number of colors supported + * by the console. The pseudo_palette is used only if the visual is + * in directcolor or truecolor mode. With other visuals, the + * pseudo_palette is not used. (This might change in the future.) + * + * The contents of the pseudo_palette is in raw pixel format. Ie, each + * entry can be written directly to the framebuffer without any conversion. + * The pseudo_palette is (void *). However, if using the generic + * drawing functions (cfb_imageblit, cfb_fillrect), the pseudo_palette + * must be casted to (u32 *) _regardless_ of the bits per pixel. If the + * driver is using its own drawing functions, then it can use whatever + * size it wants. + */ + if (info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) { + u32 v; + + if (regno >= 16) + return -EINVAL; + + v = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); + + ((u32*)(info->pseudo_palette))[regno] = v; } + /* ... */ return 0; } @@ -340,6 +419,17 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, static int xxxfb_pan_display(struct fb_var_screeninfo *var, const struct fb_info *info) { + /* + * If your hardware does not support panning, _do_ _not_ implement this + * function. Creating a dummy function will just confuse user apps. + */ + + /* + * Note that even if this function is fully functional, a setting of + * 0 in both xpanstep and ypanstep means that this function will never + * get called. + */ + /* ... */ return 0; } @@ -349,15 +439,20 @@ static int xxxfb_pan_display(struct fb_var_screeninfo *var, * @blank_mode: the blank mode we want. * @info: frame buffer structure that represents a single frame buffer * - * Blank the screen if blank_mode != 0, else unblank. Return 0 if - * blanking succeeded, != 0 if un-/blanking failed due to e.g. a - * video mode which doesn't support it. Implements VESA suspend - * and powerdown modes on hardware that supports disabling hsync/vsync: - * blank_mode == 2: suspend vsync - * blank_mode == 3: suspend hsync - * blank_mode == 4: powerdown + * Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank. + * Return 0 if blanking succeeded, != 0 if un-/blanking failed due to + * e.g. a video mode which doesn't support it. * - * Returns negative errno on error, or zero on success. + * Implements VESA suspend and powerdown modes on hardware that supports + * disabling hsync/vsync: + * + * FB_BLANK_NORMAL = display is blanked, syncs are on. + * FB_BLANK_HSYNC_SUSPEND = hsync off + * FB_BLANK_VSYNC_SUSPEND = vsync off + * FB_BLANK_POWERDOWN = hsync and vsync off + * + * If implementing this function, at least support FB_BLANK_UNBLANK. + * Return !0 for any modes that are unimplemented. * */ static int xxxfb_blank(int blank_mode, const struct fb_info *info) @@ -454,6 +549,14 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) * @data: The actual data used to construct the image on the display. * @cmap: The colormap used for color images. */ + +/* + * The generic function, cfb_imageblit, expects that the bitmap scanlines are + * padded to the next byte. Most hardware accelerators may require padding to + * the next u16 or the next u32. If that is the case, the driver can specify + * this by setting info->pixmap.scan_align = 2 or 4. See a more + * comprehensive description of the pixmap below. + */ } /** @@ -517,6 +620,7 @@ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) */ void xxxfb_rotate(struct fb_info *info, int angle) { +/* Will be deprecated */ } /** @@ -540,6 +644,9 @@ void xxxfb_poll(struct fb_info *info, poll_table *wait) * so we can have consistent display output. * * @info: frame buffer structure that represents a single frame buffer + * + * If the driver has implemented its own hardware-based drawing function, + * implementing this function is highly recommended. */ void xxxfb_sync(struct fb_info *info) { @@ -549,20 +656,25 @@ void xxxfb_sync(struct fb_info *info) * Initialization */ -int __init xxxfb_init(void) +/* static int __init xxfb_probe (struct device *device) -- for platform devs */ +static int __init xxxfb_probe(struct pci_dev *dev, + const_struct pci_device_id *ent) { + struct fb_info *info; + struct xxx_par *par; + struct device = &dev->dev; /* for pci drivers */ int cmap_len, retval; /* - * For kernel boot options (in 'video=xxxfb:<options>' format) + * Dynamically allocate info and par */ -#ifndef MODULE - char *option = NULL; + info = framebuffer_alloc(sizeof(struct xxx_par), device); - if (fb_get_options("xxxfb", &option)) - return -ENODEV; - xxxfb_setup(option); -#endif + if (!info) { + /* goto error path */ + } + + par = info->par; /* * Here we set the screen_base to the virtual memory address @@ -570,18 +682,87 @@ int __init xxxfb_init(void) * from the bus layer and then translate it to virtual memory * space via ioremap. Consult ioport.h. */ - info.screen_base = framebuffer_virtual_memory; - info.fbops = &xxxfb_ops; - info.fix = xxxfb_fix; - info.pseudo_palette = pseudo_palette; - + info->screen_base = framebuffer_virtual_memory; + info->fbops = &xxxfb_ops; + info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be + * used, so mark it as __initdata + */ + info->pseudo_palette = pseudo_palette; /* The pseudopalette is an + * 16-member array + */ /* * Set up flags to indicate what sort of acceleration your * driver can provide (pan/wrap/copyarea/etc.) and whether it * is a module -- see FBINFO_* in include/linux/fb.h + * + * If your hardware can support any of the hardware accelerated functions + * fbcon performance will improve if info->flags is set properly. + * + * FBINFO_HWACCEL_COPYAREA - hardware moves + * FBINFO_HWACCEL_FILLRECT - hardware fills + * FBINFO_HWACCEL_IMAGEBLIT - hardware mono->color expansion + * FBINFO_HWACCEL_YPAN - hardware can pan display in y-axis + * FBINFO_HWACCEL_YWRAP - hardware can wrap display in y-axis + * FBINFO_HWACCEL_DISABLED - supports hardware accels, but disabled + * FBINFO_READS_FAST - if set, prefer moves over mono->color expansion + * FBINFO_MISC_TILEBLITTING - hardware can do tile blits + * + * NOTE: These are for fbcon use only. + */ + info->flags = FBINFO_DEFAULT; + +/********************* This stage is optional ******************************/ + /* + * The struct pixmap is a scratch pad for the drawing functions. This + * is where the monochrome bitmap is constructed by the higher layers + * and then passed to the accelerator. For drivers that uses + * cfb_imageblit, you can skip this part. For those that have a more + * rigorous requirement, this stage is needed + */ + + /* PIXMAP_SIZE should be small enough to optimize drawing, but not + * large enough that memory is wasted. A safe size is + * (max_xres * max_font_height/8). max_xres is driver dependent, + * max_font_height is 32. + */ + info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL); + if (!info->pixmap.addr) { + /* goto error */ + } + + info->pixmap.size = PIXMAP_SIZE; + + /* + * FB_PIXMAP_SYSTEM - memory is in system ram + * FB_PIXMAP_IO - memory is iomapped + * FB_PIXMAP_SYNC - if set, will call fb_sync() per access to pixmap, + * usually if FB_PIXMAP_IO is set. + * + * Currently, FB_PIXMAP_IO is unimplemented. + */ + info->pixmap.flags = FB_PIXMAP_SYSTEM; + + /* + * scan_align is the number of padding for each scanline. It is in bytes. + * Thus for accelerators that need padding to the next u32, put 4 here. + */ + info->pixmap.scan_align = 4; + + /* + * buf_align is the amount to be padded for the buffer. For example, + * the i810fb needs a scan_align of 2 but expects it to be fed with + * dwords, so a buf_align = 4 is required. */ - info.flags = FBINFO_DEFAULT; - info.par = current_par; + info->pixmap.buf_align = 4; + + /* access_align is how many bits can be accessed from the framebuffer + * ie. some epson cards allow 16-bit access only. Most drivers will + * be safe with u32 here. + * + * NOTE: This field is currently unused. + */ + info->pixmap.scan_align = 32 +/***************************** End optional stage ***************************/ /* * This should give a reasonable default video mode. The following is @@ -590,42 +771,145 @@ int __init xxxfb_init(void) if (!mode_option) mode_option = "640x480@60"; - retval = fb_find_mode(&info.var, &info, mode_option, NULL, 0, NULL, 8); + retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8); if (!retval || retval == 4) return -EINVAL; /* This has to been done !!! */ - fb_alloc_cmap(&info.cmap, cmap_len, 0); + fb_alloc_cmap(info->cmap, cmap_len, 0); /* * The following is done in the case of having hardware with a static * mode. If we are setting the mode ourselves we don't call this. */ - info.var = xxxfb_var; - - if (register_framebuffer(&info) < 0) + info->var = xxxfb_var; + + /* + * For drivers that can... + */ + xxxfb_check_var(&info->var, info); + + /* + * Does a call to fb_set_par() before register_framebuffer needed? This + * will depend on you and the hardware. If you are sure that your driver + * is the only device in the system, a call to fb_set_par() is safe. + * + * Hardware in x86 systems has a VGA core. Calling set_par() at this + * point will corrupt the VGA console, so it might be safer to skip a + * call to set_par here and just allow fbcon to do it for you. + */ + /* xxxfb_set_par(info); */ + + if (register_framebuffer(info) < 0) return -EINVAL; - printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, - info.fix.id); + printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, + info->fix.id); + pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */ return 0; } /* * Cleanup */ +/* static void __exit xxxfb_remove(struct device *device) */ +static void __exit xxxfb_remove(struct pci_dev *dev) +{ + struct fb_info *info = pci_get_drv_data(dev); + /* or dev_get_drv_data(device); */ + + if (info) { + unregister_framebuffer(info); + fb_dealloc_cmap(&info.cmap); + /* ... */ + framebuffer_release(info); + } + + return 0; +} -static void __exit xxxfb_cleanup(void) +#if CONFIG_PCI +/* For PCI drivers */ +static struct pci_driver xxxfb_driver = { + .name = "xxxfb", + .id_table = xxxfb_devices, + .probe = xxxfb_probe, + .remove = __devexit_p(xxxfb_remove), + .suspend = xxxfb_suspend, /* optional */ + .resume = xxxfb_resume, /* optional */ +}; + +static int __init xxxfb_init(void) { - /* - * If your driver supports multiple boards, you should unregister and - * clean up all instances. - */ + /* + * For kernel boot options (in 'video=xxxfb:<options>' format) + */ +#ifndef MODULE + char *option = NULL; - unregister_framebuffer(info); - fb_dealloc_cmap(&info.cmap); - /* ... */ + if (fb_get_options("xxxfb", &option)) + return -ENODEV; + xxxfb_setup(option); +#endif + + return pci_register_driver(&xxxfb_driver); +} + +static void __exit xxxfb_exit(void) +{ + pci_unregister_driver(&xxxfb_driver); } +#else +#include <linux/platform_device.h> +/* for platform devices */ +static struct device_driver xxxfb_driver = { + .name = "xxxfb", + .bus = &platform_bus_type, + .probe = xxxfb_probe, + .remove = xxxfb_remove, + .suspend = xxxfb_suspend, /* optional */ + .resume = xxxfb_resume, /* optional */ +}; + +static struct platform_device xxxfb_device = { + .name = "xxxfb", +}; + +static int __init xxxfb_init(void) +{ + int ret; + /* + * For kernel boot options (in 'video=xxxfb:<options>' format) + */ +#ifndef MODULE + char *option = NULL; + + if (fb_get_options("xxxfb", &option)) + return -ENODEV; + xxxfb_setup(option); +#endif + ret = driver_register(&xxxfb_driver); + + if (!ret) { + ret = platform_device_register(&xxxfb_device); + if (ret) + driver_unregister(&xxxfb_driver); + } + + return ret; +} + +static void __exit xxxfb_exit(void) +{ + platform_device_unregister(&xxxfb_device); + driver_unregister(&xxxfb_driver); +} +#endif + +MODULE_LICENSE("GPL"); +module_init(xxxfb_init); +module_exit(xxxfb_exit); + /* * Setup diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index e0f14df840d..8a5ce210bb2 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -382,7 +382,7 @@ static void sstfb_clear_screen(struct fb_info *info) static int sstfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; int hSyncOff = var->xres + var->right_margin + var->left_margin; int vSyncOff = var->yres + var->lower_margin + var->upper_margin; int vBackPorch = var->left_margin, yDim = var->yres; @@ -542,7 +542,7 @@ static int sstfb_check_var(struct fb_var_screeninfo *var, */ static int sstfb_set_par(struct fb_info *info) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0; struct pci_dev *sst_dev = par->dev; unsigned int freq; @@ -748,13 +748,14 @@ static int sstfb_set_par(struct fb_info *info) static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { + struct sstfb_par *par = info->par; u32 col; f_dddprintk("sstfb_setcolreg\n"); f_dddprintk("%-2d rgbt: %#x, %#x, %#x, %#x\n", regno, red, green, blue, transp); - if (regno >= 16) - return -EINVAL; + if (regno > 15) + return 0; red >>= (16 - info->var.red.length); green >>= (16 - info->var.green.length); @@ -765,7 +766,7 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | (blue << info->var.blue.offset) | (transp << info->var.transp.offset); - ((u32 *)info->pseudo_palette)[regno] = col; + par->palette[regno] = col; return 0; } @@ -773,7 +774,7 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, static int sstfb_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg, struct fb_info *info ) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; struct pci_dev *sst_dev = par->dev; u32 fbiinit0, tmp, val; u_long p; @@ -830,7 +831,7 @@ static int sstfb_ioctl(struct inode *inode, struct file *file, #if 0 static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; u32 stride = info->fix.line_length; if (!IS_VOODOO2(par)) @@ -855,7 +856,7 @@ static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) */ static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; u32 stride = info->fix.line_length; if (!IS_VOODOO2(par)) @@ -925,7 +926,7 @@ static int __devinit sst_get_memsize(struct fb_info *info, __u32 *memsize) static int __devinit sst_detect_att(struct fb_info *info) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; int i, mir, dir; for (i=0; i<3; i++) { @@ -950,7 +951,7 @@ static int __devinit sst_detect_att(struct fb_info *info) static int __devinit sst_detect_ti(struct fb_info *info) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; int i, mir, dir; for (i = 0; i<3; i++) { @@ -986,7 +987,7 @@ static int __devinit sst_detect_ti(struct fb_info *info) */ static int __devinit sst_detect_ics(struct fb_info *info) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; int m_clk0_1, m_clk0_7, m_clk1_b; int n_clk0_1, n_clk0_7, n_clk1_b; int i; @@ -1023,7 +1024,7 @@ static int __devinit sst_detect_ics(struct fb_info *info) static int sst_set_pll_att_ti(struct fb_info *info, const struct pll_timing *t, const int clock) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; u8 cr0, cc; /* enable indexed mode */ @@ -1077,7 +1078,7 @@ static int sst_set_pll_att_ti(struct fb_info *info, static int sst_set_pll_ics(struct fb_info *info, const struct pll_timing *t, const int clock) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; u8 pll_ctrl; sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL); @@ -1114,7 +1115,7 @@ static int sst_set_pll_ics(struct fb_info *info, static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; u8 cr0; sst_dac_write(DACREG_WMA, 0); /* backdoor */ @@ -1149,7 +1150,7 @@ static void sst_set_vidmod_att_ti(struct fb_info *info, const int bpp) static void sst_set_vidmod_ics(struct fb_info *info, const int bpp) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; switch(bpp) { case 16: @@ -1308,7 +1309,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par) static void __devexit sst_shutdown(struct fb_info *info) { - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; struct pci_dev *dev = par->dev; struct pll_timing gfx_timings; int Fout; @@ -1394,12 +1395,6 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, struct sst_spec *spec; int err; - struct all_info { - struct fb_info info; - struct sstfb_par par; - u32 pseudo_palette[16]; - } *all; - /* Enable device in PCI config. */ if ((err=pci_enable_device(pdev))) { eprintk("cannot enable device\n"); @@ -1407,14 +1402,13 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, } /* Allocate the fb and par structures. */ - all = kmalloc(sizeof(*all), GFP_KERNEL); - if (!all) + info = framebuffer_alloc(sizeof(struct sstfb_par), &pdev->dev); + if (!info) return -ENOMEM; - memset(all, 0, sizeof(*all)); - pci_set_drvdata(pdev, all); + + pci_set_drvdata(pdev, info); - info = &all->info; - par = info->par = &all->par; + par = info->par; fix = &info->fix; par->type = id->driver_data; @@ -1471,7 +1465,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, info->flags = FBINFO_DEFAULT; info->fbops = &sstfb_ops; - info->pseudo_palette = &all->pseudo_palette; + info->pseudo_palette = par->palette; fix->type = FB_TYPE_PACKED_PIXELS; fix->visual = FB_VISUAL_TRUECOLOR; @@ -1527,7 +1521,7 @@ fail_mmio_remap: fail_fb_mem: release_mem_region(fix->mmio_start, info->fix.mmio_len); fail_mmio_mem: - kfree(info); + framebuffer_release(info); return -ENXIO; /* no voodoo detected */ } @@ -1537,7 +1531,7 @@ static void __devexit sstfb_remove(struct pci_dev *pdev) struct fb_info *info; info = pci_get_drvdata(pdev); - par = (struct sstfb_par *) info->par; + par = info->par; sst_shutdown(info); unregister_framebuffer(info); @@ -1545,7 +1539,7 @@ static void __devexit sstfb_remove(struct pci_dev *pdev) iounmap(par->mmio_vbase); release_mem_region(info->fix.smem_start, 0x400000); release_mem_region(info->fix.mmio_start, info->fix.mmio_len); - kfree(info); + framebuffer_release(info); } @@ -1613,7 +1607,7 @@ static int sstfb_dump_regs(struct fb_info *info) const int pci_s = sizeof(pci_regs)/sizeof(pci_regs[0]); const int sst_s = sizeof(sst_regs)/sizeof(sst_regs[0]); - struct sstfb_par *par = (struct sstfb_par *) info->par; + struct sstfb_par *par = info->par; struct pci_dev *dev = par->dev; u32 pci_res[pci_s]; u32 sst_res[sst_s]; diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index fbb17332afd..56d71d6e9a7 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -3,7 +3,7 @@ * Low level Frame buffer driver for HP workstations with * STI (standard text interface) video firmware. * - * Copyright (C) 2001-2004 Helge Deller <deller@gmx.de> + * Copyright (C) 2001-2005 Helge Deller <deller@gmx.de> * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de> * * Based on: @@ -73,16 +73,13 @@ #include "sticore.h" /* REGION_BASE(fb_info, index) returns the virtual address for region <index> */ -#ifdef __LP64__ - #define REGION_BASE(fb_info, index) \ - (fb_info->sti->glob_cfg->region_ptrs[index] | 0xffffffff00000000) -#else - #define REGION_BASE(fb_info, index) \ - fb_info->sti->glob_cfg->region_ptrs[index] -#endif +#define REGION_BASE(fb_info, index) \ + F_EXTEND(fb_info->sti->glob_cfg->region_ptrs[index]) #define NGLEDEVDEPROM_CRT_REGION 1 +#define NR_PALETTE 256 + typedef struct { __s32 video_config_reg; __s32 misc_video_start; @@ -112,7 +109,7 @@ struct stifb_info { ngle_rom_t ngle_rom; struct sti_struct *sti; int deviceSpecificConfig; - u32 pseudo_palette[256]; + u32 pseudo_palette[16]; }; static int __initdata stifb_bpp_pref[MAX_STI_ROMS]; @@ -352,10 +349,10 @@ ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) #define IS_888_DEVICE(fb) \ (!(IS_24_DEVICE(fb))) -#define GET_FIFO_SLOTS(fb, cnt, numslots) \ -{ while (cnt < numslots) \ +#define GET_FIFO_SLOTS(fb, cnt, numslots) \ +{ while (cnt < numslots) \ cnt = READ_WORD(fb, REG_34); \ - cnt -= numslots; \ + cnt -= numslots; \ } #define IndexedDcd 0 /* Pixel data is indexed (pseudo) color */ @@ -995,7 +992,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, struct stifb_info *fb = (struct stifb_info *) info; u32 color; - if (regno >= 256) /* no. of hw registers */ + if (regno >= NR_PALETTE) return 1; red >>= 8; @@ -1005,8 +1002,8 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, DEBUG_OFF(); START_IMAGE_COLORMAP_ACCESS(fb); - - if (fb->info.var.grayscale) { + + if (unlikely(fb->info.var.grayscale)) { /* gray = 0.30*R + 0.59*G + 0.11*B */ color = ((red * 77) + (green * 151) + @@ -1017,17 +1014,17 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, (blue)); } - if (info->var.bits_per_pixel == 32) { - ((u32 *)(info->pseudo_palette))[regno] = - (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset); - } else { - ((u32 *)(info->pseudo_palette))[regno] = regno; + if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) { + struct fb_var_screeninfo *var = &fb->info.var; + if (regno < 16) + ((u32 *)fb->info.pseudo_palette)[regno] = + regno << var->red.offset | + regno << var->green.offset | + regno << var->blue.offset; } WRITE_IMAGE_COLOR(fb, regno, color); - + if (fb->id == S9000_ID_HCRX) { NgleLutBltCtl lutBltCtl; @@ -1066,9 +1063,9 @@ stifb_blank(int blank_mode, struct fb_info *info) case S9000_ID_HCRX: HYPER_ENABLE_DISABLE_DISPLAY(fb, enable); break; - case S9000_ID_A1659A:; /* fall through */ - case S9000_ID_TIMBER:; - case CRX24_OVERLAY_PLANES:; + case S9000_ID_A1659A: /* fall through */ + case S9000_ID_TIMBER: + case CRX24_OVERLAY_PLANES: default: ENABLE_DISABLE_DISPLAY(fb, enable); break; @@ -1250,12 +1247,10 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom)); if ((fb->sti->regions_phys[0] & 0xfc000000) == (fb->sti->regions_phys[2] & 0xfc000000)) - sti_rom_address = fb->sti->regions_phys[0]; + sti_rom_address = F_EXTEND(fb->sti->regions_phys[0]); else - sti_rom_address = fb->sti->regions_phys[1]; -#ifdef __LP64__ - sti_rom_address |= 0xffffffff00000000; -#endif + sti_rom_address = F_EXTEND(fb->sti->regions_phys[1]); + fb->deviceSpecificConfig = gsc_readl(sti_rom_address); if (IS_24_DEVICE(fb)) { if (bpp_pref == 8 || bpp_pref == 32) @@ -1315,7 +1310,7 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) break; case 32: fix->type = FB_TYPE_PACKED_PIXELS; - fix->visual = FB_VISUAL_TRUECOLOR; + fix->visual = FB_VISUAL_DIRECTCOLOR; var->red.length = var->green.length = var->blue.length = var->transp.length = 8; var->blue.offset = 0; var->green.offset = 8; @@ -1337,7 +1332,7 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref) info->pseudo_palette = &fb->pseudo_palette; /* This has to been done !!! */ - fb_alloc_cmap(&info->cmap, 256, 0); + fb_alloc_cmap(&info->cmap, NR_PALETTE, 0); stifb_init_display(fb); if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) { @@ -1488,7 +1483,3 @@ module_exit(stifb_cleanup); MODULE_AUTHOR("Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines"); MODULE_LICENSE("GPL v2"); - -MODULE_PARM(bpp, "i"); -MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)"); - diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 9d53387e6a6..3e7baf4c9fa 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c @@ -291,7 +291,7 @@ static inline void banshee_make_room(struct tdfx_par *par, int size) static int banshee_wait_idle(struct fb_info *info) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; int i = 0; banshee_make_room(par, 1); @@ -364,7 +364,7 @@ static u32 do_calc_pll(int freq, int* freq_out) static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; int i; banshee_wait_idle(info); @@ -469,7 +469,7 @@ static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; u32 lpitch; if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 && @@ -558,7 +558,7 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) static int tdfxfb_set_par(struct fb_info *info) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; u32 hdispend, hsyncsta, hsyncend, htotal; u32 hd, hs, he, ht, hbs, hbe; u32 vd, vs, ve, vt, vbs, vbe; @@ -780,7 +780,7 @@ static int tdfxfb_set_par(struct fb_info *info) static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,unsigned transp,struct fb_info *info) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; u32 rgbcol; if (regno >= info->cmap.len || regno > 255) return 1; @@ -794,11 +794,15 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, break; /* Truecolor has no hardware color palettes. */ case FB_VISUAL_TRUECOLOR: - rgbcol = (CNVT_TOHW( red, info->var.red.length) << info->var.red.offset) | - (CNVT_TOHW( green, info->var.green.length) << info->var.green.offset) | - (CNVT_TOHW( blue, info->var.blue.length) << info->var.blue.offset) | - (CNVT_TOHW( transp, info->var.transp.length) << info->var.transp.offset); - ((u32*)(info->pseudo_palette))[regno] = rgbcol; + rgbcol = (CNVT_TOHW( red, info->var.red.length) << + info->var.red.offset) | + (CNVT_TOHW( green, info->var.green.length) << + info->var.green.offset) | + (CNVT_TOHW( blue, info->var.blue.length) << + info->var.blue.offset) | + (CNVT_TOHW( transp, info->var.transp.length) << + info->var.transp.offset); + par->palette[regno] = rgbcol; break; default: DPRINTK("bad depth %u\n", info->var.bits_per_pixel); @@ -810,7 +814,7 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ static int tdfxfb_blank(int blank, struct fb_info *info) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; u32 dacmode, state = 0, vgablank = 0; dacmode = tdfx_inl(par, DACMODE); @@ -855,7 +859,7 @@ static int tdfxfb_blank(int blank, struct fb_info *info) static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; u32 addr; if (nopan || var->xoffset || (var->yoffset > var->yres_virtual)) @@ -878,7 +882,7 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var, */ static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; u32 bpp = info->var.bits_per_pixel; u32 stride = info->fix.line_length; u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); @@ -894,7 +898,7 @@ static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { tdfx_outl(par, COLORFORE, rect->color); } else { /* FB_VISUAL_TRUECOLOR */ - tdfx_outl(par, COLORFORE, ((u32*)(info->pseudo_palette))[rect->color]); + tdfx_outl(par, COLORFORE, par->palette[rect->color]); } tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24)); tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16)); @@ -906,7 +910,7 @@ static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect */ static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; u32 bpp = info->var.bits_per_pixel; u32 stride = info->fix.line_length; @@ -938,7 +942,7 @@ static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; int size = image->height * ((image->width * image->depth + 7)>>3); int fifo_free; int i, stride = info->fix.line_length; @@ -961,8 +965,10 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) break; case FB_VISUAL_TRUECOLOR: default: - tdfx_outl(par, COLORFORE, ((u32*)(info->pseudo_palette))[image->fg_color]); - tdfx_outl(par, COLORBACK, ((u32*)(info->pseudo_palette))[image->bg_color]); + tdfx_outl(par, COLORFORE, + par->palette[image->fg_color]); + tdfx_outl(par, COLORBACK, + par->palette[image->bg_color]); } #ifdef __BIG_ENDIAN srcfmt = 0x400000 | BIT(20); @@ -1007,7 +1013,7 @@ static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) #ifdef TDFX_HARDWARE_CURSOR static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) { - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; unsigned long flags; /* @@ -1157,18 +1163,17 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, { struct tdfx_par *default_par; struct fb_info *info; - int size, err, lpitch; + int err, lpitch; if ((err = pci_enable_device(pdev))) { printk(KERN_WARNING "tdfxfb: Can't enable pdev: %d\n", err); return err; } - size = sizeof(struct tdfx_par)+256*sizeof(u32); + info = framebuffer_alloc(sizeof(struct tdfx_par), &pdev->dev); - info = framebuffer_alloc(size, &pdev->dev); - - if (!info) return -ENOMEM; + if (!info) + return -ENOMEM; default_par = info->par; @@ -1248,7 +1253,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, info->fbops = &tdfxfb_ops; info->fix = tdfx_fix; - info->pseudo_palette = (void *)(default_par + 1); + info->pseudo_palette = default_par->palette; info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; #ifdef CONFIG_FB_3DFX_ACCEL info->flags |= FBINFO_HWACCEL_FILLRECT | @@ -1307,7 +1312,7 @@ out_err: } #ifndef MODULE -void tdfxfb_setup(char *options) +static void tdfxfb_setup(char *options) { char* this_opt; @@ -1340,7 +1345,7 @@ void tdfxfb_setup(char *options) static void __devexit tdfxfb_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); - struct tdfx_par *par = (struct tdfx_par *) info->par; + struct tdfx_par *par = info->par; unregister_framebuffer(info); iounmap(par->regbase_virt); diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 3e58ddc2bc3..8982e540214 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -57,7 +57,6 @@ static unsigned short *pmi_base = NULL; static void (*pmi_start)(void); static void (*pmi_pal)(void); static int depth; -static int vga_compat; /* --------------------------------------------------------------------- */ @@ -67,15 +66,6 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, #ifdef __i386__ int offset; - if (!ypan) - return -EINVAL; - if (var->xoffset) - return -EINVAL; - if (var->yoffset > var->yres_virtual) - return -EINVAL; - if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual) - return -EINVAL; - offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4; __asm__ __volatile__( @@ -90,37 +80,6 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, return 0; } -static int vesafb_blank(int blank, struct fb_info *info) -{ - int err = 1; - - if (vga_compat) { - int loop = 10000; - u8 seq = 0, crtc17 = 0; - - if (blank == FB_BLANK_POWERDOWN) { - seq = 0x20; - crtc17 = 0x00; - err = 0; - } else { - seq = 0x00; - crtc17 = 0x80; - err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL; - } - - vga_wseq(NULL, 0x00, 0x01); - seq |= vga_rseq(NULL, 0x01) & ~0x20; - vga_wseq(NULL, 0x00, seq); - - crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80; - while (loop--); - vga_wcrt(NULL, 0x17, crtc17); - vga_wseq(NULL, 0x00, 0x03); - } - - return err; -} - static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue) { @@ -205,7 +164,6 @@ static struct fb_ops vesafb_ops = { .owner = THIS_MODULE, .fb_setcolreg = vesafb_setcolreg, .fb_pan_display = vesafb_pan_display, - .fb_blank = vesafb_blank, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, @@ -459,9 +417,8 @@ static int __init vesafb_probe(struct platform_device *dev) info->flags = FBINFO_FLAG_DEFAULT | (ypan) ? FBINFO_HWACCEL_YPAN : 0; - vga_compat = (screen_info.capabilities & 2) ? 0 : 1; - printk("vesafb: Mode is %sVGA compatible\n", - (vga_compat) ? "" : "not "); + if (!ypan) + info->fbops->fb_pan_display = NULL; if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { err = -ENOMEM; diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 226ae8a8848..f3f16fd9f23 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -705,15 +705,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, static int vga16fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - if (var->xoffset + info->var.xres > info->var.xres_virtual || - var->yoffset + info->var.yres > info->var.yres_virtual) - return -EINVAL; - vga16fb_pan_var(info, var); - - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - info->var.vmode &= ~FB_VMODE_YWRAP; return 0; } diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c index d9e01daee63..15179ec6233 100644 --- a/drivers/video/vgastate.c +++ b/drivers/video/vgastate.c @@ -356,10 +356,11 @@ int save_vga(struct vgastate *state) { struct regstate *saved; - saved = kmalloc(sizeof(struct regstate), GFP_KERNEL); + saved = kzalloc(sizeof(struct regstate), GFP_KERNEL); + if (saved == NULL) return 1; - memset (saved, 0, sizeof(struct regstate)); + state->vidstate = (void *)saved; if (state->flags & VGA_SAVE_CMAP) { |