diff options
author | Marcin Slusarz <marcin.slusarz@gmail.com> | 2010-05-16 11:33:09 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-05-18 02:19:30 -0400 |
commit | 3b9676e7ac6eff4f50f1b48b6c36664f55b79507 (patch) | |
tree | b9c1367db290a66f1cba4f78a488f7e25e779b79 /drivers | |
parent | 06415c564fb98562a4d6b6215615deb2d1cc0dae (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.c | 7 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 14 | ||||
-rw-r--r-- | drivers/video/vga16fb.c | 26 |
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) | |||
668 | static int nouveau_remove_conflicting_drivers(struct drm_device *dev) | 668 | static 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 | ||
1503 | void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name) | 1503 | #define VGA_FB_PHYS 0xA0000 |
1504 | void 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 | ||
1266 | static 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 | |||
1266 | static struct fb_ops vga16fb_ops = { | 1274 | static 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 | } |