Implement proper front door loading for vpe 6.1.
Signed-off-by: Lang Yu <Lang.Yu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
        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;
 
        AMDGPU_UCODE_ID_DMCUB,
        AMDGPU_UCODE_ID_VPE_CTX,
        AMDGPU_UCODE_ID_VPE_CTL,
+       AMDGPU_UCODE_ID_VPE,
        AMDGPU_UCODE_ID_MAXIMUM,
 };
 
 
 
 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;
        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;
 
        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;
 }
 
 
        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);
 
        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
 };
 
 
        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 */