diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/Kconfig | 4 | ||||
-rw-r--r-- | drivers/video/aty/radeon_base.c | 5 | ||||
-rw-r--r-- | drivers/video/console/fbcon.c | 3 | ||||
-rw-r--r-- | drivers/video/fbcmap.c | 96 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 7 | ||||
-rw-r--r-- | drivers/video/fbmon.c | 2 | ||||
-rw-r--r-- | drivers/video/fbsysfs.c | 90 | ||||
-rw-r--r-- | drivers/video/modedb.c | 5 | ||||
-rw-r--r-- | drivers/video/nvidia/nvidia.c | 7 | ||||
-rw-r--r-- | drivers/video/pm2fb.c | 16 | ||||
-rw-r--r-- | drivers/video/riva/fbdev.c | 2 | ||||
-rw-r--r-- | drivers/video/sa1100fb.c | 2 | ||||
-rw-r--r-- | drivers/video/tridentfb.c | 28 | ||||
-rw-r--r-- | drivers/video/vesafb.c | 47 |
14 files changed, 207 insertions, 107 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 04d3120..cde0ed0 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1399,8 +1399,8 @@ config FB_TX3912 Say Y here to enable kernel support for the on-board framebuffer. config FB_G364 - bool - depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 + bool "G364 frame buffer support" + depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 47a6b12..e7e8b52 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -2521,6 +2521,11 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) radeonfb_pm_exit(rinfo); + if (rinfo->mon1_EDID) + sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr); + if (rinfo->mon2_EDID) + sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr); + #if 0 /* restore original state * diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 9dd0fbc..35c88bd 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -275,7 +275,8 @@ static void fb_flashcursor(void *private) if (!vc || !CON_IS_VISIBLE(vc) || fbcon_is_inactive(vc, info) || - registered_fb[con2fb_map[vc->vc_num]] != info) + registered_fb[con2fb_map[vc->vc_num]] != info || + vc_cons[ops->currcon].d->vc_deccm != 1) return; acquire_console_sem(); p = &fb_display[vc->vc_num]; diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index 4e5ce8f..c32a2a5 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c @@ -212,7 +212,7 @@ int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to) int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) { - int i, start; + int i, start, rc = 0; u16 *red, *green, *blue, *transp; u_int hred, hgreen, hblue, htransp = 0xffff; @@ -225,75 +225,51 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) if (start < 0 || (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)) return -EINVAL; - if (info->fbops->fb_setcmap) - return info->fbops->fb_setcmap(cmap, info); - for (i = 0; i < cmap->len; i++) { - hred = *red++; - hgreen = *green++; - hblue = *blue++; - if (transp) - htransp = *transp++; - if (info->fbops->fb_setcolreg(start++, - hred, hgreen, hblue, htransp, - info)) - break; + if (info->fbops->fb_setcmap) { + rc = info->fbops->fb_setcmap(cmap, info); + } else { + for (i = 0; i < cmap->len; i++) { + hred = *red++; + hgreen = *green++; + hblue = *blue++; + if (transp) + htransp = *transp++; + if (info->fbops->fb_setcolreg(start++, + hred, hgreen, hblue, + htransp, info)) + break; + } } - return 0; + if (rc == 0) + fb_copy_cmap(cmap, &info->cmap); + + return rc; } int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) { - int i, start; - u16 __user *red, *green, *blue, *transp; - u_int hred, hgreen, hblue, htransp = 0xffff; - - red = cmap->red; - green = cmap->green; - blue = cmap->blue; - transp = cmap->transp; - start = cmap->start; + int rc, size = cmap->len * sizeof(u16); + struct fb_cmap umap; - if (start < 0 || (!info->fbops->fb_setcolreg && - !info->fbops->fb_setcmap)) + if (cmap->start < 0 || (!info->fbops->fb_setcolreg && + !info->fbops->fb_setcmap)) return -EINVAL; - /* If we can batch, do it */ - if (info->fbops->fb_setcmap && cmap->len > 1) { - struct fb_cmap umap; - int size = cmap->len * sizeof(u16); - int rc; - - memset(&umap, 0, sizeof(struct fb_cmap)); - rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL); - if (rc) - return rc; - if (copy_from_user(umap.red, red, size) || - copy_from_user(umap.green, green, size) || - copy_from_user(umap.blue, blue, size) || - (transp && copy_from_user(umap.transp, transp, size))) { - rc = -EFAULT; - } - umap.start = start; - if (rc == 0) - rc = info->fbops->fb_setcmap(&umap, info); - fb_dealloc_cmap(&umap); + memset(&umap, 0, sizeof(struct fb_cmap)); + rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); + if (rc) return rc; + if (copy_from_user(umap.red, cmap->red, size) || + copy_from_user(umap.green, cmap->green, size) || + copy_from_user(umap.blue, cmap->blue, size) || + (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { + fb_dealloc_cmap(&umap); + return -EFAULT; } - - for (i = 0; i < cmap->len; i++, red++, blue++, green++) { - if (get_user(hred, red) || - get_user(hgreen, green) || - get_user(hblue, blue) || - (transp && get_user(htransp, transp))) - return -EFAULT; - if (info->fbops->fb_setcolreg(start++, - hred, hgreen, hblue, htransp, - info)) - return 0; - if (transp) - transp++; - } - return 0; + umap.start = cmap->start; + rc = fb_set_cmap(&umap, info); + fb_dealloc_cmap(&umap); + return rc; } /** diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 2222de6..d2e19f6 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -80,10 +80,12 @@ EXPORT_SYMBOL(fb_get_color_depth); */ void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) { - int i; + int i, j; for (i = height; i--; ) { - memcpy(dst, src, s_pitch); + /* s_pitch is a few bytes at the most, memcpy is suboptimal */ + for (j = 0; j < s_pitch; j++) + dst[j] = src[j]; src += s_pitch; dst += d_pitch; } @@ -1164,6 +1166,7 @@ static void __exit fbmem_exit(void) { class_destroy(fb_class); + unregister_chrdev(FB_MAJOR, "fb"); } module_exit(fbmem_exit); diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 6cd1976..c2718bb 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -1241,6 +1241,8 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) vtotal *= 2; hfreq = pixclock/htotal; + hfreq = (hfreq + 500) / 1000 * 1000; + vfreq = hfreq/vtotal; return (vfreq < vfmin || vfreq > vfmax || diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index ddc9443..1147b89 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -242,10 +242,68 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf) fb_info->var.yres_virtual); } -static ssize_t store_cmap(struct class_device *class_device, const char * buf, +/* Format for cmap is "%02x%c%4x%4x%4x\n" */ +/* %02x entry %c transp %4x red %4x blue %4x green \n */ +/* 256 rows at 16 chars equals 4096, the normal page size */ +/* the code will automatically adjust for different page sizes */ +static ssize_t store_cmap(struct class_device *class_device, const char *buf, size_t count) { -// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); + struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); + int rc, i, start, length, transp = 0; + + if ((count > PAGE_SIZE) || ((count % 16) != 0)) + return -EINVAL; + + if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) + return -EINVAL; + + sscanf(buf, "%02x", &start); + length = count / 16; + + for (i = 0; i < length; i++) + if (buf[i * 16 + 2] != ' ') + transp = 1; + + /* If we can batch, do it */ + if (fb_info->fbops->fb_setcmap && length > 1) { + struct fb_cmap umap; + + memset(&umap, 0, sizeof(umap)); + if ((rc = fb_alloc_cmap(&umap, length, transp))) + return rc; + + umap.start = start; + for (i = 0; i < length; i++) { + sscanf(&buf[i * 16 + 3], "%4hx", &umap.red[i]); + sscanf(&buf[i * 16 + 7], "%4hx", &umap.blue[i]); + sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]); + if (transp) + umap.transp[i] = (buf[i * 16 + 2] != ' '); + } + rc = fb_info->fbops->fb_setcmap(&umap, fb_info); + fb_copy_cmap(&umap, &fb_info->cmap); + fb_dealloc_cmap(&umap); + + return rc; + } + for (i = 0; i < length; i++) { + u16 red, blue, green, tsp; + + sscanf(&buf[i * 16 + 3], "%4hx", &red); + sscanf(&buf[i * 16 + 7], "%4hx", &blue); + sscanf(&buf[i * 16 + 11], "%4hx", &green); + tsp = (buf[i * 16 + 2] != ' '); + if ((rc = fb_info->fbops->fb_setcolreg(start++, + red, green, blue, tsp, fb_info))) + return rc; + + fb_info->cmap.red[i] = red; + fb_info->cmap.blue[i] = blue; + fb_info->cmap.green[i] = green; + if (transp) + fb_info->cmap.transp[i] = tsp; + } return 0; } @@ -253,20 +311,24 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf) { struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); - unsigned int offset = 0, i; + unsigned int i; if (!fb_info->cmap.red || !fb_info->cmap.blue || - !fb_info->cmap.green || !fb_info->cmap.transp) + !fb_info->cmap.green) + return -EINVAL; + + if (fb_info->cmap.len > PAGE_SIZE / 16) return -EINVAL; + /* don't mess with the format, the buffer is PAGE_SIZE */ + /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */ for (i = 0; i < fb_info->cmap.len; i++) { - offset += snprintf(buf, PAGE_SIZE - offset, - "%d,%d,%d,%d,%d\n", i + fb_info->cmap.start, - fb_info->cmap.red[i], fb_info->cmap.blue[i], - fb_info->cmap.green[i], - fb_info->cmap.transp[i]); + snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, + ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), + fb_info->cmap.red[i], fb_info->cmap.blue[i], + fb_info->cmap.green[i]); } - return offset; + return 16 * fb_info->cmap.len; } static ssize_t store_blank(struct class_device *class_device, const char * buf, @@ -352,6 +414,13 @@ static ssize_t show_pan(struct class_device *class_device, char *buf) fb_info->var.xoffset); } +static ssize_t show_name(struct class_device *class_device, char *buf) +{ + struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); + + return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); +} + static struct class_device_attribute class_device_attrs[] = { __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), @@ -362,6 +431,7 @@ static struct class_device_attribute class_device_attrs[] = { __ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes), __ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan), __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), + __ATTR(name, S_IRUGO, show_name, NULL), }; int fb_init_class_device(struct fb_info *fb_info) diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index fbf659b..3edc9f4 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -246,6 +246,11 @@ static const struct fb_videomode modedb[] = { /* 480x300 @ 72 Hz, 48.0 kHz hsync */ NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 0, FB_VMODE_DOUBLE + }, { + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */ + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED }, }; diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index b2e6b24..52b1685 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -1324,6 +1324,13 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) fb_videomode_to_var(&nvidiafb_default_var, &modedb); nvidiafb_default_var.bits_per_pixel = 8; + } else if (par->fpWidth && par->fpHeight) { + char buf[16]; + + memset(buf, 0, 16); + snprintf(buf, 15, "%dx%d", par->fpWidth, par->fpHeight); + fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, + specs->modedb_len, &modedb, 8); } if (mode_option) diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 5dcedde..42c17ef 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c @@ -138,27 +138,27 @@ static struct fb_var_screeninfo pm2fb_var __devinitdata = { * Utility functions */ -inline static u32 RD32(unsigned char __iomem *base, s32 off) +static inline u32 RD32(unsigned char __iomem *base, s32 off) { return fb_readl(base + off); } -inline static void WR32(unsigned char __iomem *base, s32 off, u32 v) +static inline void WR32(unsigned char __iomem *base, s32 off, u32 v) { fb_writel(v, base + off); } -inline static u32 pm2_RD(struct pm2fb_par* p, s32 off) +static inline u32 pm2_RD(struct pm2fb_par* p, s32 off) { return RD32(p->v_regs, off); } -inline static void pm2_WR(struct pm2fb_par* p, s32 off, u32 v) +static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v) { WR32(p->v_regs, off, v); } -inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) +static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) { int index = PM2R_RD_INDEXED_DATA; switch (p->type) { @@ -174,7 +174,7 @@ inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) return pm2_RD(p, index); } -inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) +static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) { int index = PM2R_RD_INDEXED_DATA; switch (p->type) { @@ -190,7 +190,7 @@ inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) pm2_WR(p, index, v); } -inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) +static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) { pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); mb(); @@ -200,7 +200,7 @@ inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) #ifdef CONFIG_FB_PM2_FIFO_DISCONNECT #define WAIT_FIFO(p,a) #else -inline static void WAIT_FIFO(struct pm2fb_par* p, u32 a) +static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a) { while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a ); mb(); diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 6a9e183..ae297e2 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -1826,7 +1826,7 @@ static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev) #ifdef CONFIG_PPC_OF if (!riva_get_EDID_OF(info, pdev)) printk(PFX "could not retrieve EDID from OF\n"); -#elif CONFIG_FB_RIVA_I2C +#elif defined(CONFIG_FB_RIVA_I2C) if (!riva_get_EDID_i2c(info)) printk(PFX "could not retrieve EDID from DDC/I2C\n"); #endif diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 2d29db7..beeec7b 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -598,7 +598,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, * requests for the LCD controller. If we hit this, it means we're * doing nothing but LCD DMA. */ -static unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var) +static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var) { /* * Period = pixclock * bits_per_byte * bytes_per_transfer diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index da8004e..698ca92 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c @@ -454,13 +454,16 @@ static struct accel_switch accel_image = { static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr) { int bpp = info->var.bits_per_pixel; - int col; + int col = 0; switch (bpp) { default: - case 8: col = fr->color; + case 8: col |= fr->color; + col |= col << 8; + col |= col << 16; break; case 16: col = ((u32 *)(info->pseudo_palette))[fr->color]; + break; case 32: col = ((u32 *)(info->pseudo_palette))[fr->color]; break; @@ -882,8 +885,9 @@ static int tridentfb_set_par(struct fb_info *info) write3X4(GraphEngReg, 0x80); //enable GE for text acceleration -// if (info->var.accel_flags & FB_ACCELF_TEXT) -//FIXME acc->init_accel(info->var.xres,bpp); +#ifdef CONFIG_FB_TRIDENT_ACCEL + acc->init_accel(info->var.xres,bpp); +#endif switch (bpp) { case 8: tmp = 0x00; break; @@ -900,7 +904,7 @@ static int tridentfb_set_par(struct fb_info *info) write3X4(DRAMControl, tmp); //both IO,linear enable write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); - write3X4(Performance,0x20); + write3X4(Performance,0x92); write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable /* convert from picoseconds to MHz */ @@ -981,12 +985,14 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green, t_outb(green>>10,0x3C9); t_outb(blue>>10,0x3C9); - } else - if (bpp == 16) /* RGB 565 */ - ((u32*)info->pseudo_palette)[regno] = (red & 0xF800) | - ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11); - else - if (bpp == 32) /* ARGB 8888 */ + } else if (bpp == 16) { /* RGB 565 */ + u32 col; + + col = (red & 0xF800) | ((green & 0xFC00) >> 5) | + ((blue & 0xF800) >> 11); + col |= col << 16; + ((u32 *)(info->pseudo_palette))[regno] = col; + } else if (bpp == 32) /* ARGB 8888 */ ((u32*)info->pseudo_palette)[regno] = ((transp & 0xFF00) <<16) | ((red & 0xFF00) << 8) | diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 9ed1a93..a272592 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { }; static int inverse = 0; -static int mtrr = 1; +static int mtrr = 3; /* default to write-combining */ 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 ??? */ @@ -204,8 +204,8 @@ static int __init vesafb_setup(char *options) pmi_setpal=0; else if (! strcmp(this_opt, "pmipal")) pmi_setpal=1; - else if (! strcmp(this_opt, "mtrr")) - mtrr=1; + else if (! strncmp(this_opt, "mtrr:", 5)) + mtrr = simple_strtoul(this_opt+5, NULL, 0); else if (! strcmp(this_opt, "nomtrr")) mtrr=0; else if (! strncmp(this_opt, "vtotal:", 7)) @@ -387,14 +387,39 @@ static int __init vesafb_probe(struct device *device) if (mtrr) { unsigned int temp_size = size_total; - /* Find the largest power-of-two */ - while (temp_size & (temp_size - 1)) - temp_size &= (temp_size - 1); - - /* Try and find a power of two to add */ - while (temp_size > PAGE_SIZE && - mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { - temp_size >>= 1; + unsigned int type = 0; + + switch (mtrr) { + case 1: + type = MTRR_TYPE_UNCACHABLE; + break; + case 2: + type = MTRR_TYPE_WRBACK; + break; + case 3: + type = MTRR_TYPE_WRCOMB; + break; + case 4: + type = MTRR_TYPE_WRTHROUGH; + break; + default: + type = 0; + break; + } + + if (type) { + int rc; + + /* Find the largest power-of-two */ + while (temp_size & (temp_size - 1)) + temp_size &= (temp_size - 1); + + /* Try and find a power of two to add */ + do { + rc = mtrr_add(vesafb_fix.smem_start, temp_size, + type, 1); + temp_size >>= 1; + } while (temp_size >= PAGE_SIZE && rc == -EINVAL); } } |