aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/fbmem.c10
-rw-r--r--drivers/video/fbsysfs.c22
-rw-r--r--drivers/video/intelfb/intelfbdrv.c50
-rw-r--r--drivers/video/modedb.c5
-rw-r--r--drivers/video/nvidia/nvidia.c7
-rw-r--r--drivers/video/pxafb.c8
-rw-r--r--drivers/video/radeonfb.c2
-rw-r--r--drivers/video/sa1100fb.c2
-rw-r--r--drivers/video/tridentfb.c28
-rw-r--r--drivers/video/vesafb.c47
11 files changed, 122 insertions, 61 deletions
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index cbff98337aa6..5fe182d6e4ab 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
6 6
7config VGA_CONSOLE 7config VGA_CONSOLE
8 bool "VGA text console" if EMBEDDED || !X86 8 bool "VGA text console" if EMBEDDED || !X86
9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC 9 depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE
10 default y 10 default y
11 help 11 help
12 Saying Y here will allow you to use Linux in text mode through a 12 Saying Y here will allow you to use Linux in text mode through a
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 40784a944d05..4ff853fbe0be 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -80,10 +80,12 @@ EXPORT_SYMBOL(fb_get_color_depth);
80 */ 80 */
81void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) 81void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height)
82{ 82{
83 int i; 83 int i, j;
84 84
85 for (i = height; i--; ) { 85 for (i = height; i--; ) {
86 memcpy(dst, src, s_pitch); 86 /* s_pitch is a few bytes at the most, memcpy is suboptimal */
87 for (j = 0; j < s_pitch; j++)
88 dst[j] = src[j];
87 src += s_pitch; 89 src += s_pitch;
88 dst += d_pitch; 90 dst += d_pitch;
89 } 91 }
@@ -626,7 +628,7 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
626int 628int
627fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) 629fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
628{ 630{
629 int err; 631 int err, flags = info->flags;
630 632
631 if (var->activate & FB_ACTIVATE_INV_MODE) { 633 if (var->activate & FB_ACTIVATE_INV_MODE) {
632 struct fb_videomode mode1, mode2; 634 struct fb_videomode mode1, mode2;
@@ -680,7 +682,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
680 !list_empty(&info->modelist)) 682 !list_empty(&info->modelist))
681 err = fb_add_videomode(&mode, &info->modelist); 683 err = fb_add_videomode(&mode, &info->modelist);
682 684
683 if (!err && info->flags & FBINFO_MISC_USEREVENT) { 685 if (!err && (flags & FBINFO_MISC_USEREVENT)) {
684 struct fb_event event; 686 struct fb_event event;
685 687
686 info->flags &= ~FBINFO_MISC_USEREVENT; 688 info->flags &= ~FBINFO_MISC_USEREVENT;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 63b505cce4ec..1147b899f007 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -244,15 +244,15 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf)
244 244
245/* Format for cmap is "%02x%c%4x%4x%4x\n" */ 245/* Format for cmap is "%02x%c%4x%4x%4x\n" */
246/* %02x entry %c transp %4x red %4x blue %4x green \n */ 246/* %02x entry %c transp %4x red %4x blue %4x green \n */
247/* 255 rows at 16 chars equals 4096 */ 247/* 256 rows at 16 chars equals 4096, the normal page size */
248/* PAGE_SIZE can be 4096 or larger */ 248/* the code will automatically adjust for different page sizes */
249static ssize_t store_cmap(struct class_device *class_device, const char *buf, 249static ssize_t store_cmap(struct class_device *class_device, const char *buf,
250 size_t count) 250 size_t count)
251{ 251{
252 struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); 252 struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
253 int rc, i, start, length, transp = 0; 253 int rc, i, start, length, transp = 0;
254 254
255 if ((count > 4096) || ((count % 16) != 0) || (PAGE_SIZE < 4096)) 255 if ((count > PAGE_SIZE) || ((count % 16) != 0))
256 return -EINVAL; 256 return -EINVAL;
257 257
258 if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) 258 if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
@@ -317,18 +317,18 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf)
317 !fb_info->cmap.green) 317 !fb_info->cmap.green)
318 return -EINVAL; 318 return -EINVAL;
319 319
320 if (PAGE_SIZE < 4096) 320 if (fb_info->cmap.len > PAGE_SIZE / 16)
321 return -EINVAL; 321 return -EINVAL;
322 322
323 /* don't mess with the format, the buffer is PAGE_SIZE */ 323 /* don't mess with the format, the buffer is PAGE_SIZE */
324 /* 255 entries at 16 chars per line equals 4096 = PAGE_SIZE */ 324 /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */
325 for (i = 0; i < fb_info->cmap.len; i++) { 325 for (i = 0; i < fb_info->cmap.len; i++) {
326 sprintf(&buf[ i * 16], "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, 326 snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
327 ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), 327 ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
328 fb_info->cmap.red[i], fb_info->cmap.blue[i], 328 fb_info->cmap.red[i], fb_info->cmap.blue[i],
329 fb_info->cmap.green[i]); 329 fb_info->cmap.green[i]);
330 } 330 }
331 return 4096; 331 return 16 * fb_info->cmap.len;
332} 332}
333 333
334static ssize_t store_blank(struct class_device *class_device, const char * buf, 334static ssize_t store_blank(struct class_device *class_device, const char * buf,
@@ -414,6 +414,13 @@ static ssize_t show_pan(struct class_device *class_device, char *buf)
414 fb_info->var.xoffset); 414 fb_info->var.xoffset);
415} 415}
416 416
417static ssize_t show_name(struct class_device *class_device, char *buf)
418{
419 struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
420
421 return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id);
422}
423
417static struct class_device_attribute class_device_attrs[] = { 424static struct class_device_attribute class_device_attrs[] = {
418 __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), 425 __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
419 __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), 426 __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
@@ -424,6 +431,7 @@ static struct class_device_attribute class_device_attrs[] = {
424 __ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes), 431 __ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes),
425 __ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan), 432 __ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan),
426 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), 433 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
434 __ATTR(name, S_IRUGO, show_name, NULL),
427}; 435};
428 436
429int fb_init_class_device(struct fb_info *fb_info) 437int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 298bc9cd99e7..a112a1786855 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -583,23 +583,6 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
583 return -ENODEV; 583 return -ENODEV;
584 } 584 }
585 585
586 /* Map the fb and MMIO regions */
587 dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
588 (dinfo->aperture.physical, dinfo->aperture.size);
589 if (!dinfo->aperture.virtual) {
590 ERR_MSG("Cannot remap FB region.\n");
591 cleanup(dinfo);
592 return -ENODEV;
593 }
594 dinfo->mmio_base =
595 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
596 INTEL_REG_SIZE);
597 if (!dinfo->mmio_base) {
598 ERR_MSG("Cannot remap MMIO region.\n");
599 cleanup(dinfo);
600 return -ENODEV;
601 }
602
603 /* Get the chipset info. */ 586 /* Get the chipset info. */
604 dinfo->pci_chipset = pdev->device; 587 dinfo->pci_chipset = pdev->device;
605 588
@@ -630,9 +613,15 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
630 dinfo->accel = 0; 613 dinfo->accel = 0;
631 } 614 }
632 615
616 if (MB(voffset) < stolen_size)
617 offset = (stolen_size >> 12);
618 else
619 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
620
633 /* Framebuffer parameters - Use all the stolen memory if >= vram */ 621 /* Framebuffer parameters - Use all the stolen memory if >= vram */
634 if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) { 622 if (ROUND_UP_TO_PAGE(stolen_size) >= ((offset << 12) + MB(vram))) {
635 dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size); 623 dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size);
624 dinfo->fb.offset = 0;
636 dinfo->fbmem_gart = 0; 625 dinfo->fbmem_gart = 0;
637 } else { 626 } else {
638 dinfo->fb.size = MB(vram); 627 dinfo->fb.size = MB(vram);
@@ -663,11 +652,6 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
663 return -ENODEV; 652 return -ENODEV;
664 } 653 }
665 654
666 if (MB(voffset) < stolen_size)
667 offset = (stolen_size >> 12);
668 else
669 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
670
671 /* set the mem offsets - set them after the already used pages */ 655 /* set the mem offsets - set them after the already used pages */
672 if (dinfo->accel) { 656 if (dinfo->accel) {
673 dinfo->ring.offset = offset + gtt_info.current_memory; 657 dinfo->ring.offset = offset + gtt_info.current_memory;
@@ -682,6 +666,26 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
682 + (dinfo->cursor.size >> 12); 666 + (dinfo->cursor.size >> 12);
683 } 667 }
684 668
669 /* Map the fb and MMIO regions */
670 /* ioremap only up to the end of used aperture */
671 dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
672 (dinfo->aperture.physical, (dinfo->fb.offset << 12)
673 + dinfo->fb.size);
674 if (!dinfo->aperture.virtual) {
675 ERR_MSG("Cannot remap FB region.\n");
676 cleanup(dinfo);
677 return -ENODEV;
678 }
679
680 dinfo->mmio_base =
681 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
682 INTEL_REG_SIZE);
683 if (!dinfo->mmio_base) {
684 ERR_MSG("Cannot remap MMIO region.\n");
685 cleanup(dinfo);
686 return -ENODEV;
687 }
688
685 /* Allocate memories (which aren't stolen) */ 689 /* Allocate memories (which aren't stolen) */
686 if (dinfo->accel) { 690 if (dinfo->accel) {
687 if (!(dinfo->gtt_ring_mem = 691 if (!(dinfo->gtt_ring_mem =
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index fbf659b6dab0..3edc9f49344b 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -246,6 +246,11 @@ static const struct fb_videomode modedb[] = {
246 /* 480x300 @ 72 Hz, 48.0 kHz hsync */ 246 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
247 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, 247 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
248 0, FB_VMODE_DOUBLE 248 0, FB_VMODE_DOUBLE
249 }, {
250 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
253 FB_VMODE_NONINTERLACED
249 }, 254 },
250}; 255};
251 256
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index b2e6b2407869..52b16850a54e 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)
1324 1324
1325 fb_videomode_to_var(&nvidiafb_default_var, &modedb); 1325 fb_videomode_to_var(&nvidiafb_default_var, &modedb);
1326 nvidiafb_default_var.bits_per_pixel = 8; 1326 nvidiafb_default_var.bits_per_pixel = 8;
1327 } else if (par->fpWidth && par->fpHeight) {
1328 char buf[16];
1329
1330 memset(buf, 0, 16);
1331 snprintf(buf, 15, "%dx%d", par->fpWidth, par->fpHeight);
1332 fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
1333 specs->modedb_len, &modedb, 8);
1327 } 1334 }
1328 1335
1329 if (mode_option) 1336 if (mode_option)
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 16e37a535d85..30112816420c 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -717,6 +717,9 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
717 DPRINTK("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2); 717 DPRINTK("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
718 DPRINTK("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3); 718 DPRINTK("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
719 719
720 /* enable LCD controller clock */
721 pxa_set_cken(CKEN16_LCD, 1);
722
720 /* Sequence from 11.7.10 */ 723 /* Sequence from 11.7.10 */
721 LCCR3 = fbi->reg_lccr3; 724 LCCR3 = fbi->reg_lccr3;
722 LCCR2 = fbi->reg_lccr2; 725 LCCR2 = fbi->reg_lccr2;
@@ -750,6 +753,9 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
750 753
751 schedule_timeout(20 * HZ / 1000); 754 schedule_timeout(20 * HZ / 1000);
752 remove_wait_queue(&fbi->ctrlr_wait, &wait); 755 remove_wait_queue(&fbi->ctrlr_wait, &wait);
756
757 /* disable LCD controller clock */
758 pxa_set_cken(CKEN16_LCD, 0);
753} 759}
754 760
755/* 761/*
@@ -1299,8 +1305,6 @@ int __init pxafb_probe(struct device *dev)
1299 ret = -ENOMEM; 1305 ret = -ENOMEM;
1300 goto failed; 1306 goto failed;
1301 } 1307 }
1302 /* enable LCD controller clock */
1303 pxa_set_cken(CKEN16_LCD, 1);
1304 1308
1305 ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi); 1309 ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi);
1306 if (ret) { 1310 if (ret) {
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index c46387024b1d..a78b9bd8f897 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -80,7 +80,7 @@
80#include <video/radeon.h> 80#include <video/radeon.h>
81#include <linux/radeonfb.h> 81#include <linux/radeonfb.h>
82 82
83#define DEBUG 1 83#define DEBUG 0
84 84
85#if DEBUG 85#if DEBUG
86#define RTRACE printk 86#define RTRACE printk
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 2d29db7ef800..beeec7b51425 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,
598 * requests for the LCD controller. If we hit this, it means we're 598 * requests for the LCD controller. If we hit this, it means we're
599 * doing nothing but LCD DMA. 599 * doing nothing but LCD DMA.
600 */ 600 */
601static unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var) 601static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var)
602{ 602{
603 /* 603 /*
604 * Period = pixclock * bits_per_byte * bytes_per_transfer 604 * Period = pixclock * bits_per_byte * bytes_per_transfer
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index da8004e5d03d..698ca9232e73 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -454,13 +454,16 @@ static struct accel_switch accel_image = {
454static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr) 454static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr)
455{ 455{
456 int bpp = info->var.bits_per_pixel; 456 int bpp = info->var.bits_per_pixel;
457 int col; 457 int col = 0;
458 458
459 switch (bpp) { 459 switch (bpp) {
460 default: 460 default:
461 case 8: col = fr->color; 461 case 8: col |= fr->color;
462 col |= col << 8;
463 col |= col << 16;
462 break; 464 break;
463 case 16: col = ((u32 *)(info->pseudo_palette))[fr->color]; 465 case 16: col = ((u32 *)(info->pseudo_palette))[fr->color];
466
464 break; 467 break;
465 case 32: col = ((u32 *)(info->pseudo_palette))[fr->color]; 468 case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
466 break; 469 break;
@@ -882,8 +885,9 @@ static int tridentfb_set_par(struct fb_info *info)
882 885
883 write3X4(GraphEngReg, 0x80); //enable GE for text acceleration 886 write3X4(GraphEngReg, 0x80); //enable GE for text acceleration
884 887
885// if (info->var.accel_flags & FB_ACCELF_TEXT) 888#ifdef CONFIG_FB_TRIDENT_ACCEL
886//FIXME acc->init_accel(info->var.xres,bpp); 889 acc->init_accel(info->var.xres,bpp);
890#endif
887 891
888 switch (bpp) { 892 switch (bpp) {
889 case 8: tmp = 0x00; break; 893 case 8: tmp = 0x00; break;
@@ -900,7 +904,7 @@ static int tridentfb_set_par(struct fb_info *info)
900 write3X4(DRAMControl, tmp); //both IO,linear enable 904 write3X4(DRAMControl, tmp); //both IO,linear enable
901 905
902 write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); 906 write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
903 write3X4(Performance,0x20); 907 write3X4(Performance,0x92);
904 write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable 908 write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable
905 909
906 /* convert from picoseconds to MHz */ 910 /* convert from picoseconds to MHz */
@@ -981,12 +985,14 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
981 t_outb(green>>10,0x3C9); 985 t_outb(green>>10,0x3C9);
982 t_outb(blue>>10,0x3C9); 986 t_outb(blue>>10,0x3C9);
983 987
984 } else 988 } else if (bpp == 16) { /* RGB 565 */
985 if (bpp == 16) /* RGB 565 */ 989 u32 col;
986 ((u32*)info->pseudo_palette)[regno] = (red & 0xF800) | 990
987 ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11); 991 col = (red & 0xF800) | ((green & 0xFC00) >> 5) |
988 else 992 ((blue & 0xF800) >> 11);
989 if (bpp == 32) /* ARGB 8888 */ 993 col |= col << 16;
994 ((u32 *)(info->pseudo_palette))[regno] = col;
995 } else if (bpp == 32) /* ARGB 8888 */
990 ((u32*)info->pseudo_palette)[regno] = 996 ((u32*)info->pseudo_palette)[regno] =
991 ((transp & 0xFF00) <<16) | 997 ((transp & 0xFF00) <<16) |
992 ((red & 0xFF00) << 8) | 998 ((red & 0xFF00) << 8) |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 9ed1a931dd31..a272592b0373 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
45}; 45};
46 46
47static int inverse = 0; 47static int inverse = 0;
48static int mtrr = 1; 48static int mtrr = 3; /* default to write-combining */
49static int vram_remap __initdata = 0; /* Set amount of memory to be used */ 49static int vram_remap __initdata = 0; /* Set amount of memory to be used */
50static int vram_total __initdata = 0; /* Set total amount of memory */ 50static int vram_total __initdata = 0; /* Set total amount of memory */
51static int pmi_setpal = 0; /* pmi for palette changes ??? */ 51static int pmi_setpal = 0; /* pmi for palette changes ??? */
@@ -204,8 +204,8 @@ static int __init vesafb_setup(char *options)
204 pmi_setpal=0; 204 pmi_setpal=0;
205 else if (! strcmp(this_opt, "pmipal")) 205 else if (! strcmp(this_opt, "pmipal"))
206 pmi_setpal=1; 206 pmi_setpal=1;
207 else if (! strcmp(this_opt, "mtrr")) 207 else if (! strncmp(this_opt, "mtrr:", 5))
208 mtrr=1; 208 mtrr = simple_strtoul(this_opt+5, NULL, 0);
209 else if (! strcmp(this_opt, "nomtrr")) 209 else if (! strcmp(this_opt, "nomtrr"))
210 mtrr=0; 210 mtrr=0;
211 else if (! strncmp(this_opt, "vtotal:", 7)) 211 else if (! strncmp(this_opt, "vtotal:", 7))
@@ -387,14 +387,39 @@ static int __init vesafb_probe(struct device *device)
387 387
388 if (mtrr) { 388 if (mtrr) {
389 unsigned int temp_size = size_total; 389 unsigned int temp_size = size_total;
390 /* Find the largest power-of-two */ 390 unsigned int type = 0;
391 while (temp_size & (temp_size - 1)) 391
392 temp_size &= (temp_size - 1); 392 switch (mtrr) {
393 393 case 1:
394 /* Try and find a power of two to add */ 394 type = MTRR_TYPE_UNCACHABLE;
395 while (temp_size > PAGE_SIZE && 395 break;
396 mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { 396 case 2:
397 temp_size >>= 1; 397 type = MTRR_TYPE_WRBACK;
398 break;
399 case 3:
400 type = MTRR_TYPE_WRCOMB;
401 break;
402 case 4:
403 type = MTRR_TYPE_WRTHROUGH;
404 break;
405 default:
406 type = 0;
407 break;
408 }
409
410 if (type) {
411 int rc;
412
413 /* Find the largest power-of-two */
414 while (temp_size & (temp_size - 1))
415 temp_size &= (temp_size - 1);
416
417 /* Try and find a power of two to add */
418 do {
419 rc = mtrr_add(vesafb_fix.smem_start, temp_size,
420 type, 1);
421 temp_size >>= 1;
422 } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
398 } 423 }
399 } 424 }
400 425