From: Lang Yu <Lang.Yu@xxxxxxx> Implement proper front door loading for vpe 6.1. Signed-off-by: Lang Yu <Lang.Yu@xxxxxxx> Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 3 ++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c | 38 +++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h | 5 +++ drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h | 1 + drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c | 15 +++++++++ 6 files changed, 63 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 0eef555e3ef8..bd70715d329f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2396,6 +2396,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode, case AMDGPU_UCODE_ID_VPE_CTL: *type = GFX_FW_TYPE_VPEC_FW2; break; + case AMDGPU_UCODE_ID_VPE: + *type = GFX_FW_TYPE_VPE; + break; case AMDGPU_UCODE_ID_MAXIMUM: default: return -EINVAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index 0b601efa2944..4db6d0090893 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -489,6 +489,7 @@ enum AMDGPU_UCODE_ID { AMDGPU_UCODE_ID_DMCUB, AMDGPU_UCODE_ID_VPE_CTX, AMDGPU_UCODE_ID_VPE_CTL, + AMDGPU_UCODE_ID_VPE, AMDGPU_UCODE_ID_MAXIMUM, }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c index a84e03a9b0fc..ae070072705a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c @@ -37,6 +37,17 @@ static void vpe_set_ring_funcs(struct amdgpu_device *adev); +int amdgpu_vpe_psp_update_sram(struct amdgpu_device *adev) +{ + struct amdgpu_firmware_info ucode = { + .ucode_id = AMDGPU_UCODE_ID_VPE, + .mc_addr = adev->vpe.cmdbuf_gpu_addr, + .ucode_size = 8, + }; + + return psp_execute_ip_fw_load(&adev->psp, &ucode); +} + int amdgpu_vpe_init_microcode(struct amdgpu_vpe *vpe) { struct amdgpu_device *adev = vpe->ring.adev; @@ -126,12 +137,35 @@ static int vpe_early_init(void *handle) return 0; } + +static int vpe_common_init(struct amdgpu_vpe *vpe) +{ + struct amdgpu_device *adev = container_of(vpe, struct amdgpu_device, vpe); + int r; + + r = amdgpu_bo_create_kernel(adev, PAGE_SIZE, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_GTT, + &adev->vpe.cmdbuf_obj, + &adev->vpe.cmdbuf_gpu_addr, + (void **)&adev->vpe.cmdbuf_cpu_addr); + if (r) { + dev_err(adev->dev, "VPE: failed to allocate cmdbuf bo %d\n", r); + return r; + } + + return 0; +} + static int vpe_sw_init(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_vpe *vpe = &adev->vpe; int ret; + ret = vpe_common_init(vpe); + if (ret) + goto out; + ret = vpe_irq_init(vpe); if (ret) goto out; @@ -157,6 +191,10 @@ static int vpe_sw_fini(void *handle) vpe_ring_fini(vpe); + amdgpu_bo_free_kernel(&adev->vpe.cmdbuf_obj, + &adev->vpe.cmdbuf_gpu_addr, + (void **)&adev->vpe.cmdbuf_cpu_addr); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h index 010fa7f308fd..b590205d6a28 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.h @@ -59,8 +59,13 @@ struct amdgpu_vpe { const struct firmware *fw; uint32_t fw_version; uint32_t feature_version; + + struct amdgpu_bo *cmdbuf_obj; + uint64_t cmdbuf_gpu_addr; + uint32_t *cmdbuf_cpu_addr; }; +int amdgpu_vpe_psp_update_sram(struct amdgpu_device *adev); int amdgpu_vpe_init_microcode(struct amdgpu_vpe *vpe); int amdgpu_vpe_ring_init(struct amdgpu_vpe *vpe); int amdgpu_vpe_ring_fini(struct amdgpu_vpe *vpe); diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h index fd11115429c8..dfd60db97012 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h @@ -295,6 +295,7 @@ enum psp_gfx_fw_type { GFX_FW_TYPE_RS64_MEC_P3_STACK = 97, /* RS64 MEC stack P3 SOC21 */ GFX_FW_TYPE_VPEC_FW1 = 100, /* VPEC FW1 To Save VPE */ GFX_FW_TYPE_VPEC_FW2 = 101, /* VPEC FW2 To Save VPE */ + GFX_FW_TYPE_VPE = 102, GFX_FW_TYPE_MAX }; diff --git a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c index 1a483d38e70d..1259b150dc96 100644 --- a/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vpe_v6_1.c @@ -84,6 +84,21 @@ static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe) ret = REG_SET_FIELD(ret, VPEC_CNTL, UMSCH_INT_ENABLE, 0); WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL), ret); + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + uint32_t f32_offset, f32_cntl; + + f32_offset = vpe_get_reg_offset(vpe, 0, regVPEC_F32_CNTL); + f32_cntl = RREG32(f32_offset); + f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, HALT, 0); + f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, TH1_RESET, 0); + + adev->vpe.cmdbuf_cpu_addr[0] = f32_offset; + adev->vpe.cmdbuf_cpu_addr[1] = f32_cntl; + + amdgpu_vpe_psp_update_sram(adev); + return 0; + } + vpe_hdr = (const struct vpe_firmware_header_v1_0 *)adev->vpe.fw->data; /* Thread 0(command thread) ucode offset/size */ -- 2.41.0