diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-06-28 14:06:39 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-06-28 14:06:39 -0400 |
commit | f28e71617ddaf2483e3e5c5237103484a303743f (patch) | |
tree | 67627d2d8ddbf6a4449371e9261d796c013b1fa1 /drivers/video | |
parent | dc6a78f1af10d28fb8c395034ae1e099b85c05b0 (diff) | |
parent | a39727f212426b9d5f9267b3318a2afaf9922d3b (diff) |
Merge ../linux-2.6/
Conflicts:
drivers/scsi/aacraid/comminit.c
Fixed up by removing the now renamed CONFIG_IOMMU option from
aacraid
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/video')
46 files changed, 2015 insertions, 1427 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 168ede7902b..17de4c84db6 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -4,6 +4,21 @@ menu "Graphics support" +config FIRMWARE_EDID + bool "Enable firmware EDID" + default y + ---help--- + This enables access to the EDID transferred from the firmware. + On the i386, this is from the Video BIOS. Enable this if DDC/I2C + transfers do not work for your driver and if you are using + nvidiafb, i810fb or savagefb. + + In general, choosing Y for this option is safe. If you + experience extremely long delays while booting before you get + something on your display, try setting this to N. Matrox cards in + combination with certain motherboards and monitors are known to + suffer from this problem. + config FB tristate "Support for frame buffer devices" ---help--- @@ -70,22 +85,6 @@ config FB_MACMODES depends on FB default n -config FB_FIRMWARE_EDID - bool "Enable firmware EDID" - depends on FB - default y - ---help--- - This enables access to the EDID transferred from the firmware. - On the i386, this is from the Video BIOS. Enable this if DDC/I2C - transfers do not work for your driver and if you are using - nvidiafb, i810fb or savagefb. - - In general, choosing Y for this option is safe. If you - experience extremely long delays while booting before you get - something on your display, try setting this to N. Matrox cards in - combination with certain motherboards and monitors are known to - suffer from this problem. - config FB_BACKLIGHT bool depends on FB @@ -551,10 +550,14 @@ config FB_VESA You will get a boot time penguin logo at no additional cost. Please read <file:Documentation/fb/vesafb.txt>. If unsure, say Y. -config VIDEO_SELECT - bool - depends on FB_VESA - default y +config FB_IMAC + bool "Intel-based Macintosh Framebuffer Support" + depends on (FB = y) && X86 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Intel-based Macintosh config FB_HGA tristate "Hercules mono graphics support" @@ -578,12 +581,6 @@ config FB_HGA_ACCEL This will compile the Hercules mono graphics with acceleration functions. - -config VIDEO_SELECT - bool - depends on (FB = y) && X86 - default y - config FB_SGIVW tristate "SGI Visual Workstation framebuffer support" depends on FB && X86_VISWS diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 23de3b2c785..c335e9bc3b2 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -4,15 +4,15 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_VT) += console/ -obj-$(CONFIG_LOGO) += logo/ -obj-$(CONFIG_SYSFS) += backlight/ - obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o fb-objs := $(fb-y) +obj-$(CONFIG_VT) += console/ +obj-$(CONFIG_LOGO) += logo/ +obj-$(CONFIG_SYSFS) += backlight/ + obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o @@ -97,6 +97,7 @@ obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o +obj-$(CONFIG_FB_IMAC) += imacfb.o obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o obj-$(CONFIG_FB_OF) += offb.o diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index db878fd55fb..11cf7fcb1d5 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -100,7 +100,7 @@ #ifndef CONFIG_PPC_PMAC /* default mode */ -static struct fb_var_screeninfo default_var __initdata = { +static struct fb_var_screeninfo default_var __devinitdata = { /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */ 640, 480, 640, 480, 0, 0, 8, 0, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, @@ -123,7 +123,7 @@ static struct fb_var_screeninfo default_var = { /* default modedb mode */ /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */ -static struct fb_videomode defaultmode __initdata = { +static struct fb_videomode defaultmode __devinitdata = { .refresh = 60, .xres = 640, .yres = 480, @@ -335,7 +335,7 @@ static const struct aty128_meminfo sdr_sgram = static const struct aty128_meminfo ddr_sgram = { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" }; -static struct fb_fix_screeninfo aty128fb_fix __initdata = { +static struct fb_fix_screeninfo aty128fb_fix __devinitdata = { .id = "ATY Rage128", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -345,15 +345,15 @@ static struct fb_fix_screeninfo aty128fb_fix __initdata = { .accel = FB_ACCEL_ATI_RAGE128, }; -static char *mode_option __initdata = NULL; +static char *mode_option __devinitdata = NULL; #ifdef CONFIG_PPC_PMAC -static int default_vmode __initdata = VMODE_1024_768_60; -static int default_cmode __initdata = CMODE_8; +static int default_vmode __devinitdata = VMODE_1024_768_60; +static int default_cmode __devinitdata = CMODE_8; #endif -static int default_crt_on __initdata = 0; -static int default_lcd_on __initdata = 1; +static int default_crt_on __devinitdata = 0; +static int default_lcd_on __devinitdata = 1; #ifdef CONFIG_MTRR static int mtrr = 1; @@ -445,9 +445,9 @@ static int aty128_encode_var(struct fb_var_screeninfo *var, static int aty128_decode_var(struct fb_var_screeninfo *var, struct aty128fb_par *par); #if 0 -static void __init aty128_get_pllinfo(struct aty128fb_par *par, +static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, void __iomem *bios); -static void __init __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); +static void __devinit __iomem *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par); #endif static void aty128_timings(struct aty128fb_par *par); static void aty128_init_engine(struct aty128fb_par *par); @@ -573,7 +573,7 @@ static void aty_pll_writeupdate(const struct aty128fb_par *par) /* write to the scratch register to test r/w functionality */ -static int __init register_test(const struct aty128fb_par *par) +static int __devinit register_test(const struct aty128fb_par *par) { u32 val; int flag = 0; @@ -772,7 +772,7 @@ static u32 depth_to_dst(u32 depth) #ifndef __sparc__ -static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) +static void __iomem * __devinit aty128_map_ROM(const struct aty128fb_par *par, struct pci_dev *dev) { u16 dptr; u8 rom_type; @@ -856,7 +856,7 @@ static void __iomem * __init aty128_map_ROM(const struct aty128fb_par *par, stru return NULL; } -static void __init aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) +static void __devinit aty128_get_pllinfo(struct aty128fb_par *par, unsigned char __iomem *bios) { unsigned int bios_hdr; unsigned int bios_pll; @@ -903,7 +903,7 @@ static void __iomem * __devinit aty128_find_mem_vbios(struct aty128fb_par *par) #endif /* ndef(__sparc__) */ /* fill in known card constants if pll_block is not available */ -static void __init aty128_timings(struct aty128fb_par *par) +static void __devinit aty128_timings(struct aty128fb_par *par) { #ifdef CONFIG_PPC_OF /* instead of a table lookup, assume OF has properly @@ -1645,7 +1645,7 @@ static int aty128fb_sync(struct fb_info *info) } #ifndef MODULE -static int __init aty128fb_setup(char *options) +static int __devinit aty128fb_setup(char *options) { char *this_opt; @@ -1893,7 +1893,7 @@ static void aty128_early_resume(void *data) } #endif /* CONFIG_PPC_PMAC */ -static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent) { struct fb_info *info = pci_get_drvdata(pdev); struct aty128fb_par *par = info->par; @@ -2037,7 +2037,7 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id * #ifdef CONFIG_PCI /* register a card ++ajoshi */ -static int __init aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned long fb_addr, reg_addr; struct aty128fb_par *par; @@ -2556,7 +2556,7 @@ static int aty128_pci_resume(struct pci_dev *pdev) } -static int __init aty128fb_init(void) +static int __devinit aty128fb_init(void) { #ifndef MODULE char *option = NULL; diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index c5185f7cf4b..22e720611bf 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -316,12 +316,12 @@ static int vram; static int pll; static int mclk; static int xclk; -static int comp_sync __initdata = -1; +static int comp_sync __devinitdata = -1; static char *mode; #ifdef CONFIG_PPC -static int default_vmode __initdata = VMODE_CHOOSE; -static int default_cmode __initdata = CMODE_CHOOSE; +static int default_vmode __devinitdata = VMODE_CHOOSE; +static int default_cmode __devinitdata = CMODE_CHOOSE; module_param_named(vmode, default_vmode, int, 0); MODULE_PARM_DESC(vmode, "int: video mode for mac"); @@ -330,10 +330,10 @@ MODULE_PARM_DESC(cmode, "int: color mode for mac"); #endif #ifdef CONFIG_ATARI -static unsigned int mach64_count __initdata = 0; -static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, }; -static unsigned long phys_size[FB_MAX] __initdata = { 0, }; -static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, }; +static unsigned int mach64_count __devinitdata = 0; +static unsigned long phys_vmembase[FB_MAX] __devinitdata = { 0, }; +static unsigned long phys_size[FB_MAX] __devinitdata = { 0, }; +static unsigned long phys_guiregbase[FB_MAX] __devinitdata = { 0, }; #endif /* top -> down is an evolution of mach64 chipset, any corrections? */ @@ -583,7 +583,7 @@ static u32 atyfb_get_pixclock(struct fb_var_screeninfo *var, struct atyfb_par *p * Apple monitor sense */ -static int __init read_aty_sense(const struct atyfb_par *par) +static int __devinit read_aty_sense(const struct atyfb_par *par) { int sense, i; @@ -1281,6 +1281,14 @@ static int atyfb_set_par(struct fb_info *info) par->accel_flags = var->accel_flags; /* hack */ + if (var->accel_flags) { + info->fbops->fb_sync = atyfb_sync; + info->flags &= ~FBINFO_HWACCEL_DISABLED; + } else { + info->fbops->fb_sync = NULL; + info->flags |= FBINFO_HWACCEL_DISABLED; + } + if (par->blitter_may_be_busy) wait_for_idle(par); @@ -2253,7 +2261,7 @@ static void aty_bl_exit(struct atyfb_par *par) #endif /* CONFIG_FB_ATY_BACKLIGHT */ -static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk) +static void __devinit aty_calc_mem_refresh(struct atyfb_par *par, int xclk) { const int ragepro_tbl[] = { 44, 50, 55, 66, 75, 80, 100 @@ -2313,7 +2321,7 @@ static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par, } #endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ -static int __init aty_init(struct fb_info *info, const char *name) +static int __devinit aty_init(struct fb_info *info, const char *name) { struct atyfb_par *par = (struct atyfb_par *) info->par; const char *ramname = NULL, *xtal; @@ -2394,12 +2402,15 @@ static int __init aty_init(struct fb_info *info, const char *name) break; } switch (clk_type) { +#ifdef CONFIG_ATARI case CLK_ATI18818_1: par->pll_ops = &aty_pll_ati18818_1; break; +#else case CLK_IBMRGB514: par->pll_ops = &aty_pll_ibm514; break; +#endif #if 0 /* dead code */ case CLK_STG1703: par->pll_ops = &aty_pll_stg1703; @@ -2604,7 +2615,11 @@ static int __init aty_init(struct fb_info *info, const char *name) info->fbops = &atyfb_ops; info->pseudo_palette = pseudo_palette; - info->flags = FBINFO_FLAG_DEFAULT; + info->flags = FBINFO_DEFAULT | + FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_FILLRECT | + FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_YPAN; #ifdef CONFIG_PMAC_BACKLIGHT if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { @@ -2733,7 +2748,7 @@ aty_init_exit: } #ifdef CONFIG_ATARI -static int __init store_video_par(char *video_str, unsigned char m64_num) +static int __devinit store_video_par(char *video_str, unsigned char m64_num) { char *p; unsigned long vmembase, size, guiregbase; @@ -3764,7 +3779,7 @@ static struct pci_driver atyfb_driver = { #endif /* CONFIG_PCI */ #ifndef MODULE -static int __init atyfb_setup(char *options) +static int __devinit atyfb_setup(char *options) { char *this_opt; @@ -3836,7 +3851,7 @@ static int __init atyfb_setup(char *options) } #endif /* MODULE */ -static int __init atyfb_init(void) +static int __devinit atyfb_init(void) { #ifndef MODULE char *option = NULL; diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c index c98f4a44213..1490e5e1c23 100644 --- a/drivers/video/aty/mach64_accel.c +++ b/drivers/video/aty/mach64_accel.c @@ -200,8 +200,6 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) if (!area->width || !area->height) return; if (!par->accel_flags) { - if (par->blitter_may_be_busy) - wait_for_idle(par); cfb_copyarea(info, area); return; } @@ -248,8 +246,6 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) if (!rect->width || !rect->height) return; if (!par->accel_flags) { - if (par->blitter_may_be_busy) - wait_for_idle(par); cfb_fillrect(info, rect); return; } @@ -288,14 +284,10 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) return; if (!par->accel_flags || (image->depth != 1 && info->var.bits_per_pixel != image->depth)) { - if (par->blitter_may_be_busy) - wait_for_idle(par); - cfb_imageblit(info, image); return; } - wait_for_idle(par); pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par); host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN; @@ -425,8 +417,6 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) } } - wait_for_idle(par); - /* restore pix_width */ wait_for_fifo(1, par); aty_st_le32(DP_PIX_WIDTH, pix_width_save, par); diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c index ad8b7496f85..2a7f381c330 100644 --- a/drivers/video/aty/mach64_cursor.c +++ b/drivers/video/aty/mach64_cursor.c @@ -66,11 +66,6 @@ static const u8 cursor_bits_lookup[16] = { 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55 }; -static const u8 cursor_mask_lookup[16] = { - 0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02, - 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00 -}; - static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct atyfb_par *par = (struct atyfb_par *) info->par; @@ -130,13 +125,13 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) fg_idx = cursor->image.fg_color; bg_idx = cursor->image.bg_color; - fg = (info->cmap.red[fg_idx] << 24) | - (info->cmap.green[fg_idx] << 16) | - (info->cmap.blue[fg_idx] << 8) | 15; + fg = ((info->cmap.red[fg_idx] & 0xff) << 24) | + ((info->cmap.green[fg_idx] & 0xff) << 16) | + ((info->cmap.blue[fg_idx] & 0xff) << 8) | 0xff; - bg = (info->cmap.red[bg_idx] << 24) | - (info->cmap.green[bg_idx] << 16) | - (info->cmap.blue[bg_idx] << 8); + bg = ((info->cmap.red[bg_idx] & 0xff) << 24) | + ((info->cmap.green[bg_idx] & 0xff) << 16) | + ((info->cmap.blue[bg_idx] & 0xff) << 8); wait_for_fifo(2, par); aty_st_le32(CUR_CLR0, bg, par); @@ -166,19 +161,17 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) switch (cursor->rop) { case ROP_XOR: // Upper 4 bits of mask data - fb_writeb(cursor_mask_lookup[m >> 4 ] | - cursor_bits_lookup[(b ^ m) >> 4], dst++); + fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++); // Lower 4 bits of mask - fb_writeb(cursor_mask_lookup[m & 0x0f ] | - cursor_bits_lookup[(b ^ m) & 0x0f], dst++); + fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f], + dst++); break; case ROP_COPY: // Upper 4 bits of mask data - fb_writeb(cursor_mask_lookup[m >> 4 ] | - cursor_bits_lookup[(b & m) >> 4], dst++); + fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++); // Lower 4 bits of mask - fb_writeb(cursor_mask_lookup[m & 0x0f ] | - cursor_bits_lookup[(b & m) & 0x0f], dst++); + fb_writeb(cursor_bits_lookup[(b & m) & 0x0f], + dst++); break; } } @@ -194,7 +187,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor) return 0; } -int __init aty_init_cursor(struct fb_info *info) +int __devinit aty_init_cursor(struct fb_info *info) { unsigned long addr; diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index c5ecbb02e01..68b15645b89 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -2379,7 +2379,6 @@ err_release_pci0: err_release_fb: framebuffer_release(info); err_disable: - pci_disable_device(pdev); err_out: return ret; } @@ -2436,7 +2435,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) #endif fb_dealloc_cmap(&info->cmap); framebuffer_release(info); - pci_disable_device(pdev); } diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 789450bb0bc..9ef68cd83bb 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -7,6 +7,8 @@ * Karl Lessard <klessard@sunrisetelecom.com> * <c.pellegrin@exadron.com> * + * PM support added by Rodolfo Giometti <giometti@linux.it> + * * Copyright 2002 MontaVista Software * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com @@ -602,17 +604,52 @@ int au1100fb_drv_remove(struct device *dev) return 0; } +#ifdef CONFIG_PM +static u32 sys_clksrc; +static struct au1100fb_regs fbregs; + int au1100fb_drv_suspend(struct device *dev, pm_message_t state) { - /* TODO */ + struct au1100fb_device *fbdev = dev_get_drvdata(dev); + + if (!fbdev) + return 0; + + /* Save the clock source state */ + sys_clksrc = au_readl(SYS_CLKSRC); + + /* Blank the LCD */ + au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); + + /* Stop LCD clocking */ + au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC); + + memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); + return 0; } int au1100fb_drv_resume(struct device *dev) { - /* TODO */ + struct au1100fb_device *fbdev = dev_get_drvdata(dev); + + if (!fbdev) + return 0; + + memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); + + /* Restart LCD clocking */ + au_writel(sys_clksrc, SYS_CLKSRC); + + /* Unblank the LCD */ + au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); + return 0; } +#else +#define au1100fb_drv_suspend NULL +#define au1100fb_drv_resume NULL +#endif static struct device_driver au1100fb_driver = { .name = "au1100-lcd", @@ -706,8 +743,7 @@ void __exit au1100fb_cleanup(void) { driver_unregister(&au1100fb_driver); - if (drv_info.opt_mode) - kfree(drv_info.opt_mode); + kfree(drv_info.opt_mode); } module_init(au1100fb_init); diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index b895eaaa73f..022f9d3473f 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT config BACKLIGHT_CLASS_DEVICE tristate "Lowlevel Backlight controls" - depends on BACKLIGHT_LCD_SUPPORT + depends on BACKLIGHT_LCD_SUPPORT && FB default m help This framework adds support for low-level control of the LCD @@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE config LCD_CLASS_DEVICE tristate "Lowlevel LCD controls" - depends on BACKLIGHT_LCD_SUPPORT + depends on BACKLIGHT_LCD_SUPPORT && FB default m help This framework adds support for low-level control of LCD. @@ -50,6 +50,14 @@ config BACKLIGHT_CORGI If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the backlight driver. +config BACKLIGHT_LOCOMO + tristate "Sharp LOCOMO LCD/Backlight Driver" + depends on BACKLIGHT_DEVICE && SHARP_LOCOMO + default y + help + If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to + enable the LCD/backlight driver. + config BACKLIGHT_HP680 tristate "HP Jornada 680 Backlight Driver" depends on BACKLIGHT_DEVICE && SH_HP6XX diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 744210c38e7..65e5553fc84 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o -obj-$(CONFIG_SHARP_LOCOMO) += locomolcd.o +obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index a71e984c93d..ffc72ae3ada 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -27,7 +27,7 @@ static int hp680bl_suspended; static int current_intensity = 0; -static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(bl_lock); static struct backlight_device *hp680_backlight_device; static void hp680bl_send_intensity(struct backlight_device *bd) diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 60831bb2368..bd879b7ec11 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -17,6 +17,8 @@ #include <linux/delay.h> #include <linux/device.h> #include <linux/interrupt.h> +#include <linux/fb.h> +#include <linux/backlight.h> #include <asm/hardware/locomo.h> #include <asm/irq.h> @@ -25,7 +27,10 @@ #include "../../../arch/arm/mach-sa1100/generic.h" +static struct backlight_device *locomolcd_bl_device; static struct locomo_dev *locomolcd_dev; +static unsigned long locomolcd_flags; +#define LOCOMOLCD_SUSPENDED 0x01 static void locomolcd_on(int comadj) { @@ -89,12 +94,10 @@ void locomolcd_power(int on) } /* read comadj */ - if (comadj == -1) { - if (machine_is_poodle()) - comadj = 118; - if (machine_is_collie()) - comadj = 128; - } + if (comadj == -1 && machine_is_collie()) + comadj = 128; + if (comadj == -1 && machine_is_poodle()) + comadj = 118; if (on) locomolcd_on(comadj); @@ -105,26 +108,100 @@ void locomolcd_power(int on) } EXPORT_SYMBOL(locomolcd_power); -static int poodle_lcd_probe(struct locomo_dev *dev) + +static int current_intensity; + +static int locomolcd_set_intensity(struct backlight_device *bd) +{ + int intensity = bd->props->brightness; + + if (bd->props->power != FB_BLANK_UNBLANK) + intensity = 0; + if (bd->props->fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + if (locomolcd_flags & LOCOMOLCD_SUSPENDED) + intensity = 0; + + switch (intensity) { + /* AC and non-AC are handled differently, but produce same results in sharp code? */ + case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break; + case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break; + case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break; + case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break; + case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break; + + default: + return -ENODEV; + } + current_intensity = intensity; + return 0; +} + +static int locomolcd_get_intensity(struct backlight_device *bd) +{ + return current_intensity; +} + +static struct backlight_properties locomobl_data = { + .owner = THIS_MODULE, + .get_brightness = locomolcd_get_intensity, + .update_status = locomolcd_set_intensity, + .max_brightness = 4, +}; + +#ifdef CONFIG_PM +static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state) +{ + locomolcd_flags |= LOCOMOLCD_SUSPENDED; + locomolcd_set_intensity(locomolcd_bl_device); + return 0; +} + +static int locomolcd_resume(struct locomo_dev *dev) +{ + locomolcd_flags &= ~LOCOMOLCD_SUSPENDED; + locomolcd_set_intensity(locomolcd_bl_device); + return 0; +} +#else +#define locomolcd_suspend NULL +#define locomolcd_resume NULL +#endif + +static int locomolcd_probe(struct locomo_dev *dev) { unsigned long flags; local_irq_save(flags); locomolcd_dev = dev; + locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0); + /* the poodle_lcd_power function is called for the first time * from fs_initcall, which is before locomo is activated. * We need to recall poodle_lcd_power here*/ -#ifdef CONFIG_MACH_POODLE - locomolcd_power(1); -#endif + if (machine_is_poodle()) + locomolcd_power(1); + local_irq_restore(flags); + + locomolcd_bl_device = backlight_device_register("locomo-bl", NULL, &locomobl_data); + + if (IS_ERR (locomolcd_bl_device)) + return PTR_ERR (locomolcd_bl_device); + + /* Set up frontlight so that screen is readable */ + locomobl_data.brightness = 2; + locomolcd_set_intensity(locomolcd_bl_device); + return 0; } -static int poodle_lcd_remove(struct locomo_dev *dev) +static int locomolcd_remove(struct locomo_dev *dev) { unsigned long flags; + + backlight_device_unregister(locomolcd_bl_device); local_irq_save(flags); locomolcd_dev = NULL; local_irq_restore(flags); @@ -136,19 +213,33 @@ static struct locomo_driver poodle_lcd_driver = { .name = "locomo-backlight", }, .devid = LOCOMO_DEVID_BACKLIGHT, - .probe = poodle_lcd_probe, - .remove = poodle_lcd_remove, + .probe = locomolcd_probe, + .remove = locomolcd_remove, + .suspend = locomolcd_suspend, + .resume = locomolcd_resume, }; -static int __init poodle_lcd_init(void) + +static int __init locomolcd_init(void) { int ret = locomo_driver_register(&poodle_lcd_driver); - if (ret) return ret; + if (ret) + return ret; #ifdef CONFIG_SA1100_COLLIE sa1100fb_lcd_power = locomolcd_power; #endif return 0; } -device_initcall(poodle_lcd_init); +static void __exit locomolcd_exit(void) +{ + locomo_driver_unregister(&poodle_lcd_driver); +} + +module_init(locomolcd_init); +module_exit(locomolcd_exit); + +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>"); +MODULE_DESCRIPTION("Collie LCD driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c index 8ba6152db2f..ad8a89bf8ea 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/cfbimgblt.c @@ -230,6 +230,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * tab = cfb_tab16; break; case 32: + default: tab = cfb_tab32; break; } diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 1103010af54..dda240eb736 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -2227,7 +2227,6 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo) release_region(0x3C0, 32); pci_release_regions(pdev); framebuffer_release(cinfo->info); - pci_disable_device(pdev); } #endif /* CONFIG_PCI */ @@ -2458,7 +2457,6 @@ err_release_regions: err_release_fb: framebuffer_release(info); err_disable: - pci_disable_device(pdev); err_out: return ret; } diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 47ba1a79adc..5dc4083552d 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -125,6 +125,8 @@ static int softback_lines; static int first_fb_vc; static int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; +static int fbcon_has_exited; + /* font data */ static char fontname[40]; @@ -140,7 +142,6 @@ static const struct consw fb_con; #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row) -static void fbcon_free_font(struct display *); static int fbcon_set_origin(struct vc_data *); #define CURSOR_DRAW_DELAY (1) @@ -194,6 +195,9 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p, int line, int count, int dy); static void fbcon_modechanged(struct fb_info *info); static void fbcon_set_all_vcs(struct fb_info *info); +static void fbcon_start(void); +static void fbcon_exit(void); +static struct class_device *fbcon_class_device; #ifdef CONFIG_MAC /* @@ -252,7 +256,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) if (!ops || ops->currcon < 0 || rotate > 3) return; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { vc = vc_cons[i].d; if (!vc || vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[i]] != info) @@ -389,15 +393,18 @@ static void fb_flashcursor(void *private) int c; int mode; - if (ops->currcon != -1) + acquire_console_sem(); + if (ops && ops->currcon != -1) vc = vc_cons[ops->currcon].d; if (!vc || !CON_IS_VISIBLE(vc) || fbcon_is_inactive(vc, info) || registered_fb[con2fb_map[vc->vc_num]] != info || - vc_cons[ops->currcon].d->vc_deccm != 1) + vc_cons[ops->currcon].d->vc_deccm != 1) { + release_console_sem(); return; - acquire_console_sem(); + } + p = &fb_display[vc->vc_num]; c = scr_readw((u16 *) vc->vc_pos); mode = (!ops->cursor_flash || ops->cursor_state.enable) ? @@ -528,7 +535,7 @@ static int search_fb_in_map(int idx) { int i, retval = 0; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] == idx) retval = 1; } @@ -539,7 +546,7 @@ static int search_for_mapped_con(void) { int i, retval = 0; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] != -1) retval = 1; } @@ -561,6 +568,7 @@ static int fbcon_takeover(int show_logo) err = take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); + if (err) { for (i = first_fb_vc; i <= last_fb_vc; i++) { con2fb_map[i] = -1; @@ -795,8 +803,8 @@ static int set_con2fb_map(int unit, int newidx, int user) if (oldidx == newidx) return 0; - if (!info) - err = -EINVAL; + if (!info || fbcon_has_exited) + return -EINVAL; if (!err && !search_for_mapped_con()) { info_idx = newidx; @@ -832,6 +840,9 @@ static int set_con2fb_map(int unit, int newidx, int user) con2fb_init_display(vc, info, unit, show_logo); } + if (!search_fb_in_map(info_idx)) + info_idx = newidx; + release_console_sem(); return err; } @@ -1034,6 +1045,7 @@ static const char *fbcon_startup(void) #endif /* CONFIG_MAC */ fbcon_add_cursor_timer(info); + fbcon_has_exited = 0; return display_desc; } @@ -1061,17 +1073,36 @@ static void fbcon_init(struct vc_data *vc, int init) /* If we are not the first console on this fb, copy the font from that console */ - t = &fb_display[svc->vc_num]; - if (!vc->vc_font.data) { - vc->vc_font.data = (void *)(p->fontdata = t->fontdata); - vc->vc_font.width = (*default_mode)->vc_font.width; - vc->vc_font.height = (*default_mode)->vc_font.height; - p->userfont = t->userfont; - if (p->userfont) - REFCOUNT(p->fontdata)++; + t = &fb_display[fg_console]; + if (!p->fontdata) { + if (t->fontdata) { + struct vc_data *fvc = vc_cons[fg_console].d; + + vc->vc_font.data = (void *)(p->fontdata = + fvc->vc_font.data); + vc->vc_font.width = fvc->vc_font.width; + vc->vc_font.height = fvc->vc_font.height; + p->userfont = t->userfont; + + if (p->userfont) + REFCOUNT(p->fontdata)++; + } else { + const struct font_desc *font = NULL; + + if (!fontname[0] || !(font = find_font(fontname))) + font = get_default_font(info->var.xres, + info->var.yres); + vc->vc_font.width = font->width; + vc->vc_font.height = font->height; + vc->vc_font.data = (void *)(p->fontdata = font->data); + vc->vc_font.charcount = 256; /* FIXME Need to + support more fonts */ + } } + if (p->userfont) charcnt = FNTCHARCNT(p->fontdata); + vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; if (charcnt == 256) { @@ -1145,13 +1176,47 @@ static void fbcon_init(struct vc_data *vc, int init) ops->p = &fb_display[fg_console]; } +static void fbcon_free_font(struct display *p) +{ + if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); + p->fontdata = NULL; + p->userfont = 0; +} + static void fbcon_deinit(struct vc_data *vc) { struct display *p = &fb_display[vc->vc_num]; + struct fb_info *info; + struct fbcon_ops *ops; + int idx; - if (info_idx != -1) - return; fbcon_free_font(p); + idx = con2fb_map[vc->vc_num]; + + if (idx == -1) + goto finished; + + info = registered_fb[idx]; + + if (!info) + goto finished; + + ops = info->fbcon_par; + + if (!ops) + goto finished; + + if (CON_IS_VISIBLE(vc)) + fbcon_del_cursor_timer(info); + + ops->flags &= ~FBCON_FLAGS_INIT; +finished: + + if (!con_is_bound(&fb_con)) + fbcon_exit(); + + return; } /* ====================================================================== */ @@ -2099,12 +2164,11 @@ static int fbcon_switch(struct vc_data *vc) if (info->fbops->fb_set_par) info->fbops->fb_set_par(info); - if (old_info != info) { + if (old_info != info) fbcon_del_cursor_timer(old_info); - fbcon_add_cursor_timer(info); - } } + fbcon_add_cursor_timer(info); set_blitting_type(vc, info); ops->cursor_reset = 1; @@ -2222,14 +2286,6 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) return 0; } -static void fbcon_free_font(struct display *p) -{ - if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) - kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); - p->fontdata = NULL; - p->userfont = 0; -} - static int fbcon_get_font(struct vc_data *vc, struct console_font *font) { u8 *fontdata = vc->vc_font.data; @@ -2443,7 +2499,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne FNTSUM(new_data) = csum; /* Check if the same font is on some other console already */ - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { struct vc_data *tmp = vc_cons[i].d; if (fb_display[i].userfont && @@ -2768,7 +2824,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) if (!ops || ops->currcon < 0) return; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { vc = vc_cons[i].d; if (!vc || vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[i]] != info) @@ -2830,22 +2886,57 @@ static int fbcon_mode_deleted(struct fb_info *info, return found; } +static int fbcon_fb_unregistered(int idx) +{ + int i; + + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map[i] == idx) + con2fb_map[i] = -1; + } + + if (idx == info_idx) { + info_idx = -1; + + for (i = 0; i < FB_MAX; i++) { + if (registered_fb[i] != NULL) { + info_idx = i; + break; + } + } + } + + if (info_idx != -1) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map[i] == -1) + con2fb_map[i] = info_idx; + } + } + + if (!num_registered_fb) + unregister_con_driver(&fb_con); + + return 0; +} + static int fbcon_fb_registered(int idx) { int ret = 0, i; if (info_idx == -1) { - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map_boot[i] == idx) { info_idx = idx; break; } } + if (info_idx != -1) ret = fbcon_takeover(1); } else { - for (i = 0; i < MAX_NR_CONSOLES; i++) { - if (con2fb_map_boot[i] == idx) + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map_boot[i] == idx && + con2fb_map[i] == -1) set_con2fb_map(i, idx, 0); } } @@ -2882,7 +2973,7 @@ static void fbcon_new_modelist(struct fb_info *info) struct fb_var_screeninfo var; struct fb_videomode *mode; - for (i = 0; i < MAX_NR_CONSOLES; i++) { + for (i = first_fb_vc; i <= last_fb_vc; i++) { if (registered_fb[con2fb_map[i]] != info) continue; if (!fb_display[i].mode) @@ -2910,6 +3001,14 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_con2fbmap *con2fb; int ret = 0; + /* + * ignore all events except driver registration and deregistration + * if fbcon is not active + */ + if (fbcon_has_exited && !(action == FB_EVENT_FB_REGISTERED || + action == FB_EVENT_FB_UNREGISTERED)) + goto done; + switch(action) { case FB_EVENT_SUSPEND: fbcon_suspended(info); @@ -2930,6 +3029,9 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_FB_REGISTERED: ret = fbcon_fb_registered(info->node); break; + case FB_EVENT_FB_UNREGISTERED: + ret = fbcon_fb_unregistered(info->node); + break; case FB_EVENT_SET_CONSOLE_MAP: con2fb = event->data; ret = set_con2fb_map(con2fb->console - 1, @@ -2945,16 +3047,9 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_NEW_MODELIST: fbcon_new_modelist(info); break; - case FB_EVENT_SET_CON_ROTATE: - fbcon_rotate(info, *(int *)event->data); - break; - case FB_EVENT_GET_CON_ROTATE: - ret = fbcon_get_rotate(info); - break; - case FB_EVENT_SET_CON_ROTATE_ALL: - fbcon_rotate_all(info, *(int *)event->data); } +done: return ret; } @@ -2992,27 +3087,181 @@ static struct notifier_block fbcon_event_notifier = { .notifier_call = fbcon_event_notify, }; -static int __init fb_console_init(void) +static ssize_t store_rotate(struct class_device *class_device, + const char *buf, size_t count) { - int i; + struct fb_info *info; + int rotate, idx; + char **last = NULL; + + if (fbcon_has_exited) + return count; acquire_console_sem(); - fb_register_client(&fbcon_event_notifier); + idx = con2fb_map[fg_console]; + + if (idx == -1 || registered_fb[idx] == NULL) + goto err; + + info = registered_fb[idx]; + rotate = simple_strtoul(buf, last, 0); + fbcon_rotate(info, rotate); +err: release_console_sem(); + return count; +} - for (i = 0; i < MAX_NR_CONSOLES; i++) - con2fb_map[i] = -1; +static ssize_t store_rotate_all(struct class_device *class_device, + const char *buf, size_t count) +{ + struct fb_info *info; + int rotate, idx; + char **last = NULL; + + if (fbcon_has_exited) + return count; + + acquire_console_sem(); + idx = con2fb_map[fg_console]; + + if (idx == -1 || registered_fb[idx] == NULL) + goto err; + info = registered_fb[idx]; + rotate = simple_strtoul(buf, last, 0); + fbcon_rotate_all(info, rotate); +err: + release_console_sem(); + return count; +} + +static ssize_t show_rotate(struct class_device *class_device, char *buf) +{ + struct fb_info *info; + int rotate = 0, idx; + + if (fbcon_has_exited) + return 0; + + acquire_console_sem(); + idx = con2fb_map[fg_console]; + + if (idx == -1 || registered_fb[idx] == NULL) + goto err; + + info = registered_fb[idx]; + rotate = fbcon_get_rotate(info); +err: + release_console_sem(); + return snprintf(buf, PAGE_SIZE, "%d\n", rotate); +} + +static struct class_device_attribute class_device_attrs[] = { + __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), + __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all), +}; + +static int fbcon_init_class_device(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_create_file(fbcon_class_device, + &class_device_attrs[i]); + return 0; +} + +static void fbcon_start(void) +{ if (num_registered_fb) { + int i; + + acquire_console_sem(); + for (i = 0; i < FB_MAX; i++) { if (registered_fb[i] != NULL) { info_idx = i; break; } } + + release_console_sem(); fbcon_takeover(0); } +} + +static void fbcon_exit(void) +{ + struct fb_info *info; + int i, j, mapped; + + if (fbcon_has_exited) + return; + +#ifdef CONFIG_ATARI + free_irq(IRQ_AUTO_4, fbcon_vbl_handler); +#endif +#ifdef CONFIG_MAC + if (MACH_IS_MAC && vbl_detected) + free_irq(IRQ_MAC_VBL, fbcon_vbl_handler); +#endif + + kfree((void *)softback_buf); + softback_buf = 0UL; + + for (i = 0; i < FB_MAX; i++) { + mapped = 0; + info = registered_fb[i]; + + if (info == NULL) + continue; + + for (j = first_fb_vc; j <= last_fb_vc; j++) { + if (con2fb_map[j] == i) + mapped = 1; + } + + if (mapped) { + if (info->fbops->fb_release) + info->fbops->fb_release(info, 0); + module_put(info->fbops->owner); + + if (info->fbcon_par) { + fbcon_del_cursor_timer(info); + kfree(info->fbcon_par); + info->fbcon_par = NULL; + } + if (info->queue.func == fb_flashcursor) + info->queue.func = NULL; + } + } + + fbcon_has_exited = 1; +} + +static int __init fb_console_init(void) +{ + int i; + + acquire_console_sem(); + fb_register_client(&fbcon_event_notifier); + fbcon_class_device = + class_device_create(fb_class, NULL, MKDEV(0, 0), NULL, "fbcon"); + + if (IS_ERR(fbcon_class_device)) { + printk(KERN_WARNING "Unable to create class_device " + "for fbcon; errno = %ld\n", + PTR_ERR(fbcon_class_device)); + fbcon_class_device = NULL; + } else + fbcon_init_class_device(); + + for (i = 0; i < MAX_NR_CONSOLES; i++) + con2fb_map[i] = -1; + + release_console_sem(); + fbcon_start(); return 0; } @@ -3020,12 +3269,24 @@ module_init(fb_console_init); #ifdef MODULE +static void __exit fbcon_deinit_class_device(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_remove_file(fbcon_class_device, + &class_device_attrs[i]); +} + static void __exit fb_console_exit(void) { acquire_console_sem(); fb_unregister_client(&fbcon_event_notifier); + fbcon_deinit_class_device(); + class_device_destroy(fb_class, MKDEV(0, 0)); + fbcon_exit(); release_console_sem(); - give_up_console(&fb_con); + unregister_con_driver(&fb_con); } module_exit(fb_console_exit); diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index c38c3d8e7a7..3487a636370 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -175,6 +175,7 @@ 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); +extern struct class *fb_class; #define FBCON_ATTRIBUTE_UNDERLINE 1 #define FBCON_ATTRIBUTE_REVERSE 2 diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 7f939d066a5..c89f90edf8a 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -308,7 +308,7 @@ static void __init mda_initialize(void) outb_p(0x00, mda_gfx_port); } -static const char __init *mdacon_startup(void) +static const char *mdacon_startup(void) { mda_num_columns = 80; mda_num_lines = 25; diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index e99fe30e568..03041311711 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -51,6 +51,7 @@ static int topscan; static int xcurs_correction = 29; static int newport_xsize; static int newport_ysize; +static int newport_has_init; static int newport_set_def_font(int unit, struct console_font *op); @@ -283,6 +284,15 @@ static void newport_get_revisions(void) xcurs_correction = 21; } +static void newport_exit(void) +{ + int i; + + /* free memory used by user font */ + for (i = 0; i < MAX_NR_CONSOLES; i++) + newport_set_def_font(i, NULL); +} + /* Can't be __init, take_over_console may call it later */ static const char *newport_startup(void) { @@ -290,8 +300,10 @@ static const char *newport_startup(void) if (!sgi_gfxaddr) return NULL; - npregs = (struct newport_regs *) /* ioremap cannot fail */ - ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); + + if (!npregs) + npregs = (struct newport_regs *)/* ioremap cannot fail */ + ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); npregs->cset.config = NPORT_CFG_GD0; if (newport_wait(npregs)) @@ -307,11 +319,11 @@ static const char *newport_startup(void) newport_reset(); newport_get_revisions(); newport_get_screensize(); + newport_has_init = 1; return "SGI Newport"; out_unmap: - iounmap((void *)npregs); return NULL; } @@ -324,11 +336,10 @@ static void newport_init(struct vc_data *vc, int init) static void newport_deinit(struct vc_data *c) { - int i; - - /* free memory used by user font */ - for (i = 0; i < MAX_NR_CONSOLES; i++) - newport_set_def_font(i, NULL); + if (!con_is_bound(&newport_con) && newport_has_init) { + newport_exit(); + newport_has_init = 0; + } } static void newport_clear(struct vc_data *vc, int sy, int sx, int height, @@ -728,16 +739,23 @@ const struct consw newport_con = { #ifdef MODULE static int __init newport_console_init(void) { + + if (!sgi_gfxaddr) + return NULL; + + if (!npregs) + npregs = (struct newport_regs *)/* ioremap cannot fail */ + ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); + return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); } +module_init(newport_console_init); static void __exit newport_console_exit(void) { give_up_console(&newport_con); iounmap((void *)npregs); } - -module_init(newport_console_init); module_exit(newport_console_exit); #endif diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c index 04f42fcaac5..d6e6ad537f9 100644 --- a/drivers/video/console/promcon.c +++ b/drivers/video/console/promcon.c @@ -109,7 +109,7 @@ promcon_end(struct vc_data *conp, char *b) return b - p; } -const char __init *promcon_startup(void) +const char *promcon_startup(void) { const char *display_desc = "PROM"; int node; @@ -133,7 +133,7 @@ const char __init *promcon_startup(void) return display_desc; } -static void __init +static void promcon_init_unimap(struct vc_data *conp) { mm_segment_t old_fs = get_fs(); diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index fd5940f4127..45c4f227e56 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -75,7 +75,7 @@ static inline void cursor_undrawn(void) cursor_drawn = 0; } -static const char *__init sticon_startup(void) +static const char *sticon_startup(void) { return "STI console"; } diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index e64d42e2449..f32b590730f 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -114,6 +114,7 @@ static int vga_512_chars; static int vga_video_font_height; static int vga_scan_lines; static unsigned int vga_rolled_over = 0; +static int vga_init_done; static int __init no_scroll(char *str) { @@ -190,7 +191,7 @@ static void vgacon_scrollback_init(int pitch) } } -static void __init vgacon_scrollback_startup(void) +static void vgacon_scrollback_startup(void) { vgacon_scrollback = alloc_bootmem(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024); @@ -355,7 +356,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines) } #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ -static const char __init *vgacon_startup(void) +static const char *vgacon_startup(void) { const char *display_desc = NULL; u16 saved1, saved2; @@ -523,7 +524,12 @@ static const char __init *vgacon_startup(void) vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; vgacon_yres = vga_scan_lines; - vgacon_scrollback_startup(); + + if (!vga_init_done) { + vgacon_scrollback_startup(); + vga_init_done = 1; + } + return display_desc; } @@ -531,10 +537,20 @@ static void vgacon_init(struct vc_data *c, int init) { unsigned long p; - /* We cannot be loaded as a module, therefore init is always 1 */ + /* + * We cannot be loaded as a module, therefore init is always 1, + * but vgacon_init can be called more than once, and init will + * not be 1. + */ c->vc_can_do_color = vga_can_do_color; - c->vc_cols = vga_video_num_columns; - c->vc_rows = vga_video_num_lines; + + /* set dimensions manually if init != 0 since vc_resize() will fail */ + if (init) { + c->vc_cols = vga_video_num_columns; + c->vc_rows = vga_video_num_lines; + } else + vc_resize(c, vga_video_num_columns, vga_video_num_lines); + c->vc_scan_lines = vga_scan_lines; c->vc_font.height = vga_video_font_height; c->vc_complement_mask = 0x7700; diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c index 082759447bf..f0a621ecc28 100644 --- a/drivers/video/epson1355fb.c +++ b/drivers/video/epson1355fb.c @@ -605,11 +605,6 @@ static void clearfb16(struct fb_info *info) fb_writeb(0, dst); } -static void epson1355fb_platform_release(struct device *device) -{ - dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n"); -} - static int epson1355fb_remove(struct platform_device *dev) { struct fb_info *info = platform_get_drvdata(dev); @@ -733,13 +728,7 @@ static struct platform_driver epson1355fb_driver = { }, }; -static struct platform_device epson1355fb_device = { - .name = "epson1355fb", - .id = 0, - .dev = { - .release = epson1355fb_platform_release, - } -}; +static struct platform_device *epson1355fb_device; int __init epson1355fb_init(void) { @@ -749,11 +738,21 @@ int __init epson1355fb_init(void) return -ENODEV; ret = platform_driver_register(&epson1355fb_driver); + if (!ret) { - ret = platform_device_register(&epson1355fb_device); - if (ret) + epson1355fb_device = platform_device_alloc("epson1355fb", 0); + + if (epson1355fb_device) + ret = platform_device_add(epson1355fb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(epson1355fb_device); platform_driver_unregister(&epson1355fb_driver); + } } + return ret; } @@ -762,7 +761,7 @@ module_init(epson1355fb_init); #ifdef MODULE static void __exit epson1355fb_exit(void) { - platform_device_unregister(&epson1355fb_device); + platform_device_unregister(epson1355fb_device); platform_driver_unregister(&epson1355fb_driver); } diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c index ac90883dc3a..b5498999c4e 100644 --- a/drivers/video/fbcvt.c +++ b/drivers/video/fbcvt.c @@ -376,4 +376,3 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb) return 0; } -EXPORT_SYMBOL(fb_find_mode_cvt); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 372aa177682..31143afe7c9 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -34,7 +34,6 @@ #endif #include <linux/devfs_fs_kernel.h> #include <linux/err.h> -#include <linux/kernel.h> #include <linux/device.h> #include <linux/efi.h> @@ -162,7 +161,6 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size } #ifdef CONFIG_LOGO -#include <linux/linux_logo.h> static inline unsigned safe_shift(unsigned d, int n) { @@ -336,11 +334,11 @@ static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height) static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height) { - int i, j, w = width - 1; + int i, j, h = height - 1; for (i = 0; i < height; i++) for (j = 0; j < width; j++) - out[height * j + w - i] = *in++; + out[height * j + h - i] = *in++; } static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height) @@ -358,24 +356,24 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst, u32 tmp; if (rotate == FB_ROTATE_UD) { - image->dx = info->var.xres - image->width; - image->dy = info->var.yres - image->height; fb_rotate_logo_ud(image->data, dst, image->width, image->height); + image->dx = info->var.xres - image->width; + image->dy = info->var.yres - image->height; } else if (rotate == FB_ROTATE_CW) { - tmp = image->width; - image->width = image->height; - image->height = tmp; - image->dx = info->var.xres - image->height; fb_rotate_logo_cw(image->data, dst, image->width, image->height); - } else if (rotate == FB_ROTATE_CCW) { tmp = image->width; image->width = image->height; image->height = tmp; - image->dy = info->var.yres - image->width; + image->dx = info->var.xres - image->width; + } else if (rotate == FB_ROTATE_CCW) { fb_rotate_logo_ccw(image->data, dst, image->width, image->height); + tmp = image->width; + image->width = image->height; + image->height = tmp; + image->dy = info->var.yres - image->height; } image->data = dst; @@ -435,7 +433,7 @@ int fb_prepare_logo(struct fb_info *info, int rotate) depth = info->var.green.length; } - if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { + if (info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR && depth > 4) { /* assume console colormap */ depth = 4; } @@ -1278,8 +1276,8 @@ static struct file_operations fb_fops = { #endif }; -static struct class *fb_class; - +struct class *fb_class; +EXPORT_SYMBOL(fb_class); /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure @@ -1355,6 +1353,7 @@ register_framebuffer(struct fb_info *fb_info) int unregister_framebuffer(struct fb_info *fb_info) { + struct fb_event event; int i; i = fb_info->node; @@ -1362,13 +1361,17 @@ unregister_framebuffer(struct fb_info *fb_info) return -EINVAL; devfs_remove("fb/%d", i); - if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) + if (fb_info->pixmap.addr && + (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); fb_destroy_modelist(&fb_info->modelist); registered_fb[i]=NULL; num_registered_fb--; fb_cleanup_class_device(fb_info); class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); + event.info = fb_info; + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_FB_UNREGISTERED, &event); return 0; } @@ -1491,28 +1494,6 @@ int fb_new_modelist(struct fb_info *info) return err; } -/** - * fb_con_duit - user<->fbcon passthrough - * @info: struct fb_info - * @event: notification event to be passed to fbcon - * @data: private data - * - * DESCRIPTION - * This function is an fbcon-user event passing channel - * which bypasses fbdev. This is hopefully temporary - * until a user interface for fbcon is created - */ -int fb_con_duit(struct fb_info *info, int event, void *data) -{ - struct fb_event evnt; - - evnt.info = info; - evnt.data = data; - - return blocking_notifier_call_chain(&fb_notifier_list, event, &evnt); -} -EXPORT_SYMBOL(fb_con_duit); - static char *video_options[FB_MAX]; static int ofonly; @@ -1622,6 +1603,5 @@ EXPORT_SYMBOL(fb_set_suspend); EXPORT_SYMBOL(fb_register_client); EXPORT_SYMBOL(fb_unregister_client); EXPORT_SYMBOL(fb_get_options); -EXPORT_SYMBOL(fb_new_modelist); MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 53beeb4a999..3ccfff715a5 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -29,9 +29,9 @@ #include <linux/tty.h> #include <linux/fb.h> #include <linux/module.h> +#include <linux/pci.h> #include <video/edid.h> #ifdef CONFIG_PPC_OF -#include <linux/pci.h> #include <asm/prom.h> #include <asm/pci-bridge.h> #endif @@ -605,6 +605,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) block = edid + DETAILED_TIMING_DESCRIPTIONS_START; DPRINTK(" Monitor Operating Limits: "); + for (i = 0; i < 4; i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { if (edid_is_limits_block(block)) { specs->hfmin = H_MIN_RATE * 1000; @@ -618,11 +619,12 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) break; } } - + /* estimate monitor limits based on modes supported */ if (retval) { - struct fb_videomode *modes; + struct fb_videomode *modes, *mode; int num_modes, i, hz, hscan, pixclock; + int vtotal, htotal; modes = fb_create_modedb(edid, &num_modes); if (!modes) { @@ -632,20 +634,38 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) retval = 0; for (i = 0; i < num_modes; i++) { - hz = modes[i].refresh; + mode = &modes[i]; pixclock = PICOS2KHZ(modes[i].pixclock) * 1000; - hscan = (modes[i].yres * 105 * hz + 5000)/100; + htotal = mode->xres + mode->right_margin + mode->hsync_len + + mode->left_margin; + vtotal = mode->yres + mode->lower_margin + mode->vsync_len + + mode->upper_margin; + + if (mode->vmode & FB_VMODE_INTERLACED) + vtotal /= 2; + + if (mode->vmode & FB_VMODE_DOUBLE) + vtotal *= 2; + + hscan = (pixclock + htotal / 2) / htotal; + hscan = (hscan + 500) / 1000 * 1000; + hz = (hscan + vtotal / 2) / vtotal; if (specs->dclkmax == 0 || specs->dclkmax < pixclock) specs->dclkmax = pixclock; + if (specs->dclkmin == 0 || specs->dclkmin > pixclock) specs->dclkmin = pixclock; + if (specs->hfmax == 0 || specs->hfmax < hscan) specs->hfmax = hscan; + if (specs->hfmin == 0 || specs->hfmin > hscan) specs->hfmin = hscan; + if (specs->vfmax == 0 || specs->vfmax < hz) specs->vfmax = hz; + if (specs->vfmin == 0 || specs->vfmin > hz) specs->vfmin = hz; } @@ -1281,8 +1301,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) -EINVAL : 0; } -#if defined(CONFIG_FB_FIRMWARE_EDID) && defined(__i386__) -#include <linux/pci.h> +#if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86) /* * We need to ensure that the EDID block is only returned for diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 3ceb8c1b392..4f78f234473 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -100,13 +100,22 @@ static int mode_string(char *buf, unsigned int offset, const struct fb_videomode *mode) { char m = 'U'; + char v = 'p'; + if (mode->flag & FB_MODE_IS_DETAILED) m = 'D'; if (mode->flag & FB_MODE_IS_VESA) m = 'V'; if (mode->flag & FB_MODE_IS_STANDARD) m = 'S'; - return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d-%d\n", m, mode->xres, mode->yres, mode->refresh); + + if (mode->vmode & FB_VMODE_INTERLACED) + v = 'i'; + if (mode->vmode & FB_VMODE_DOUBLE) + v = 'd'; + + return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d%c-%d\n", + m, mode->xres, mode->yres, v, mode->refresh); } static ssize_t store_mode(struct class_device *class_device, const char * buf, @@ -238,45 +247,6 @@ static ssize_t show_rotate(struct class_device *class_device, char *buf) return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); } -static ssize_t store_con_rotate(struct class_device *class_device, - const char *buf, size_t count) -{ - struct fb_info *fb_info = class_get_devdata(class_device); - int rotate; - char **last = NULL; - - acquire_console_sem(); - rotate = simple_strtoul(buf, last, 0); - fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate); - release_console_sem(); - return count; -} - -static ssize_t store_con_rotate_all(struct class_device *class_device, - const char *buf, size_t count) -{ - struct fb_info *fb_info = class_get_devdata(class_device); - int rotate; - char **last = NULL; - - acquire_console_sem(); - rotate = simple_strtoul(buf, last, 0); - fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate); - release_console_sem(); - return count; -} - -static ssize_t show_con_rotate(struct class_device *class_device, char *buf) -{ - struct fb_info *fb_info = class_get_devdata(class_device); - int rotate; - - acquire_console_sem(); - rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL); - release_console_sem(); - return snprintf(buf, PAGE_SIZE, "%d\n", rotate); -} - static ssize_t store_virtual(struct class_device *class_device, const char * buf, size_t count) { @@ -493,8 +463,6 @@ static struct class_device_attribute class_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), __ATTR(stride, S_IRUGO, show_stride, NULL), __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), #ifdef CONFIG_FB_BACKLIGHT __ATTR(bl_curve, S_IRUGO|S_IWUSR, show_bl_curve, store_bl_curve), diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c index 20e69156d72..4d3a8871d3d 100644 --- a/drivers/video/geode/gx1fb_core.c +++ b/drivers/video/geode/gx1fb_core.c @@ -376,8 +376,6 @@ static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id * release_mem_region(gx1_gx_base() + 0x8300, 0x100); } - pci_disable_device(pdev); - if (info) framebuffer_release(info); return ret; @@ -399,7 +397,6 @@ static void gx1fb_remove(struct pci_dev *pdev) iounmap(par->dc_regs); release_mem_region(gx1_gx_base() + 0x8300, 0x100); - pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); framebuffer_release(info); diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c index 89c34b15f5d..5ef12a3dfa5 100644 --- a/drivers/video/geode/gxfb_core.c +++ b/drivers/video/geode/gxfb_core.c @@ -354,8 +354,6 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i pci_release_region(pdev, 2); } - pci_disable_device(pdev); - if (info) framebuffer_release(info); return ret; @@ -377,7 +375,6 @@ static void gxfb_remove(struct pci_dev *pdev) iounmap(par->dc_regs); pci_release_region(pdev, 2); - pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); framebuffer_release(info); diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 44aa2ffff97..a1f7d80f0ac 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -2110,9 +2110,6 @@ static void i810fb_release_resource(struct fb_info *info, if (par->res_flags & MMIO_REQ) release_mem_region(par->mmio_start_phys, MMIO_SIZE); - if (par->res_flags & PCI_DEVICE_ENABLED) - pci_disable_device(par->dev); - framebuffer_release(info); } diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c new file mode 100644 index 00000000000..7b1c168c834 --- /dev/null +++ b/drivers/video/imacfb.c @@ -0,0 +1,345 @@ +/* + * framebuffer driver for Intel Based Mac's + * + * (c) 2006 Edgar Hucek <gimli@dark-green.com> + * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de> + * + */ + +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/fb.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/tty.h> + +#include <asm/io.h> + +#include <video/vga.h> + +typedef enum _MAC_TYPE { + M_I17, + M_I20, + M_MINI, + M_MACBOOK, + M_NEW +} MAC_TYPE; + +/* --------------------------------------------------------------------- */ + +static struct fb_var_screeninfo imacfb_defined __initdata = { + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .right_margin = 32, + .upper_margin = 16, + .lower_margin = 4, + .vsync_len = 4, + .vmode = FB_VMODE_NONINTERLACED, +}; + +static struct fb_fix_screeninfo imacfb_fix __initdata = { + .id = "IMAC VGA", + .type = FB_TYPE_PACKED_PIXELS, + .accel = FB_ACCEL_NONE, + .visual = FB_VISUAL_TRUECOLOR, +}; + +static int inverse; +static int model = M_NEW; +static int manual_height; +static int manual_width; + +#define DEFAULT_FB_MEM 1024*1024*16 + +/* --------------------------------------------------------------------- */ + +static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + /* + * Set a single color register. The values supplied are + * already rounded down to the hardware's capabilities + * (according to the entries in the `var' structure). Return + * != 0 for invalid regno. + */ + + if (regno >= info->cmap.len) + return 1; + + if (regno < 16) { + red >>= 8; + green >>= 8; + blue >>= 8; + ((u32 *)(info->pseudo_palette))[regno] = + (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); + } + return 0; +} + +static struct fb_ops imacfb_ops = { + .owner = THIS_MODULE, + .fb_setcolreg = imacfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, +}; + +static int __init imacfb_setup(char *options) +{ + char *this_opt; + + if (!options || !*options) + return 0; + + while ((this_opt = strsep(&options, ",")) != NULL) { + if (!*this_opt) continue; + + if (!strcmp(this_opt, "inverse")) + inverse = 1; + else if (!strcmp(this_opt, "i17")) + model = M_I17; + else if (!strcmp(this_opt, "i20")) + model = M_I20; + else if (!strcmp(this_opt, "mini")) + model = M_MINI; + else if (!strcmp(this_opt, "macbook")) + model = M_MACBOOK; + else if (!strncmp(this_opt, "height:", 7)) + manual_height = simple_strtoul(this_opt+7, NULL, 0); + else if (!strncmp(this_opt, "width:", 6)) + manual_width = simple_strtoul(this_opt+6, NULL, 0); + } + return 0; +} + +static int __init imacfb_probe(struct platform_device *dev) +{ + struct fb_info *info; + int err; + unsigned int size_vmode; + unsigned int size_remap; + unsigned int size_total; + + screen_info.lfb_depth = 32; + screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000; + screen_info.pages=1; + screen_info.blue_size = 8; + screen_info.blue_pos = 0; + screen_info.green_size = 8; + screen_info.green_pos = 8; + screen_info.red_size = 8; + screen_info.red_pos = 16; + screen_info.rsvd_size = 8; + screen_info.rsvd_pos = 24; + + switch (model) { + case M_I17: + screen_info.lfb_width = 1440; + screen_info.lfb_height = 900; + screen_info.lfb_linelength = 1472 * 4; + screen_info.lfb_base = 0x80010000; + break; + case M_NEW: + case M_I20: + screen_info.lfb_width = 1680; + screen_info.lfb_height = 1050; + screen_info.lfb_linelength = 1728 * 4; + screen_info.lfb_base = 0x80010000; + break; + case M_MINI: + screen_info.lfb_width = 1024; + screen_info.lfb_height = 768; + screen_info.lfb_linelength = 2048 * 4; + screen_info.lfb_base = 0x80000000; + break; + case M_MACBOOK: + screen_info.lfb_width = 1280; + screen_info.lfb_height = 800; + screen_info.lfb_linelength = 2048 * 4; + screen_info.lfb_base = 0x80000000; + break; + } + + /* if the user wants to manually specify height/width, + we will override the defaults */ + /* TODO: eventually get auto-detection working */ + if (manual_height > 0) + screen_info.lfb_height = manual_height; + if (manual_width > 0) + screen_info.lfb_width = manual_width; + + imacfb_fix.smem_start = screen_info.lfb_base; + imacfb_defined.bits_per_pixel = screen_info.lfb_depth; + imacfb_defined.xres = screen_info.lfb_width; + imacfb_defined.yres = screen_info.lfb_height; + imacfb_fix.line_length = screen_info.lfb_linelength; + + /* size_vmode -- that is the amount of memory needed for the + * used video mode, i.e. the minimum amount of + * memory we need. */ + size_vmode = imacfb_defined.yres * imacfb_fix.line_length; + + /* size_total -- all video memory we have. Used for + * entries, ressource allocation and bounds + * checking. */ + size_total = screen_info.lfb_size * 65536; + if (size_total < size_vmode) + size_total = size_vmode; + + /* size_remap -- the amount of video memory we are going to + * use for imacfb. With modern cards it is no + * option to simply use size_total as that + * wastes plenty of kernel address space. */ + size_remap = size_vmode * 2; + if (size_remap < size_vmode) + size_remap = size_vmode; + if (size_remap > size_total) + size_remap = size_total; + imacfb_fix.smem_len = size_remap; + +#ifndef __i386__ + screen_info.imacpm_seg = 0; +#endif + + if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) { + printk(KERN_WARNING + "imacfb: cannot reserve video memory at 0x%lx\n", + imacfb_fix.smem_start); + /* We cannot make this fatal. Sometimes this comes from magic + spaces our resource handlers simply don't know about */ + } + + info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev); + if (!info) { + err = -ENOMEM; + goto err_release_mem; + } + info->pseudo_palette = info->par; + info->par = NULL; + + info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len); + if (!info->screen_base) { + printk(KERN_ERR "imacfb: abort, cannot ioremap video memory " + "0x%x @ 0x%lx\n", + imacfb_fix.smem_len, imacfb_fix.smem_start); + err = -EIO; + goto err_unmap; + } + + printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, " + "using %dk, total %dk\n", + imacfb_fix.smem_start, info->screen_base, + size_remap/1024, size_total/1024); + printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n", + imacfb_defined.xres, imacfb_defined.yres, + imacfb_defined.bits_per_pixel, imacfb_fix.line_length, + screen_info.pages); + + imacfb_defined.xres_virtual = imacfb_defined.xres; + imacfb_defined.yres_virtual = imacfb_fix.smem_len / + imacfb_fix.line_length; + printk(KERN_INFO "imacfb: scrolling: redraw\n"); + imacfb_defined.yres_virtual = imacfb_defined.yres; + + /* some dummy values for timing to make fbset happy */ + imacfb_defined.pixclock = 10000000 / imacfb_defined.xres * + 1000 / imacfb_defined.yres; + imacfb_defined.left_margin = (imacfb_defined.xres / 8) & 0xf8; + imacfb_defined.hsync_len = (imacfb_defined.xres / 8) & 0xf8; + + imacfb_defined.red.offset = screen_info.red_pos; + imacfb_defined.red.length = screen_info.red_size; + imacfb_defined.green.offset = screen_info.green_pos; + imacfb_defined.green.length = screen_info.green_size; + imacfb_defined.blue.offset = screen_info.blue_pos; + imacfb_defined.blue.length = screen_info.blue_size; + imacfb_defined.transp.offset = screen_info.rsvd_pos; + imacfb_defined.transp.length = screen_info.rsvd_size; + + printk(KERN_INFO "imacfb: %s: " + "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n", + "Truecolor", + screen_info.rsvd_size, + screen_info.red_size, + screen_info.green_size, + screen_info.blue_size, + screen_info.rsvd_pos, + screen_info.red_pos, + screen_info.green_pos, + screen_info.blue_pos); + + imacfb_fix.ypanstep = 0; + imacfb_fix.ywrapstep = 0; + + /* request failure does not faze us, as vgacon probably has this + * region already (FIXME) */ + request_region(0x3c0, 32, "imacfb"); + + info->fbops = &imacfb_ops; + info->var = imacfb_defined; + info->fix = imacfb_fix; + info->flags = FBINFO_FLAG_DEFAULT; + + if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { + err = -ENOMEM; + goto err_unmap; + } + if (register_framebuffer(info)<0) { + err = -EINVAL; + goto err_fb_dealoc; + } + printk(KERN_INFO "fb%d: %s frame buffer device\n", + info->node, info->fix.id); + return 0; + +err_fb_dealoc: + fb_dealloc_cmap(&info->cmap); +err_unmap: + iounmap(info->screen_base); + framebuffer_release(info); +err_release_mem: + release_mem_region(imacfb_fix.smem_start, size_total); + return err; +} + +static struct platform_driver imacfb_driver = { + .probe = imacfb_probe, + .driver = { + .name = "imacfb", + }, +}; + +static struct platform_device imacfb_device = { + .name = "imacfb", +}; + +static int __init imacfb_init(void) +{ + int ret; + char *option = NULL; + + /* ignore error return of fb_get_options */ + fb_get_options("imacfb", &option); + imacfb_setup(option); + ret = platform_driver_register(&imacfb_driver); + + if (!ret) { + ret = platform_device_register(&imacfb_device); + if (ret) + platform_driver_unregister(&imacfb_driver); + } + return ret; +} +module_init(imacfb_init); + +MODULE_LICENSE("GPL"); diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c index c0385c6f7db..d21321ca7c3 100644 --- a/drivers/video/macmodes.c +++ b/drivers/video/macmodes.c @@ -327,7 +327,6 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, } return -EINVAL; } -EXPORT_SYMBOL(mac_var_to_vmode); /** * mac_map_monitor_sense - Convert monitor sense to vmode @@ -371,8 +370,9 @@ EXPORT_SYMBOL(mac_map_monitor_sense); * */ -int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info, - const char *mode_option, unsigned int default_bpp) +int __devinit mac_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, const char *mode_option, + unsigned int default_bpp) { const struct fb_videomode *db = NULL; unsigned int dbsize = 0; diff --git a/drivers/video/macmodes.h b/drivers/video/macmodes.h index 232f5a09a49..babeb81f467 100644 --- a/drivers/video/macmodes.h +++ b/drivers/video/macmodes.h @@ -55,9 +55,10 @@ extern int mac_vmode_to_var(int vmode, int cmode, extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode, int *cmode); extern int mac_map_monitor_sense(int sense); -extern int __init mac_find_mode(struct fb_var_screeninfo *var, - struct fb_info *info, const char *mode_option, - unsigned int default_bpp); +extern int __devinit mac_find_mode(struct fb_var_screeninfo *var, + struct fb_info *info, + const char *mode_option, + unsigned int default_bpp); /* diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 26a1c618a20..ff5454601e2 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -259,6 +259,10 @@ static const struct fb_videomode modedb[] = { /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED + }, { + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, + 0, FB_VMODE_NONINTERLACED }, }; @@ -787,8 +791,9 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var, if (diff > d) { diff = d; best = mode; - } else if (diff == d && mode->refresh > best->refresh) - best = mode; + } else if (diff == d && best && + mode->refresh > best->refresh) + best = mode; } } return best; @@ -1016,8 +1021,6 @@ EXPORT_SYMBOL(fb_videomode_to_var); EXPORT_SYMBOL(fb_var_to_videomode); EXPORT_SYMBOL(fb_mode_is_equal); EXPORT_SYMBOL(fb_add_videomode); -EXPORT_SYMBOL(fb_delete_videomode); -EXPORT_SYMBOL(fb_destroy_modelist); EXPORT_SYMBOL(fb_match_mode); EXPORT_SYMBOL(fb_find_best_mode); EXPORT_SYMBOL(fb_find_nearest_mode); diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 24b12f71d5a..2f156b724d1 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -1333,17 +1333,22 @@ static int neofb_blank(int blank_mode, struct fb_info *info) * run "setterm -powersave powerdown" to take advantage */ struct neofb_par *par = info->par; - int seqflags, lcdflags, dpmsflags, reg; - + int seqflags, lcdflags, dpmsflags, reg, tmpdisp; /* - * Reload the value stored in the register, if sensible. It might have - * been changed via FN keystroke. + * Read back the register bits related to display configuration. They might + * have been changed underneath the driver via Fn key stroke. + */ + neoUnlock(); + tmpdisp = vga_rgfx(NULL, 0x20) & 0x03; + neoLock(&par->state); + + /* In case we blank the screen, we want to store the possibly new + * configuration in the driver. During un-blank, we re-apply this setting, + * since the LCD bit will be cleared in order to switch off the backlight. */ if (par->PanelDispCntlRegRead) { - neoUnlock(); - par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; - neoLock(&par->state); + par->PanelDispCntlReg1 = tmpdisp; } par->PanelDispCntlRegRead = !blank_mode; @@ -1378,12 +1383,21 @@ static int neofb_blank(int blank_mode, struct fb_info *info) break; case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ - lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ + /* + * During a blank operation with the LID shut, we might store "LCD off" + * by mistake. Due to timing issues, the BIOS may switch the lights + * back on, and we turn it back off once we "unblank". + * + * So here is an attempt to implement ">=" - if we are in the process + * of unblanking, and the LCD bit is unset in the driver but set in the + * register, we must keep it. + */ + lcdflags = ((par->PanelDispCntlReg1 | tmpdisp) & 0x02); /* LCD normal */ dpmsflags = 0x00; /* no hsync/vsync suppression */ break; case FB_BLANK_UNBLANK: /* unblank */ seqflags = 0; /* Enable sequencer */ - lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ + lcdflags = ((par->PanelDispCntlReg1 | tmpdisp) & 0x02); /* LCD normal */ dpmsflags = 0x00; /* no hsync/vsync suppression */ #ifdef CONFIG_TOSHIBA /* Do we still need this ? */ diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c index 99c3a8e6a23..9ed640d3572 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/nvidia/nv_hw.c @@ -886,7 +886,10 @@ void NVCalcStateExt(struct nvidia_par *par, case NV_ARCH_20: case NV_ARCH_30: default: - if (((par->Chipset & 0xffff) == 0x01A0) || + if ((par->Chipset & 0xfff0) == 0x0240) { + state->arbitration0 = 256; + state->arbitration1 = 0x0480; + } else if (((par->Chipset & 0xffff) == 0x01A0) || ((par->Chipset & 0xffff) == 0x01f0)) { nForceUpdateArbitrationSettings(VClk, pixelDepth * 8, @@ -1235,6 +1238,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) break; case 0x0160: case 0x01D0: + case 0x0240: NV_WR32(par->PMC, 0x1700, NV_RD32(par->PFB, 0x020C)); NV_WR32(par->PMC, 0x1704, 0); @@ -1359,7 +1363,9 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state) if(((par->Chipset & 0xfff0) != 0x0160) && ((par->Chipset & 0xfff0) - != 0x0220)) + != 0x0220) && + ((par->Chipset & 0xfff0) + != 0x240)) NV_WR32(par->PGRAPH, 0x6900 + i*4, NV_RD32(par->PFB, diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 03a7c1e9ce3..7b5cffb2785 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -67,359 +67,10 @@ #define MAX_CURS 32 static struct pci_device_id nvidiafb_pci_tbl[] = { - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_460_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_410_GO_M16, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_4000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_580_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_MAC, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_280_NVS, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_380_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_980_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_780_XGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700_GOGL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_2000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5650, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO700, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250_32, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_NVS_280_PCI, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_500, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5300, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_3000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5500, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5100, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_700, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900ZT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_4000, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6600, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6610_XL, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_FX_540, - 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, PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280, - 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, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0316, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0317, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x031D, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x031E, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x031F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0329, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x032F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0345, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0349, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x034B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x034F, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x00c0, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_6800A_LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_GO1400, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x00cd, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_QUADRO_FX_1400, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0142, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0143, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0144, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0145, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0146, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0147, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0148, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0149, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x014b, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x14c, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x014d, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0160, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0162, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0163, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0165, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0169, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016b, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016c, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016d, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x016e, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0210, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x021d, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x021e, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0220, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0221, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0222, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {PCI_VENDOR_ID_NVIDIA, 0x0228, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} /* terminate list */ + {PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0}, + { 0, } }; - MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl); /* command line data, set in nvidiafb_setup() */ @@ -1465,10 +1116,10 @@ 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); + printk(KERN_INFO PFX "Device 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) @@ -1476,9 +1127,9 @@ static u32 __devinit nvidia_get_chipset(struct fb_info *info) else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */ id = 0x10DE0000 | ((id << 8) & 0x0000ff00) | ((id >> 8) & 0x000000ff); + printk(KERN_INFO PFX "Subsystem ID: %x \n", id); } - printk("nvidiafb: Actual id - %x\n", id); return id; } @@ -1520,6 +1171,7 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info) case 0x0210: case 0x0220: case 0x0230: + case 0x0240: case 0x0290: case 0x0390: arch = NV_ARCH_40; @@ -1567,7 +1219,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, if (pci_request_regions(pd, "nvidiafb")) { printk(KERN_ERR PFX "cannot request PCI regions\n"); - goto err_out_request; + goto err_out_enable; } par->FlatPanel = flatpanel; @@ -1596,7 +1248,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, } 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) { @@ -1687,10 +1338,8 @@ err_out_free_base1: 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: - pci_disable_device(pd); err_out_enable: kfree(info->pixmap.addr); err_out_kfree: @@ -1720,7 +1369,6 @@ static void __exit nvidiafb_remove(struct pci_dev *pd) nvidia_delete_i2c_busses(par); iounmap(par->REGS); pci_release_regions(pd); - pci_disable_device(pd); kfree(info->pixmap.addr); framebuffer_release(info); pci_set_drvdata(pd, NULL); diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index d4384ab1df6..12af58c5cf1 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -2152,7 +2152,6 @@ err_iounmap_ctrl_base: err_release_region: pci_release_regions(pd); err_disable_device: - pci_disable_device(pd); err_free_pixmap: kfree(info->pixmap.addr); err_framebuffer_release: @@ -2187,7 +2186,6 @@ static void __exit rivafb_remove(struct pci_dev *pd) if (par->riva.Architecture == NV_ARCH_03) iounmap(par->riva.PRAMIN); pci_release_regions(pd); - pci_disable_device(pd); kfree(info->pixmap.addr); framebuffer_release(info); pci_set_drvdata(pd, NULL); diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index 9451932fbaf..fbc41185068 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c @@ -641,6 +641,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) int ret; int irq; int i; + u32 lcdcon1; mach_info = pdev->dev.platform_data; if (mach_info == NULL) { @@ -672,6 +673,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) memcpy(&info->regs, &mach_info->regs, sizeof(info->regs)); + /* Stop the video and unset ENVID if set */ + info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; + lcdcon1 = readl(S3C2410_LCDCON1); + writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); + info->mach_info = pdev->dev.platform_data; fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; @@ -794,15 +800,14 @@ dealloc_fb: * shutdown the lcd controller */ -static void s3c2410fb_stop_lcd(void) +static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) { unsigned long flags; - unsigned long tmp; local_irq_save(flags); - tmp = readl(S3C2410_LCDCON1); - writel(tmp & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); + fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; + writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); local_irq_restore(flags); } @@ -816,7 +821,7 @@ static int s3c2410fb_remove(struct platform_device *pdev) struct s3c2410fb_info *info = fbinfo->par; int irq; - s3c2410fb_stop_lcd(); + s3c2410fb_stop_lcd(info); msleep(1); s3c2410fb_unmap_video_memory(info); @@ -844,7 +849,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) struct fb_info *fbinfo = platform_get_drvdata(dev); struct s3c2410fb_info *info = fbinfo->par; - s3c2410fb_stop_lcd(); + s3c2410fb_stop_lcd(info); /* sleep before disabling the clock, we need to ensure * the LCD DMA engine is not going to get back on the bus diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h index 58cfdfb4183..e648a6c0f6d 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/savage/savagefb.h @@ -147,7 +147,27 @@ struct xtimings { int interlaced; }; +struct savage_reg { + unsigned char MiscOutReg; /* Misc */ + unsigned char CRTC[25]; /* Crtc Controller */ + unsigned char Sequencer[5]; /* Video Sequencer */ + unsigned char Graphics[9]; /* Video Graphics */ + unsigned char Attribute[21]; /* Video Atribute */ + unsigned int mode, refresh; + unsigned char SR08, SR0E, SR0F; + unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR29, SR30; + unsigned char SR54[8]; + unsigned char Clock; + unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C; + unsigned char CR40, CR41, CR42, CR43, CR45; + unsigned char CR50, CR51, CR53, CR55, CR58, CR5B, CR5D, CR5E; + unsigned char CR60, CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F; + unsigned char CR86, CR88; + unsigned char CR90, CR91, CRB0; + unsigned int STREAMS[22]; /* yuck, streams regs */ + unsigned int MMPR0, MMPR1, MMPR2, MMPR3; +}; /* --------------------------------------------------------------------- */ #define NR_PALETTE 256 @@ -167,6 +187,8 @@ struct savagefb_par { struct pci_dev *pcidev; savage_chipset chip; struct savagefb_i2c_chan chan; + struct savage_reg state; + struct savage_reg save; unsigned char *edid; u32 pseudo_palette[16]; int paletteEnabled; @@ -179,6 +201,7 @@ struct savagefb_par { int minClock; int numClocks; int clock[4]; + int MCLK, REFCLK, LCDclk; struct { u8 __iomem *vbase; u32 pbase; @@ -196,7 +219,6 @@ struct savagefb_par { volatile u32 __iomem *bci_base; unsigned int bci_ptr; - u32 cob_offset; u32 cob_size; int cob_index; @@ -204,7 +226,6 @@ struct savagefb_par { void (*SavageWaitIdle) (struct savagefb_par *par); void (*SavageWaitFifo) (struct savagefb_par *par, int space); - int MCLK, REFCLK, LCDclk; int HorizScaleFactor; /* Panels size */ @@ -217,26 +238,6 @@ struct savagefb_par { int depth; int vwidth; - - unsigned char MiscOutReg; /* Misc */ - unsigned char CRTC[25]; /* Crtc Controller */ - unsigned char Sequencer[5]; /* Video Sequencer */ - unsigned char Graphics[9]; /* Video Graphics */ - unsigned char Attribute[21]; /* Video Atribute */ - - unsigned int mode, refresh; - unsigned char SR08, SR0E, SR0F; - unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR29, SR30; - unsigned char SR54[8]; - unsigned char Clock; - unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C; - unsigned char CR40, CR41, CR42, CR43, CR45; - unsigned char CR50, CR51, CR53, CR55, CR58, CR5B, CR5D, CR5E; - unsigned char CR60, CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F; - unsigned char CR86, CR88; - unsigned char CR90, CR91, CRB0; - unsigned int STREAMS[22]; /* yuck, streams regs */ - unsigned int MMPR0, MMPR1, MMPR2, MMPR3; }; #define BCI_BD_BW_DISABLE 0x10000000 diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 0da624e6524..78883cf66a4 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -86,15 +86,15 @@ MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips"); /* --------------------------------------------------------------------- */ -static void vgaHWSeqReset (struct savagefb_par *par, int start) +static void vgaHWSeqReset(struct savagefb_par *par, int start) { if (start) - VGAwSEQ (0x00, 0x01, par); /* Synchronous Reset */ + VGAwSEQ(0x00, 0x01, par); /* Synchronous Reset */ else - VGAwSEQ (0x00, 0x03, par); /* End Reset */ + VGAwSEQ(0x00, 0x03, par); /* End Reset */ } -static void vgaHWProtect (struct savagefb_par *par, int on) +static void vgaHWProtect(struct savagefb_par *par, int on) { unsigned char tmp; @@ -102,10 +102,10 @@ static void vgaHWProtect (struct savagefb_par *par, int on) /* * Turn off screen and disable sequencer. */ - tmp = VGArSEQ (0x01, par); + tmp = VGArSEQ(0x01, par); - vgaHWSeqReset (par, 1); /* start synchronous reset */ - VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */ + vgaHWSeqReset(par, 1); /* start synchronous reset */ + VGAwSEQ(0x01, tmp | 0x20, par);/* disable the display */ VGAenablePalette(par); } else { @@ -113,75 +113,76 @@ static void vgaHWProtect (struct savagefb_par *par, int on) * Reenable sequencer, then turn on screen. */ - tmp = VGArSEQ (0x01, par); + tmp = VGArSEQ(0x01, par); - VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */ - vgaHWSeqReset (par, 0); /* clear synchronous reset */ + VGAwSEQ(0x01, tmp & ~0x20, par);/* reenable display */ + vgaHWSeqReset(par, 0); /* clear synchronous reset */ VGAdisablePalette(par); } } -static void vgaHWRestore (struct savagefb_par *par) +static void vgaHWRestore(struct savagefb_par *par, struct savage_reg *reg) { int i; - VGAwMISC (par->MiscOutReg, par); + VGAwMISC(reg->MiscOutReg, par); for (i = 1; i < 5; i++) - VGAwSEQ (i, par->Sequencer[i], par); + VGAwSEQ(i, reg->Sequencer[i], par); /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */ - VGAwCR (17, par->CRTC[17] & ~0x80, par); + VGAwCR(17, reg->CRTC[17] & ~0x80, par); for (i = 0; i < 25; i++) - VGAwCR (i, par->CRTC[i], par); + VGAwCR(i, reg->CRTC[i], par); for (i = 0; i < 9; i++) - VGAwGR (i, par->Graphics[i], par); + VGAwGR(i, reg->Graphics[i], par); VGAenablePalette(par); for (i = 0; i < 21; i++) - VGAwATTR (i, par->Attribute[i], par); + VGAwATTR(i, reg->Attribute[i], par); VGAdisablePalette(par); } -static void vgaHWInit (struct fb_var_screeninfo *var, - struct savagefb_par *par, - struct xtimings *timings) +static void vgaHWInit(struct fb_var_screeninfo *var, + struct savagefb_par *par, + struct xtimings *timings, + struct savage_reg *reg) { - par->MiscOutReg = 0x23; + reg->MiscOutReg = 0x23; if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT)) - par->MiscOutReg |= 0x40; + reg->MiscOutReg |= 0x40; if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT)) - par->MiscOutReg |= 0x80; + reg->MiscOutReg |= 0x80; /* * Time Sequencer */ - par->Sequencer[0x00] = 0x00; - par->Sequencer[0x01] = 0x01; - par->Sequencer[0x02] = 0x0F; - par->Sequencer[0x03] = 0x00; /* Font select */ - par->Sequencer[0x04] = 0x0E; /* Misc */ + reg->Sequencer[0x00] = 0x00; + reg->Sequencer[0x01] = 0x01; + reg->Sequencer[0x02] = 0x0F; + reg->Sequencer[0x03] = 0x00; /* Font select */ + reg->Sequencer[0x04] = 0x0E; /* Misc */ /* * CRTC Controller */ - par->CRTC[0x00] = (timings->HTotal >> 3) - 5; - par->CRTC[0x01] = (timings->HDisplay >> 3) - 1; - par->CRTC[0x02] = (timings->HSyncStart >> 3) - 1; - par->CRTC[0x03] = (((timings->HSyncEnd >> 3) - 1) & 0x1f) | 0x80; - par->CRTC[0x04] = (timings->HSyncStart >> 3); - par->CRTC[0x05] = ((((timings->HSyncEnd >> 3) - 1) & 0x20) << 2) | + reg->CRTC[0x00] = (timings->HTotal >> 3) - 5; + reg->CRTC[0x01] = (timings->HDisplay >> 3) - 1; + reg->CRTC[0x02] = (timings->HSyncStart >> 3) - 1; + reg->CRTC[0x03] = (((timings->HSyncEnd >> 3) - 1) & 0x1f) | 0x80; + reg->CRTC[0x04] = (timings->HSyncStart >> 3); + reg->CRTC[0x05] = ((((timings->HSyncEnd >> 3) - 1) & 0x20) << 2) | (((timings->HSyncEnd >> 3)) & 0x1f); - par->CRTC[0x06] = (timings->VTotal - 2) & 0xFF; - par->CRTC[0x07] = (((timings->VTotal - 2) & 0x100) >> 8) | + reg->CRTC[0x06] = (timings->VTotal - 2) & 0xFF; + reg->CRTC[0x07] = (((timings->VTotal - 2) & 0x100) >> 8) | (((timings->VDisplay - 1) & 0x100) >> 7) | ((timings->VSyncStart & 0x100) >> 6) | (((timings->VSyncStart - 1) & 0x100) >> 5) | @@ -189,27 +190,27 @@ static void vgaHWInit (struct fb_var_screeninfo *var, (((timings->VTotal - 2) & 0x200) >> 4) | (((timings->VDisplay - 1) & 0x200) >> 3) | ((timings->VSyncStart & 0x200) >> 2); - par->CRTC[0x08] = 0x00; - par->CRTC[0x09] = (((timings->VSyncStart - 1) & 0x200) >> 4) | 0x40; + reg->CRTC[0x08] = 0x00; + reg->CRTC[0x09] = (((timings->VSyncStart - 1) & 0x200) >> 4) | 0x40; if (timings->dblscan) - par->CRTC[0x09] |= 0x80; - - par->CRTC[0x0a] = 0x00; - par->CRTC[0x0b] = 0x00; - par->CRTC[0x0c] = 0x00; - par->CRTC[0x0d] = 0x00; - par->CRTC[0x0e] = 0x00; - par->CRTC[0x0f] = 0x00; - par->CRTC[0x10] = timings->VSyncStart & 0xff; - par->CRTC[0x11] = (timings->VSyncEnd & 0x0f) | 0x20; - par->CRTC[0x12] = (timings->VDisplay - 1) & 0xff; - par->CRTC[0x13] = var->xres_virtual >> 4; - par->CRTC[0x14] = 0x00; - par->CRTC[0x15] = (timings->VSyncStart - 1) & 0xff; - par->CRTC[0x16] = (timings->VSyncEnd - 1) & 0xff; - par->CRTC[0x17] = 0xc3; - par->CRTC[0x18] = 0xff; + reg->CRTC[0x09] |= 0x80; + + reg->CRTC[0x0a] = 0x00; + reg->CRTC[0x0b] = 0x00; + reg->CRTC[0x0c] = 0x00; + reg->CRTC[0x0d] = 0x00; + reg->CRTC[0x0e] = 0x00; + reg->CRTC[0x0f] = 0x00; + reg->CRTC[0x10] = timings->VSyncStart & 0xff; + reg->CRTC[0x11] = (timings->VSyncEnd & 0x0f) | 0x20; + reg->CRTC[0x12] = (timings->VDisplay - 1) & 0xff; + reg->CRTC[0x13] = var->xres_virtual >> 4; + reg->CRTC[0x14] = 0x00; + reg->CRTC[0x15] = (timings->VSyncStart - 1) & 0xff; + reg->CRTC[0x16] = (timings->VSyncEnd - 1) & 0xff; + reg->CRTC[0x17] = 0xc3; + reg->CRTC[0x18] = 0xff; /* * are these unnecessary? @@ -220,38 +221,38 @@ static void vgaHWInit (struct fb_var_screeninfo *var, /* * Graphics Display Controller */ - par->Graphics[0x00] = 0x00; - par->Graphics[0x01] = 0x00; - par->Graphics[0x02] = 0x00; - par->Graphics[0x03] = 0x00; - par->Graphics[0x04] = 0x00; - par->Graphics[0x05] = 0x40; - par->Graphics[0x06] = 0x05; /* only map 64k VGA memory !!!! */ - par->Graphics[0x07] = 0x0F; - par->Graphics[0x08] = 0xFF; - - - par->Attribute[0x00] = 0x00; /* standard colormap translation */ - par->Attribute[0x01] = 0x01; - par->Attribute[0x02] = 0x02; - par->Attribute[0x03] = 0x03; - par->Attribute[0x04] = 0x04; - par->Attribute[0x05] = 0x05; - par->Attribute[0x06] = 0x06; - par->Attribute[0x07] = 0x07; - par->Attribute[0x08] = 0x08; - par->Attribute[0x09] = 0x09; - par->Attribute[0x0a] = 0x0A; - par->Attribute[0x0b] = 0x0B; - par->Attribute[0x0c] = 0x0C; - par->Attribute[0x0d] = 0x0D; - par->Attribute[0x0e] = 0x0E; - par->Attribute[0x0f] = 0x0F; - par->Attribute[0x10] = 0x41; - par->Attribute[0x11] = 0xFF; - par->Attribute[0x12] = 0x0F; - par->Attribute[0x13] = 0x00; - par->Attribute[0x14] = 0x00; + reg->Graphics[0x00] = 0x00; + reg->Graphics[0x01] = 0x00; + reg->Graphics[0x02] = 0x00; + reg->Graphics[0x03] = 0x00; + reg->Graphics[0x04] = 0x00; + reg->Graphics[0x05] = 0x40; + reg->Graphics[0x06] = 0x05; /* only map 64k VGA memory !!!! */ + reg->Graphics[0x07] = 0x0F; + reg->Graphics[0x08] = 0xFF; + + + reg->Attribute[0x00] = 0x00; /* standard colormap translation */ + reg->Attribute[0x01] = 0x01; + reg->Attribute[0x02] = 0x02; + reg->Attribute[0x03] = 0x03; + reg->Attribute[0x04] = 0x04; + reg->Attribute[0x05] = 0x05; + reg->Attribute[0x06] = 0x06; + reg->Attribute[0x07] = 0x07; + reg->Attribute[0x08] = 0x08; + reg->Attribute[0x09] = 0x09; + reg->Attribute[0x0a] = 0x0A; + reg->Attribute[0x0b] = 0x0B; + reg->Attribute[0x0c] = 0x0C; + reg->Attribute[0x0d] = 0x0D; + reg->Attribute[0x0e] = 0x0E; + reg->Attribute[0x0f] = 0x0F; + reg->Attribute[0x10] = 0x41; + reg->Attribute[0x11] = 0xFF; + reg->Attribute[0x12] = 0x0F; + reg->Attribute[0x13] = 0x00; + reg->Attribute[0x14] = 0x00; } /* -------------------- Hardware specific routines ------------------------- */ @@ -304,15 +305,15 @@ savage2000_waitidle(struct savagefb_par *par) while ((savage_in32(0x48C60, par) & 0x009fffff)); } - +#ifdef CONFIG_FB_SAVAGE_ACCEL static void -SavageSetup2DEngine (struct savagefb_par *par) +SavageSetup2DEngine(struct savagefb_par *par) { unsigned long GlobalBitmapDescriptor; GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE; - BCI_BD_SET_BPP (GlobalBitmapDescriptor, par->depth); - BCI_BD_SET_STRIDE (GlobalBitmapDescriptor, par->vwidth); + BCI_BD_SET_BPP(GlobalBitmapDescriptor, par->depth); + BCI_BD_SET_STRIDE(GlobalBitmapDescriptor, par->vwidth); switch(par->chip) { case S3_SAVAGE3D: @@ -361,32 +362,48 @@ SavageSetup2DEngine (struct savagefb_par *par) vga_out8(0x3d5, 0x0c, par); /* Set stride to use GBD. */ - vga_out8 (0x3d4, 0x50, par); - vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par); + vga_out8(0x3d4, 0x50, par); + vga_out8(0x3d5, vga_in8(0x3d5, par) | 0xC1, par); /* Enable 2D engine. */ - vga_out8 (0x3d4, 0x40, par); - vga_out8 (0x3d5, 0x01, par); + vga_out8(0x3d4, 0x40, par); + vga_out8(0x3d5, 0x01, par); - savage_out32 (MONO_PAT_0, ~0, par); - savage_out32 (MONO_PAT_1, ~0, par); + savage_out32(MONO_PAT_0, ~0, par); + savage_out32(MONO_PAT_1, ~0, par); /* Setup plane masks */ - savage_out32 (0x8128, ~0, par); /* enable all write planes */ - savage_out32 (0x812C, ~0, par); /* enable all read planes */ - savage_out16 (0x8134, 0x27, par); - savage_out16 (0x8136, 0x07, par); + savage_out32(0x8128, ~0, par); /* enable all write planes */ + savage_out32(0x812C, ~0, par); /* enable all read planes */ + savage_out16(0x8134, 0x27, par); + savage_out16(0x8136, 0x07, par); /* Now set the GBD */ par->bci_ptr = 0; - par->SavageWaitFifo (par, 4); + par->SavageWaitFifo(par, 4); - BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD1 ); - BCI_SEND( 0 ); - BCI_SEND( BCI_CMD_SETREG | (1 << 16) | BCI_GBD2 ); - BCI_SEND( GlobalBitmapDescriptor ); + BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD1); + BCI_SEND(0); + BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2); + BCI_SEND(GlobalBitmapDescriptor); } +static void savagefb_set_clip(struct fb_info *info) +{ + struct savagefb_par *par = info->par; + int cmd; + + cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; + par->bci_ptr = 0; + par->SavageWaitFifo(par,3); + BCI_SEND(cmd); + BCI_SEND(BCI_CLIP_TL(0, 0)); + BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff)); +} +#else +static void SavageSetup2DEngine(struct savagefb_par *par) {} + +#endif static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2, int max_n2, long freq_min, @@ -398,11 +415,11 @@ static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, unsigned char n1, n2, best_n1=16+2, best_n2=2, best_m=125+2; if (freq < freq_min / (1 << max_n2)) { - printk (KERN_ERR "invalid frequency %ld Khz\n", freq); + printk(KERN_ERR "invalid frequency %ld Khz\n", freq); freq = freq_min / (1 << max_n2); } if (freq > freq_max / (1 << min_n2)) { - printk (KERN_ERR "invalid frequency %ld Khz\n", freq); + printk(KERN_ERR "invalid frequency %ld Khz\n", freq); freq = freq_max / (1 << min_n2); } @@ -453,12 +470,12 @@ static int common_calc_clock(long freq, int min_m, int min_n1, int max_n1, BASE_FREQ; if (m < min_m + 2 || m > 127+2) continue; - if((m * BASE_FREQ >= freq_min * n1) && - (m * BASE_FREQ <= freq_max * n1)) { + if ((m * BASE_FREQ >= freq_min * n1) && + (m * BASE_FREQ <= freq_max * n1)) { diff = freq * (1 << n2) * n1 - BASE_FREQ * m; - if(diff < 0) + if (diff < 0) diff = -diff; - if(diff < best_diff) { + if (diff < best_diff) { best_diff = diff; best_m = m; best_n1 = n1; @@ -468,7 +485,7 @@ static int common_calc_clock(long freq, int min_m, int min_n1, int max_n1, } } - if(max_n1 == 63) + if (max_n1 == 63) *ndiv = (best_n1 - 2) | (best_n2 << 6); else *ndiv = (best_n1 - 2) | (best_n2 << 5); @@ -488,23 +505,23 @@ static void SavagePrintRegs(void) int vgaCRReg = 0x3d5; printk(KERN_DEBUG "SR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE " - "xF" ); + "xF"); - for( i = 0; i < 0x70; i++ ) { - if( !(i % 16) ) - printk(KERN_DEBUG "\nSR%xx ", i >> 4 ); - vga_out8( 0x3c4, i, par); - printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) ); + for (i = 0; i < 0x70; i++) { + if (!(i % 16)) + printk(KERN_DEBUG "\nSR%xx ", i >> 4); + vga_out8(0x3c4, i, par); + printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par)); } printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC " - "xD xE xF" ); + "xD xE xF"); - for( i = 0; i < 0xB7; i++ ) { - if( !(i % 16) ) - printk(KERN_DEBUG "\nCR%xx ", i >> 4 ); - vga_out8( vgaCRIndex, i, par); - printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) ); + for (i = 0; i < 0xB7; i++) { + if (!(i % 16)) + printk(KERN_DEBUG "\nCR%xx ", i >> 4); + vga_out8(vgaCRIndex, i, par); + printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par)); } printk(KERN_DEBUG "\n\n"); @@ -513,156 +530,309 @@ static void SavagePrintRegs(void) /* --------------------------------------------------------------------- */ -static void savage_get_default_par(struct savagefb_par *par) +static void savage_get_default_par(struct savagefb_par *par, struct savage_reg *reg) { unsigned char cr3a, cr53, cr66; - vga_out16 (0x3d4, 0x4838, par); - vga_out16 (0x3d4, 0xa039, par); - vga_out16 (0x3c4, 0x0608, par); - - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x80, par); - vga_out8 (0x3d4, 0x3a, par); - cr3a = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3a | 0x80, par); - vga_out8 (0x3d4, 0x53, par); - cr53 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr53 & 0x7f, par); - - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); - - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); + vga_out16(0x3d4, 0x4838, par); + vga_out16(0x3d4, 0xa039, par); + vga_out16(0x3c4, 0x0608, par); + + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x53, par); + cr53 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr53 & 0x7f, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); /* unlock extended seq regs */ - vga_out8 (0x3c4, 0x08, par); - par->SR08 = vga_in8 (0x3c5, par); - vga_out8 (0x3c5, 0x06, par); + vga_out8(0x3c4, 0x08, par); + reg->SR08 = vga_in8(0x3c5, par); + vga_out8(0x3c5, 0x06, par); /* now save all the extended regs we need */ - vga_out8 (0x3d4, 0x31, par); - par->CR31 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x32, par); - par->CR32 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x34, par); - par->CR34 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x36, par); - par->CR36 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x3a, par); - par->CR3A = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x40, par); - par->CR40 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x42, par); - par->CR42 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x45, par); - par->CR45 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x50, par); - par->CR50 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x51, par); - par->CR51 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x53, par); - par->CR53 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x58, par); - par->CR58 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x60, par); - par->CR60 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x66, par); - par->CR66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x67, par); - par->CR67 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x68, par); - par->CR68 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x69, par); - par->CR69 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x6f, par); - par->CR6F = vga_in8 (0x3d5, par); - - vga_out8 (0x3d4, 0x33, par); - par->CR33 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x86, par); - par->CR86 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x88, par); - par->CR88 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x90, par); - par->CR90 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x91, par); - par->CR91 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0xb0, par); - par->CRB0 = vga_in8 (0x3d5, par) | 0x80; + vga_out8(0x3d4, 0x31, par); + reg->CR31 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x32, par); + reg->CR32 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x34, par); + reg->CR34 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x36, par); + reg->CR36 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x3a, par); + reg->CR3A = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x40, par); + reg->CR40 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x42, par); + reg->CR42 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x45, par); + reg->CR45 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x50, par); + reg->CR50 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x51, par); + reg->CR51 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x53, par); + reg->CR53 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x58, par); + reg->CR58 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x60, par); + reg->CR60 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x66, par); + reg->CR66 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x67, par); + reg->CR67 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x68, par); + reg->CR68 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x69, par); + reg->CR69 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x6f, par); + reg->CR6F = vga_in8(0x3d5, par); + + vga_out8(0x3d4, 0x33, par); + reg->CR33 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x86, par); + reg->CR86 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x88, par); + reg->CR88 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x90, par); + reg->CR90 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x91, par); + reg->CR91 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0xb0, par); + reg->CRB0 = vga_in8(0x3d5, par) | 0x80; + + /* extended mode timing regs */ + vga_out8(0x3d4, 0x3b, par); + reg->CR3B = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x3c, par); + reg->CR3C = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x43, par); + reg->CR43 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x5d, par); + reg->CR5D = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x5e, par); + reg->CR5E = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x65, par); + reg->CR65 = vga_in8(0x3d5, par); + + /* save seq extended regs for DCLK PLL programming */ + vga_out8(0x3c4, 0x0e, par); + reg->SR0E = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x0f, par); + reg->SR0F = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x10, par); + reg->SR10 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x11, par); + reg->SR11 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x12, par); + reg->SR12 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x13, par); + reg->SR13 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x29, par); + reg->SR29 = vga_in8(0x3c5, par); + + vga_out8(0x3c4, 0x15, par); + reg->SR15 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x30, par); + reg->SR30 = vga_in8(0x3c5, par); + vga_out8(0x3c4, 0x18, par); + reg->SR18 = vga_in8(0x3c5, par); + + /* Save flat panel expansion regsters. */ + if (par->chip == S3_SAVAGE_MX) { + int i; + + for (i = 0; i < 8; i++) { + vga_out8(0x3c4, 0x54+i, par); + reg->SR54[i] = vga_in8(0x3c5, par); + } + } + + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); + + /* now save MIU regs */ + if (par->chip != S3_SAVAGE_MX) { + reg->MMPR0 = savage_in32(FIFO_CONTROL_REG, par); + reg->MMPR1 = savage_in32(MIU_CONTROL_REG, par); + reg->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par); + reg->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par); + } + + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); +} + +static void savage_set_default_par(struct savagefb_par *par, + struct savage_reg *reg) +{ + unsigned char cr3a, cr53, cr66; + + vga_out16(0x3d4, 0x4838, par); + vga_out16(0x3d4, 0xa039, par); + vga_out16(0x3c4, 0x0608, par); + + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x53, par); + cr53 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr53 & 0x7f, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + + /* unlock extended seq regs */ + vga_out8(0x3c4, 0x08, par); + vga_out8(0x3c5, reg->SR08, par); + vga_out8(0x3c5, 0x06, par); + + /* now restore all the extended regs we need */ + vga_out8(0x3d4, 0x31, par); + vga_out8(0x3d5, reg->CR31, par); + vga_out8(0x3d4, 0x32, par); + vga_out8(0x3d5, reg->CR32, par); + vga_out8(0x3d4, 0x34, par); + vga_out8(0x3d5, reg->CR34, par); + vga_out8(0x3d4, 0x36, par); + vga_out8(0x3d5,reg->CR36, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, reg->CR3A, par); + vga_out8(0x3d4, 0x40, par); + vga_out8(0x3d5, reg->CR40, par); + vga_out8(0x3d4, 0x42, par); + vga_out8(0x3d5, reg->CR42, par); + vga_out8(0x3d4, 0x45, par); + vga_out8(0x3d5, reg->CR45, par); + vga_out8(0x3d4, 0x50, par); + vga_out8(0x3d5, reg->CR50, par); + vga_out8(0x3d4, 0x51, par); + vga_out8(0x3d5, reg->CR51, par); + vga_out8(0x3d4, 0x53, par); + vga_out8(0x3d5, reg->CR53, par); + vga_out8(0x3d4, 0x58, par); + vga_out8(0x3d5, reg->CR58, par); + vga_out8(0x3d4, 0x60, par); + vga_out8(0x3d5, reg->CR60, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, reg->CR66, par); + vga_out8(0x3d4, 0x67, par); + vga_out8(0x3d5, reg->CR67, par); + vga_out8(0x3d4, 0x68, par); + vga_out8(0x3d5, reg->CR68, par); + vga_out8(0x3d4, 0x69, par); + vga_out8(0x3d5, reg->CR69, par); + vga_out8(0x3d4, 0x6f, par); + vga_out8(0x3d5, reg->CR6F, par); + + vga_out8(0x3d4, 0x33, par); + vga_out8(0x3d5, reg->CR33, par); + vga_out8(0x3d4, 0x86, par); + vga_out8(0x3d5, reg->CR86, par); + vga_out8(0x3d4, 0x88, par); + vga_out8(0x3d5, reg->CR88, par); + vga_out8(0x3d4, 0x90, par); + vga_out8(0x3d5, reg->CR90, par); + vga_out8(0x3d4, 0x91, par); + vga_out8(0x3d5, reg->CR91, par); + vga_out8(0x3d4, 0xb0, par); + vga_out8(0x3d5, reg->CRB0, par); /* extended mode timing regs */ - vga_out8 (0x3d4, 0x3b, par); - par->CR3B = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x3c, par); - par->CR3C = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x43, par); - par->CR43 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x5d, par); - par->CR5D = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x5e, par); - par->CR5E = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x65, par); - par->CR65 = vga_in8 (0x3d5, par); + vga_out8(0x3d4, 0x3b, par); + vga_out8(0x3d5, reg->CR3B, par); + vga_out8(0x3d4, 0x3c, par); + vga_out8(0x3d5, reg->CR3C, par); + vga_out8(0x3d4, 0x43, par); + vga_out8(0x3d5, reg->CR43, par); + vga_out8(0x3d4, 0x5d, par); + vga_out8(0x3d5, reg->CR5D, par); + vga_out8(0x3d4, 0x5e, par); + vga_out8(0x3d5, reg->CR5E, par); + vga_out8(0x3d4, 0x65, par); + vga_out8(0x3d5, reg->CR65, par); /* save seq extended regs for DCLK PLL programming */ - vga_out8 (0x3c4, 0x0e, par); - par->SR0E = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x0f, par); - par->SR0F = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x10, par); - par->SR10 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x11, par); - par->SR11 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x12, par); - par->SR12 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x13, par); - par->SR13 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x29, par); - par->SR29 = vga_in8 (0x3c5, par); - - vga_out8 (0x3c4, 0x15, par); - par->SR15 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x30, par); - par->SR30 = vga_in8 (0x3c5, par); - vga_out8 (0x3c4, 0x18, par); - par->SR18 = vga_in8 (0x3c5, par); + vga_out8(0x3c4, 0x0e, par); + vga_out8(0x3c5, reg->SR0E, par); + vga_out8(0x3c4, 0x0f, par); + vga_out8(0x3c5, reg->SR0F, par); + vga_out8(0x3c4, 0x10, par); + vga_out8(0x3c5, reg->SR10, par); + vga_out8(0x3c4, 0x11, par); + vga_out8(0x3c5, reg->SR11, par); + vga_out8(0x3c4, 0x12, par); + vga_out8(0x3c5, reg->SR12, par); + vga_out8(0x3c4, 0x13, par); + vga_out8(0x3c5, reg->SR13, par); + vga_out8(0x3c4, 0x29, par); + vga_out8(0x3c5, reg->SR29, par); + + vga_out8(0x3c4, 0x15, par); + vga_out8(0x3c5, reg->SR15, par); + vga_out8(0x3c4, 0x30, par); + vga_out8(0x3c5, reg->SR30, par); + vga_out8(0x3c4, 0x18, par); + vga_out8(0x3c5, reg->SR18, par); /* Save flat panel expansion regsters. */ if (par->chip == S3_SAVAGE_MX) { int i; for (i = 0; i < 8; i++) { - vga_out8 (0x3c4, 0x54+i, par); - par->SR54[i] = vga_in8 (0x3c5, par); + vga_out8(0x3c4, 0x54+i, par); + vga_out8(0x3c5, reg->SR54[i], par); } } - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x80, par); - vga_out8 (0x3d4, 0x3a, par); - cr3a = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); /* now save MIU regs */ if (par->chip != S3_SAVAGE_MX) { - par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par); - par->MMPR1 = savage_in32(MIU_CONTROL_REG, par); - par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par); - par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par); + savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par); + savage_out32(MIU_CONTROL_REG, reg->MMPR1, par); + savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par); + savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par); } - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); } static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) @@ -683,8 +853,8 @@ static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode var->vmode = modedb->vmode; } -static int savagefb_check_var (struct fb_var_screeninfo *var, - struct fb_info *info) +static int savagefb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) { struct savagefb_par *par = info->par; int memlen, vramlen, mode_valid = 0; @@ -750,10 +920,10 @@ static int savagefb_check_var (struct fb_var_screeninfo *var, if (par->SavagePanelWidth && (var->xres > par->SavagePanelWidth || var->yres > par->SavagePanelHeight)) { - printk (KERN_INFO "Mode (%dx%d) larger than the LCD panel " - "(%dx%d)\n", var->xres, var->yres, - par->SavagePanelWidth, - par->SavagePanelHeight); + printk(KERN_INFO "Mode (%dx%d) larger than the LCD panel " + "(%dx%d)\n", var->xres, var->yres, + par->SavagePanelWidth, + par->SavagePanelHeight); return -1; } @@ -788,8 +958,9 @@ static int savagefb_check_var (struct fb_var_screeninfo *var, } -static int savagefb_decode_var (struct fb_var_screeninfo *var, - struct savagefb_par *par) +static int savagefb_decode_var(struct fb_var_screeninfo *var, + struct savagefb_par *par, + struct savage_reg *reg) { struct xtimings timings; int width, dclk, i, j; /*, refresh; */ @@ -799,7 +970,7 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, DBG("savagefb_decode_var"); - memset (&timings, 0, sizeof(timings)); + memset(&timings, 0, sizeof(timings)); if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */ timings.Clock = 1000000000 / pixclock; @@ -831,39 +1002,39 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, * This will allocate the datastructure and initialize all of the * generic VGA registers. */ - vgaHWInit (var, par, &timings); + vgaHWInit(var, par, &timings, reg); /* We need to set CR67 whether or not we use the BIOS. */ dclk = timings.Clock; - par->CR67 = 0x00; + reg->CR67 = 0x00; - switch( var->bits_per_pixel ) { + switch(var->bits_per_pixel) { case 8: - if( (par->chip == S3_SAVAGE2000) && (dclk >= 230000) ) - par->CR67 = 0x10; /* 8bpp, 2 pixels/clock */ + if ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) + reg->CR67 = 0x10; /* 8bpp, 2 pixels/clock */ else - par->CR67 = 0x00; /* 8bpp, 1 pixel/clock */ + reg->CR67 = 0x00; /* 8bpp, 1 pixel/clock */ break; case 15: - if ( S3_SAVAGE_MOBILE_SERIES(par->chip) || - ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) ) - par->CR67 = 0x30; /* 15bpp, 2 pixel/clock */ + if (S3_SAVAGE_MOBILE_SERIES(par->chip) || + ((par->chip == S3_SAVAGE2000) && (dclk >= 230000))) + reg->CR67 = 0x30; /* 15bpp, 2 pixel/clock */ else - par->CR67 = 0x20; /* 15bpp, 1 pixels/clock */ + reg->CR67 = 0x20; /* 15bpp, 1 pixels/clock */ break; case 16: - if( S3_SAVAGE_MOBILE_SERIES(par->chip) || - ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)) ) - par->CR67 = 0x50; /* 16bpp, 2 pixel/clock */ + if (S3_SAVAGE_MOBILE_SERIES(par->chip) || + ((par->chip == S3_SAVAGE2000) && (dclk >= 230000))) + reg->CR67 = 0x50; /* 16bpp, 2 pixel/clock */ else - par->CR67 = 0x40; /* 16bpp, 1 pixels/clock */ + reg->CR67 = 0x40; /* 16bpp, 1 pixels/clock */ break; case 24: - par->CR67 = 0x70; + reg->CR67 = 0x70; break; case 32: - par->CR67 = 0xd0; + reg->CR67 = 0xd0; break; } @@ -872,61 +1043,61 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, * match. Fall back to traditional register-crunching. */ - vga_out8 (0x3d4, 0x3a, par); - tmp = vga_in8 (0x3d5, par); + vga_out8(0x3d4, 0x3a, par); + tmp = vga_in8(0x3d5, par); if (1 /*FIXME:psav->pci_burst*/) - par->CR3A = (tmp & 0x7f) | 0x15; + reg->CR3A = (tmp & 0x7f) | 0x15; else - par->CR3A = tmp | 0x95; + reg->CR3A = tmp | 0x95; - par->CR53 = 0x00; - par->CR31 = 0x8c; - par->CR66 = 0x89; + reg->CR53 = 0x00; + reg->CR31 = 0x8c; + reg->CR66 = 0x89; - vga_out8 (0x3d4, 0x58, par); - par->CR58 = vga_in8 (0x3d5, par) & 0x80; - par->CR58 |= 0x13; + vga_out8(0x3d4, 0x58, par); + reg->CR58 = vga_in8(0x3d5, par) & 0x80; + reg->CR58 |= 0x13; - par->SR15 = 0x03 | 0x80; - par->SR18 = 0x00; - par->CR43 = par->CR45 = par->CR65 = 0x00; + reg->SR15 = 0x03 | 0x80; + reg->SR18 = 0x00; + reg->CR43 = reg->CR45 = reg->CR65 = 0x00; - vga_out8 (0x3d4, 0x40, par); - par->CR40 = vga_in8 (0x3d5, par) & ~0x01; + vga_out8(0x3d4, 0x40, par); + reg->CR40 = vga_in8(0x3d5, par) & ~0x01; - par->MMPR0 = 0x010400; - par->MMPR1 = 0x00; - par->MMPR2 = 0x0808; - par->MMPR3 = 0x08080810; + reg->MMPR0 = 0x010400; + reg->MMPR1 = 0x00; + reg->MMPR2 = 0x0808; + reg->MMPR3 = 0x08080810; - SavageCalcClock (dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r); + SavageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r); /* m = 107; n = 4; r = 2; */ if (par->MCLK <= 0) { - par->SR10 = 255; - par->SR11 = 255; + reg->SR10 = 255; + reg->SR11 = 255; } else { - common_calc_clock (par->MCLK, 1, 1, 31, 0, 3, 135000, 270000, - &par->SR11, &par->SR10); - /* par->SR10 = 80; // MCLK == 286000 */ - /* par->SR11 = 125; */ + common_calc_clock(par->MCLK, 1, 1, 31, 0, 3, 135000, 270000, + ®->SR11, ®->SR10); + /* reg->SR10 = 80; // MCLK == 286000 */ + /* reg->SR11 = 125; */ } - par->SR12 = (r << 6) | (n & 0x3f); - par->SR13 = m & 0xff; - par->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; + reg->SR12 = (r << 6) | (n & 0x3f); + reg->SR13 = m & 0xff; + reg->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; if (var->bits_per_pixel < 24) - par->MMPR0 -= 0x8000; + reg->MMPR0 -= 0x8000; else - par->MMPR0 -= 0x4000; + reg->MMPR0 -= 0x4000; if (timings.interlaced) - par->CR42 = 0x20; + reg->CR42 = 0x20; else - par->CR42 = 0x00; + reg->CR42 = 0x00; - par->CR34 = 0x10; /* display fifo */ + reg->CR34 = 0x10; /* display fifo */ i = ((((timings.HTotal >> 3) - 5) & 0x100) >> 8) | ((((timings.HDisplay >> 3) - 1) & 0x100) >> 7) | @@ -938,77 +1109,77 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var, if ((timings.HSyncEnd >> 3) - (timings.HSyncStart >> 3) > 32) i |= 0x20; - j = (par->CRTC[0] + ((i & 0x01) << 8) + - par->CRTC[4] + ((i & 0x10) << 4) + 1) / 2; + j = (reg->CRTC[0] + ((i & 0x01) << 8) + + reg->CRTC[4] + ((i & 0x10) << 4) + 1) / 2; - if (j - (par->CRTC[4] + ((i & 0x10) << 4)) < 4) { - if (par->CRTC[4] + ((i & 0x10) << 4) + 4 <= - par->CRTC[0] + ((i & 0x01) << 8)) - j = par->CRTC[4] + ((i & 0x10) << 4) + 4; + if (j - (reg->CRTC[4] + ((i & 0x10) << 4)) < 4) { + if (reg->CRTC[4] + ((i & 0x10) << 4) + 4 <= + reg->CRTC[0] + ((i & 0x01) << 8)) + j = reg->CRTC[4] + ((i & 0x10) << 4) + 4; else - j = par->CRTC[0] + ((i & 0x01) << 8) + 1; + j = reg->CRTC[0] + ((i & 0x01) << 8) + 1; } - par->CR3B = j & 0xff; + reg->CR3B = j & 0xff; i |= (j & 0x100) >> 2; - par->CR3C = (par->CRTC[0] + ((i & 0x01) << 8)) / 2; - par->CR5D = i; - par->CR5E = (((timings.VTotal - 2) & 0x400) >> 10) | + reg->CR3C = (reg->CRTC[0] + ((i & 0x01) << 8)) / 2; + reg->CR5D = i; + reg->CR5E = (((timings.VTotal - 2) & 0x400) >> 10) | (((timings.VDisplay - 1) & 0x400) >> 9) | (((timings.VSyncStart) & 0x400) >> 8) | (((timings.VSyncStart) & 0x400) >> 6) | 0x40; width = (var->xres_virtual * ((var->bits_per_pixel+7) / 8)) >> 3; - par->CR91 = par->CRTC[19] = 0xff & width; - par->CR51 = (0x300 & width) >> 4; - par->CR90 = 0x80 | (width >> 8); - par->MiscOutReg |= 0x0c; + reg->CR91 = reg->CRTC[19] = 0xff & width; + reg->CR51 = (0x300 & width) >> 4; + reg->CR90 = 0x80 | (width >> 8); + reg->MiscOutReg |= 0x0c; /* Set frame buffer description. */ if (var->bits_per_pixel <= 8) - par->CR50 = 0; + reg->CR50 = 0; else if (var->bits_per_pixel <= 16) - par->CR50 = 0x10; + reg->CR50 = 0x10; else - par->CR50 = 0x30; + reg->CR50 = 0x30; if (var->xres_virtual <= 640) - par->CR50 |= 0x40; + reg->CR50 |= 0x40; else if (var->xres_virtual == 800) - par->CR50 |= 0x80; + reg->CR50 |= 0x80; else if (var->xres_virtual == 1024) - par->CR50 |= 0x00; + reg->CR50 |= 0x00; else if (var->xres_virtual == 1152) - par->CR50 |= 0x01; + reg->CR50 |= 0x01; else if (var->xres_virtual == 1280) - par->CR50 |= 0xc0; + reg->CR50 |= 0xc0; else if (var->xres_virtual == 1600) - par->CR50 |= 0x81; + reg->CR50 |= 0x81; else - par->CR50 |= 0xc1; /* Use GBD */ + reg->CR50 |= 0xc1; /* Use GBD */ - if( par->chip == S3_SAVAGE2000 ) - par->CR33 = 0x08; + if (par->chip == S3_SAVAGE2000) + reg->CR33 = 0x08; else - par->CR33 = 0x20; + reg->CR33 = 0x20; - par->CRTC[0x17] = 0xeb; + reg->CRTC[0x17] = 0xeb; - par->CR67 |= 1; + reg->CR67 |= 1; vga_out8(0x3d4, 0x36, par); - par->CR36 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x68, par); - par->CR68 = vga_in8 (0x3d5, par); - par->CR69 = 0; - vga_out8 (0x3d4, 0x6f, par); - par->CR6F = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x86, par); - par->CR86 = vga_in8 (0x3d5, par); - vga_out8 (0x3d4, 0x88, par); - par->CR88 = vga_in8 (0x3d5, par) | 0x08; - vga_out8 (0x3d4, 0xb0, par); - par->CRB0 = vga_in8 (0x3d5, par) | 0x80; + reg->CR36 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x68, par); + reg->CR68 = vga_in8(0x3d5, par); + reg->CR69 = 0; + vga_out8(0x3d4, 0x6f, par); + reg->CR6F = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x86, par); + reg->CR86 = vga_in8(0x3d5, par); + vga_out8(0x3d4, 0x88, par); + reg->CR88 = vga_in8(0x3d5, par) | 0x08; + vga_out8(0x3d4, 0xb0, par); + reg->CRB0 = vga_in8(0x3d5, par) | 0x80; return 0; } @@ -1037,11 +1208,11 @@ static int savagefb_setcolreg(unsigned regno, switch (info->var.bits_per_pixel) { case 8: - vga_out8 (0x3c8, regno, par); + vga_out8(0x3c8, regno, par); - vga_out8 (0x3c9, red >> 10, par); - vga_out8 (0x3c9, green >> 10, par); - vga_out8 (0x3c9, blue >> 10, par); + vga_out8(0x3c9, red >> 10, par); + vga_out8(0x3c9, green >> 10, par); + vga_out8(0x3c9, blue >> 10, par); break; case 16: @@ -1075,21 +1246,21 @@ static int savagefb_setcolreg(unsigned regno, return 0; } -static void savagefb_set_par_int (struct savagefb_par *par) +static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *reg) { unsigned char tmp, cr3a, cr66, cr67; - DBG ("savagefb_set_par_int"); + DBG("savagefb_set_par_int"); - par->SavageWaitIdle (par); + par->SavageWaitIdle(par); - vga_out8 (0x3c2, 0x23, par); + vga_out8(0x3c2, 0x23, par); - vga_out16 (0x3d4, 0x4838, par); - vga_out16 (0x3d4, 0xa539, par); - vga_out16 (0x3c4, 0x0608, par); + vga_out16(0x3d4, 0x4838, par); + vga_out16(0x3d4, 0xa539, par); + vga_out16(0x3c4, 0x0608, par); - vgaHWProtect (par, 1); + vgaHWProtect(par, 1); /* * Some Savage/MX and /IX systems go nuts when trying to exit the @@ -1099,203 +1270,202 @@ static void savagefb_set_par_int (struct savagefb_par *par) */ VerticalRetraceWait(par); - vga_out8 (0x3d4, 0x67, par); - cr67 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */ + vga_out8(0x3d4, 0x67, par); + cr67 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */ - vga_out8 (0x3d4, 0x23, par); - vga_out8 (0x3d5, 0x00, par); - vga_out8 (0x3d4, 0x26, par); - vga_out8 (0x3d5, 0x00, par); + vga_out8(0x3d4, 0x23, par); + vga_out8(0x3d5, 0x00, par); + vga_out8(0x3d4, 0x26, par); + vga_out8(0x3d5, 0x00, par); /* restore extended regs */ - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, par->CR66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, par->CR3A, par); - vga_out8 (0x3d4, 0x31, par); - vga_out8 (0x3d5, par->CR31, par); - vga_out8 (0x3d4, 0x32, par); - vga_out8 (0x3d5, par->CR32, par); - vga_out8 (0x3d4, 0x58, par); - vga_out8 (0x3d5, par->CR58, par); - vga_out8 (0x3d4, 0x53, par); - vga_out8 (0x3d5, par->CR53 & 0x7f, par); - - vga_out16 (0x3c4, 0x0608, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, reg->CR66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, reg->CR3A, par); + vga_out8(0x3d4, 0x31, par); + vga_out8(0x3d5, reg->CR31, par); + vga_out8(0x3d4, 0x32, par); + vga_out8(0x3d5, reg->CR32, par); + vga_out8(0x3d4, 0x58, par); + vga_out8(0x3d5, reg->CR58, par); + vga_out8(0x3d4, 0x53, par); + vga_out8(0x3d5, reg->CR53 & 0x7f, par); + + vga_out16(0x3c4, 0x0608, par); /* Restore DCLK registers. */ - vga_out8 (0x3c4, 0x0e, par); - vga_out8 (0x3c5, par->SR0E, par); - vga_out8 (0x3c4, 0x0f, par); - vga_out8 (0x3c5, par->SR0F, par); - vga_out8 (0x3c4, 0x29, par); - vga_out8 (0x3c5, par->SR29, par); - vga_out8 (0x3c4, 0x15, par); - vga_out8 (0x3c5, par->SR15, par); + vga_out8(0x3c4, 0x0e, par); + vga_out8(0x3c5, reg->SR0E, par); + vga_out8(0x3c4, 0x0f, par); + vga_out8(0x3c5, reg->SR0F, par); + vga_out8(0x3c4, 0x29, par); + vga_out8(0x3c5, reg->SR29, par); + vga_out8(0x3c4, 0x15, par); + vga_out8(0x3c5, reg->SR15, par); /* Restore flat panel expansion regsters. */ - if( par->chip == S3_SAVAGE_MX ) { + if (par->chip == S3_SAVAGE_MX) { int i; - for( i = 0; i < 8; i++ ) { - vga_out8 (0x3c4, 0x54+i, par); - vga_out8 (0x3c5, par->SR54[i], par); + for (i = 0; i < 8; i++) { + vga_out8(0x3c4, 0x54+i, par); + vga_out8(0x3c5, reg->SR54[i], par); } } - vgaHWRestore (par); + vgaHWRestore (par, reg); /* extended mode timing registers */ - vga_out8 (0x3d4, 0x53, par); - vga_out8 (0x3d5, par->CR53, par); - vga_out8 (0x3d4, 0x5d, par); - vga_out8 (0x3d5, par->CR5D, par); - vga_out8 (0x3d4, 0x5e, par); - vga_out8 (0x3d5, par->CR5E, par); - vga_out8 (0x3d4, 0x3b, par); - vga_out8 (0x3d5, par->CR3B, par); - vga_out8 (0x3d4, 0x3c, par); - vga_out8 (0x3d5, par->CR3C, par); - vga_out8 (0x3d4, 0x43, par); - vga_out8 (0x3d5, par->CR43, par); - vga_out8 (0x3d4, 0x65, par); - vga_out8 (0x3d5, par->CR65, par); + vga_out8(0x3d4, 0x53, par); + vga_out8(0x3d5, reg->CR53, par); + vga_out8(0x3d4, 0x5d, par); + vga_out8(0x3d5, reg->CR5D, par); + vga_out8(0x3d4, 0x5e, par); + vga_out8(0x3d5, reg->CR5E, par); + vga_out8(0x3d4, 0x3b, par); + vga_out8(0x3d5, reg->CR3B, par); + vga_out8(0x3d4, 0x3c, par); + vga_out8(0x3d5, reg->CR3C, par); + vga_out8(0x3d4, 0x43, par); + vga_out8(0x3d5, reg->CR43, par); + vga_out8(0x3d4, 0x65, par); + vga_out8(0x3d5, reg->CR65, par); /* restore the desired video mode with cr67 */ - vga_out8 (0x3d4, 0x67, par); + vga_out8(0x3d4, 0x67, par); /* following part not present in X11 driver */ - cr67 = vga_in8 (0x3d5, par) & 0xf; - vga_out8 (0x3d5, 0x50 | cr67, par); - udelay (10000); - vga_out8 (0x3d4, 0x67, par); + cr67 = vga_in8(0x3d5, par) & 0xf; + vga_out8(0x3d5, 0x50 | cr67, par); + udelay(10000); + vga_out8(0x3d4, 0x67, par); /* end of part */ - vga_out8 (0x3d5, par->CR67 & ~0x0c, par); + vga_out8(0x3d5, reg->CR67 & ~0x0c, par); /* other mode timing and extended regs */ - vga_out8 (0x3d4, 0x34, par); - vga_out8 (0x3d5, par->CR34, par); - vga_out8 (0x3d4, 0x40, par); - vga_out8 (0x3d5, par->CR40, par); - vga_out8 (0x3d4, 0x42, par); - vga_out8 (0x3d5, par->CR42, par); - vga_out8 (0x3d4, 0x45, par); - vga_out8 (0x3d5, par->CR45, par); - vga_out8 (0x3d4, 0x50, par); - vga_out8 (0x3d5, par->CR50, par); - vga_out8 (0x3d4, 0x51, par); - vga_out8 (0x3d5, par->CR51, par); + vga_out8(0x3d4, 0x34, par); + vga_out8(0x3d5, reg->CR34, par); + vga_out8(0x3d4, 0x40, par); + vga_out8(0x3d5, reg->CR40, par); + vga_out8(0x3d4, 0x42, par); + vga_out8(0x3d5, reg->CR42, par); + vga_out8(0x3d4, 0x45, par); + vga_out8(0x3d5, reg->CR45, par); + vga_out8(0x3d4, 0x50, par); + vga_out8(0x3d5, reg->CR50, par); + vga_out8(0x3d4, 0x51, par); + vga_out8(0x3d5, reg->CR51, par); /* memory timings */ - vga_out8 (0x3d4, 0x36, par); - vga_out8 (0x3d5, par->CR36, par); - vga_out8 (0x3d4, 0x60, par); - vga_out8 (0x3d5, par->CR60, par); - vga_out8 (0x3d4, 0x68, par); - vga_out8 (0x3d5, par->CR68, par); - vga_out8 (0x3d4, 0x69, par); - vga_out8 (0x3d5, par->CR69, par); - vga_out8 (0x3d4, 0x6f, par); - vga_out8 (0x3d5, par->CR6F, par); - - vga_out8 (0x3d4, 0x33, par); - vga_out8 (0x3d5, par->CR33, par); - vga_out8 (0x3d4, 0x86, par); - vga_out8 (0x3d5, par->CR86, par); - vga_out8 (0x3d4, 0x88, par); - vga_out8 (0x3d5, par->CR88, par); - vga_out8 (0x3d4, 0x90, par); - vga_out8 (0x3d5, par->CR90, par); - vga_out8 (0x3d4, 0x91, par); - vga_out8 (0x3d5, par->CR91, par); + vga_out8(0x3d4, 0x36, par); + vga_out8(0x3d5, reg->CR36, par); + vga_out8(0x3d4, 0x60, par); + vga_out8(0x3d5, reg->CR60, par); + vga_out8(0x3d4, 0x68, par); + vga_out8(0x3d5, reg->CR68, par); + vga_out8(0x3d4, 0x69, par); + vga_out8(0x3d5, reg->CR69, par); + vga_out8(0x3d4, 0x6f, par); + vga_out8(0x3d5, reg->CR6F, par); + + vga_out8(0x3d4, 0x33, par); + vga_out8(0x3d5, reg->CR33, par); + vga_out8(0x3d4, 0x86, par); + vga_out8(0x3d5, reg->CR86, par); + vga_out8(0x3d4, 0x88, par); + vga_out8(0x3d5, reg->CR88, par); + vga_out8(0x3d4, 0x90, par); + vga_out8(0x3d5, reg->CR90, par); + vga_out8(0x3d4, 0x91, par); + vga_out8(0x3d5, reg->CR91, par); if (par->chip == S3_SAVAGE4) { - vga_out8 (0x3d4, 0xb0, par); - vga_out8 (0x3d5, par->CRB0, par); + vga_out8(0x3d4, 0xb0, par); + vga_out8(0x3d5, reg->CRB0, par); } - vga_out8 (0x3d4, 0x32, par); - vga_out8 (0x3d5, par->CR32, par); + vga_out8(0x3d4, 0x32, par); + vga_out8(0x3d5, reg->CR32, par); /* unlock extended seq regs */ - vga_out8 (0x3c4, 0x08, par); - vga_out8 (0x3c5, 0x06, par); + vga_out8(0x3c4, 0x08, par); + vga_out8(0x3c5, 0x06, par); /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates * that we should leave the default SR10 and SR11 values there. */ - if (par->SR10 != 255) { - vga_out8 (0x3c4, 0x10, par); - vga_out8 (0x3c5, par->SR10, par); - vga_out8 (0x3c4, 0x11, par); - vga_out8 (0x3c5, par->SR11, par); + if (reg->SR10 != 255) { + vga_out8(0x3c4, 0x10, par); + vga_out8(0x3c5, reg->SR10, par); + vga_out8(0x3c4, 0x11, par); + vga_out8(0x3c5, reg->SR11, par); } /* restore extended seq regs for dclk */ - vga_out8 (0x3c4, 0x0e, par); - vga_out8 (0x3c5, par->SR0E, par); - vga_out8 (0x3c4, 0x0f, par); - vga_out8 (0x3c5, par->SR0F, par); - vga_out8 (0x3c4, 0x12, par); - vga_out8 (0x3c5, par->SR12, par); - vga_out8 (0x3c4, 0x13, par); - vga_out8 (0x3c5, par->SR13, par); - vga_out8 (0x3c4, 0x29, par); - vga_out8 (0x3c5, par->SR29, par); - - vga_out8 (0x3c4, 0x18, par); - vga_out8 (0x3c5, par->SR18, par); + vga_out8(0x3c4, 0x0e, par); + vga_out8(0x3c5, reg->SR0E, par); + vga_out8(0x3c4, 0x0f, par); + vga_out8(0x3c5, reg->SR0F, par); + vga_out8(0x3c4, 0x12, par); + vga_out8(0x3c5, reg->SR12, par); + vga_out8(0x3c4, 0x13, par); + vga_out8(0x3c5, reg->SR13, par); + vga_out8(0x3c4, 0x29, par); + vga_out8(0x3c5, reg->SR29, par); + vga_out8(0x3c4, 0x18, par); + vga_out8(0x3c5, reg->SR18, par); /* load new m, n pll values for dclk & mclk */ - vga_out8 (0x3c4, 0x15, par); - tmp = vga_in8 (0x3c5, par) & ~0x21; + vga_out8(0x3c4, 0x15, par); + tmp = vga_in8(0x3c5, par) & ~0x21; - vga_out8 (0x3c5, tmp | 0x03, par); - vga_out8 (0x3c5, tmp | 0x23, par); - vga_out8 (0x3c5, tmp | 0x03, par); - vga_out8 (0x3c5, par->SR15, par); - udelay (100); + vga_out8(0x3c5, tmp | 0x03, par); + vga_out8(0x3c5, tmp | 0x23, par); + vga_out8(0x3c5, tmp | 0x03, par); + vga_out8(0x3c5, reg->SR15, par); + udelay(100); - vga_out8 (0x3c4, 0x30, par); - vga_out8 (0x3c5, par->SR30, par); - vga_out8 (0x3c4, 0x08, par); - vga_out8 (0x3c5, par->SR08, par); + vga_out8(0x3c4, 0x30, par); + vga_out8(0x3c5, reg->SR30, par); + vga_out8(0x3c4, 0x08, par); + vga_out8(0x3c5, reg->SR08, par); /* now write out cr67 in full, possibly starting STREAMS */ VerticalRetraceWait(par); - vga_out8 (0x3d4, 0x67, par); - vga_out8 (0x3d5, par->CR67, par); + vga_out8(0x3d4, 0x67, par); + vga_out8(0x3d5, reg->CR67, par); - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x80, par); - vga_out8 (0x3d4, 0x3a, par); - cr3a = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3a | 0x80, par); + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x80, par); + vga_out8(0x3d4, 0x3a, par); + cr3a = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3a | 0x80, par); if (par->chip != S3_SAVAGE_MX) { VerticalRetraceWait(par); - savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par); - par->SavageWaitIdle (par); - savage_out32 (MIU_CONTROL_REG, par->MMPR1, par); - par->SavageWaitIdle (par); - savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par); - par->SavageWaitIdle (par); - savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par); + savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par); + par->SavageWaitIdle(par); + savage_out32(MIU_CONTROL_REG, reg->MMPR1, par); + par->SavageWaitIdle(par); + savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par); + par->SavageWaitIdle(par); + savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par); } - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66, par); - vga_out8 (0x3d4, 0x3a, par); - vga_out8 (0x3d5, cr3a, par); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66, par); + vga_out8(0x3d4, 0x3a, par); + vga_out8(0x3d5, cr3a, par); - SavageSetup2DEngine (par); - vgaHWProtect (par, 0); + SavageSetup2DEngine(par); + vgaHWProtect(par, 0); } -static void savagefb_update_start (struct savagefb_par *par, - struct fb_var_screeninfo *var) +static void savagefb_update_start(struct savagefb_par *par, + struct fb_var_screeninfo *var) { int base; @@ -1305,8 +1475,8 @@ static void savagefb_update_start (struct savagefb_par *par, /* now program the start address registers */ vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par); vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par); - vga_out8 (0x3d4, 0x69, par); - vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par); + vga_out8(0x3d4, 0x69, par); + vga_out8(0x3d5, (base & 0x7f0000) >> 16, par); } @@ -1325,29 +1495,14 @@ 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 = info->par; - int cmd; - - cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; - par->bci_ptr = 0; - par->SavageWaitFifo(par,3); - BCI_SEND(cmd); - BCI_SEND(BCI_CLIP_TL(0, 0)); - BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff)); -} -#endif - -static int savagefb_set_par (struct fb_info *info) +static int savagefb_set_par(struct fb_info *info) { struct savagefb_par *par = info->par; struct fb_var_screeninfo *var = &info->var; int err; DBG("savagefb_set_par"); - err = savagefb_decode_var (var, par); + err = savagefb_decode_var(var, par, &par->state); if (err) return err; @@ -1366,8 +1521,8 @@ static int savagefb_set_par (struct fb_info *info) par->maxClock = par->dacSpeedBpp; par->minClock = 10000; - savagefb_set_par_int (par); - fb_set_cmap (&info->cmap, info); + savagefb_set_par_int(par, &par->state); + fb_set_cmap(&info->cmap, info); savagefb_set_fix(info); savagefb_set_clip(info); @@ -1378,12 +1533,12 @@ static int savagefb_set_par (struct fb_info *info) /* * Pan or Wrap the Display */ -static int savagefb_pan_display (struct fb_var_screeninfo *var, - struct fb_info *info) +static int savagefb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *info) { struct savagefb_par *par = info->par; - savagefb_update_start (par, var); + savagefb_update_start(par, var); return 0; } @@ -1440,6 +1595,22 @@ static int savagefb_blank(int blank, struct fb_info *info) return (blank == FB_BLANK_NORMAL) ? 1 : 0; } +static void savagefb_save_state(struct fb_info *info) +{ + struct savagefb_par *par = info->par; + + savage_get_default_par(par, &par->save); +} + +static void savagefb_restore_state(struct fb_info *info) +{ + struct savagefb_par *par = info->par; + + savagefb_blank(FB_BLANK_POWERDOWN, info); + savage_set_default_par(par, &par->save); + savagefb_blank(FB_BLANK_UNBLANK, info); +} + static struct fb_ops savagefb_ops = { .owner = THIS_MODULE, .fb_check_var = savagefb_check_var, @@ -1447,6 +1618,8 @@ static struct fb_ops savagefb_ops = { .fb_setcolreg = savagefb_setcolreg, .fb_pan_display = savagefb_pan_display, .fb_blank = savagefb_blank, + .fb_save_state = savagefb_save_state, + .fb_restore_state = savagefb_restore_state, #if defined(CONFIG_FB_SAVAGE_ACCEL) .fb_fillrect = savagefb_fillrect, .fb_copyarea = savagefb_copyarea, @@ -1479,59 +1652,59 @@ static struct fb_var_screeninfo __devinitdata savagefb_var800x600x8 = { .vmode = FB_VMODE_NONINTERLACED }; -static void savage_enable_mmio (struct savagefb_par *par) +static void savage_enable_mmio(struct savagefb_par *par) { unsigned char val; - DBG ("savage_enable_mmio\n"); + DBG("savage_enable_mmio\n"); - val = vga_in8 (0x3c3, par); - vga_out8 (0x3c3, val | 0x01, par); - val = vga_in8 (0x3cc, par); - vga_out8 (0x3c2, val | 0x01, par); + val = vga_in8(0x3c3, par); + vga_out8(0x3c3, val | 0x01, par); + val = vga_in8(0x3cc, par); + vga_out8(0x3c2, val | 0x01, par); if (par->chip >= S3_SAVAGE4) { - vga_out8 (0x3d4, 0x40, par); - val = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, val | 1, par); + vga_out8(0x3d4, 0x40, par); + val = vga_in8(0x3d5, par); + vga_out8(0x3d5, val | 1, par); } } -static void savage_disable_mmio (struct savagefb_par *par) +static void savage_disable_mmio(struct savagefb_par *par) { unsigned char val; - DBG ("savage_disable_mmio\n"); + DBG("savage_disable_mmio\n"); - if(par->chip >= S3_SAVAGE4 ) { - vga_out8 (0x3d4, 0x40, par); - val = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, val | 1, par); + if (par->chip >= S3_SAVAGE4) { + vga_out8(0x3d4, 0x40, par); + val = vga_in8(0x3d5, par); + vga_out8(0x3d5, val | 1, par); } } -static int __devinit savage_map_mmio (struct fb_info *info) +static int __devinit savage_map_mmio(struct fb_info *info) { struct savagefb_par *par = info->par; - DBG ("savage_map_mmio"); + DBG("savage_map_mmio"); - if (S3_SAVAGE3D_SERIES (par->chip)) - par->mmio.pbase = pci_resource_start (par->pcidev, 0) + + if (S3_SAVAGE3D_SERIES(par->chip)) + par->mmio.pbase = pci_resource_start(par->pcidev, 0) + SAVAGE_NEWMMIO_REGBASE_S3; else - par->mmio.pbase = pci_resource_start (par->pcidev, 0) + + par->mmio.pbase = pci_resource_start(par->pcidev, 0) + SAVAGE_NEWMMIO_REGBASE_S4; par->mmio.len = SAVAGE_NEWMMIO_REGSIZE; - par->mmio.vbase = ioremap (par->mmio.pbase, par->mmio.len); + par->mmio.vbase = ioremap(par->mmio.pbase, par->mmio.len); if (!par->mmio.vbase) { - printk ("savagefb: unable to map memory mapped IO\n"); + printk("savagefb: unable to map memory mapped IO\n"); return -ENOMEM; } else - printk (KERN_INFO "savagefb: mapped io at %p\n", + printk(KERN_INFO "savagefb: mapped io at %p\n", par->mmio.vbase); info->fix.mmio_start = par->mmio.pbase; @@ -1540,15 +1713,15 @@ static int __devinit savage_map_mmio (struct fb_info *info) par->bci_base = (u32 __iomem *)(par->mmio.vbase + BCI_BUFFER_OFFSET); par->bci_ptr = 0; - savage_enable_mmio (par); + savage_enable_mmio(par); return 0; } -static void savage_unmap_mmio (struct fb_info *info) +static void savage_unmap_mmio(struct fb_info *info) { struct savagefb_par *par = info->par; - DBG ("savage_unmap_mmio"); + DBG("savage_unmap_mmio"); savage_disable_mmio(par); @@ -1558,46 +1731,46 @@ static void savage_unmap_mmio (struct fb_info *info) } } -static int __devinit savage_map_video (struct fb_info *info, - int video_len) +static int __devinit savage_map_video(struct fb_info *info, + int video_len) { struct savagefb_par *par = info->par; int resource; DBG("savage_map_video"); - if (S3_SAVAGE3D_SERIES (par->chip)) + if (S3_SAVAGE3D_SERIES(par->chip)) resource = 0; else resource = 1; - par->video.pbase = pci_resource_start (par->pcidev, resource); + par->video.pbase = pci_resource_start(par->pcidev, resource); par->video.len = video_len; - par->video.vbase = ioremap (par->video.pbase, par->video.len); + par->video.vbase = ioremap(par->video.pbase, par->video.len); if (!par->video.vbase) { - printk ("savagefb: unable to map screen memory\n"); + printk("savagefb: unable to map screen memory\n"); return -ENOMEM; } else - printk (KERN_INFO "savagefb: mapped framebuffer at %p, " - "pbase == %x\n", par->video.vbase, par->video.pbase); + printk(KERN_INFO "savagefb: mapped framebuffer at %p, " + "pbase == %x\n", par->video.vbase, par->video.pbase); info->fix.smem_start = par->video.pbase; info->fix.smem_len = par->video.len - par->cob_size; info->screen_base = par->video.vbase; #ifdef CONFIG_MTRR - par->video.mtrr = mtrr_add (par->video.pbase, video_len, - MTRR_TYPE_WRCOMB, 1); + par->video.mtrr = mtrr_add(par->video.pbase, video_len, + MTRR_TYPE_WRCOMB, 1); #endif /* Clear framebuffer, it's all white in memory after boot */ - memset_io (par->video.vbase, 0, par->video.len); + memset_io(par->video.vbase, 0, par->video.len); return 0; } -static void savage_unmap_video (struct fb_info *info) +static void savage_unmap_video(struct fb_info *info) { struct savagefb_par *par = info->par; @@ -1605,16 +1778,16 @@ static void savage_unmap_video (struct fb_info *info) if (par->video.vbase) { #ifdef CONFIG_MTRR - mtrr_del (par->video.mtrr, par->video.pbase, par->video.len); + mtrr_del(par->video.mtrr, par->video.pbase, par->video.len); #endif - iounmap (par->video.vbase); + iounmap(par->video.vbase); par->video.vbase = NULL; info->screen_base = NULL; } } -static int savage_init_hw (struct savagefb_par *par) +static int savage_init_hw(struct savagefb_par *par) { unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp; @@ -1656,7 +1829,7 @@ static int savage_init_hw (struct savagefb_par *par) switch (par->chip) { case S3_SAVAGE3D: - videoRam = RamSavage3D[ (config1 & 0xC0) >> 6 ] * 1024; + videoRam = RamSavage3D[(config1 & 0xC0) >> 6 ] * 1024; break; case S3_SAVAGE4: @@ -1667,22 +1840,22 @@ static int savage_init_hw (struct savagefb_par *par) * can do it different... */ vga_out8(0x3d4, 0x68, par); /* memory control 1 */ - if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) ) + if ((vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6)) RamSavage4[1] = 8; /*FALLTHROUGH*/ case S3_SAVAGE2000: - videoRam = RamSavage4[ (config1 & 0xE0) >> 5 ] * 1024; + videoRam = RamSavage4[(config1 & 0xE0) >> 5] * 1024; break; case S3_SAVAGE_MX: case S3_SUPERSAVAGE: - videoRam = RamSavageMX[ (config1 & 0x0E) >> 1 ] * 1024; + videoRam = RamSavageMX[(config1 & 0x0E) >> 1] * 1024; break; case S3_PROSAVAGE: - videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ] * 1024; + videoRam = RamSavageNB[(config1 & 0xE0) >> 5] * 1024; break; default: @@ -1693,31 +1866,31 @@ static int savage_init_hw (struct savagefb_par *par) videoRambytes = videoRam * 1024; - printk (KERN_INFO "savagefb: probed videoram: %dk\n", videoRam); + printk(KERN_INFO "savagefb: probed videoram: %dk\n", videoRam); /* reset graphics engine to avoid memory corruption */ - vga_out8 (0x3d4, 0x66, par); - cr66 = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr66 | 0x02, par); - udelay (10000); + vga_out8(0x3d4, 0x66, par); + cr66 = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr66 | 0x02, par); + udelay(10000); - vga_out8 (0x3d4, 0x66, par); - vga_out8 (0x3d5, cr66 & ~0x02, par); /* clear reset flag */ - udelay (10000); + vga_out8(0x3d4, 0x66, par); + vga_out8(0x3d5, cr66 & ~0x02, par); /* clear reset flag */ + udelay(10000); /* * reset memory interface, 3D engine, AGP master, PCI master, * master engine unit, motion compensation/LPB */ - vga_out8 (0x3d4, 0x3f, par); - cr3f = vga_in8 (0x3d5, par); - vga_out8 (0x3d5, cr3f | 0x08, par); - udelay (10000); + vga_out8(0x3d4, 0x3f, par); + cr3f = vga_in8(0x3d5, par); + vga_out8(0x3d5, cr3f | 0x08, par); + udelay(10000); - vga_out8 (0x3d4, 0x3f, par); - vga_out8 (0x3d5, cr3f & ~0x08, par); /* clear reset flags */ - udelay (10000); + vga_out8(0x3d4, 0x3f, par); + vga_out8(0x3d5, cr3f & ~0x08, par); /* clear reset flags */ + udelay(10000); /* Savage ramdac speeds */ par->numClocks = 4; @@ -1740,7 +1913,7 @@ static int savage_init_hw (struct savagefb_par *par) n1 = n & 0x1f; n2 = (n >> 5) & 0x03; par->MCLK = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100; - printk (KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n", + printk(KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n", par->MCLK); /* check for DVI/flat panel */ @@ -1769,12 +1942,12 @@ static int savage_init_hw (struct savagefb_par *par) /* Check LCD panel parrmation */ if (par->display_type == DISP_LCD) { - unsigned char cr6b = VGArCR( 0x6b, par); + unsigned char cr6b = VGArCR(0x6b, par); - int panelX = (VGArSEQ (0x61, par) + - ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8; - int panelY = (VGArSEQ (0x69, par) + - ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1); + int panelX = (VGArSEQ(0x61, par) + + ((VGArSEQ(0x66, par) & 0x02) << 7) + 1) * 8; + int panelY = (VGArSEQ(0x69, par) + + ((VGArSEQ(0x6e, par) & 0x70) << 4) + 1); char * sTechnology = "Unknown"; @@ -1796,26 +1969,26 @@ static int savage_init_hw (struct savagefb_par *par) ActiveDUO = 0x80 }; - if ((VGArSEQ (0x39, par) & 0x03) == 0) { + if ((VGArSEQ(0x39, par) & 0x03) == 0) { sTechnology = "TFT"; - } else if ((VGArSEQ (0x30, par) & 0x01) == 0) { + } else if ((VGArSEQ(0x30, par) & 0x01) == 0) { sTechnology = "DSTN"; } else { sTechnology = "STN"; } - printk (KERN_INFO "savagefb: %dx%d %s LCD panel detected %s\n", - panelX, panelY, sTechnology, - cr6b & ActiveLCD ? "and active" : "but not active"); + printk(KERN_INFO "savagefb: %dx%d %s LCD panel detected %s\n", + panelX, panelY, sTechnology, + cr6b & ActiveLCD ? "and active" : "but not active"); - if( cr6b & ActiveLCD ) { + if (cr6b & ActiveLCD) { /* * If the LCD is active and panel expansion is enabled, * we probably want to kill the HW cursor. */ - printk (KERN_INFO "savagefb: Limiting video mode to " - "%dx%d\n", panelX, panelY ); + printk(KERN_INFO "savagefb: Limiting video mode to " + "%dx%d\n", panelX, panelY); par->SavagePanelWidth = panelX; par->SavagePanelHeight = panelY; @@ -1824,9 +1997,10 @@ static int savage_init_hw (struct savagefb_par *par) par->display_type = DISP_CRT; } - savage_get_default_par (par); + savage_get_default_par(par, &par->state); + par->save = par->state; - if( S3_SAVAGE4_SERIES(par->chip) ) { + if (S3_SAVAGE4_SERIES(par->chip)) { /* * The Savage4 and ProSavage have COB coherency bugs which * render the buffer useless. We disable it. @@ -1845,9 +2019,9 @@ static int savage_init_hw (struct savagefb_par *par) return videoRambytes; } -static int __devinit savage_init_fb_info (struct fb_info *info, - struct pci_dev *dev, - const struct pci_device_id *id) +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 = info->par; int err = 0; @@ -1863,63 +2037,63 @@ static int __devinit savage_init_fb_info (struct fb_info *info, switch (info->fix.accel) { case FB_ACCEL_SUPERSAVAGE: par->chip = S3_SUPERSAVAGE; - snprintf (info->fix.id, 16, "SuperSavage"); + snprintf(info->fix.id, 16, "SuperSavage"); break; case FB_ACCEL_SAVAGE4: par->chip = S3_SAVAGE4; - snprintf (info->fix.id, 16, "Savage4"); + snprintf(info->fix.id, 16, "Savage4"); break; case FB_ACCEL_SAVAGE3D: par->chip = S3_SAVAGE3D; - snprintf (info->fix.id, 16, "Savage3D"); + snprintf(info->fix.id, 16, "Savage3D"); break; case FB_ACCEL_SAVAGE3D_MV: par->chip = S3_SAVAGE3D; - snprintf (info->fix.id, 16, "Savage3D-MV"); + snprintf(info->fix.id, 16, "Savage3D-MV"); break; case FB_ACCEL_SAVAGE2000: par->chip = S3_SAVAGE2000; - snprintf (info->fix.id, 16, "Savage2000"); + snprintf(info->fix.id, 16, "Savage2000"); break; case FB_ACCEL_SAVAGE_MX_MV: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/MX-MV"); + snprintf(info->fix.id, 16, "Savage/MX-MV"); break; case FB_ACCEL_SAVAGE_MX: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/MX"); + snprintf(info->fix.id, 16, "Savage/MX"); break; case FB_ACCEL_SAVAGE_IX_MV: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/IX-MV"); + snprintf(info->fix.id, 16, "Savage/IX-MV"); break; case FB_ACCEL_SAVAGE_IX: par->chip = S3_SAVAGE_MX; - snprintf (info->fix.id, 16, "Savage/IX"); + snprintf(info->fix.id, 16, "Savage/IX"); break; case FB_ACCEL_PROSAVAGE_PM: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavagePM"); + snprintf(info->fix.id, 16, "ProSavagePM"); break; case FB_ACCEL_PROSAVAGE_KM: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavageKM"); + snprintf(info->fix.id, 16, "ProSavageKM"); break; case FB_ACCEL_S3TWISTER_P: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "TwisterP"); + snprintf(info->fix.id, 16, "TwisterP"); break; case FB_ACCEL_S3TWISTER_K: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "TwisterK"); + snprintf(info->fix.id, 16, "TwisterK"); break; case FB_ACCEL_PROSAVAGE_DDR: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavageDDR"); + snprintf(info->fix.id, 16, "ProSavageDDR"); break; case FB_ACCEL_PROSAVAGE_DDRK: par->chip = S3_PROSAVAGE; - snprintf (info->fix.id, 16, "ProSavage8"); + snprintf(info->fix.id, 16, "ProSavage8"); break; } @@ -1960,7 +2134,7 @@ static int __devinit savage_init_fb_info (struct fb_info *info, info->pixmap.buf_align = 4; info->pixmap.access_align = 32; - err = fb_alloc_cmap (&info->cmap, NR_PALETTE, 0); + err = fb_alloc_cmap(&info->cmap, NR_PALETTE, 0); if (!err) info->flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | @@ -1972,8 +2146,8 @@ static int __devinit savage_init_fb_info (struct fb_info *info, /* --------------------------------------------------------------------- */ -static int __devinit savagefb_probe (struct pci_dev* dev, - const struct pci_device_id* id) +static int __devinit savagefb_probe(struct pci_dev* dev, + const struct pci_device_id* id) { struct fb_info *info; struct savagefb_par *par; @@ -2085,12 +2259,12 @@ static int __devinit savagefb_probe (struct pci_dev* dev, fb_destroy_modedb(info->monspecs.modedb); info->monspecs.modedb = NULL; - err = register_framebuffer (info); + err = register_framebuffer(info); if (err < 0) goto failed; - printk (KERN_INFO "fb: S3 %s frame buffer device\n", - info->fix.id); + printk(KERN_INFO "fb: S3 %s frame buffer device\n", + info->fix.id); /* * Our driver data @@ -2103,10 +2277,10 @@ static int __devinit savagefb_probe (struct pci_dev* dev, #ifdef CONFIG_FB_SAVAGE_I2C savagefb_delete_i2c_busses(info); #endif - fb_alloc_cmap (&info->cmap, 0, 0); + fb_alloc_cmap(&info->cmap, 0, 0); savage_unmap_video(info); failed_video: - savage_unmap_mmio (info); + savage_unmap_mmio(info); failed_mmio: kfree(info->pixmap.addr); failed_init: @@ -2117,7 +2291,7 @@ static int __devinit savagefb_probe (struct pci_dev* dev, return err; } -static void __devexit savagefb_remove (struct pci_dev *dev) +static void __devexit savagefb_remove(struct pci_dev *dev) { struct fb_info *info = pci_get_drvdata(dev); @@ -2129,16 +2303,16 @@ static void __devexit savagefb_remove (struct pci_dev *dev) * we will be leaving hooks that could cause * oopsen laying around. */ - if (unregister_framebuffer (info)) - printk (KERN_WARNING "savagefb: danger danger! " - "Oopsen imminent!\n"); + if (unregister_framebuffer(info)) + printk(KERN_WARNING "savagefb: danger danger! " + "Oopsen imminent!\n"); #ifdef CONFIG_FB_SAVAGE_I2C savagefb_delete_i2c_busses(info); #endif - fb_alloc_cmap (&info->cmap, 0, 0); - savage_unmap_video (info); - savage_unmap_mmio (info); + fb_alloc_cmap(&info->cmap, 0, 0); + savage_unmap_video(info); + savage_unmap_mmio(info); kfree(info->pixmap.addr); pci_release_regions(dev); framebuffer_release(info); @@ -2151,7 +2325,7 @@ static void __devexit savagefb_remove (struct pci_dev *dev) } } -static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) +static int savagefb_suspend(struct pci_dev* dev, pm_message_t state) { struct fb_info *info = pci_get_drvdata(dev); struct savagefb_par *par = info->par; @@ -2177,6 +2351,7 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) info->fbops->fb_sync(info); savagefb_blank(FB_BLANK_POWERDOWN, info); + savage_set_default_par(par, &par->save); savage_disable_mmio(par); pci_save_state(dev); pci_disable_device(dev); @@ -2186,7 +2361,7 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) return 0; } -static int savagefb_resume (struct pci_dev* dev) +static int savagefb_resume(struct pci_dev* dev) { struct fb_info *info = pci_get_drvdata(dev); struct savagefb_par *par = info->par; @@ -2210,15 +2385,15 @@ static int savagefb_resume (struct pci_dev* dev) pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); - if(pci_enable_device(dev)) + if (pci_enable_device(dev)) DBG("err"); pci_set_master(dev); savage_enable_mmio(par); savage_init_hw(par); - savagefb_set_par (info); + savagefb_set_par(info); + fb_set_suspend(info, 0); savagefb_blank(FB_BLANK_UNBLANK, info); - fb_set_suspend (info, 0); release_console_sem(); return 0; @@ -2311,10 +2486,10 @@ static struct pci_driver savagefb_driver = { /* **************************** exit-time only **************************** */ -static void __exit savage_done (void) +static void __exit savage_done(void) { DBG("savage_done"); - pci_unregister_driver (&savagefb_driver); + pci_unregister_driver(&savagefb_driver); } @@ -2345,7 +2520,7 @@ static int __init savagefb_init(void) return -ENODEV; savagefb_setup(option); - return pci_register_driver (&savagefb_driver); + return pci_register_driver(&savagefb_driver); } diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 8adf5bf91ee..c63c0e721b8 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -275,7 +275,7 @@ sisfb_search_mode(char *name, BOOLEAN quiet) static void __devinit sisfb_get_vga_mode_from_kernel(void) { -#if (defined(__i386__) || defined(__x86_64__)) && defined(CONFIG_VIDEO_SELECT) +#ifdef CONFIG_X86 char mymode[32]; int mydepth = screen_info.lfb_depth; diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c index 9b707771d75..67f429e9318 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/skeletonfb.c @@ -906,11 +906,6 @@ static void __exit xxxfb_exit(void) } #endif -MODULE_LICENSE("GPL"); -module_init(xxxfb_init); -module_exit(xxxfb_exit); - - /* * Setup */ diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c index 7398bd48ba6..6c2c78ab982 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/tgafb.c @@ -26,7 +26,6 @@ #include <linux/selection.h> #include <asm/io.h> #include <video/tgafb.h> -#include <linux/selection.h> /* * Local functions. diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index b0b9acfdd43..5718924b677 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -51,7 +51,7 @@ static int inverse = 0; static int mtrr = 0; /* disable mtrr */ static int vram_remap __initdata = 0; /* Set amount of memory to be used */ static int vram_total __initdata = 0; /* Set total amount of memory */ -static int pmi_setpal = 0; /* pmi for palette changes ??? */ +static int pmi_setpal = 1; /* pmi for palette changes ??? */ static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ static unsigned short *pmi_base = NULL; static void (*pmi_start)(void); @@ -80,15 +80,30 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, return 0; } -static void vesa_setpalette(int regno, unsigned red, unsigned green, +static int vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue) { int shift = 16 - depth; + int err = -EINVAL; + +/* + * Try VGA registers first... + */ + if (vga_compat) { + outb_p(regno, dac_reg); + outb_p(red >> shift, dac_val); + outb_p(green >> shift, dac_val); + outb_p(blue >> shift, dac_val); + err = 0; + } #ifdef __i386__ - struct { u_char blue, green, red, pad; } entry; +/* + * Fallback to the PMI.... + */ + if (err && pmi_setpal) { + struct { u_char blue, green, red, pad; } entry; - if (pmi_setpal) { entry.red = red >> shift; entry.green = green >> shift; entry.blue = blue >> shift; @@ -102,26 +117,19 @@ static void vesa_setpalette(int regno, unsigned red, unsigned green, "d" (regno), /* EDX */ "D" (&entry), /* EDI */ "S" (&pmi_pal)); /* ESI */ - return; + err = 0; } #endif -/* - * without protected mode interface and if VGA compatible, - * try VGA registers... - */ - if (vga_compat) { - outb_p(regno, dac_reg); - outb_p(red >> shift, dac_val); - outb_p(green >> shift, dac_val); - outb_p(blue >> shift, dac_val); - } + return err; } static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *info) { + int err = 0; + /* * Set a single color register. The values supplied are * already rounded down to the hardware's capabilities @@ -133,7 +141,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, return 1; if (info->var.bits_per_pixel == 8) - vesa_setpalette(regno,red,green,blue); + err = vesa_setpalette(regno,red,green,blue); else if (regno < 16) { switch (info->var.bits_per_pixel) { case 16: @@ -164,7 +172,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green, } } - return 0; + return err; } static struct fb_ops vesafb_ops = { @@ -460,9 +468,7 @@ static struct platform_driver vesafb_driver = { }, }; -static struct platform_device vesafb_device = { - .name = "vesafb", -}; +static struct platform_device *vesafb_device; static int __init vesafb_init(void) { @@ -475,10 +481,19 @@ static int __init vesafb_init(void) ret = platform_driver_register(&vesafb_driver); if (!ret) { - ret = platform_device_register(&vesafb_device); - if (ret) + vesafb_device = platform_device_alloc("vesafb", 0); + + if (vesafb_device) + ret = platform_device_add(vesafb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(vesafb_device); platform_driver_unregister(&vesafb_driver); + } } + return ret; } module_init(vesafb_init); diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c index 77eed1fd994..d073ffb6e1f 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/vfb.c @@ -398,12 +398,6 @@ static int __init vfb_setup(char *options) * Initialisation */ -static void vfb_platform_release(struct device *device) -{ - // This is called when the reference count goes to zero. - dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n"); -} - static int __init vfb_probe(struct platform_device *dev) { struct fb_info *info; @@ -482,13 +476,7 @@ static struct platform_driver vfb_driver = { }, }; -static struct platform_device vfb_device = { - .name = "vfb", - .id = 0, - .dev = { - .release = vfb_platform_release, - } -}; +static struct platform_device *vfb_device; static int __init vfb_init(void) { @@ -508,10 +496,19 @@ static int __init vfb_init(void) ret = platform_driver_register(&vfb_driver); if (!ret) { - ret = platform_device_register(&vfb_device); - if (ret) + vfb_device = platform_device_alloc("vfb", 0); + + if (vfb_device) + ret = platform_device_add(vfb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(vfb_device); platform_driver_unregister(&vfb_driver); + } } + return ret; } @@ -520,7 +517,7 @@ module_init(vfb_init); #ifdef MODULE static void __exit vfb_exit(void) { - platform_device_unregister(&vfb_device); + platform_device_unregister(vfb_device); platform_driver_unregister(&vfb_driver); } diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 4fd2a272e03..3c404c9bd36 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -1334,9 +1334,8 @@ static int vga16fb_setup(char *options) } #endif -static int __init vga16fb_probe(struct device *device) +static int __init vga16fb_probe(struct platform_device *dev) { - struct platform_device *dev = to_platform_device(device); struct fb_info *info; struct vga16fb_par *par; int i; @@ -1403,7 +1402,7 @@ static int __init vga16fb_probe(struct device *device) printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); - dev_set_drvdata(device, info); + platform_set_drvdata(dev, info); return 0; @@ -1417,9 +1416,9 @@ static int __init vga16fb_probe(struct device *device) return ret; } -static int vga16fb_remove(struct device *device) +static int vga16fb_remove(struct platform_device *dev) { - struct fb_info *info = dev_get_drvdata(device); + struct fb_info *info = platform_get_drvdata(dev); if (info) { unregister_framebuffer(info); @@ -1432,16 +1431,15 @@ static int vga16fb_remove(struct device *device) return 0; } -static struct device_driver vga16fb_driver = { - .name = "vga16fb", - .bus = &platform_bus_type, +static struct platform_driver vga16fb_driver = { .probe = vga16fb_probe, .remove = vga16fb_remove, + .driver = { + .name = "vga16fb", + }, }; -static struct platform_device vga16fb_device = { - .name = "vga16fb", -}; +static struct platform_device *vga16fb_device; static int __init vga16fb_init(void) { @@ -1454,12 +1452,20 @@ static int __init vga16fb_init(void) vga16fb_setup(option); #endif - ret = driver_register(&vga16fb_driver); + ret = platform_driver_register(&vga16fb_driver); if (!ret) { - ret = platform_device_register(&vga16fb_device); - if (ret) - driver_unregister(&vga16fb_driver); + vga16fb_device = platform_device_alloc("vga16fb", 0); + + if (vga16fb_device) + ret = platform_device_add(vga16fb_device); + else + ret = -ENOMEM; + + if (ret) { + platform_device_put(vga16fb_device); + platform_driver_unregister(&vga16fb_driver); + } } return ret; @@ -1467,8 +1473,8 @@ static int __init vga16fb_init(void) static void __exit vga16fb_exit(void) { - platform_device_unregister(&vga16fb_device); - driver_unregister(&vga16fb_driver); + platform_device_unregister(vga16fb_device); + platform_driver_unregister(&vga16fb_driver); } MODULE_LICENSE("GPL"); |