X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fstifb.c;h=3e16e2d9d55dd50a39187b9d332e41b67b4723e1;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=8b76a919297e4bd0f7693eb81e8fdba3d401a175;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 8b76a9192..3e16e2d9d 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -3,7 +3,7 @@ * Low level Frame buffer driver for HP workstations with * STI (standard text interface) video firmware. * - * Copyright (C) 2001-2004 Helge Deller + * Copyright (C) 2001-2006 Helge Deller * Portions Copyright (C) 2001 Thomas Bogendoerfer * * Based on: @@ -54,7 +54,6 @@ #undef DEBUG_STIFB_REGS /* debug sti register accesses */ -#include #include #include #include @@ -73,16 +72,13 @@ #include "sticore.h" /* REGION_BASE(fb_info, index) returns the virtual address for region */ -#ifdef __LP64__ - #define REGION_BASE(fb_info, index) \ - (fb_info->sti->glob_cfg->region_ptrs[index] | 0xffffffff00000000) -#else - #define REGION_BASE(fb_info, index) \ - fb_info->sti->glob_cfg->region_ptrs[index] -#endif +#define REGION_BASE(fb_info, index) \ + F_EXTEND(fb_info->sti->glob_cfg->region_ptrs[index]) #define NGLEDEVDEPROM_CRT_REGION 1 +#define NR_PALETTE 256 + typedef struct { __s32 video_config_reg; __s32 misc_video_start; @@ -115,8 +111,7 @@ struct stifb_info { u32 pseudo_palette[16]; }; -static int __initdata bpp = 8; /* parameter from modprobe */ -static int __initdata stifb_force_bpp[MAX_STI_ROMS]; +static int __initdata stifb_bpp_pref[MAX_STI_ROMS]; /* ------------------- chipset specific functions -------------------------- */ @@ -155,15 +150,15 @@ static int __initdata stifb_force_bpp[MAX_STI_ROMS]; #define REG_44 0x210030 #define REG_45 0x210034 -#define READ_BYTE(fb,reg) __raw_readb((fb)->info.fix.mmio_start + (reg)) -#define READ_WORD(fb,reg) __raw_readl((fb)->info.fix.mmio_start + (reg)) +#define READ_BYTE(fb,reg) gsc_readb((fb)->info.fix.mmio_start + (reg)) +#define READ_WORD(fb,reg) gsc_readl((fb)->info.fix.mmio_start + (reg)) #ifndef DEBUG_STIFB_REGS # define DEBUG_OFF() # define DEBUG_ON() -# define WRITE_BYTE(value,fb,reg) __raw_writeb((value),(fb)->info.fix.mmio_start + (reg)) -# define WRITE_WORD(value,fb,reg) __raw_writel((value),(fb)->info.fix.mmio_start + (reg)) +# define WRITE_BYTE(value,fb,reg) gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)) +# define WRITE_WORD(value,fb,reg) gsc_writel((value),(fb)->info.fix.mmio_start + (reg)) #else static int debug_on = 1; # define DEBUG_OFF() debug_on=0 @@ -171,11 +166,11 @@ static int __initdata stifb_force_bpp[MAX_STI_ROMS]; # define WRITE_BYTE(value,fb,reg) do { if (debug_on) \ printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \ __FUNCTION__, reg, value, READ_BYTE(fb,reg)); \ - __raw_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0) + gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0) # define WRITE_WORD(value,fb,reg) do { if (debug_on) \ printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \ __FUNCTION__, reg, value, READ_WORD(fb,reg)); \ - __raw_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0) + gsc_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0) #endif /* DEBUG_STIFB_REGS */ @@ -353,10 +348,10 @@ ARTIST_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb, int enable) #define IS_888_DEVICE(fb) \ (!(IS_24_DEVICE(fb))) -#define GET_FIFO_SLOTS(fb, cnt, numslots) \ -{ while (cnt < numslots) \ +#define GET_FIFO_SLOTS(fb, cnt, numslots) \ +{ while (cnt < numslots) \ cnt = READ_WORD(fb, REG_34); \ - cnt -= numslots; \ + cnt -= numslots; \ } #define IndexedDcd 0 /* Pixel data is indexed (pseudo) color */ @@ -518,7 +513,7 @@ rattlerSetupPlanes(struct stifb_info *fb) SETUP_HW(fb); WRITE_BYTE(1, fb, REG_16b1); - fb_memset(fb->info.fix.smem_start, 0xff, + fb_memset((void*)fb->info.fix.smem_start, 0xff, fb->info.var.yres*fb->info.fix.line_length); CRX24_SET_OVLY_MASK(fb); @@ -912,83 +907,6 @@ SETUP_HCRX(struct stifb_info *fb) /* ------------------- driver specific functions --------------------------- */ -#define TMPBUFLEN 2048 - -static ssize_t -stifb_read(struct file *file, char *buf, size_t count, loff_t *ppos) -{ - unsigned long p = *ppos; - struct inode *inode = file->f_dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; - char tmpbuf[TMPBUFLEN]; - - if (!info || ! info->screen_base) - return -ENODEV; - - if (p >= info->fix.smem_len) - return 0; - if (count >= info->fix.smem_len) - count = info->fix.smem_len; - if (count + p > info->fix.smem_len) - count = info->fix.smem_len - p; - if (count > sizeof(tmpbuf)) - count = sizeof(tmpbuf); - if (count) { - char *base_addr; - - base_addr = info->screen_base; - memcpy_fromio(&tmpbuf, base_addr+p, count); - count -= copy_to_user(buf, &tmpbuf, count); - if (!count) - return -EFAULT; - *ppos += count; - } - return count; -} - -static ssize_t -stifb_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - struct inode *inode = file->f_dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; - unsigned long p = *ppos; - size_t c; - int err; - char tmpbuf[TMPBUFLEN]; - - if (!info || !info->screen_base) - return -ENODEV; - - if (p > info->fix.smem_len) - return -ENOSPC; - if (count >= info->fix.smem_len) - count = info->fix.smem_len; - err = 0; - if (count + p > info->fix.smem_len) { - count = info->fix.smem_len - p; - err = -ENOSPC; - } - - p += (unsigned long)info->screen_base; - c = count; - while (c) { - int len = c > sizeof(tmpbuf) ? sizeof(tmpbuf) : c; - err = -EFAULT; - if (copy_from_user(&tmpbuf, buf, len)) - break; - memcpy_toio(p, &tmpbuf, len); - c -= len; - p += len; - buf += len; - *ppos += len; - } - if (count-c) - return (count-c); - return err; -} - static int stifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) @@ -996,7 +914,7 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, struct stifb_info *fb = (struct stifb_info *) info; u32 color; - if (regno >= 256) /* no. of hw registers */ + if (regno >= NR_PALETTE) return 1; red >>= 8; @@ -1006,8 +924,8 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, DEBUG_OFF(); START_IMAGE_COLORMAP_ACCESS(fb); - - if (fb->info.var.grayscale) { + + if (unlikely(fb->info.var.grayscale)) { /* gray = 0.30*R + 0.59*G + 0.11*B */ color = ((red * 77) + (green * 151) + @@ -1018,8 +936,17 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, (blue)); } + if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) { + struct fb_var_screeninfo *var = &fb->info.var; + if (regno < 16) + ((u32 *)fb->info.pseudo_palette)[regno] = + regno << var->red.offset | + regno << var->green.offset | + regno << var->blue.offset; + } + WRITE_IMAGE_COLOR(fb, regno, color); - + if (fb->id == S9000_ID_HCRX) { NgleLutBltCtl lutBltCtl; @@ -1031,14 +958,6 @@ stifb_setcolreg(u_int regno, u_int red, u_int green, /* 0x100 is same as used in WRITE_IMAGE_COLOR() */ START_COLORMAPLOAD(fb, lutBltCtl.all); SETUP_FB(fb); - - /* info->var.bits_per_pixel == 32 */ - if (regno < 16) - ((u32 *)(info->pseudo_palette))[regno] = - (red << info->var.red.offset) | - (green << info->var.green.offset) | - (blue << info->var.blue.offset); - } else { /* cleanup colormap hardware */ FINISH_IMAGE_COLORMAP_ACCESS(fb); @@ -1066,9 +985,9 @@ stifb_blank(int blank_mode, struct fb_info *info) case S9000_ID_HCRX: HYPER_ENABLE_DISABLE_DISPLAY(fb, enable); break; - case S9000_ID_A1659A:; /* fall through */ - case S9000_ID_TIMBER:; - case CRX24_OVERLAY_PLANES:; + case S9000_ID_A1659A: /* fall through */ + case S9000_ID_TIMBER: + case CRX24_OVERLAY_PLANES: default: ENABLE_DISABLE_DISPLAY(fb, enable); break; @@ -1140,14 +1059,11 @@ stifb_init_display(struct stifb_info *fb) static struct fb_ops stifb_ops = { .owner = THIS_MODULE, - .fb_read = stifb_read, - .fb_write = stifb_write, .fb_setcolreg = stifb_setcolreg, .fb_blank = stifb_blank, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, - .fb_cursor = soft_cursor, }; @@ -1156,7 +1072,7 @@ static struct fb_ops stifb_ops = { */ int __init -stifb_init_fb(struct sti_struct *sti, int force_bpp) +stifb_init_fb(struct sti_struct *sti, int bpp_pref) { struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; @@ -1166,7 +1082,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) char *dev_name; int bpp, xres, yres; - fb = kmalloc(sizeof(*fb), GFP_ATOMIC); + fb = kzalloc(sizeof(*fb), GFP_ATOMIC); if (!fb) { printk(KERN_ERR "stifb: Could not allocate stifb structure\n"); return -ENODEV; @@ -1175,7 +1091,6 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) info = &fb->info; /* set struct to a known state */ - memset(fb, 0, sizeof(*fb)); fix = &info->fix; var = &info->var; @@ -1238,7 +1153,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */ /* FIXME: TomCat supports two heads: * fb.iobase = REGION_BASE(fb_info,3); - * fb.screen_base = (void*) REGION_BASE(fb_info,2); + * fb.screen_base = ioremap_nocache(REGION_BASE(fb_info,2),xxx); * for now we only support the left one ! */ xres = fb->ngle_rom.x_size_visible; yres = fb->ngle_rom.y_size_visible; @@ -1251,16 +1166,14 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom)); if ((fb->sti->regions_phys[0] & 0xfc000000) == (fb->sti->regions_phys[2] & 0xfc000000)) - sti_rom_address = fb->sti->regions_phys[0]; + sti_rom_address = F_EXTEND(fb->sti->regions_phys[0]); else - sti_rom_address = fb->sti->regions_phys[1]; -#ifdef __LP64__ - sti_rom_address |= 0xffffffff00000000; -#endif - fb->deviceSpecificConfig = __raw_readl(sti_rom_address); + sti_rom_address = F_EXTEND(fb->sti->regions_phys[1]); + + fb->deviceSpecificConfig = gsc_readl(sti_rom_address); if (IS_24_DEVICE(fb)) { - if (force_bpp == 8 || force_bpp == 32) - bpp = force_bpp; + if (bpp_pref == 8 || bpp_pref == 32) + bpp = bpp_pref; else bpp = 32; } else @@ -1316,7 +1229,7 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) break; case 32: fix->type = FB_TYPE_PACKED_PIXELS; - fix->visual = FB_VISUAL_TRUECOLOR; + fix->visual = FB_VISUAL_DIRECTCOLOR; var->red.length = var->green.length = var->blue.length = var->transp.length = 8; var->blue.offset = 0; var->green.offset = 8; @@ -1333,12 +1246,13 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) strcpy(fix->id, "stifb"); info->fbops = &stifb_ops; - info->screen_base = (void*) REGION_BASE(fb,1); + info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len); + info->screen_size = fix->smem_len; info->flags = FBINFO_DEFAULT; info->pseudo_palette = &fb->pseudo_palette; /* This has to been done !!! */ - fb_alloc_cmap(&info->cmap, 256, 0); + fb_alloc_cmap(&info->cmap, NR_PALETTE, 0); stifb_init_display(fb); if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) { @@ -1409,21 +1323,24 @@ stifb_init(void) def_sti = sti_get_rom(0); if (def_sti) { - for (i = 1; i < MAX_STI_ROMS; i++) { + for (i = 1; i <= MAX_STI_ROMS; i++) { sti = sti_get_rom(i); - if (sti == def_sti && bpp > 0) - stifb_force_bpp[i] = bpp; + if (!sti) + break; + if (sti == def_sti) { + stifb_init_fb(sti, stifb_bpp_pref[i - 1]); + break; + } } - stifb_init_fb(def_sti, stifb_force_bpp[i]); } - for (i = 1; i < MAX_STI_ROMS; i++) { + for (i = 1; i <= MAX_STI_ROMS; i++) { sti = sti_get_rom(i); - if (!sti || sti==def_sti) + if (!sti) break; - if (bpp > 0) - stifb_force_bpp[i] = bpp; - stifb_init_fb(sti, stifb_force_bpp[i]); + if (sti == def_sti) + continue; + stifb_init_fb(sti, stifb_bpp_pref[i - 1]); } return 0; } @@ -1438,7 +1355,7 @@ stifb_cleanup(void) struct sti_struct *sti; int i; - for (i = 1; i < MAX_STI_ROMS; i++) { + for (i = 1; i <= MAX_STI_ROMS; i++) { sti = sti_get_rom(i); if (!sti) break; @@ -1460,7 +1377,7 @@ stifb_setup(char *options) int i; if (!options || !*options) - return 0; + return 1; if (strncmp(options, "off", 3) == 0) { stifb_disabled = 1; @@ -1470,14 +1387,12 @@ stifb_setup(char *options) if (strncmp(options, "bpp", 3) == 0) { options += 3; for (i = 0; i < MAX_STI_ROMS; i++) { - if (*options++ == ':') { - stifb_force_bpp[i] = simple_strtoul(options, &options, 10); - bpp = -1; - } else + if (*options++ != ':') break; + stifb_bpp_pref[i] = simple_strtoul(options, &options, 10); } } - return 0; + return 1; } __setup("stifb=", stifb_setup); @@ -1488,7 +1403,3 @@ module_exit(stifb_cleanup); MODULE_AUTHOR("Helge Deller , Thomas Bogendoerfer "); MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines"); MODULE_LICENSE("GPL v2"); - -MODULE_PARM(bpp, "i"); -MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)"); -