mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-10 07:50:04 +00:00
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>
This commit is contained in:
parent
06415c564f
commit
3b9676e7ac
@ -668,11 +668,16 @@ static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
|
|||||||
static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
|
static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
|
bool primary = false;
|
||||||
dev_priv->apertures = nouveau_get_apertures(dev);
|
dev_priv->apertures = nouveau_get_apertures(dev);
|
||||||
if (!dev_priv->apertures)
|
if (!dev_priv->apertures)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb");
|
#ifdef CONFIG_X86
|
||||||
|
primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1500,19 +1500,26 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name)
|
#define VGA_FB_PHYS 0xA0000
|
||||||
|
void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||||
|
const char *name, bool primary)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* check all firmware fbs and kick off if the base addr overlaps */
|
/* check all firmware fbs and kick off if the base addr overlaps */
|
||||||
for (i = 0 ; i < FB_MAX; i++) {
|
for (i = 0 ; i < FB_MAX; i++) {
|
||||||
|
struct apertures_struct *gen_aper;
|
||||||
if (!registered_fb[i])
|
if (!registered_fb[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
|
if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fb_do_apertures_overlap(registered_fb[i]->apertures, a)) {
|
gen_aper = registered_fb[i]->apertures;
|
||||||
|
if (fb_do_apertures_overlap(gen_aper, a) ||
|
||||||
|
(primary && gen_aper && gen_aper->count &&
|
||||||
|
gen_aper->ranges[0].base == VGA_FB_PHYS)) {
|
||||||
|
|
||||||
printk(KERN_ERR "fb: conflicting fb hw usage "
|
printk(KERN_ERR "fb: conflicting fb hw usage "
|
||||||
"%s vs %s - removing generic driver\n",
|
"%s vs %s - removing generic driver\n",
|
||||||
name, registered_fb[i]->fix.id);
|
name, registered_fb[i]->fix.id);
|
||||||
@ -1545,7 +1552,8 @@ register_framebuffer(struct fb_info *fb_info)
|
|||||||
if (fb_check_foreignness(fb_info))
|
if (fb_check_foreignness(fb_info))
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id);
|
remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id,
|
||||||
|
fb_is_primary_device(fb_info));
|
||||||
|
|
||||||
num_registered_fb++;
|
num_registered_fb++;
|
||||||
for (i = 0 ; i < FB_MAX; i++)
|
for (i = 0 ; i < FB_MAX; i++)
|
||||||
|
@ -1263,10 +1263,19 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image
|
|||||||
vga_imageblit_color(info, image);
|
vga_imageblit_color(info, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vga16fb_destroy(struct fb_info *info)
|
||||||
|
{
|
||||||
|
iounmap(info->screen_base);
|
||||||
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
/* XXX unshare VGA regions */
|
||||||
|
framebuffer_release(info);
|
||||||
|
}
|
||||||
|
|
||||||
static struct fb_ops vga16fb_ops = {
|
static struct fb_ops vga16fb_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.fb_open = vga16fb_open,
|
.fb_open = vga16fb_open,
|
||||||
.fb_release = vga16fb_release,
|
.fb_release = vga16fb_release,
|
||||||
|
.fb_destroy = vga16fb_destroy,
|
||||||
.fb_check_var = vga16fb_check_var,
|
.fb_check_var = vga16fb_check_var,
|
||||||
.fb_set_par = vga16fb_set_par,
|
.fb_set_par = vga16fb_set_par,
|
||||||
.fb_setcolreg = vga16fb_setcolreg,
|
.fb_setcolreg = vga16fb_setcolreg,
|
||||||
@ -1306,6 +1315,11 @@ static int __devinit vga16fb_probe(struct platform_device *dev)
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_fb_alloc;
|
goto err_fb_alloc;
|
||||||
}
|
}
|
||||||
|
info->apertures = alloc_apertures(1);
|
||||||
|
if (!info->apertures) {
|
||||||
|
ret = -ENOMEM;
|
||||||
|
goto err_ioremap;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
|
/* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
|
||||||
info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS, 0);
|
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)
|
|||||||
info->fix = vga16fb_fix;
|
info->fix = vga16fb_fix;
|
||||||
/* supports rectangles with widths of multiples of 8 */
|
/* supports rectangles with widths of multiples of 8 */
|
||||||
info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31;
|
info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31;
|
||||||
info->flags = FBINFO_FLAG_DEFAULT |
|
info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE |
|
||||||
FBINFO_HWACCEL_YPAN;
|
FBINFO_HWACCEL_YPAN;
|
||||||
|
|
||||||
i = (info->var.bits_per_pixel == 8) ? 256 : 16;
|
i = (info->var.bits_per_pixel == 8) ? 256 : 16;
|
||||||
@ -1354,6 +1368,9 @@ static int __devinit vga16fb_probe(struct platform_device *dev)
|
|||||||
|
|
||||||
vga16fb_update_fix(info);
|
vga16fb_update_fix(info);
|
||||||
|
|
||||||
|
info->apertures->ranges[0].base = VGA_FB_PHYS;
|
||||||
|
info->apertures->ranges[0].size = VGA_FB_PHYS_LEN;
|
||||||
|
|
||||||
if (register_framebuffer(info) < 0) {
|
if (register_framebuffer(info) < 0) {
|
||||||
printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
|
printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@ -1380,13 +1397,8 @@ static int vga16fb_remove(struct platform_device *dev)
|
|||||||
{
|
{
|
||||||
struct fb_info *info = platform_get_drvdata(dev);
|
struct fb_info *info = platform_get_drvdata(dev);
|
||||||
|
|
||||||
if (info) {
|
if (info)
|
||||||
unregister_framebuffer(info);
|
unregister_framebuffer(info);
|
||||||
iounmap(info->screen_base);
|
|
||||||
fb_dealloc_cmap(&info->cmap);
|
|
||||||
/* XXX unshare VGA regions */
|
|
||||||
framebuffer_release(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -971,7 +971,8 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
|
|||||||
/* drivers/video/fbmem.c */
|
/* drivers/video/fbmem.c */
|
||||||
extern int register_framebuffer(struct fb_info *fb_info);
|
extern int register_framebuffer(struct fb_info *fb_info);
|
||||||
extern int unregister_framebuffer(struct fb_info *fb_info);
|
extern int unregister_framebuffer(struct fb_info *fb_info);
|
||||||
extern void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name);
|
extern void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||||
|
const char *name, bool primary);
|
||||||
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
|
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
|
||||||
extern int fb_show_logo(struct fb_info *fb_info, int rotate);
|
extern int fb_show_logo(struct fb_info *fb_info, int rotate);
|
||||||
extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
|
extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user