Add user save area parameters to mqd properties for queue creation. Validate the parameters before using for mqd initialization.
Signed-off-by: Lijo Lazar <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 ++++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 24 ++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 5 +++++ drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 14 +++++++++++++ drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 16 +++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index ec2919a9c636..1fb9539f8aca 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -904,6 +904,10 @@ struct amdgpu_mqd_prop { uint64_t fence_address; bool tmz_queue; bool kernel_queue; + /* cwsr params*/ + uint64_t ctx_save_area_addr; + uint32_t ctx_save_area_size; + uint32_t ctl_stack_size; }; struct amdgpu_mqd { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index 2f97f35e0af5..49794b0989ac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -33,6 +33,7 @@ #include "amdgpu_userq.h" #include "amdgpu_hmm.h" #include "amdgpu_userq_fence.h" +#include "amdgpu_cwsr.h" u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev) { @@ -202,6 +203,29 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev, return r; } +int amdgpu_userq_input_cwsr_params_validate( + struct amdgpu_usermode_queue *queue, + struct amdgpu_cwsr_params *cwsr_params) +{ + struct amdgpu_fpriv *fpriv = uq_mgr_to_fpriv(queue->userq_mgr); + struct amdgpu_device *adev = queue->userq_mgr->adev; + uint32_t cwsr_size; + int num_xcc; + int r; + + num_xcc = amdgpu_xcp_get_num_xcc(adev->xcp_mgr, fpriv->xcp_id); + r = amdgpu_cwsr_validate_params(queue->userq_mgr->adev, cwsr_params, + num_xcc); + if (r) + return r; + cwsr_size = amdgpu_cwsr_size_needed(queue->userq_mgr->adev, num_xcc); + if (!cwsr_size) + return -EOPNOTSUPP; + + return amdgpu_userq_input_va_validate( + adev, queue, cwsr_params->ctx_save_area_address, cwsr_size); +} + static bool amdgpu_userq_buffer_va_mapped(struct amdgpu_vm *vm, u64 addr) { struct amdgpu_bo_va_mapping *mapping; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h index 1eaa94f8a291..0eeea9fad0fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h @@ -41,6 +41,7 @@ enum amdgpu_userq_state { }; struct amdgpu_mqd_prop; +struct amdgpu_cwsr_params; struct amdgpu_userq_obj { void *cpu_ptr; @@ -153,4 +154,8 @@ int amdgpu_userq_input_va_validate(struct amdgpu_device *adev, int amdgpu_userq_gem_va_unmap_validate(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping, uint64_t saddr); +int amdgpu_userq_input_cwsr_params_validate( + struct amdgpu_usermode_queue *queue, + struct amdgpu_cwsr_params *cwsr_params); + #endif diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c index f9cae6666697..ad39b33d292a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c @@ -3239,6 +3239,20 @@ static int gfx_v12_0_compute_mqd_init(struct amdgpu_device *adev, void *m, mqd->fence_address_lo = lower_32_bits(prop->fence_address); mqd->fence_address_hi = upper_32_bits(prop->fence_address); + /* If non-zero, assume cwsr is enabled */ + if (prop->ctx_save_area_addr) { + mqd->cp_hqd_persistent_state |= + (1 << CP_HQD_PERSISTENT_STATE__QSWITCH_MODE__SHIFT); + mqd->cp_hqd_ctx_save_base_addr_lo = + lower_32_bits(prop->ctx_save_area_addr); + mqd->cp_hqd_ctx_save_base_addr_hi = + upper_32_bits(prop->ctx_save_area_addr); + mqd->cp_hqd_ctx_save_size = prop->ctx_save_area_size; + mqd->cp_hqd_cntl_stack_size = prop->ctl_stack_size; + mqd->cp_hqd_cntl_stack_offset = prop->ctl_stack_size; + mqd->cp_hqd_wg_state_offset = prop->ctl_stack_size; + } + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index 480f4806e951..0ac87618a86a 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -293,6 +293,7 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) { struct drm_amdgpu_userq_mqd_compute_gfx11 *compute_mqd; + struct amdgpu_cwsr_params cwsr_params; if (mqd_user->mqd_size != sizeof(*compute_mqd)) { DRM_ERROR("Invalid compute IP MQD size\n"); @@ -318,6 +319,21 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, userq_props->hqd_active = false; userq_props->tmz_queue = mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; + + if (amdgpu_cwsr_is_enabled(adev)) { + cwsr_params.ctx_save_area_address = + userq_props->ctx_save_area_addr; + cwsr_params.cwsr_sz = userq_props->ctx_save_area_size; + cwsr_params.ctl_stack_sz = userq_props->ctl_stack_size; + + r = amdgpu_userq_input_cwsr_params_validate( + queue, &cwsr_params); + if (r) { + kfree(compute_mqd); + goto free_mqd; + } + } + kfree(compute_mqd); } else if (queue->queue_type == AMDGPU_HW_IP_GFX) { struct drm_amdgpu_userq_mqd_gfx11 *mqd_gfx_v11; -- 2.49.0
