Skip to content

Commit ff5f643

Browse files
drobson-imgtecmripard
authored andcommitted
drm/imagination: Add GEM and VM related code
Add a GEM implementation based on drm_gem_shmem, and support code for the PowerVR GPU MMU. The GPU VA manager is used for address space management. Changes since v8: - Updated for changes to drm_gpuvm - Switched to dma_resv locking for vm ops - Removed linked lists for collecting BOs in vm_context and for freeing after ops. This is now done internally in drm_gpuvm - Corrected license identifiers Changes since v7: - kernel-doc fixes - Remove prefixes from DRM_PVR_BO_* flags - CREATE_BO ioctl now returns an error if provided size isn't page aligned - Optimised MMU flushes Changes since v6: - Don't initialise kernel_vm_ctx when using MIPS firmware processor - Rename drm_gpuva_manager uses to drm_gpuvm - Sync GEM object to device on creation Changes since v5: - Use WRITE_ONCE() when writing to page tables - Add memory barriers to page table insertion - Fixed double backing page alloc on page table objects - Fix BO mask checks in DRM_IOCTL_PVR_CREATE_BO handler - Document use of pvr_page_table_*_idx when preallocing page table objs - Remove pvr_vm_gpuva_mapping_init() - Remove NULL check for unmap op in remap function - Protect gem object with mutex during drm_gpuva_link/unlink - Defer free or release of page table pages until after TLB flush - Use drm_gpuva_op_remap_get_unmap_range() helper Changes since v4: - Correct sync function in vmap/vunmap function documentation - Update for upstream GPU VA manager - Fix missing frees when unmapping drm_gpuva objects - Always zero GEM BOs on creation Changes since v3: - Split MMU and VM code - Register page table allocations with kmemleak - Use drm_dev_{enter,exit} Changes since v2: - Use GPU VA manager - Use drm_gem_shmem Co-developed-by: Matt Coster <[email protected]> Signed-off-by: Matt Coster <[email protected]> Co-developed-by: Donald Robson <[email protected]> Signed-off-by: Donald Robson <[email protected]> Signed-off-by: Sarah Walker <[email protected]> Link: https://lore.kernel.org/r/3c96dd170efe759b73897e3675d7310a7c4b06d0.1700668843.git.donald.robson@imgtec.com Signed-off-by: Maxime Ripard <[email protected]>
1 parent f99f5f3 commit ff5f643

File tree

11 files changed

+4756
-11
lines changed

11 files changed

+4756
-11
lines changed

drivers/gpu/drm/imagination/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ config DRM_POWERVR
77
depends on DRM
88
select DRM_GEM_SHMEM_HELPER
99
select DRM_SCHED
10+
select DRM_GPUVM
1011
select FW_LOADER
1112
help
1213
Choose this option if you have a system that has an Imagination

drivers/gpu/drm/imagination/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ powervr-y := \
77
pvr_device.o \
88
pvr_device_info.o \
99
pvr_drv.o \
10-
pvr_fw.o
10+
pvr_fw.o \
11+
pvr_gem.o \
12+
pvr_mmu.o \
13+
pvr_vm.o
1114

1215
obj-$(CONFIG_DRM_POWERVR) += powervr.o

drivers/gpu/drm/imagination/pvr_device.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "pvr_fw.h"
88
#include "pvr_rogue_cr_defs.h"
9+
#include "pvr_vm.h"
910

1011
#include <drm/drm_print.h>
1112

@@ -312,7 +313,30 @@ pvr_device_gpu_init(struct pvr_device *pvr_dev)
312313
else
313314
return -EINVAL;
314315

315-
return pvr_set_dma_info(pvr_dev);
316+
err = pvr_set_dma_info(pvr_dev);
317+
if (err)
318+
return err;
319+
320+
if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) {
321+
pvr_dev->kernel_vm_ctx = pvr_vm_create_context(pvr_dev, false);
322+
if (IS_ERR(pvr_dev->kernel_vm_ctx))
323+
return PTR_ERR(pvr_dev->kernel_vm_ctx);
324+
}
325+
326+
return 0;
327+
}
328+
329+
/**
330+
* pvr_device_gpu_fini() - GPU-specific deinitialization for a PowerVR device
331+
* @pvr_dev: Target PowerVR device.
332+
*/
333+
static void
334+
pvr_device_gpu_fini(struct pvr_device *pvr_dev)
335+
{
336+
if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) {
337+
WARN_ON(!pvr_vm_context_put(pvr_dev->kernel_vm_ctx));
338+
pvr_dev->kernel_vm_ctx = NULL;
339+
}
316340
}
317341

318342
/**
@@ -364,6 +388,7 @@ pvr_device_fini(struct pvr_device *pvr_dev)
364388
* Deinitialization stages are performed in reverse order compared to
365389
* the initialization stages in pvr_device_init().
366390
*/
391+
pvr_device_gpu_fini(pvr_dev);
367392
}
368393

369394
bool

drivers/gpu/drm/imagination/pvr_device.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,24 @@ struct pvr_device {
123123
*/
124124
struct clk *mem_clk;
125125

126+
/**
127+
* @kernel_vm_ctx: Virtual memory context used for kernel mappings.
128+
*
129+
* This is used for mappings in the firmware address region when a META firmware processor
130+
* is in use.
131+
*
132+
* When a MIPS firmware processor is in use, this will be %NULL.
133+
*/
134+
struct pvr_vm_context *kernel_vm_ctx;
135+
126136
/** @fw_dev: Firmware related data. */
127137
struct pvr_fw_device fw_dev;
138+
139+
/**
140+
* @mmu_flush_cache_flags: Records which MMU caches require flushing
141+
* before submitting the next job.
142+
*/
143+
atomic_t mmu_flush_cache_flags;
128144
};
129145

130146
/**
@@ -145,6 +161,14 @@ struct pvr_file {
145161
* to_pvr_device().
146162
*/
147163
struct pvr_device *pvr_dev;
164+
165+
/**
166+
* @vm_ctx_handles: Array of VM contexts belonging to this file. Array
167+
* members are of type "struct pvr_vm_context *".
168+
*
169+
* This array is used to allocate handles returned to userspace.
170+
*/
171+
struct xarray vm_ctx_handles;
148172
};
149173

150174
/**

0 commit comments

Comments
 (0)