aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_state.c
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/nouveau_state.c
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/nouveau_state.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c43
1 files changed, 43 insertions, 0 deletions
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) {