aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2010-05-16 11:33:09 -0400
committerDave Airlie <airlied@redhat.com>2010-05-18 02:19:30 -0400
commit3b9676e7ac6eff4f50f1b48b6c36664f55b79507 (patch)
treeb9c1367db290a66f1cba4f78a488f7e25e779b79 /drivers
parent06415c564fb98562a4d6b6215615deb2d1cc0dae (diff)
vga16fb, drm: vga16fb->drm handoff
let vga16fb claim 0xA0000+0x10000 region as its aperture; drm drivers don't use it, so we have to detect it and kick vga16fb manually - but only if drm is driving the primary card Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Cc: James Simmons <jsimmons@infradead.org> Cc: Dave Airlie <airlied@redhat.com> Cc: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c7
-rw-r--r--drivers/video/fbmem.c14
-rw-r--r--drivers/video/vga16fb.c26
3 files changed, 36 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 75c5c465e08e..c667a1138c33 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -668,11 +668,16 @@ static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
668static int nouveau_remove_conflicting_drivers(struct drm_device *dev) 668static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
669{ 669{
670 struct drm_nouveau_private *dev_priv = dev->dev_private; 670 struct drm_nouveau_private *dev_priv = dev->dev_private;
671 bool primary = false;
671 dev_priv->apertures = nouveau_get_apertures(dev); 672 dev_priv->apertures = nouveau_get_apertures(dev);
672 if (!dev_priv->apertures) 673 if (!dev_priv->apertures)
673 return -ENOMEM; 674 return -ENOMEM;
674 675
675 remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb"); 676#ifdef CONFIG_X86
677 primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
678#endif
679
680 remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
676 return 0; 681 return 0;
677} 682}
678 683
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 7cfcd716fd5f..e08b7b5cb326 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1500,19 +1500,26 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena,
1500 return false; 1500 return false;
1501} 1501}
1502 1502
1503void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name) 1503#define VGA_FB_PHYS 0xA0000
1504void remove_conflicting_framebuffers(struct apertures_struct *a,
1505 const char *name, bool primary)
1504{ 1506{
1505 int i; 1507 int i;
1506 1508
1507 /* check all firmware fbs and kick off if the base addr overlaps */ 1509 /* check all firmware fbs and kick off if the base addr overlaps */
1508 for (i = 0 ; i < FB_MAX; i++) { 1510 for (i = 0 ; i < FB_MAX; i++) {
1511 struct apertures_struct *gen_aper;
1509 if (!registered_fb[i]) 1512 if (!registered_fb[i])
1510 continue; 1513 continue;
1511 1514
1512 if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) 1515 if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
1513 continue; 1516 continue;
1514 1517
1515 if (fb_do_apertures_overlap(registered_fb[i]->apertures, a)) { 1518 gen_aper = registered_fb[i]->apertures;
1519 if (fb_do_apertures_overlap(gen_aper, a) ||
1520 (primary && gen_aper && gen_aper->count &&
1521 gen_aper->ranges[0].base == VGA_FB_PHYS)) {
1522
1516 printk(KERN_ERR "fb: conflicting fb hw usage " 1523 printk(KERN_ERR "fb: conflicting fb hw usage "
1517 "%s vs %s - removing generic driver\n", 1524 "%s vs %s - removing generic driver\n",
1518 name, registered_fb[i]->fix.id); 1525 name, registered_fb[i]->fix.id);
@@ -1545,7 +1552,8 @@ register_framebuffer(struct fb_info *fb_info)
1545 if (fb_check_foreignness(fb_info)) 1552 if (fb_check_foreignness(fb_info))
1546 return -ENOSYS; 1553 return -ENOSYS;
1547 1554
1548 remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id); 1555 remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id,
1556 fb_is_primary_device(fb_info));
1549 1557
1550 num_registered_fb++; 1558 num_registered_fb++;
1551 for (i = 0 ; i < FB_MAX; i++) 1559 for (i = 0 ; i < FB_MAX; i++)
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index bf638a47a5b3..149c47ac7e93 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1263,10 +1263,19 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image
1263 vga_imageblit_color(info, image); 1263 vga_imageblit_color(info, image);
1264} 1264}
1265 1265
1266static void vga16fb_destroy(struct fb_info *info)
1267{
1268 iounmap(info->screen_base);
1269 fb_dealloc_cmap(&info->cmap);
1270 /* XXX unshare VGA regions */
1271 framebuffer_release(info);
1272}
1273
1266static struct fb_ops vga16fb_ops = { 1274static struct fb_ops vga16fb_ops = {
1267 .owner = THIS_MODULE, 1275 .owner = THIS_MODULE,
1268 .fb_open = vga16fb_open, 1276 .fb_open = vga16fb_open,
1269 .fb_release = vga16fb_release, 1277 .fb_release = vga16fb_release,
1278 .fb_destroy = vga16fb_destroy,
1270 .fb_check_var = vga16fb_check_var, 1279 .fb_check_var = vga16fb_check_var,
1271 .fb_set_par = vga16fb_set_par, 1280 .fb_set_par = vga16fb_set_par,
1272 .fb_setcolreg = vga16fb_setcolreg, 1281 .fb_setcolreg = vga16fb_setcolreg,
@@ -1306,6 +1315,11 @@ static int __devinit vga16fb_probe(struct platform_device *dev)
1306 ret = -ENOMEM; 1315 ret = -ENOMEM;
1307 goto err_fb_alloc; 1316 goto err_fb_alloc;
1308 } 1317 }
1318 info->apertures = alloc_apertures(1);
1319 if (!info->apertures) {
1320 ret = -ENOMEM;
1321 goto err_ioremap;
1322 }
1309 1323
1310 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ 1324 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
1311 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS, 0); 1325 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS, 0);
@@ -1335,7 +1349,7 @@ static int __devinit vga16fb_probe(struct platform_device *dev)
1335 info->fix = vga16fb_fix; 1349 info->fix = vga16fb_fix;
1336 /* supports rectangles with widths of multiples of 8 */ 1350 /* supports rectangles with widths of multiples of 8 */
1337 info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31; 1351 info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31;
1338 info->flags = FBINFO_FLAG_DEFAULT | 1352 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE |
1339 FBINFO_HWACCEL_YPAN; 1353 FBINFO_HWACCEL_YPAN;
1340 1354
1341 i = (info->var.bits_per_pixel == 8) ? 256 : 16; 1355 i = (info->var.bits_per_pixel == 8) ? 256 : 16;
@@ -1354,6 +1368,9 @@ static int __devinit vga16fb_probe(struct platform_device *dev)
1354 1368
1355 vga16fb_update_fix(info); 1369 vga16fb_update_fix(info);
1356 1370
1371 info->apertures->ranges[0].base = VGA_FB_PHYS;
1372 info->apertures->ranges[0].size = VGA_FB_PHYS_LEN;
1373
1357 if (register_framebuffer(info) < 0) { 1374 if (register_framebuffer(info) < 0) {
1358 printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); 1375 printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
1359 ret = -EINVAL; 1376 ret = -EINVAL;
@@ -1380,13 +1397,8 @@ static int vga16fb_remove(struct platform_device *dev)
1380{ 1397{
1381 struct fb_info *info = platform_get_drvdata(dev); 1398 struct fb_info *info = platform_get_drvdata(dev);
1382 1399
1383 if (info) { 1400 if (info)
1384 unregister_framebuffer(info); 1401 unregister_framebuffer(info);
1385 iounmap(info->screen_base);
1386 fb_dealloc_cmap(&info->cmap);
1387 /* XXX unshare VGA regions */
1388 framebuffer_release(info);
1389 }
1390 1402
1391 return 0; 1403 return 0;
1392} 1404}