#include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
+#include "gt/intel_gt.h"
+#include "gt/intel_region_lmem.h"
 #include "i915_drv.h"
 #include "i915_gem_stolen.h"
 #include "i915_reg.h"
 
        /* Exclude the reserved region from driver use */
        mem->region.end = reserved_base - 1;
-       mem->io_size = resource_size(&mem->region);
+       mem->io_size = min(mem->io_size, resource_size(&mem->region));
 
        /* It is possible for the reserved area to end before the end of stolen
         * memory, so just consider the start. */
        if (GEM_WARN_ON(resource_size(&mem->region) == 0))
                return -ENODEV;
 
-       if (!io_mapping_init_wc(&mem->iomap,
-                               mem->io_start,
-                               mem->io_size))
-               return -EIO;
-
        /*
         * TODO: For stolen lmem we mostly just care about populating the dsm
         * related bits and setting up the drm_mm allocator for the range.
         */
        err = i915_gem_init_stolen(mem);
        if (err)
-               goto err_fini;
+               return err;
+
+       if (mem->io_size && !io_mapping_init_wc(&mem->iomap,
+                                               mem->io_start,
+                                               mem->io_size)) {
+               err = -EIO;
+               goto err_cleanup;
+       }
 
        return 0;
 
-err_fini:
-       io_mapping_fini(&mem->iomap);
+err_cleanup:
+       i915_gem_cleanup_stolen(mem->i915);
        return err;
 }
 
 static int release_stolen_lmem(struct intel_memory_region *mem)
 {
-       io_mapping_fini(&mem->iomap);
+       if (mem->io_size)
+               io_mapping_fini(&mem->iomap);
        i915_gem_cleanup_stolen(mem->i915);
        return 0;
 }
 {
        struct intel_uncore *uncore = &i915->uncore;
        struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+       resource_size_t dsm_size, dsm_base, lmem_size;
        struct intel_memory_region *mem;
+       resource_size_t io_start, io_size;
        resource_size_t min_page_size;
-       resource_size_t io_start;
-       resource_size_t lmem_size;
-       u64 lmem_base;
 
-       lmem_base = intel_uncore_read64(uncore, GEN12_DSMBASE);
-       if (GEM_WARN_ON(lmem_base >= pci_resource_len(pdev, 2)))
+       if (WARN_ON_ONCE(instance))
                return ERR_PTR(-ENODEV);
 
-       lmem_size = pci_resource_len(pdev, 2) - lmem_base;
-       io_start = pci_resource_start(pdev, 2) + lmem_base;
+       /* Use DSM base address instead for stolen memory */
+       dsm_base = intel_uncore_read64(uncore, GEN12_DSMBASE);
+       if (IS_DG1(uncore->i915)) {
+               lmem_size = pci_resource_len(pdev, 2);
+               if (WARN_ON(lmem_size < dsm_base))
+                       return ERR_PTR(-ENODEV);
+       } else {
+               resource_size_t lmem_range;
+
+               lmem_range = intel_gt_read_register(&i915->gt0, XEHPSDV_TILE0_ADDR_RANGE) & 0xFFFF;
+               lmem_size = lmem_range >> XEHPSDV_TILE_LMEM_RANGE_SHIFT;
+               lmem_size *= SZ_1G;
+       }
+
+       dsm_size = lmem_size - dsm_base;
+       if (pci_resource_len(pdev, 2) < lmem_size) {
+               io_start = 0;
+               io_size = 0;
+       } else {
+               io_start = pci_resource_start(pdev, 2) + dsm_base;
+               io_size = dsm_size;
+       }
 
        min_page_size = HAS_64K_PAGES(i915) ? I915_GTT_PAGE_SIZE_64K :
                                                I915_GTT_PAGE_SIZE_4K;
 
-       mem = intel_memory_region_create(i915, lmem_base, lmem_size,
+       mem = intel_memory_region_create(i915, dsm_base, dsm_size,
                                         min_page_size,
-                                        io_start, lmem_size,
+                                        io_start, io_size,
                                         type, instance,
                                         &i915_region_stolen_lmem_ops);
        if (IS_ERR(mem))
 
        drm_dbg(&i915->drm, "Stolen Local memory IO start: %pa\n",
                &mem->io_start);
+       drm_dbg(&i915->drm, "Stolen Local DSM base: %pa\n", &dsm_base);
 
        intel_memory_region_set_name(mem, "stolen-local");