X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fvideo%2Fneofb.c;h=24b12f71d5a83d78aa73632b772a41b5453b9fd4;hb=d52a0a95a1b47768639263f79941564a6df7e69c;hp=6ce5ba85c9c7b00cfe0df9e0a015d8a52201a052;hpb=ec9397bab20a628530ce3051167d3d0fcc2c1af7;p=linux-2.6.git diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 6ce5ba85c..24b12f71d 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -93,25 +93,25 @@ static int external; static int libretto; static int nostretch; static int nopciburst; -static char *mode_option __initdata = NULL; +static char *mode_option __devinitdata = NULL; #ifdef MODULE MODULE_AUTHOR("(c) 2001-2002 Denis Oliver Kropp "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("FBDev driver for NeoMagic PCI Chips"); -MODULE_PARM(internal, "i"); +module_param(internal, bool, 0); MODULE_PARM_DESC(internal, "Enable output on internal LCD Display."); -MODULE_PARM(external, "i"); +module_param(external, bool, 0); MODULE_PARM_DESC(external, "Enable output on external CRT."); -MODULE_PARM(libretto, "i"); +module_param(libretto, bool, 0); MODULE_PARM_DESC(libretto, "Force Libretto 100/110 800x480 LCD."); -MODULE_PARM(nostretch, "i"); +module_param(nostretch, bool, 0); MODULE_PARM_DESC(nostretch, "Disable stretching of modes smaller than LCD."); -MODULE_PARM(nopciburst, "i"); +module_param(nopciburst, bool, 0); MODULE_PARM_DESC(nopciburst, "Disable PCI burst mode."); -MODULE_PARM(mode_option, "s"); +module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Preferred video mode ('640x480-8@60', etc)"); #endif @@ -152,11 +152,6 @@ static biosMode bios32[] = { }; #endif -static inline u32 read_le32(int regindex, const struct neofb_par *par) -{ - return readl(par->neo2200 + par->cursorOff + regindex); -} - static inline void write_le32(int regindex, u32 val, const struct neofb_par *par) { writel(val, par->neo2200 + par->cursorOff + regindex); @@ -170,20 +165,20 @@ static int neoFindMode(int xres, int yres, int depth) switch (depth) { case 8: - size = sizeof(bios8) / sizeof(biosMode); + size = ARRAY_SIZE(bios8); mode = bios8; break; case 16: - size = sizeof(bios16) / sizeof(biosMode); + size = ARRAY_SIZE(bios16); mode = bios16; break; case 24: - size = sizeof(bios24) / sizeof(biosMode); + size = ARRAY_SIZE(bios24); mode = bios24; break; #ifdef NO_32BIT_SUPPORT_YET case 32: - size = sizeof(bios32) / sizeof(biosMode); + size = ARRAY_SIZE(bios32); mode = bios32; break; #endif @@ -405,21 +400,21 @@ static void neoUnlock(void) */ static int paletteEnabled = 0; -inline void VGAenablePalette(void) +static inline void VGAenablePalette(void) { vga_r(NULL, VGA_IS1_RC); vga_w(NULL, VGA_ATT_W, 0x00); paletteEnabled = 1; } -inline void VGAdisablePalette(void) +static inline void VGAdisablePalette(void) { vga_r(NULL, VGA_IS1_RC); vga_w(NULL, VGA_ATT_W, 0x20); paletteEnabled = 0; } -inline void VGAwATTR(u8 index, u8 value) +static inline void VGAwATTR(u8 index, u8 value) { if (paletteEnabled) index &= ~0x20; @@ -430,7 +425,7 @@ inline void VGAwATTR(u8 index, u8 value) vga_wattr(NULL, index, value); } -void vgaHWProtect(int on) +static void vgaHWProtect(int on) { unsigned char tmp; @@ -490,11 +485,9 @@ static void vgaHWRestore(const struct fb_info *info, */ static inline int neo2200_sync(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; - int waitcycles; + struct neofb_par *par = info->par; - while (par->neo2200->bltStat & 1) - waitcycles++; + while (readl(&par->neo2200->bltStat) & 1); return 0; } @@ -530,8 +523,8 @@ static inline void neo2200_wait_fifo(struct fb_info *info, static inline void neo2200_accel_init(struct fb_info *info, struct fb_var_screeninfo *var) { - struct neofb_par *par = (struct neofb_par *) info->par; - Neo2200 *neo2200 = par->neo2200; + struct neofb_par *par = info->par; + Neo2200 __iomem *neo2200 = par->neo2200; u32 bltMod, pitch; neo2200_sync(info); @@ -556,8 +549,8 @@ static inline void neo2200_accel_init(struct fb_info *info, return; } - neo2200->bltStat = bltMod << 16; - neo2200->pitch = (pitch << 16) | pitch; + writel(bltMod << 16, &neo2200->bltStat); + writel((pitch << 16) | pitch, &neo2200->pitch); } /* --------------------------------------------------------------------- */ @@ -565,7 +558,7 @@ static inline void neo2200_accel_init(struct fb_info *info, static int neofb_open(struct fb_info *info, int user) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int cnt = atomic_read(&par->ref_count); if (!cnt) { @@ -580,7 +573,7 @@ neofb_open(struct fb_info *info, int user) static int neofb_release(struct fb_info *info, int user) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int cnt = atomic_read(&par->ref_count); if (!cnt) @@ -595,7 +588,7 @@ neofb_release(struct fb_info *info, int user) static int neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; unsigned int pixclock = var->pixclock; struct xtimings timings; int memlen, vramlen; @@ -762,7 +755,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) static int neofb_set_par(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; struct xtimings timings; unsigned char temp; int i, clock_hi = 0; @@ -848,6 +841,9 @@ static int neofb_set_par(struct fb_info *info) par->SysIfaceCntl2 = 0xc0; /* VESA Bios sets this to 0x80! */ + /* Initialize: by default, we want display config register to be read */ + par->PanelDispCntlRegRead = 1; + /* Enable any user specified display devices. */ par->PanelDispCntlReg1 = 0x00; if (par->internal_display) @@ -858,7 +854,7 @@ static int neofb_set_par(struct fb_info *info) /* If the user did not specify any display devices, then... */ if (par->PanelDispCntlReg1 == 0x00) { /* Default to internal (i.e., LCD) only. */ - par->PanelDispCntlReg1 |= 0x02; + par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; } /* If we are using a fixed mode, then tell the chip we are. */ @@ -1221,7 +1217,7 @@ static int neofb_set_par(struct fb_info *info) static void neofb_update_start(struct fb_info *info, struct fb_var_screeninfo *var) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; struct vgastate *state = &par->state; int oldExtCRTDispAddr; int Base; @@ -1320,7 +1316,7 @@ static int neofb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, /* * (Un)Blank the display. */ -int neofb_blank(int blank_mode, struct fb_info *info) +static int neofb_blank(int blank_mode, struct fb_info *info) { /* * Blank the screen if blank_mode != 0, else unblank. @@ -1336,11 +1332,23 @@ int neofb_blank(int blank_mode, struct fb_info *info) * wms...Enable VESA DPMS compatible powerdown mode * run "setterm -powersave powerdown" to take advantage */ - struct neofb_par *par = (struct neofb_par *)info->par; + struct neofb_par *par = info->par; int seqflags, lcdflags, dpmsflags, reg; + + /* + * Reload the value stored in the register, if sensible. It might have + * been changed via FN keystroke. + */ + if (par->PanelDispCntlRegRead) { + neoUnlock(); + par->PanelDispCntlReg1 = vga_rgfx(NULL, 0x20) & 0x03; + neoLock(&par->state); + } + par->PanelDispCntlRegRead = !blank_mode; + switch (blank_mode) { - case 4: /* powerdown - both sync lines down */ + case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ lcdflags = 0; /* LCD off */ dpmsflags = NEO_GR01_SUPPRESS_HSYNC | @@ -1358,22 +1366,22 @@ int neofb_blank(int blank_mode, struct fb_info *info) } #endif break; - case 3: /* hsync off */ + case FB_BLANK_HSYNC_SUSPEND: /* hsync off */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ lcdflags = 0; /* LCD off */ dpmsflags = NEO_GR01_SUPPRESS_HSYNC; break; - case 2: /* vsync off */ + case FB_BLANK_VSYNC_SUSPEND: /* vsync off */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ lcdflags = 0; /* LCD off */ dpmsflags = NEO_GR01_SUPPRESS_VSYNC; break; - case 1: /* just blank screen (backlight stays on) */ + case FB_BLANK_NORMAL: /* just blank screen (backlight stays on) */ seqflags = VGA_SR01_SCREEN_OFF; /* Disable sequencer */ lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ - dpmsflags = 0; /* no hsync/vsync suppression */ + dpmsflags = 0x00; /* no hsync/vsync suppression */ break; - case 0: /* unblank */ + case FB_BLANK_UNBLANK: /* unblank */ seqflags = 0; /* Enable sequencer */ lcdflags = par->PanelDispCntlReg1 & 0x02; /* LCD normal */ dpmsflags = 0x00; /* no hsync/vsync suppression */ @@ -1409,7 +1417,7 @@ int neofb_blank(int blank_mode, struct fb_info *info) static void neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; u_long dst, rop; dst = rect->dx + rect->dy * info->var.xres_virtual; @@ -1418,34 +1426,34 @@ neo2200_fillrect(struct fb_info *info, const struct fb_fillrect *rect) neo2200_wait_fifo(info, 4); /* set blt control */ - par->neo2200->bltCntl = NEO_BC3_FIFO_EN | - NEO_BC0_SRC_IS_FG | NEO_BC3_SKIP_MAPPING | - // NEO_BC3_DST_XY_ADDR | - // NEO_BC3_SRC_XY_ADDR | - rop; + writel(NEO_BC3_FIFO_EN | + NEO_BC0_SRC_IS_FG | NEO_BC3_SKIP_MAPPING | + // NEO_BC3_DST_XY_ADDR | + // NEO_BC3_SRC_XY_ADDR | + rop, &par->neo2200->bltCntl); switch (info->var.bits_per_pixel) { case 8: - par->neo2200->fgColor = rect->color; + writel(rect->color, &par->neo2200->fgColor); break; case 16: case 24: - par->neo2200->fgColor = - ((u32 *) (info->pseudo_palette))[rect->color]; + writel(((u32 *) (info->pseudo_palette))[rect->color], + &par->neo2200->fgColor); break; } - par->neo2200->dstStart = - dst * ((info->var.bits_per_pixel + 7) >> 3); - par->neo2200->xyExt = - (rect->height << 16) | (rect->width & 0xffff); + writel(dst * ((info->var.bits_per_pixel + 7) >> 3), + &par->neo2200->dstStart); + writel((rect->height << 16) | (rect->width & 0xffff), + &par->neo2200->xyExt); } static void neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) { u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; u_long src, dst, bltCntl; bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000; @@ -1466,18 +1474,18 @@ neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area) neo2200_wait_fifo(info, 4); /* set blt control */ - par->neo2200->bltCntl = bltCntl; + writel(bltCntl, &par->neo2200->bltCntl); - par->neo2200->srcStart = src; - par->neo2200->dstStart = dst; - par->neo2200->xyExt = - (area->height << 16) | (area->width & 0xffff); + writel(src, &par->neo2200->srcStart); + writel(dst, &par->neo2200->dstStart); + writel((area->height << 16) | (area->width & 0xffff), + &par->neo2200->xyExt); } static void neo2200_imageblit(struct fb_info *info, const struct fb_image *image) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int s_pitch = (image->width * image->depth + 7) >> 3; int scan_align = info->pixmap.scan_align - 1; int buf_align = info->pixmap.buf_align - 1; @@ -1509,32 +1517,31 @@ neo2200_imageblit(struct fb_info *info, const struct fb_image *image) switch (info->var.bits_per_pixel) { case 8: - par->neo2200->fgColor = image->fg_color; - par->neo2200->bgColor = image->bg_color; + writel(image->fg_color, &par->neo2200->fgColor); + writel(image->bg_color, &par->neo2200->bgColor); break; case 16: case 24: - par->neo2200->fgColor = - ((u32 *) (info->pseudo_palette))[image->fg_color]; - par->neo2200->bgColor = - ((u32 *) (info->pseudo_palette))[image->bg_color]; + writel(((u32 *) (info->pseudo_palette))[image->fg_color], + &par->neo2200->fgColor); + writel(((u32 *) (info->pseudo_palette))[image->bg_color], + &par->neo2200->bgColor); break; } - par->neo2200->bltCntl = NEO_BC0_SYS_TO_VID | + writel(NEO_BC0_SYS_TO_VID | NEO_BC3_SKIP_MAPPING | bltCntl_flags | // NEO_BC3_DST_XY_ADDR | - 0x0c0000; + 0x0c0000, &par->neo2200->bltCntl); - par->neo2200->srcStart = 0; + writel(0, &par->neo2200->srcStart); // par->neo2200->dstStart = (image->dy << 16) | (image->dx & 0xffff); - par->neo2200->dstStart = - ((image->dx & 0xffff) * (info->var.bits_per_pixel >> 3) + - image->dy * info->fix.line_length); - par->neo2200->xyExt = - (image->height << 16) | (image->width & 0xffff); + writel(((image->dx & 0xffff) * (info->var.bits_per_pixel >> 3) + + image->dy * info->fix.line_length), &par->neo2200->dstStart); + writel((image->height << 16) | (image->width & 0xffff), + &par->neo2200->xyExt); - memcpy(par->mmio_vbase + 0x100000, image->data, data_len); + memcpy_toio(par->mmio_vbase + 0x100000, image->data, data_len); } static void @@ -1671,7 +1678,6 @@ static struct fb_ops neofb_ops = { .fb_fillrect = neofb_fillrect, .fb_copyarea = neofb_copyarea, .fb_imageblit = neofb_imageblit, - .fb_cursor = soft_cursor, }; /* --------------------------------------------------------------------- */ @@ -1693,11 +1699,31 @@ static struct fb_videomode __devinitdata mode800x480 = { static int __devinit neo_map_mmio(struct fb_info *info, struct pci_dev *dev) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; DBG("neo_map_mmio"); - info->fix.mmio_start = pci_resource_start(dev, 1); + switch (info->fix.accel) { + case FB_ACCEL_NEOMAGIC_NM2070: + info->fix.mmio_start = pci_resource_start(dev, 0)+ + 0x100000; + break; + case FB_ACCEL_NEOMAGIC_NM2090: + case FB_ACCEL_NEOMAGIC_NM2093: + info->fix.mmio_start = pci_resource_start(dev, 0)+ + 0x200000; + break; + case FB_ACCEL_NEOMAGIC_NM2160: + case FB_ACCEL_NEOMAGIC_NM2097: + case FB_ACCEL_NEOMAGIC_NM2200: + case FB_ACCEL_NEOMAGIC_NM2230: + case FB_ACCEL_NEOMAGIC_NM2360: + case FB_ACCEL_NEOMAGIC_NM2380: + info->fix.mmio_start = pci_resource_start(dev, 1); + break; + default: + info->fix.mmio_start = pci_resource_start(dev, 0); + } info->fix.mmio_len = MMIO_SIZE; if (!request_mem_region @@ -1720,7 +1746,7 @@ static int __devinit neo_map_mmio(struct fb_info *info, static void neo_unmap_mmio(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; DBG("neo_unmap_mmio"); @@ -1765,7 +1791,7 @@ static int __devinit neo_map_video(struct fb_info *info, #endif /* Clear framebuffer, it's all white in memory after boot */ - memset(info->screen_base, 0, info->fix.smem_len); + memset_io(info->screen_base, 0, info->fix.smem_len); /* Allocate Cursor drawing pad. info->fix.smem_len -= PAGE_SIZE; @@ -1783,7 +1809,7 @@ static void neo_unmap_video(struct fb_info *info) #ifdef CONFIG_MTRR { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; mtrr_del(par->mtrr, info->fix.smem_start, info->fix.smem_len); @@ -1798,7 +1824,7 @@ static void neo_unmap_video(struct fb_info *info) static int __devinit neo_scan_monitor(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; unsigned char type, display; int w; @@ -1877,7 +1903,7 @@ static int __devinit neo_scan_monitor(struct fb_info *info) static int __devinit neo_init_hw(struct fb_info *info) { - struct neofb_par *par = (struct neofb_par *) info->par; + struct neofb_par *par = info->par; int videoRam = 896; int maxClock = 65000; int CursorMem = 1024; @@ -1946,7 +1972,7 @@ static int __devinit neo_init_hw(struct fb_info *info) maxWidth = 1280; maxHeight = 1024; /* ???? */ - par->neo2200 = (Neo2200 *) par->mmio_vbase; + par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase; break; case FB_ACCEL_NEOMAGIC_NM2230: videoRam = 3008; @@ -1957,7 +1983,7 @@ static int __devinit neo_init_hw(struct fb_info *info) maxWidth = 1280; maxHeight = 1024; /* ???? */ - par->neo2200 = (Neo2200 *) par->mmio_vbase; + par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase; break; case FB_ACCEL_NEOMAGIC_NM2360: videoRam = 4096; @@ -1968,7 +1994,7 @@ static int __devinit neo_init_hw(struct fb_info *info) maxWidth = 1280; maxHeight = 1024; /* ???? */ - par->neo2200 = (Neo2200 *) par->mmio_vbase; + par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase; break; case FB_ACCEL_NEOMAGIC_NM2380: videoRam = 6144; @@ -1979,7 +2005,7 @@ static int __devinit neo_init_hw(struct fb_info *info) maxWidth = 1280; maxHeight = 1024; /* ???? */ - par->neo2200 = (Neo2200 *) par->mmio_vbase; + par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase; break; } /* @@ -2001,7 +2027,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st struct fb_info *info; struct neofb_par *par; - info = framebuffer_alloc(sizeof(struct neofb_par) + sizeof(u32) * 256, &dev->dev); + info = framebuffer_alloc(sizeof(struct neofb_par), &dev->dev); if (!info) return NULL; @@ -2016,6 +2042,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st par->internal_display = internal; par->external_display = external; + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; switch (info->fix.accel) { case FB_ACCEL_NEOMAGIC_NM2070: @@ -2035,15 +2062,27 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st break; case FB_ACCEL_NEOMAGIC_NM2200: sprintf(info->fix.id, "MagicGraph 256AV"); + info->flags |= FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT; break; case FB_ACCEL_NEOMAGIC_NM2230: sprintf(info->fix.id, "MagicGraph 256AV+"); + info->flags |= FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT; break; case FB_ACCEL_NEOMAGIC_NM2360: sprintf(info->fix.id, "MagicGraph 256ZX"); + info->flags |= FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT; break; case FB_ACCEL_NEOMAGIC_NM2380: sprintf(info->fix.id, "MagicGraph 256XL+"); + info->flags |= FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT; break; } @@ -2055,10 +2094,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st info->fix.accel = id->driver_data; info->fbops = &neofb_ops; - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | - FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_COPYAREA | - FBINFO_HWACCEL_COPYAREA; - info->pseudo_palette = (void *) (par + 1); + info->pseudo_palette = par->palette; return info; } @@ -2236,7 +2272,8 @@ static struct pci_driver neofb_driver = { /* ************************* init in-kernel code ************************** */ -int __init neofb_setup(char *options) +#ifndef MODULE +static int __init neofb_setup(char *options) { char *this_opt; @@ -2264,8 +2301,9 @@ int __init neofb_setup(char *options) } return 0; } +#endif /* MODULE */ -int __init neofb_init(void) +static int __init neofb_init(void) { #ifndef MODULE char *option = NULL;