[Intel-gfx] [PATCH 3/3] drm/i915: Lookup stolen region reserved during early PCI quirk processing
Chris Wilson
chris at chris-wilson.co.uk
Fri Jul 26 00:27:17 CEST 2013
As we now hook into the early PCI quirk table to earmark the Intel
Graphics Stolen region (inserting it into the iomem_resource) to prevent
it conflicting with any later resource allocations, we can simply walk
the iomem_resource tree and find it for our use. Thereby removing all of
our own code to define the stolen region.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/char/agp/intel-gtt.c | 93 +++-------------------------------
drivers/gpu/drm/i915/i915_drv.h | 3 +-
drivers/gpu/drm/i915/i915_gem_gtt.c | 15 +-----
drivers/gpu/drm/i915/i915_gem_stolen.c | 70 +++++--------------------
include/drm/intel-gtt.h | 2 +-
5 files changed, 26 insertions(+), 157 deletions(-)
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index b8e2014..586efed 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -343,90 +343,14 @@ static const struct aper_size_info_fixed intel_fake_agp_sizes[] = {
static unsigned int intel_gtt_stolen_size(void)
{
- u16 gmch_ctrl;
- u8 rdct;
- int local = 0;
- static const int ddt[4] = { 0, 16, 32, 64 };
- unsigned int stolen_size = 0;
-
- if (INTEL_GTT_GEN == 1)
- return 0; /* no stolen mem on i81x */
-
- pci_read_config_word(intel_private.bridge_dev,
- I830_GMCH_CTRL, &gmch_ctrl);
-
- if (intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
- intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
- switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
- case I830_GMCH_GMS_STOLEN_512:
- stolen_size = KB(512);
- break;
- case I830_GMCH_GMS_STOLEN_1024:
- stolen_size = MB(1);
- break;
- case I830_GMCH_GMS_STOLEN_8192:
- stolen_size = MB(8);
- break;
- case I830_GMCH_GMS_LOCAL:
- rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE);
- stolen_size = (I830_RDRAM_ND(rdct) + 1) *
- MB(ddt[I830_RDRAM_DDT(rdct)]);
- local = 1;
- break;
- default:
- stolen_size = 0;
- break;
- }
- } else {
- switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
- case I855_GMCH_GMS_STOLEN_1M:
- stolen_size = MB(1);
- break;
- case I855_GMCH_GMS_STOLEN_4M:
- stolen_size = MB(4);
- break;
- case I855_GMCH_GMS_STOLEN_8M:
- stolen_size = MB(8);
- break;
- case I855_GMCH_GMS_STOLEN_16M:
- stolen_size = MB(16);
- break;
- case I855_GMCH_GMS_STOLEN_32M:
- stolen_size = MB(32);
- break;
- case I915_GMCH_GMS_STOLEN_48M:
- stolen_size = MB(48);
- break;
- case I915_GMCH_GMS_STOLEN_64M:
- stolen_size = MB(64);
- break;
- case G33_GMCH_GMS_STOLEN_128M:
- stolen_size = MB(128);
- break;
- case G33_GMCH_GMS_STOLEN_256M:
- stolen_size = MB(256);
- break;
- case INTEL_GMCH_GMS_STOLEN_96M:
- stolen_size = MB(96);
- break;
- case INTEL_GMCH_GMS_STOLEN_160M:
- stolen_size = MB(160);
- break;
- case INTEL_GMCH_GMS_STOLEN_224M:
- stolen_size = MB(224);
- break;
- case INTEL_GMCH_GMS_STOLEN_352M:
- stolen_size = MB(352);
- break;
- default:
- stolen_size = 0;
- break;
- }
- }
+ struct resource *r;
+ unsigned int stolen_size;
- if (stolen_size > 0) {
- dev_info(&intel_private.bridge_dev->dev, "detected %dK %s memory\n",
- stolen_size / KB(1), local ? "local" : "stolen");
+ r = lookup_resource_by_name(&iomem_resource, E820_STOLEN_IGFX_STRING);
+ if (r) {
+ stolen_size = r->end - r->start + 1;
+ dev_info(&intel_private.bridge_dev->dev, "detected %dK stolen memory\n",
+ stolen_size / KB(1));
} else {
dev_info(&intel_private.bridge_dev->dev,
"no pre-allocated video memory detected\n");
@@ -1404,11 +1328,10 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
}
EXPORT_SYMBOL(intel_gmch_probe);
-void intel_gtt_get(size_t *gtt_total, size_t *stolen_size,
+void intel_gtt_get(size_t *gtt_total,
phys_addr_t *mappable_base, unsigned long *mappable_end)
{
*gtt_total = intel_private.gtt_total_entries << PAGE_SHIFT;
- *stolen_size = intel_private.stolen_size;
*mappable_base = intel_private.gma_bus_addr;
*mappable_end = intel_private.gtt_mappable_entries << PAGE_SHIFT;
}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ae36612..ec14124 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -513,7 +513,6 @@ struct i915_address_space {
*/
struct i915_gtt {
struct i915_address_space base;
- size_t stolen_size; /* Total size of stolen memory */
unsigned long mappable_end; /* End offset that we can CPU map */
struct io_mapping *mappable; /* Mapping to our CPU mappable region */
@@ -528,7 +527,7 @@ struct i915_gtt {
/* global gtt ops */
int (*gtt_probe)(struct drm_device *dev, size_t *gtt_total,
- size_t *stolen, phys_addr_t *mappable_base,
+ phys_addr_t *mappable_base,
unsigned long *mappable_end);
};
#define gtt_total_entries(gtt) ((gtt).base.total >> PAGE_SHIFT)
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 3b639a9..1294cee 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -784,16 +784,8 @@ static inline unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
return snb_gmch_ctl << 20;
}
-static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl)
-{
- snb_gmch_ctl >>= SNB_GMCH_GMS_SHIFT;
- snb_gmch_ctl &= SNB_GMCH_GMS_MASK;
- return snb_gmch_ctl << 25; /* 32 MB units */
-}
-
static int gen6_gmch_probe(struct drm_device *dev,
size_t *gtt_total,
- size_t *stolen,
phys_addr_t *mappable_base,
unsigned long *mappable_end)
{
@@ -820,7 +812,6 @@ static int gen6_gmch_probe(struct drm_device *dev,
pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl);
- *stolen = gen6_get_stolen_size(snb_gmch_ctl);
*gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT;
/* For Modern GENs the PTEs and register space are split in the BAR */
@@ -853,7 +844,6 @@ static void gen6_gmch_remove(struct i915_address_space *vm)
static int i915_gmch_probe(struct drm_device *dev,
size_t *gtt_total,
- size_t *stolen,
phys_addr_t *mappable_base,
unsigned long *mappable_end)
{
@@ -866,7 +856,7 @@ static int i915_gmch_probe(struct drm_device *dev,
return -EIO;
}
- intel_gtt_get(gtt_total, stolen, mappable_base, mappable_end);
+ intel_gtt_get(gtt_total, mappable_base, mappable_end);
dev_priv->gtt.do_idle_maps = needs_idle_maps(dev_priv->dev);
dev_priv->gtt.base.clear_range = i915_ggtt_clear_range;
@@ -902,7 +892,7 @@ int i915_gem_gtt_init(struct drm_device *dev)
gtt->base.pte_encode = gen6_pte_encode;
}
- ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size,
+ ret = gtt->gtt_probe(dev, >t->base.total,
>t->mappable_base, >t->mappable_end);
if (ret)
return ret;
@@ -913,7 +903,6 @@ int i915_gem_gtt_init(struct drm_device *dev)
DRM_INFO("Memory usable by graphics device = %zdM\n",
gtt->base.total >> 20);
DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20);
- DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20);
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index cacf769..f1f41f6 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -28,6 +28,7 @@
#include <drm/drmP.h>
#include <drm/i915_drm.h>
+#include <uapi/asm/e820.h>
#include "i915_drv.h"
/*
@@ -42,54 +43,6 @@
* for is a boon.
*/
-static unsigned long i915_stolen_to_physical(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- struct resource *r;
- u32 base;
-
- /* Almost universally we can find the Graphics Base of Stolen Memory
- * at offset 0x5c in the igfx configuration space. On a few (desktop)
- * machines this is also mirrored in the bridge device at different
- * locations, or in the MCHBAR. On gen2, the layout is again slightly
- * different with the Graphics Segment immediately following Top of
- * Memory (or Top of Usable DRAM). Note it appears that TOUD is only
- * reported by 865g, so we just use the top of memory as determined
- * by the e820 probe.
- *
- * XXX However gen2 requires an unavailable symbol.
- */
- base = 0;
- if (INTEL_INFO(dev)->gen >= 3) {
- /* Read Graphics Base of Stolen Memory directly */
- pci_read_config_dword(dev->pdev, 0x5c, &base);
- base &= ~((1<<20) - 1);
- } else { /* GEN2 */
-#if 0
- /* Stolen is immediately above Top of Memory */
- base = max_low_pfn_mapped << PAGE_SHIFT;
-#endif
- }
-
- if (base == 0)
- return 0;
-
- /* Verify that nothing else uses this physical address. Stolen
- * memory should be reserved by the BIOS and hidden from the
- * kernel. So if the region is already marked as busy, something
- * is seriously wrong.
- */
- r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size,
- "Graphics Stolen Memory");
- if (r == NULL) {
- DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n",
- base, base + (uint32_t)dev_priv->gtt.stolen_size);
- base = 0;
- }
-
- return base;
-}
-
static int i915_setup_compression(struct drm_device *dev, int size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -188,24 +141,29 @@ void i915_gem_cleanup_stolen(struct drm_device *dev)
int i915_gem_init_stolen(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+ struct resource *r;
int bios_reserved = 0;
+ size_t size;
- dev_priv->mm.stolen_base = i915_stolen_to_physical(dev);
- if (dev_priv->mm.stolen_base == 0)
+ /* Did we reserve our stolen region during early PCI quirks? */
+ r = lookup_resource_by_name(&iomem_resource, E820_STOLEN_IGFX_STRING);
+ if (r == NULL)
return 0;
- DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n",
- dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base);
+ size = r->end - r->start + 1;
+ DRM_DEBUG_DRIVER("found %zd bytes of stolen memory at %08qx\n",
+ size, r->start);
+
+ dev_priv->mm.stolen_base = r->start;
if (IS_VALLEYVIEW(dev))
bios_reserved = 1024*1024; /* top 1M on VLV/BYT */
- if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size))
+ if (WARN_ON(bios_reserved > size))
return 0;
/* Basic memrange allocator for stolen space */
- drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size -
- bios_reserved);
+ drm_mm_init(&dev_priv->mm.stolen, 0, size - bios_reserved);
return 0;
}
@@ -219,7 +177,7 @@ i915_pages_create_for_stolen(struct drm_device *dev,
struct scatterlist *sg;
DRM_DEBUG_DRIVER("offset=0x%x, size=%d\n", offset, size);
- BUG_ON(offset > dev_priv->gtt.stolen_size - size);
+ BUG_ON(offset > dev_priv->mm.stolen.head_node.size - size);
/* We hide that we have no struct page backing our stolen object
* by wrapping the contiguous physical allocation with a fake
diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h
index b08bdad..c0b5602 100644
--- a/include/drm/intel-gtt.h
+++ b/include/drm/intel-gtt.h
@@ -3,7 +3,7 @@
#ifndef _DRM_INTEL_GTT_H
#define _DRM_INTEL_GTT_H
-void intel_gtt_get(size_t *gtt_total, size_t *stolen_size,
+void intel_gtt_get(size_t *gtt_total,
phys_addr_t *mappable_base, unsigned long *mappable_end);
int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
--
1.8.3.2
More information about the Intel-gfx
mailing list