aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_dma.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-12 05:28:17 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-13 07:33:42 -0400
commite188719a2891f01b3100dca4ae3a055fb5a7ab52 (patch)
tree7d62b339c322886454f60e7fe233d329d659d7c3 /drivers/gpu/drm/i915/i915_dma.c
parent8ecd1a6615f0d9de6759aafe229bc1cc4ee99c7b (diff)
drm/i915: kick any firmware framebuffers before claiming the gtt
Especially vesafb likes to map everything as uc- (yikes), and if that mapping hangs around still while we try to map the gtt as wc the kernel will downgrade our request to uc-, resulting in abyssal performance. Unfortunately we can't do this as early as readon does (i.e. as the first thing we do when initializing the hw) because our fb/mmio space region moves around on a per-gen basis. So I've had to move it below the gtt initialization, but that seems to work, too. The important thing is that we do this before we set up the gtt wc mapping. Now an altogether different question is why people compile their kernels with vesafb enabled, but I guess making things just work isn't bad per se ... v2: - s/radeondrmfb/inteldrmfb/ - fix up error handling v3: Kill #ifdef X86, this is Intel after all. Noticed by Ben Widawsky. v4: Jani Nikula complained about the pointless bool primary initialization. v5: Don't oops if we can't allocate, noticed by Chris Wilson. v6: Resolve conflicts with agp rework and fixup whitespace. Reported-and-tested-by: "Kilarski, Bernard R" <bernard.r.kilarski@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index cf512e7178b4..fa8f2699344b 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1404,6 +1404,27 @@ i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base,
1404 } 1404 }
1405} 1405}
1406 1406
1407static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
1408{
1409 struct apertures_struct *ap;
1410 struct pci_dev *pdev = dev_priv->dev->pdev;
1411 bool primary;
1412
1413 ap = alloc_apertures(1);
1414 if (!ap)
1415 return;
1416
1417 ap->ranges[0].base = dev_priv->dev->agp->base;
1418 ap->ranges[0].size =
1419 dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
1420 primary =
1421 pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
1422
1423 remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
1424
1425 kfree(ap);
1426}
1427
1407/** 1428/**
1408 * i915_driver_load - setup chip and create an initial config 1429 * i915_driver_load - setup chip and create an initial config
1409 * @dev: DRM device 1430 * @dev: DRM device
@@ -1449,6 +1470,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1449 goto free_priv; 1470 goto free_priv;
1450 } 1471 }
1451 1472
1473 ret = intel_gmch_probe(dev_priv->bridge_dev, dev->pdev, NULL);
1474 if (!ret) {
1475 DRM_ERROR("failed to set up gmch\n");
1476 ret = -EIO;
1477 goto put_bridge;
1478 }
1479
1480 dev_priv->mm.gtt = intel_gtt_get();
1481 if (!dev_priv->mm.gtt) {
1482 DRM_ERROR("Failed to initialize GTT\n");
1483 ret = -ENODEV;
1484 goto put_gmch;
1485 }
1486
1487 i915_kick_out_firmware_fb(dev_priv);
1488
1452 pci_set_master(dev->pdev); 1489 pci_set_master(dev->pdev);
1453 1490
1454 /* overlay on gen2 is broken and can't address above 1G */ 1491 /* overlay on gen2 is broken and can't address above 1G */
@@ -1471,20 +1508,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1471 if (!dev_priv->regs) { 1508 if (!dev_priv->regs) {
1472 DRM_ERROR("failed to map registers\n"); 1509 DRM_ERROR("failed to map registers\n");
1473 ret = -EIO; 1510 ret = -EIO;
1474 goto put_bridge;
1475 }
1476
1477 ret = intel_gmch_probe(dev_priv->bridge_dev, dev->pdev, NULL);
1478 if (!ret) {
1479 DRM_ERROR("failed to set up gmch\n");
1480 ret = -EIO;
1481 goto out_rmmap;
1482 }
1483
1484 dev_priv->mm.gtt = intel_gtt_get();
1485 if (!dev_priv->mm.gtt) {
1486 DRM_ERROR("Failed to initialize GTT\n");
1487 ret = -ENODEV;
1488 goto put_gmch; 1511 goto put_gmch;
1489 } 1512 }
1490 1513
@@ -1496,7 +1519,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1496 aperture_size); 1519 aperture_size);
1497 if (dev_priv->mm.gtt_mapping == NULL) { 1520 if (dev_priv->mm.gtt_mapping == NULL) {
1498 ret = -EIO; 1521 ret = -EIO;
1499 goto put_gmch; 1522 goto out_rmmap;
1500 } 1523 }
1501 1524
1502 i915_mtrr_setup(dev_priv, dev_priv->mm.gtt_base_addr, 1525 i915_mtrr_setup(dev_priv, dev_priv->mm.gtt_base_addr,
@@ -1618,10 +1641,10 @@ out_mtrrfree:
1618 dev_priv->mm.gtt_mtrr = -1; 1641 dev_priv->mm.gtt_mtrr = -1;
1619 } 1642 }
1620 io_mapping_free(dev_priv->mm.gtt_mapping); 1643 io_mapping_free(dev_priv->mm.gtt_mapping);
1621put_gmch:
1622 intel_gmch_remove();
1623out_rmmap: 1644out_rmmap:
1624 pci_iounmap(dev->pdev, dev_priv->regs); 1645 pci_iounmap(dev->pdev, dev_priv->regs);
1646put_gmch:
1647 intel_gmch_remove();
1625put_bridge: 1648put_bridge:
1626 pci_dev_put(dev_priv->bridge_dev); 1649 pci_dev_put(dev_priv->bridge_dev);
1627free_priv: 1650free_priv: