summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/gem/i915_gem_pages.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2020-01-15 16:57:53 +1000
committerDave Airlie <airlied@redhat.com>2020-01-15 16:57:54 +1000
commit71e7274066c646bb3d9da39d2f4db0a6404c0a2d (patch)
tree8aa56017bf44c03357bb02eae12334326949a15a /drivers/gpu/drm/i915/gem/i915_gem_pages.c
parentdd22dfa62c9cb2669ed4b181e359645108c69578 (diff)
parentf2221a50494037af98206713155c8d4f2e7bccaa (diff)
downloadtalos-op-linux-71e7274066c646bb3d9da39d2f4db0a6404c0a2d.tar.gz
talos-op-linux-71e7274066c646bb3d9da39d2f4db0a6404c0a2d.zip
Merge tag 'drm-intel-next-2020-01-14' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Final drm/i915 features for v5.6: - DP MST fixes (José) - Fix intel_bw_state memory leak (Pankaj Bharadiya) - Switch context id allocation to xarray (Tvrtko) - ICL/EHL/TGL workarounds (Matt Roper, Tvrtko) - Debugfs for LMEM details (Lukasz Fiedorowicz) - Prefer platform acronyms over codenames in symbols (Lucas) - Tiled and port sync mode fixes for fbdev and DP (Manasi) - DSI panel and backlight enable GPIO fixes (Hans de Goede) - Relax audio min CDCLK requirements on non-GLK (Kai Vehmanen) - Plane alignment and dimension check fixes (Imre) - Fix state checks for PSR (José) - Remove ICL+ clock gating programming (José) - Static checker fixes around bool usage (Ma Feng) - Bring back tests for self-contained headers in i915 (Masahiro Yamada) - Fix DP MST disable sequence (Ville) - Start converting i915 to the new drm device based logging macros (Wambui Karuga) - Add DSI VBT I2C sequence execution (Vivek Kasireddy) - Start using function pointers and ops structs in uc code (Michal) - Fix PMU names to not use colons or dashes (Tvrtko) - TGL media decompression support (DK, Imre) - Split i915_gem_gtt.[ch] to more manageable chunks (Matthew Auld) - Create dumb buffers in LMEM where available (Ram) - Extend mmap support for LMEM (Abdiel) - Selftest updates (Chris) - Hack bump up CDCLK on TGL to avoid underruns (Stan) - Use intel_encoder and intel_connector more instead of drm counterparts (Ville) - Build error fixes (Zhang Xiaoxu) - Fixes related to GPU and engine initialization/resume (Chris) - Support for prefaulting discontiguous objects (Abdiel) - Support discontiguous LMEM object maps (Chris) - Various GEM and GT improvements and fixes (Chris) - Merge pinctrl dependencies branch for the DSI GPIO updates (Jani) - Backmerge drm-next for new logging macros (Jani) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Jani Nikula <jani.nikula@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/87sgkil0v9.fsf@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/gem/i915_gem_pages.c')
-rw-r--r--drivers/gpu/drm/i915/gem/i915_gem_pages.c79
1 files changed, 47 insertions, 32 deletions
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
index 75197ca696a8..54aca5c9101e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
@@ -158,9 +158,7 @@ static void __i915_gem_object_reset_page_iter(struct drm_i915_gem_object *obj)
static void unmap_object(struct drm_i915_gem_object *obj, void *ptr)
{
- if (i915_gem_object_is_lmem(obj))
- io_mapping_unmap((void __force __iomem *)ptr);
- else if (is_vmalloc_addr(ptr))
+ if (is_vmalloc_addr(ptr))
vunmap(ptr);
else
kunmap(kmap_to_page(ptr));
@@ -236,46 +234,44 @@ unlock:
return err;
}
+static inline pte_t iomap_pte(resource_size_t base,
+ dma_addr_t offset,
+ pgprot_t prot)
+{
+ return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot));
+}
+
/* The 'mapping' part of i915_gem_object_pin_map() below */
static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
enum i915_map_type type)
{
- unsigned long n_pages = obj->base.size >> PAGE_SHIFT;
+ unsigned long n_pte = obj->base.size >> PAGE_SHIFT;
struct sg_table *sgt = obj->mm.pages;
- struct sgt_iter sgt_iter;
- struct page *page;
- struct page *stack_pages[32];
- struct page **pages = stack_pages;
- unsigned long i = 0;
+ pte_t *stack[32], **mem;
+ struct vm_struct *area;
pgprot_t pgprot;
- void *addr;
- if (i915_gem_object_is_lmem(obj)) {
- void __iomem *io;
-
- if (type != I915_MAP_WC)
- return NULL;
-
- io = i915_gem_object_lmem_io_map(obj, 0, obj->base.size);
- return (void __force *)io;
- }
+ if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
+ return NULL;
/* A single page can always be kmapped */
- if (n_pages == 1 && type == I915_MAP_WB)
+ if (n_pte == 1 && type == I915_MAP_WB)
return kmap(sg_page(sgt->sgl));
- if (n_pages > ARRAY_SIZE(stack_pages)) {
+ mem = stack;
+ if (n_pte > ARRAY_SIZE(stack)) {
/* Too big for stack -- allocate temporary array instead */
- pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL);
- if (!pages)
+ mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL);
+ if (!mem)
return NULL;
}
- for_each_sgt_page(page, sgt_iter, sgt)
- pages[i++] = page;
-
- /* Check that we have the expected number of pages */
- GEM_BUG_ON(i != n_pages);
+ area = alloc_vm_area(obj->base.size, mem);
+ if (!area) {
+ if (mem != stack)
+ kvfree(mem);
+ return NULL;
+ }
switch (type) {
default:
@@ -288,12 +284,31 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
pgprot = pgprot_writecombine(PAGE_KERNEL_IO);
break;
}
- addr = vmap(pages, n_pages, 0, pgprot);
- if (pages != stack_pages)
- kvfree(pages);
+ if (i915_gem_object_has_struct_page(obj)) {
+ struct sgt_iter iter;
+ struct page *page;
+ pte_t **ptes = mem;
+
+ for_each_sgt_page(page, iter, sgt)
+ **ptes++ = mk_pte(page, pgprot);
+ } else {
+ resource_size_t iomap;
+ struct sgt_iter iter;
+ pte_t **ptes = mem;
+ dma_addr_t addr;
+
+ iomap = obj->mm.region->iomap.base;
+ iomap -= obj->mm.region->region.start;
+
+ for_each_sgt_daddr(addr, iter, sgt)
+ **ptes++ = iomap_pte(iomap, addr, pgprot);
+ }
+
+ if (mem != stack)
+ kvfree(mem);
- return addr;
+ return area->addr;
}
/* get, pin, and map the pages of the object into kernel space */
OpenPOWER on IntegriCloud