drm/i915: Put the mm in the parent address space
[cascardo/linux.git] / drivers / gpu / drm / i915 / i915_gem_stolen.c
index 08dd923..5d38cb0 100644 (file)
@@ -46,6 +46,7 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct pci_dev *pdev = dev_priv->bridge_dev;
+       struct resource *r;
        u32 base;
 
        /* On the machines I have tested the Graphics Base of Stolen Memory
@@ -88,6 +89,22 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
 #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;
 }
 
@@ -198,6 +215,9 @@ int i915_gem_init_stolen(struct drm_device *dev)
        if (IS_VALLEYVIEW(dev))
                bios_reserved = 1024*1024; /* top 1M on VLV/BYT */
 
+       if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size))
+               return 0;
+
        /* Basic memrange allocator for stolen space */
        drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->gtt.stolen_size -
                    bios_reserved);
@@ -376,8 +396,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
         */
        obj->gtt_space.start = gtt_offset;
        obj->gtt_space.size = size;
-       if (drm_mm_initialized(&dev_priv->mm.gtt_space)) {
-               ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space,
+       if (drm_mm_initialized(&dev_priv->gtt.base.mm)) {
+               ret = drm_mm_reserve_node(&dev_priv->gtt.base.mm,
                                          &obj->gtt_space);
                if (ret) {
                        DRM_DEBUG_KMS("failed to allocate stolen GTT space\n");