aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/aty/radeon_base.c5
-rw-r--r--drivers/video/console/fbcon.c3
-rw-r--r--drivers/video/fbcmap.c96
-rw-r--r--drivers/video/fbmem.c7
-rw-r--r--drivers/video/fbmon.c2
-rw-r--r--drivers/video/fbsysfs.c82
-rw-r--r--drivers/video/imxfb.c14
-rw-r--r--drivers/video/imxfb.h1
-rw-r--r--drivers/video/pm2fb.c16
-rw-r--r--drivers/video/riva/fbdev.c2
-rw-r--r--drivers/video/vesafb.c47
12 files changed, 177 insertions, 102 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 04d3120f7236..cde0ed097af6 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1399,8 +1399,8 @@ config FB_TX3912
1399 Say Y here to enable kernel support for the on-board framebuffer. 1399 Say Y here to enable kernel support for the on-board framebuffer.
1400 1400
1401config FB_G364 1401config FB_G364
1402 bool 1402 bool "G364 frame buffer support"
1403 depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 1403 depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
1404 select FB_CFB_FILLRECT 1404 select FB_CFB_FILLRECT
1405 select FB_CFB_COPYAREA 1405 select FB_CFB_COPYAREA
1406 select FB_CFB_IMAGEBLIT 1406 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 47a6b12bc968..e7e8b52014c3 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)
2521 2521
2522 radeonfb_pm_exit(rinfo); 2522 radeonfb_pm_exit(rinfo);
2523 2523
2524 if (rinfo->mon1_EDID)
2525 sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr);
2526 if (rinfo->mon2_EDID)
2527 sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
2528
2524#if 0 2529#if 0
2525 /* restore original state 2530 /* restore original state
2526 * 2531 *
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 9dd0fbccf994..35c88bd7ba5e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -275,7 +275,8 @@ static void fb_flashcursor(void *private)
275 275
276 if (!vc || !CON_IS_VISIBLE(vc) || 276 if (!vc || !CON_IS_VISIBLE(vc) ||
277 fbcon_is_inactive(vc, info) || 277 fbcon_is_inactive(vc, info) ||
278 registered_fb[con2fb_map[vc->vc_num]] != info) 278 registered_fb[con2fb_map[vc->vc_num]] != info ||
279 vc_cons[ops->currcon].d->vc_deccm != 1)
279 return; 280 return;
280 acquire_console_sem(); 281 acquire_console_sem();
281 p = &fb_display[vc->vc_num]; 282 p = &fb_display[vc->vc_num];
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 4e5ce8f7d65e..c32a2a50bfa2 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)
212 212
213int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) 213int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
214{ 214{
215 int i, start; 215 int i, start, rc = 0;
216 u16 *red, *green, *blue, *transp; 216 u16 *red, *green, *blue, *transp;
217 u_int hred, hgreen, hblue, htransp = 0xffff; 217 u_int hred, hgreen, hblue, htransp = 0xffff;
218 218
@@ -225,75 +225,51 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
225 if (start < 0 || (!info->fbops->fb_setcolreg && 225 if (start < 0 || (!info->fbops->fb_setcolreg &&
226 !info->fbops->fb_setcmap)) 226 !info->fbops->fb_setcmap))
227 return -EINVAL; 227 return -EINVAL;
228 if (info->fbops->fb_setcmap) 228 if (info->fbops->fb_setcmap) {
229 return info->fbops->fb_setcmap(cmap, info); 229 rc = info->fbops->fb_setcmap(cmap, info);
230 for (i = 0; i < cmap->len; i++) { 230 } else {
231 hred = *red++; 231 for (i = 0; i < cmap->len; i++) {
232 hgreen = *green++; 232 hred = *red++;
233 hblue = *blue++; 233 hgreen = *green++;
234 if (transp) 234 hblue = *blue++;
235 htransp = *transp++; 235 if (transp)
236 if (info->fbops->fb_setcolreg(start++, 236 htransp = *transp++;
237 hred, hgreen, hblue, htransp, 237 if (info->fbops->fb_setcolreg(start++,
238 info)) 238 hred, hgreen, hblue,
239 break; 239 htransp, info))
240 break;
241 }
240 } 242 }
241 return 0; 243 if (rc == 0)
244 fb_copy_cmap(cmap, &info->cmap);
245
246 return rc;
242} 247}
243 248
244int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) 249int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
245{ 250{
246 int i, start; 251 int rc, size = cmap->len * sizeof(u16);
247 u16 __user *red, *green, *blue, *transp; 252 struct fb_cmap umap;
248 u_int hred, hgreen, hblue, htransp = 0xffff;
249
250 red = cmap->red;
251 green = cmap->green;
252 blue = cmap->blue;
253 transp = cmap->transp;
254 start = cmap->start;
255 253
256 if (start < 0 || (!info->fbops->fb_setcolreg && 254 if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
257 !info->fbops->fb_setcmap)) 255 !info->fbops->fb_setcmap))
258 return -EINVAL; 256 return -EINVAL;
259 257
260 /* If we can batch, do it */ 258 memset(&umap, 0, sizeof(struct fb_cmap));
261 if (info->fbops->fb_setcmap && cmap->len > 1) { 259 rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
262 struct fb_cmap umap; 260 if (rc)
263 int size = cmap->len * sizeof(u16);
264 int rc;
265
266 memset(&umap, 0, sizeof(struct fb_cmap));
267 rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL);
268 if (rc)
269 return rc;
270 if (copy_from_user(umap.red, red, size) ||
271 copy_from_user(umap.green, green, size) ||
272 copy_from_user(umap.blue, blue, size) ||
273 (transp && copy_from_user(umap.transp, transp, size))) {
274 rc = -EFAULT;
275 }
276 umap.start = start;
277 if (rc == 0)
278 rc = info->fbops->fb_setcmap(&umap, info);
279 fb_dealloc_cmap(&umap);
280 return rc; 261 return rc;
262 if (copy_from_user(umap.red, cmap->red, size) ||
263 copy_from_user(umap.green, cmap->green, size) ||
264 copy_from_user(umap.blue, cmap->blue, size) ||
265 (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
266 fb_dealloc_cmap(&umap);
267 return -EFAULT;
281 } 268 }
282 269 umap.start = cmap->start;
283 for (i = 0; i < cmap->len; i++, red++, blue++, green++) { 270 rc = fb_set_cmap(&umap, info);
284 if (get_user(hred, red) || 271 fb_dealloc_cmap(&umap);
285 get_user(hgreen, green) || 272 return rc;
286 get_user(hblue, blue) ||
287 (transp && get_user(htransp, transp)))
288 return -EFAULT;
289 if (info->fbops->fb_setcolreg(start++,
290 hred, hgreen, hblue, htransp,
291 info))
292 return 0;
293 if (transp)
294 transp++;
295 }
296 return 0;
297} 273}
298 274
299/** 275/**
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 2222de6ad844..d2e19f6dd72c 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 }
@@ -1164,6 +1166,7 @@ static void __exit
1164fbmem_exit(void) 1166fbmem_exit(void)
1165{ 1167{
1166 class_destroy(fb_class); 1168 class_destroy(fb_class);
1169 unregister_chrdev(FB_MAJOR, "fb");
1167} 1170}
1168 1171
1169module_exit(fbmem_exit); 1172module_exit(fbmem_exit);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6cd1976548d4..c2718bb94949 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)
1241 vtotal *= 2; 1241 vtotal *= 2;
1242 1242
1243 hfreq = pixclock/htotal; 1243 hfreq = pixclock/htotal;
1244 hfreq = (hfreq + 500) / 1000 * 1000;
1245
1244 vfreq = hfreq/vtotal; 1246 vfreq = hfreq/vtotal;
1245 1247
1246 return (vfreq < vfmin || vfreq > vfmax || 1248 return (vfreq < vfmin || vfreq > vfmax ||
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index ddc9443254d9..ed1d4d1ac4f7 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)
242 fb_info->var.yres_virtual); 242 fb_info->var.yres_virtual);
243} 243}
244 244
245static ssize_t store_cmap(struct class_device *class_device, const char * buf, 245/* Format for cmap is "%02x%c%4x%4x%4x\n" */
246/* %02x entry %c transp %4x red %4x blue %4x green \n */
247/* 256 rows at 16 chars equals 4096, the normal page size */
248/* the code will automatically adjust for different page sizes */
249static ssize_t store_cmap(struct class_device *class_device, const char *buf,
246 size_t count) 250 size_t count)
247{ 251{
248// 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;
254
255 if ((count > PAGE_SIZE) || ((count % 16) != 0))
256 return -EINVAL;
257
258 if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
259 return -EINVAL;
260
261 sscanf(buf, "%02x", &start);
262 length = count / 16;
263
264 for (i = 0; i < length; i++)
265 if (buf[i * 16 + 2] != ' ')
266 transp = 1;
267
268 /* If we can batch, do it */
269 if (fb_info->fbops->fb_setcmap && length > 1) {
270 struct fb_cmap umap;
271
272 memset(&umap, 0, sizeof(umap));
273 if ((rc = fb_alloc_cmap(&umap, length, transp)))
274 return rc;
275
276 umap.start = start;
277 for (i = 0; i < length; i++) {
278 sscanf(&buf[i * 16 + 3], "%4hx", &umap.red[i]);
279 sscanf(&buf[i * 16 + 7], "%4hx", &umap.blue[i]);
280 sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]);
281 if (transp)
282 umap.transp[i] = (buf[i * 16 + 2] != ' ');
283 }
284 rc = fb_info->fbops->fb_setcmap(&umap, fb_info);
285 fb_copy_cmap(&umap, &fb_info->cmap);
286 fb_dealloc_cmap(&umap);
287
288 return rc;
289 }
290 for (i = 0; i < length; i++) {
291 u16 red, blue, green, tsp;
292
293 sscanf(&buf[i * 16 + 3], "%4hx", &red);
294 sscanf(&buf[i * 16 + 7], "%4hx", &blue);
295 sscanf(&buf[i * 16 + 11], "%4hx", &green);
296 tsp = (buf[i * 16 + 2] != ' ');
297 if ((rc = fb_info->fbops->fb_setcolreg(start++,
298 red, green, blue, tsp, fb_info)))
299 return rc;
300
301 fb_info->cmap.red[i] = red;
302 fb_info->cmap.blue[i] = blue;
303 fb_info->cmap.green[i] = green;
304 if (transp)
305 fb_info->cmap.transp[i] = tsp;
306 }
249 return 0; 307 return 0;
250} 308}
251 309
@@ -253,20 +311,24 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf)
253{ 311{
254 struct fb_info *fb_info = 312 struct fb_info *fb_info =
255 (struct fb_info *)class_get_devdata(class_device); 313 (struct fb_info *)class_get_devdata(class_device);
256 unsigned int offset = 0, i; 314 unsigned int i;
257 315
258 if (!fb_info->cmap.red || !fb_info->cmap.blue || 316 if (!fb_info->cmap.red || !fb_info->cmap.blue ||
259 !fb_info->cmap.green || !fb_info->cmap.transp) 317 !fb_info->cmap.green)
318 return -EINVAL;
319
320 if (fb_info->cmap.len > PAGE_SIZE / 16)
260 return -EINVAL; 321 return -EINVAL;
261 322
323 /* don't mess with the format, the buffer is PAGE_SIZE */
324 /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */
262 for (i = 0; i < fb_info->cmap.len; i++) { 325 for (i = 0; i < fb_info->cmap.len; i++) {
263 offset += snprintf(buf, PAGE_SIZE - offset, 326 snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
264 "%d,%d,%d,%d,%d\n", i + fb_info->cmap.start, 327 ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
265 fb_info->cmap.red[i], fb_info->cmap.blue[i], 328 fb_info->cmap.red[i], fb_info->cmap.blue[i],
266 fb_info->cmap.green[i], 329 fb_info->cmap.green[i]);
267 fb_info->cmap.transp[i]);
268 } 330 }
269 return offset; 331 return 16 * fb_info->cmap.len;
270} 332}
271 333
272static 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,
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 8fe1c12a17bd..cabd53cec991 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -249,9 +249,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
249 /* disable hardware cursor */ 249 /* disable hardware cursor */
250 LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1); 250 LCDC_CPOS &= ~(CPOS_CC0 | CPOS_CC1);
251 251
252 /* fixed burst length (see erratum 11) */
253 LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2);
254
255 LCDC_RMCR = RMCR_LCDC_EN; 252 LCDC_RMCR = RMCR_LCDC_EN;
256 253
257 if(fbi->backlight_power) 254 if(fbi->backlight_power)
@@ -359,6 +356,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
359 LCDC_PCR = fbi->pcr; 356 LCDC_PCR = fbi->pcr;
360 LCDC_PWMR = fbi->pwmr; 357 LCDC_PWMR = fbi->pwmr;
361 LCDC_LSCR1 = fbi->lscr1; 358 LCDC_LSCR1 = fbi->lscr1;
359 LCDC_DMACR = fbi->dmacr;
362 360
363 return 0; 361 return 0;
364} 362}
@@ -509,6 +507,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
509 fbi->cmap_inverse = inf->cmap_inverse; 507 fbi->cmap_inverse = inf->cmap_inverse;
510 fbi->pcr = inf->pcr; 508 fbi->pcr = inf->pcr;
511 fbi->lscr1 = inf->lscr1; 509 fbi->lscr1 = inf->lscr1;
510 fbi->dmacr = inf->dmacr;
512 fbi->pwmr = inf->pwmr; 511 fbi->pwmr = inf->pwmr;
513 fbi->lcd_power = inf->lcd_power; 512 fbi->lcd_power = inf->lcd_power;
514 fbi->backlight_power = inf->backlight_power; 513 fbi->backlight_power = inf->backlight_power;
@@ -642,12 +641,12 @@ static int imxfb_remove(struct device *dev)
642{ 641{
643 struct platform_device *pdev = to_platform_device(dev); 642 struct platform_device *pdev = to_platform_device(dev);
644 struct fb_info *info = dev_get_drvdata(dev); 643 struct fb_info *info = dev_get_drvdata(dev);
644 struct imxfb_info *fbi = info->par;
645 struct resource *res; 645 struct resource *res;
646 646
647 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 647 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
648 648
649 /* disable LCD controller */ 649 imxfb_disable_controller(fbi);
650 LCDC_RMCR &= ~RMCR_LCDC_EN;
651 650
652 unregister_framebuffer(info); 651 unregister_framebuffer(info);
653 652
@@ -663,8 +662,9 @@ static int imxfb_remove(struct device *dev)
663 662
664void imxfb_shutdown(struct device * dev) 663void imxfb_shutdown(struct device * dev)
665{ 664{
666 /* disable LCD Controller */ 665 struct fb_info *info = dev_get_drvdata(dev);
667 LCDC_RMCR &= ~RMCR_LCDC_EN; 666 struct imxfb_info *fbi = info->par;
667 imxfb_disable_controller(fbi);
668} 668}
669 669
670static struct device_driver imxfb_driver = { 670static struct device_driver imxfb_driver = {
diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h
index 128c3ee515c7..e837a8b48eb8 100644
--- a/drivers/video/imxfb.h
+++ b/drivers/video/imxfb.h
@@ -54,6 +54,7 @@ struct imxfb_info {
54 u_int pcr; 54 u_int pcr;
55 u_int pwmr; 55 u_int pwmr;
56 u_int lscr1; 56 u_int lscr1;
57 u_int dmacr;
57 u_int cmap_inverse:1, 58 u_int cmap_inverse:1,
58 cmap_static:1, 59 cmap_static:1,
59 unused:30; 60 unused:30;
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 5dceddedf507..42c17efa9fb0 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -138,27 +138,27 @@ static struct fb_var_screeninfo pm2fb_var __devinitdata = {
138 * Utility functions 138 * Utility functions
139 */ 139 */
140 140
141inline static u32 RD32(unsigned char __iomem *base, s32 off) 141static inline u32 RD32(unsigned char __iomem *base, s32 off)
142{ 142{
143 return fb_readl(base + off); 143 return fb_readl(base + off);
144} 144}
145 145
146inline static void WR32(unsigned char __iomem *base, s32 off, u32 v) 146static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
147{ 147{
148 fb_writel(v, base + off); 148 fb_writel(v, base + off);
149} 149}
150 150
151inline static u32 pm2_RD(struct pm2fb_par* p, s32 off) 151static inline u32 pm2_RD(struct pm2fb_par* p, s32 off)
152{ 152{
153 return RD32(p->v_regs, off); 153 return RD32(p->v_regs, off);
154} 154}
155 155
156inline static void pm2_WR(struct pm2fb_par* p, s32 off, u32 v) 156static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
157{ 157{
158 WR32(p->v_regs, off, v); 158 WR32(p->v_regs, off, v);
159} 159}
160 160
161inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) 161static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
162{ 162{
163 int index = PM2R_RD_INDEXED_DATA; 163 int index = PM2R_RD_INDEXED_DATA;
164 switch (p->type) { 164 switch (p->type) {
@@ -174,7 +174,7 @@ inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
174 return pm2_RD(p, index); 174 return pm2_RD(p, index);
175} 175}
176 176
177inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) 177static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
178{ 178{
179 int index = PM2R_RD_INDEXED_DATA; 179 int index = PM2R_RD_INDEXED_DATA;
180 switch (p->type) { 180 switch (p->type) {
@@ -190,7 +190,7 @@ inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
190 pm2_WR(p, index, v); 190 pm2_WR(p, index, v);
191} 191}
192 192
193inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) 193static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
194{ 194{
195 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); 195 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
196 mb(); 196 mb();
@@ -200,7 +200,7 @@ inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
200#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT 200#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
201#define WAIT_FIFO(p,a) 201#define WAIT_FIFO(p,a)
202#else 202#else
203inline static void WAIT_FIFO(struct pm2fb_par* p, u32 a) 203static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
204{ 204{
205 while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a ); 205 while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a );
206 mb(); 206 mb();
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 6a9e183be41b..ae297e222681 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)
1826#ifdef CONFIG_PPC_OF 1826#ifdef CONFIG_PPC_OF
1827 if (!riva_get_EDID_OF(info, pdev)) 1827 if (!riva_get_EDID_OF(info, pdev))
1828 printk(PFX "could not retrieve EDID from OF\n"); 1828 printk(PFX "could not retrieve EDID from OF\n");
1829#elif CONFIG_FB_RIVA_I2C 1829#elif defined(CONFIG_FB_RIVA_I2C)
1830 if (!riva_get_EDID_i2c(info)) 1830 if (!riva_get_EDID_i2c(info))
1831 printk(PFX "could not retrieve EDID from DDC/I2C\n"); 1831 printk(PFX "could not retrieve EDID from DDC/I2C\n");
1832#endif 1832#endif
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