aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2010-05-16 11:29:56 -0400
committerDave Airlie <airlied@redhat.com>2010-05-18 02:19:28 -0400
commit06415c564fb98562a4d6b6215615deb2d1cc0dae (patch)
tree93982221251bc68eb292a07da72220a0c90d94f0 /drivers/gpu/drm/nouveau
parent1471ca9aa71cd37b6a7476bb6f06a3a8622ea1bd (diff)
fbmem, drm/nouveau: kick firmware framebuffers as soon as possible
Currently vesafb/efifb/... is kicked when hardware driver is registering framebuffer. To do it hardware must be fully functional, so there's a short window between start of initialisation and framebuffer registration when two drivers touch the hardware. Unfortunately sometimes it breaks nouveau initialisation. Fix it by kicking firmware driver(s) before we start touching the hardware. Reported-by: Didier Spaier <didier.spaier@epsm.fr> Tested-by: Didier Spaier <didier.spaier@epsm.fr> Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com> Cc: Ben Skeggs <bskeggs@redhat.com> Cc: Peter Jones <pjones@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c19
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c43
3 files changed, 45 insertions, 18 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 5b47b79f45e8..94d8dd27bde8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -624,6 +624,7 @@ struct drm_nouveau_private {
624 } debugfs; 624 } debugfs;
625 625
626 struct nouveau_fbdev *nfbdev; 626 struct nouveau_fbdev *nfbdev;
627 struct apertures_struct *apertures;
627}; 628};
628 629
629static inline struct drm_nouveau_private * 630static inline struct drm_nouveau_private *
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 292c7ff95105..2c2199329cc1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -183,7 +183,6 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
183 struct drm_mode_fb_cmd mode_cmd; 183 struct drm_mode_fb_cmd mode_cmd;
184 struct pci_dev *pdev = dev->pdev; 184 struct pci_dev *pdev = dev->pdev;
185 struct device *device = &pdev->dev; 185 struct device *device = &pdev->dev;
186 struct apertures_struct *aper;
187 int size, ret; 186 int size, ret;
188 187
189 mode_cmd.width = sizes->surface_width; 188 mode_cmd.width = sizes->surface_width;
@@ -267,28 +266,12 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
267 info->fix.mmio_len = pci_resource_len(pdev, 1); 266 info->fix.mmio_len = pci_resource_len(pdev, 1);
268 267
269 /* Set aperture base/size for vesafb takeover */ 268 /* Set aperture base/size for vesafb takeover */
270 aper = info->apertures = alloc_apertures(3); 269 info->apertures = dev_priv->apertures;
271 if (!info->apertures) { 270 if (!info->apertures) {
272 ret = -ENOMEM; 271 ret = -ENOMEM;
273 goto out_unref; 272 goto out_unref;
274 } 273 }
275 274
276 aper->ranges[0].base = pci_resource_start(pdev, 1);
277 aper->ranges[0].size = pci_resource_len(pdev, 1);
278 aper->count = 1;
279
280 if (pci_resource_len(pdev, 2)) {
281 aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
282 aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
283 aper->count++;
284 }
285
286 if (pci_resource_len(pdev, 3)) {
287 aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
288 aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
289 aper->count++;
290 }
291
292 info->pixmap.size = 64*1024; 275 info->pixmap.size = 64*1024;
293 info->pixmap.buf_align = 8; 276 info->pixmap.buf_align = 8;
294 info->pixmap.access_align = 32; 277 info->pixmap.access_align = 32;
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 92100a9678ba..75c5c465e08e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -639,6 +639,43 @@ static void nouveau_OF_copy_vbios_to_ramin(struct drm_device *dev)
639#endif 639#endif
640} 640}
641 641
642static struct apertures_struct *nouveau_get_apertures(struct drm_device *dev)
643{
644 struct pci_dev *pdev = dev->pdev;
645 struct apertures_struct *aper = alloc_apertures(3);
646 if (!aper)
647 return NULL;
648
649 aper->ranges[0].base = pci_resource_start(pdev, 1);
650 aper->ranges[0].size = pci_resource_len(pdev, 1);
651 aper->count = 1;
652
653 if (pci_resource_len(pdev, 2)) {
654 aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
655 aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
656 aper->count++;
657 }
658
659 if (pci_resource_len(pdev, 3)) {
660 aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
661 aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
662 aper->count++;
663 }
664
665 return aper;
666}
667
668static int nouveau_remove_conflicting_drivers(struct drm_device *dev)
669{
670 struct drm_nouveau_private *dev_priv = dev->dev_private;
671 dev_priv->apertures = nouveau_get_apertures(dev);
672 if (!dev_priv->apertures)
673 return -ENOMEM;
674
675 remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb");
676 return 0;
677}
678
642int nouveau_load(struct drm_device *dev, unsigned long flags) 679int nouveau_load(struct drm_device *dev, unsigned long flags)
643{ 680{
644 struct drm_nouveau_private *dev_priv; 681 struct drm_nouveau_private *dev_priv;
@@ -726,6 +763,12 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
726 NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", 763 NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n",
727 dev_priv->card_type, reg0); 764 dev_priv->card_type, reg0);
728 765
766 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
767 int ret = nouveau_remove_conflicting_drivers(dev);
768 if (ret)
769 return ret;
770 }
771
729 /* map larger RAMIN aperture on NV40 cards */ 772 /* map larger RAMIN aperture on NV40 cards */
730 dev_priv->ramin = NULL; 773 dev_priv->ramin = NULL;
731 if (dev_priv->card_type >= NV_40) { 774 if (dev_priv->card_type >= NV_40) {