diff options
| author | Sarah Walker <sarah.walker@imgtec.com> | 2023-11-22 16:34:34 +0000 |
|---|---|---|
| committer | Maxime Ripard <mripard@kernel.org> | 2023-11-23 09:01:46 +0100 |
| commit | cc1aeedb98ad347c06ff59e991b2f94dfb4c565d (patch) | |
| tree | 8ab0d584a8950ce0bbcb6f49d8c6b3f6335fa9e5 /drivers/gpu/drm/imagination/pvr_vm.c | |
| parent | 727538a4bbff07736ecfd704efd7e21718fca3e4 (diff) | |
drm/imagination: Implement firmware infrastructure and META FW support
The infrastructure includes parsing of the firmware image, initialising
FW-side structures, handling the kernel and firmware command
ringbuffers and starting & stopping the firmware processor.
This patch also adds the necessary support code for the META firmware
processor.
Changes since v8:
- Fix documentation for pvr_fwccb_process()
- Corrected license identifiers
Changes since v6:
- Add a minimum retry count to pvr_kccb_reserve_slot_sync()
Changes since v5:
- Add workaround for BRN 71242
- Attempt to recover GPU on MMU flush command failure
Changes since v4:
- Remove use of drm_gem_shmem_get_pages()
- Remove interrupt resource name
Changes since v3:
- Hard reset FW processor on watchdog timeout
- Switch to threaded IRQ
- Rework FW object creation/initialisation to aid hard reset
- Added MODULE_FIRMWARE()
- Use drm_dev_{enter,exit}
Signed-off-by: Sarah Walker <sarah.walker@imgtec.com>
Signed-off-by: Donald Robson <donald.robson@imgtec.com>
Link: https://lore.kernel.org/r/bb52a8dc84f296b37dc6668dfe8fbaf2ba551139.1700668843.git.donald.robson@imgtec.com
Signed-off-by: Maxime Ripard <mripard@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/imagination/pvr_vm.c')
| -rw-r--r-- | drivers/gpu/drm/imagination/pvr_vm.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/gpu/drm/imagination/pvr_vm.c b/drivers/gpu/drm/imagination/pvr_vm.c index 4c48a208c390..3ad1366294b9 100644 --- a/drivers/gpu/drm/imagination/pvr_vm.c +++ b/drivers/gpu/drm/imagination/pvr_vm.c @@ -540,6 +540,16 @@ static const struct drm_gpuvm_ops pvr_vm_gpuva_ops = { .sm_step_unmap = pvr_vm_gpuva_unmap, }; +static void +fw_mem_context_init(void *cpu_ptr, void *priv) +{ + struct rogue_fwif_fwmemcontext *fw_mem_ctx = cpu_ptr; + struct pvr_vm_context *vm_ctx = priv; + + fw_mem_ctx->pc_dev_paddr = pvr_vm_get_page_table_root_addr(vm_ctx); + fw_mem_ctx->page_cat_base_reg_set = ROGUE_FW_BIF_INVALID_PCSET; +} + /** * pvr_vm_create_context() - Create a new VM context. * @pvr_dev: Target PowerVR device. @@ -602,13 +612,19 @@ pvr_vm_create_context(struct pvr_device *pvr_dev, bool is_userspace_context) } if (is_userspace_context) { - /* TODO: Create FW mem context */ - err = -ENODEV; - goto err_put_ctx; + err = pvr_fw_object_create(pvr_dev, sizeof(struct rogue_fwif_fwmemcontext), + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, + fw_mem_context_init, vm_ctx, &vm_ctx->fw_mem_ctx_obj); + + if (err) + goto err_page_table_destroy; } return vm_ctx; +err_page_table_destroy: + pvr_mmu_context_destroy(vm_ctx->mmu_ctx); + err_put_ctx: pvr_vm_context_put(vm_ctx); @@ -628,8 +644,8 @@ pvr_vm_context_release(struct kref *ref_count) struct pvr_vm_context *vm_ctx = container_of(ref_count, struct pvr_vm_context, ref_count); - /* TODO: Destroy FW mem context */ - WARN_ON(vm_ctx->fw_mem_ctx_obj); + if (vm_ctx->fw_mem_ctx_obj) + pvr_fw_object_destroy(vm_ctx->fw_mem_ctx_obj); WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start, vm_ctx->gpuvm_mgr.mm_range)); |
