From: Likun Gao <Likun.Gao@xxxxxxx> Add new sysfs interface to shows the status of psp vbflash status. V2: rename the sysfs interface, and set more return value. (0: not start; 1: in progress; MBX115 value when vbflash finish) V3: warning fixes Signed-off-by: Likun Gao <Likun.Gao@xxxxxxx> Reviewed-by: Hawking Zhang <Hawking.Zhang@xxxxxxx> Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 25 +++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 6 ++++++ drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 15 ++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 7d0a37a94ea6..1f3f93e9eeb3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -3453,6 +3453,8 @@ static ssize_t amdgpu_psp_vbflash_write(struct file *filp, struct kobject *kobj, struct drm_device *ddev = dev_get_drvdata(dev); struct amdgpu_device *adev = drm_to_adev(ddev); + adev->psp.vbflash_done = false; + /* Safeguard against memory drain */ if (adev->psp.vbflash_image_size > AMD_VBIOS_FILE_MAX_SIZE_B) { dev_err(adev->dev, "File size cannot exceed %u", AMD_VBIOS_FILE_MAX_SIZE_B); @@ -3524,6 +3526,23 @@ static ssize_t amdgpu_psp_vbflash_read(struct file *filp, struct kobject *kobj, return 0; } +static ssize_t amdgpu_psp_vbflash_status(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = drm_to_adev(ddev); + uint32_t vbflash_status; + + vbflash_status = psp_vbflash_status(&adev->psp); + if (!adev->psp.vbflash_done) + vbflash_status = 0; + else if (adev->psp.vbflash_done && !(vbflash_status & 0x80000000)) + vbflash_status = 1; + + return sysfs_emit(buf, "0x%x\n", vbflash_status); +} + static const struct bin_attribute psp_vbflash_bin_attr = { .attr = {.name = "psp_vbflash", .mode = 0664}, .size = 0, @@ -3531,6 +3550,8 @@ static const struct bin_attribute psp_vbflash_bin_attr = { .read = amdgpu_psp_vbflash_read, }; +static DEVICE_ATTR(psp_vbflash_status, 0444, amdgpu_psp_vbflash_status, NULL); + int amdgpu_psp_sysfs_init(struct amdgpu_device *adev) { int ret = 0; @@ -3549,6 +3570,9 @@ int amdgpu_psp_sysfs_init(struct amdgpu_device *adev) ret = sysfs_create_bin_file(&adev->dev->kobj, &psp_vbflash_bin_attr); if (ret) dev_err(adev->dev, "Failed to create device file psp_vbflash"); + ret = device_create_file(adev->dev, &dev_attr_psp_vbflash_status); + if (ret) + dev_err(adev->dev, "Failed to create device file psp_vbflash_status"); return ret; default: return 0; @@ -3586,6 +3610,7 @@ static int psp_sysfs_init(struct amdgpu_device *adev) void amdgpu_psp_sysfs_fini(struct amdgpu_device *adev) { sysfs_remove_bin_file(&adev->dev->kobj, &psp_vbflash_bin_attr); + device_remove_file(adev->dev, &dev_attr_psp_vbflash_status); } static void psp_sysfs_fini(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index db7b7dbb9c93..e431f4994931 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -130,6 +130,7 @@ struct psp_funcs int (*load_usbc_pd_fw)(struct psp_context *psp, uint64_t fw_pri_mc_addr); int (*read_usbc_pd_fw)(struct psp_context *psp, uint32_t *fw_ver); int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr); + int (*vbflash_stat)(struct psp_context *psp); }; #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 @@ -375,6 +376,7 @@ struct psp_context char *vbflash_tmp_buf; size_t vbflash_image_size; + bool vbflash_done; }; struct amdgpu_psp_funcs { @@ -425,6 +427,10 @@ struct amdgpu_psp_funcs { ((psp)->funcs->update_spirom ? \ (psp)->funcs->update_spirom((psp), fw_pri_mc_addr) : -EINVAL) +#define psp_vbflash_status(psp) \ + ((psp)->funcs->vbflash_stat ? \ + (psp)->funcs->vbflash_stat((psp)) : -EINVAL) + extern const struct amd_ip_funcs psp_ip_funcs; extern const struct amdgpu_ip_block_version psp_v3_1_ip_block; diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index 894ac0c64bf6..c14abd9dd41e 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -487,6 +487,9 @@ static int psp_v13_0_exec_spi_cmd(struct psp_context *psp, int cmd) /* Ring the doorbell */ WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_73, 1); + if (cmd == C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE) + return 0; + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115), MBOX_READY_FLAG, MBOX_READY_MASK, false); if (ret) { @@ -529,6 +532,8 @@ int psp_v13_0_update_spirom(struct psp_context *psp, uint64_t fw_pri_mc_addr) if (ret) return ret; + psp->vbflash_done = true; + ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE); if (ret) return ret; @@ -536,6 +541,13 @@ int psp_v13_0_update_spirom(struct psp_context *psp, uint64_t fw_pri_mc_addr) return 0; } +int psp_v13_0_vbflash_status(struct psp_context *psp) +{ + struct amdgpu_device *adev = psp->adev; + + return RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_115); +} + static const struct psp_funcs psp_v13_0_funcs = { .init_microcode = psp_v13_0_init_microcode, .bootloader_load_kdb = psp_v13_0_bootloader_load_kdb, @@ -553,7 +565,8 @@ static const struct psp_funcs psp_v13_0_funcs = { .ring_set_wptr = psp_v13_0_ring_set_wptr, .load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw, .read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw, - .update_spirom = psp_v13_0_update_spirom + .update_spirom = psp_v13_0_update_spirom, + .vbflash_stat = psp_v13_0_vbflash_status }; void psp_v13_0_set_psp_funcs(struct psp_context *psp) -- 2.35.1