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 <ch...@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    | 98 +++++++++++++---------------------
 drivers/gpu/drm/i915/i915_gem_gtt.h    |  2 +-
 drivers/gpu/drm/i915/i915_gem_stolen.c | 17 +++---
 5 files changed, 49 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index babeee1a6127..4483f9e75aa5 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1340,8 +1340,6 @@ static void i915_driver_cleanup_mmio(struct 
drm_i915_private *dev_priv)
 static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 {
        struct drm_device *dev = dev_priv->dev;
-       struct i915_ggtt *ggtt = &dev_priv->ggtt;
-       uint32_t aperture_size;
        int ret;
 
        if (i915_inject_load_failure())
@@ -1385,7 +1383,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.
@@ -1404,19 +1401,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);
 
@@ -1457,14 +1441,11 @@ out_ggtt:
 static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
 {
        struct drm_device *dev = dev_priv->dev;
-       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 20e174f7fc9e..b51d20a4f1ea 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4112,7 +4112,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)
@@ -4202,7 +4205,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 5d718c488f23..1cdd26ea94ed 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -2706,10 +2706,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.
         *
@@ -2722,48 +2719,16 @@ 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;
-
        if (intel_vgpu_active(dev_priv)) {
                ret = intel_vgt_balloon(dev);
                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",
@@ -2773,9 +2738,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);
@@ -2811,16 +2778,20 @@ 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;
 }
 
 /**
@@ -2849,6 +2820,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)
@@ -3207,21 +3181,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 == NULL)
+               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",
@@ -3233,11 +3200,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 62be77cac5cd..2a7221b6c9c5 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -518,7 +518,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 ecf920b1f986..4bd71d6956e2 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -696,18 +696,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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to