diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_memory_region.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_memory_region.c | 104 |
1 files changed, 87 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index c70d7e286a51..ce722f20cab1 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -5,6 +5,9 @@ #include <linux/prandom.h> +#include <drm/drm_print.h> +#include <uapi/drm/i915_drm.h> + #include "intel_memory_region.h" #include "i915_drv.h" #include "i915_ttm_buddy_manager.h" @@ -17,7 +20,7 @@ static const struct { .class = INTEL_MEMORY_SYSTEM, .instance = 0, }, - [INTEL_REGION_LMEM] = { + [INTEL_REGION_LMEM_0] = { .class = INTEL_MEMORY_LOCAL, .instance = 0, }, @@ -36,7 +39,7 @@ static int __iopagetest(struct intel_memory_region *mem, u8 value, resource_size_t offset, const void *caller) { - int byte = prandom_u32_max(pagesize); + int byte = get_random_u32_below(pagesize); u8 result[3]; memset_io(va, value, pagesize); /* or GPF! */ @@ -48,7 +51,7 @@ static int __iopagetest(struct intel_memory_region *mem, if (memchr_inv(result, value, sizeof(result))) { dev_err(mem->i915->drm.dev, "Failed to read back from memory region:%pR at [%pa + %pa] for %ps; wrote %x, read (%x, %x, %x)\n", - &mem->region, &mem->io_start, &offset, caller, + &mem->region, &mem->io.start, &offset, caller, value, result[0], result[1], result[2]); return -EINVAL; } @@ -65,11 +68,11 @@ static int iopagetest(struct intel_memory_region *mem, int err; int i; - va = ioremap_wc(mem->io_start + offset, PAGE_SIZE); + va = ioremap_wc(mem->io.start + offset, PAGE_SIZE); if (!va) { dev_err(mem->i915->drm.dev, "Failed to ioremap memory region [%pa + %pa] for %ps\n", - &mem->io_start, &offset, caller); + &mem->io.start, &offset, caller); return -EFAULT; } @@ -90,17 +93,21 @@ static int iopagetest(struct intel_memory_region *mem, static resource_size_t random_page(resource_size_t last) { /* Limited to low 44b (16TiB), but should suffice for a spot check */ - return prandom_u32_max(last >> PAGE_SHIFT) << PAGE_SHIFT; + return get_random_u32_below(last >> PAGE_SHIFT) << PAGE_SHIFT; } static int iomemtest(struct intel_memory_region *mem, bool test_all, const void *caller) { - resource_size_t last = resource_size(&mem->region) - PAGE_SIZE; - resource_size_t page; + resource_size_t last, page; int err; + if (resource_size(&mem->io) < PAGE_SIZE) + return 0; + + last = resource_size(&mem->io) - PAGE_SIZE; + /* * Quick test to check read/write access to the iomap (backing store). * @@ -165,6 +172,17 @@ intel_memory_region_by_type(struct drm_i915_private *i915, return NULL; } +bool intel_memory_type_is_local(enum intel_memory_type mem_type) +{ + switch (mem_type) { + case INTEL_MEMORY_LOCAL: + case INTEL_MEMORY_STOLEN_LOCAL: + return true; + default: + return false; + } +} + /** * intel_memory_region_reserve - Reserve a memory range * @mem: The region for which we want to reserve a range. @@ -192,8 +210,7 @@ void intel_memory_region_debug(struct intel_memory_region *mr, if (mr->region_private) ttm_resource_manager_debug(mr->region_private, printer); else - drm_printf(printer, "total:%pa, available:%pa bytes\n", - &mr->total, &mr->avail); + drm_printf(printer, "total:%pa bytes\n", &mr->total); } static int intel_memory_region_memtest(struct intel_memory_region *mem, @@ -202,7 +219,7 @@ static int intel_memory_region_memtest(struct intel_memory_region *mem, struct drm_i915_private *i915 = mem->i915; int err = 0; - if (!mem->io_start) + if (!mem->io.start) return 0; if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM) || i915->params.memtest) @@ -211,12 +228,29 @@ static int intel_memory_region_memtest(struct intel_memory_region *mem, return err; } +const char *intel_memory_type_str(enum intel_memory_type type) +{ + switch (type) { + case INTEL_MEMORY_SYSTEM: + return "system"; + case INTEL_MEMORY_LOCAL: + return "local"; + case INTEL_MEMORY_STOLEN_LOCAL: + return "stolen-local"; + case INTEL_MEMORY_STOLEN_SYSTEM: + return "stolen-system"; + default: + return "unknown"; + } +} + struct intel_memory_region * intel_memory_region_create(struct drm_i915_private *i915, resource_size_t start, resource_size_t size, resource_size_t min_page_size, resource_size_t io_start, + resource_size_t io_size, u16 type, u16 instance, const struct intel_memory_region_ops *ops) @@ -229,15 +263,17 @@ intel_memory_region_create(struct drm_i915_private *i915, return ERR_PTR(-ENOMEM); mem->i915 = i915; - mem->region = (struct resource)DEFINE_RES_MEM(start, size); - mem->io_start = io_start; + mem->region = DEFINE_RES_MEM(start, size); + mem->io = DEFINE_RES_MEM(io_start, io_size); mem->min_page_size = min_page_size; mem->ops = ops; mem->total = size; - mem->avail = mem->total; mem->type = type; mem->instance = instance; + snprintf(mem->uabi_name, sizeof(mem->uabi_name), "%s%u", + intel_memory_type_str(type), instance); + mutex_init(&mem->objects.lock); INIT_LIST_HEAD(&mem->objects.list); @@ -271,6 +307,20 @@ void intel_memory_region_set_name(struct intel_memory_region *mem, va_end(ap); } +void intel_memory_region_avail(struct intel_memory_region *mr, + u64 *avail, u64 *visible_avail) +{ + if (mr->type == INTEL_MEMORY_LOCAL) { + i915_ttm_buddy_man_avail(mr->region_private, + avail, visible_avail); + *avail <<= PAGE_SHIFT; + *visible_avail <<= PAGE_SHIFT; + } else { + *avail = mr->total; + *visible_avail = mr->total; + } +} + void intel_memory_region_destroy(struct intel_memory_region *mem) { int ret = 0; @@ -294,7 +344,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915) struct intel_memory_region *mem = ERR_PTR(-ENODEV); u16 type, instance; - if (!HAS_REGION(i915, BIT(i))) + if (!HAS_REGION(i915, i)) continue; type = intel_region_map[i].class; @@ -330,8 +380,28 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915) goto out_cleanup; } - mem->id = i; - i915->mm.regions[i] = mem; + if (mem) { /* Skip on non-fatal errors */ + mem->id = i; + i915->mm.regions[i] = mem; + } + } + + for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) { + struct intel_memory_region *mem = i915->mm.regions[i]; + u64 region_size, io_size; + + if (!mem) + continue; + + region_size = resource_size(&mem->region) >> 20; + io_size = resource_size(&mem->io) >> 20; + + if (resource_size(&mem->io)) + drm_dbg(&i915->drm, "Memory region(%d): %s: %llu MiB %pR, io: %llu MiB %pR\n", + mem->id, mem->name, region_size, &mem->region, io_size, &mem->io); + else + drm_dbg(&i915->drm, "Memory region(%d): %s: %llu MiB %pR, io: n/a\n", + mem->id, mem->name, region_size, &mem->region); } return 0; |
