[Intel-gfx] [PATCH 44/64] drm/i915: Split early global GTT initialisation
Chris Wilson
chris at chris-wilson.co.uk
Thu Jul 7 08:41:50 UTC 2016
Initialising the global GTT is tricky as we wish to use the drm_mm range
manager during the modesetting initialisation (to capture stolen
allocations from the BIOS) before we actually enable GEM. To overcome
this, we currently setup the drm_mm first and then carefully rebind
them.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
drivers/gpu/drm/i915/i915_drv.c | 19 -------
drivers/gpu/drm/i915/i915_gem.c | 6 ++-
drivers/gpu/drm/i915/i915_gem_gtt.c | 99 +++++++++++++---------------------
drivers/gpu/drm/i915/i915_gem_gtt.h | 2 +-
drivers/gpu/drm/i915/i915_gem_stolen.c | 17 +++---
5 files changed, 50 insertions(+), 93 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 5f2f064b3a48..21ef73e056b2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -988,8 +988,6 @@ static void intel_sanitize_options(struct drm_i915_private *dev_priv)
static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = &dev_priv->drm;
- struct i915_ggtt *ggtt = &dev_priv->ggtt;
- uint32_t aperture_size;
int ret;
if (i915_inject_load_failure())
@@ -1035,7 +1033,6 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
}
}
-
/* 965GM sometimes incorrectly writes to hardware status page (HWS)
* using 32bit addressing, overwriting memory if HWS is located
* above 4GB.
@@ -1054,19 +1051,6 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
}
}
- aperture_size = ggtt->mappable_end;
-
- ggtt->mappable =
- io_mapping_create_wc(ggtt->mappable_base,
- aperture_size);
- if (!ggtt->mappable) {
- ret = -EIO;
- goto out_ggtt;
- }
-
- ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base,
- aperture_size);
-
pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE);
@@ -1107,14 +1091,11 @@ out_ggtt:
static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = &dev_priv->drm;
- struct i915_ggtt *ggtt = &dev_priv->ggtt;
if (dev->pdev->msi_enabled)
pci_disable_msi(dev->pdev);
pm_qos_remove_request(&dev_priv->pm_qos);
- arch_phys_wc_del(ggtt->mtrr);
- io_mapping_free(ggtt->mappable);
i915_ggtt_cleanup_hw(dev);
}
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index dd09eb0ec851..98f3945fc50f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4548,7 +4548,10 @@ int i915_gem_init(struct drm_device *dev)
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
i915_gem_init_userptr(dev_priv);
- i915_gem_init_ggtt(dev);
+
+ ret = i915_gem_init_ggtt(dev);
+ if (ret)
+ goto out_unlock;
ret = i915_gem_context_init(dev);
if (ret)
@@ -4639,7 +4642,6 @@ i915_gem_load_init(struct drm_device *dev)
SLAB_HWCACHE_ALIGN,
NULL);
- INIT_LIST_HEAD(&dev_priv->vm_list);
INIT_LIST_HEAD(&dev_priv->context_list);
INIT_LIST_HEAD(&dev_priv->mm.unbound_list);
INIT_LIST_HEAD(&dev_priv->mm.bound_list);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index a3d9c723dd02..5b09db68df73 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2751,10 +2751,7 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node,
}
}
-static int i915_gem_setup_global_gtt(struct drm_device *dev,
- u64 start,
- u64 mappable_end,
- u64 end)
+int i915_gem_init_ggtt(struct drm_device *dev)
{
/* Let GEM Manage all of the aperture.
*
@@ -2767,46 +2764,14 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
*/
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_ggtt *ggtt = &dev_priv->ggtt;
- struct drm_mm_node *entry;
- struct drm_i915_gem_object *obj;
unsigned long hole_start, hole_end;
+ struct drm_mm_node *entry;
int ret;
- BUG_ON(mappable_end > end);
-
- ggtt->base.start = start;
-
- /* Subtract the guard page before address space initialization to
- * shrink the range used by drm_mm */
- ggtt->base.total = end - start - PAGE_SIZE;
- i915_address_space_init(&ggtt->base, dev_priv);
- ggtt->base.total += PAGE_SIZE;
-
ret = intel_vgt_balloon(dev_priv);
if (ret)
return ret;
- if (!HAS_LLC(dev))
- ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
-
- /* Mark any preallocated objects as occupied */
- list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
- struct i915_vma *vma = i915_gem_obj_to_vma(obj, &ggtt->base);
-
- DRM_DEBUG_KMS("reserving preallocated space: %llx + %zx\n",
- i915_gem_obj_ggtt_offset(obj), obj->base.size);
-
- WARN_ON(i915_gem_obj_ggtt_bound(obj));
- ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
- if (ret) {
- DRM_DEBUG_KMS("Reservation failed: %i\n", ret);
- return ret;
- }
- vma->bound |= GLOBAL_BIND;
- __i915_vma_set_map_and_fenceable(vma);
- list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
- }
-
/* Clear any non-preallocated blocks */
drm_mm_for_each_hole(entry, &ggtt->base.mm, hole_start, hole_end) {
DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
@@ -2816,9 +2781,11 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
}
/* And finally clear the reserved guard page */
- ggtt->base.clear_range(&ggtt->base, end - PAGE_SIZE, PAGE_SIZE, true);
+ ggtt->base.clear_range(&ggtt->base,
+ ggtt->base.total - PAGE_SIZE, PAGE_SIZE,
+ true);
- if (USES_PPGTT(dev) && !USES_FULL_PPGTT(dev)) {
+ if (USES_PPGTT(dev_priv) && !USES_FULL_PPGTT(dev_priv)) {
struct i915_hw_ppgtt *ppgtt;
ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
@@ -2854,16 +2821,21 @@ static int i915_gem_setup_global_gtt(struct drm_device *dev,
return 0;
}
-/**
- * i915_gem_init_ggtt - Initialize GEM for Global GTT
- * @dev: DRM device
- */
-void i915_gem_init_ggtt(struct drm_device *dev)
+static void init_global_gtt(struct drm_i915_private *dev_priv)
{
- struct drm_i915_private *dev_priv = to_i915(dev);
- struct i915_ggtt *ggtt = &dev_priv->ggtt;
+ struct i915_address_space *ggtt = &dev_priv->ggtt.base;
+
+ INIT_LIST_HEAD(&dev_priv->vm_list);
- i915_gem_setup_global_gtt(dev, 0, ggtt->mappable_end, ggtt->base.total);
+ /* Subtract the guard page before address space initialization to
+ * shrink the range used by drm_mm.
+ */
+ ggtt->total -= PAGE_SIZE;
+ i915_address_space_init(ggtt, dev_priv);
+ ggtt->total += PAGE_SIZE;
+
+ if (!HAS_LLC(dev_priv))
+ ggtt->mm.color_adjust = i915_gtt_color_adjust;
}
/**
@@ -2891,6 +2863,9 @@ void i915_ggtt_cleanup_hw(struct drm_device *dev)
}
ggtt->base.cleanup(&ggtt->base);
+
+ arch_phys_wc_del(ggtt->mtrr);
+ io_mapping_free(ggtt->mappable);
}
static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
@@ -3251,21 +3226,14 @@ int i915_ggtt_init_hw(struct drm_device *dev)
if (ret)
return ret;
- if ((ggtt->base.total - 1) >> 32) {
- DRM_ERROR("We never expected a Global GTT with more than 32bits"
- "of address space! Found %lldM!\n",
- ggtt->base.total >> 20);
- ggtt->base.total = 1ULL << 32;
- ggtt->mappable_end = min(ggtt->mappable_end, ggtt->base.total);
- }
+ init_global_gtt(dev_priv);
- /*
- * Initialise stolen early so that we may reserve preallocated
- * objects for the BIOS to KMS transition.
- */
- ret = i915_gem_init_stolen(dev);
- if (ret)
- goto out_gtt_cleanup;
+ ggtt->mappable =
+ io_mapping_create_wc(ggtt->mappable_base, ggtt->mappable_end);
+ if (!ggtt->mappable)
+ return -EIO;
+
+ ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base, ggtt->mappable_end);
/* GMADR is the PCI mmio aperture into the global GTT. */
DRM_INFO("Memory usable by graphics device = %lluM\n",
@@ -3277,11 +3245,18 @@ int i915_ggtt_init_hw(struct drm_device *dev)
DRM_INFO("VT-d active for gfx access\n");
#endif
+ /*
+ * Initialise stolen early so that we may reserve preallocated
+ * objects for the BIOS to KMS transition.
+ */
+ ret = i915_gem_init_stolen(dev);
+ if (ret)
+ goto out_gtt_cleanup;
+
return 0;
out_gtt_cleanup:
ggtt->base.cleanup(&ggtt->base);
-
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h
index aa5f31d1c2ed..a0370bf950f5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -523,7 +523,7 @@ i915_page_dir_dma_addr(const struct i915_hw_ppgtt *ppgtt, const unsigned n)
int i915_ggtt_init_hw(struct drm_device *dev);
int i915_ggtt_enable_hw(struct drm_device *dev);
-void i915_gem_init_ggtt(struct drm_device *dev);
+int i915_gem_init_ggtt(struct drm_device *dev);
void i915_ggtt_cleanup_hw(struct drm_device *dev);
int i915_ppgtt_init_hw(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 310756c30723..9a8cc8c51077 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -698,18 +698,17 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
*/
vma->node.start = gtt_offset;
vma->node.size = size;
- if (drm_mm_initialized(&ggtt->base.mm)) {
- ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
- if (ret) {
- DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");
- goto err;
- }
- vma->bound |= GLOBAL_BIND;
- __i915_vma_set_map_and_fenceable(vma);
- list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
+ ret = drm_mm_reserve_node(&ggtt->base.mm, &vma->node);
+ if (ret) {
+ DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");
+ goto err;
}
+ vma->bound |= GLOBAL_BIND;
+ __i915_vma_set_map_and_fenceable(vma);
+ list_add_tail(&vma->vm_link, &ggtt->base.inactive_list);
+
list_add_tail(&obj->global_list, &dev_priv->mm.bound_list);
i915_gem_object_pin_pages(obj);
--
2.8.1
More information about the Intel-gfx
mailing list