]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/amdgpu: add sysfs to shows psp vbflash status
authorLikun Gao <Likun.Gao@amd.com>
Thu, 5 May 2022 19:45:06 +0000 (15:45 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 10 May 2022 21:53:10 +0000 (17:53 -0400)
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@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
drivers/gpu/drm/amd/amdgpu/psp_v13_0.c

index 78320f2566e501d649b3297d4083067ea907a601..d01050808626ad4f7478d75b6866193ecaccbd8a 100644 (file)
@@ -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 @@ rel_buf:
        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)
index db7b7dbb9c9386905f28329c2afc35d809d62f0e..e431f49949319aa8f388f91a5681d1356f300102 100644 (file)
@@ -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;
index 894ac0c64bf64c1115275dff28867f91742daef6..d6d79e97def99056b6d4bd5c712ecd2bb860ccc3 100644 (file)
@@ -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) {
@@ -504,7 +507,8 @@ static int psp_v13_0_exec_spi_cmd(struct psp_context *psp, int cmd)
        return 0;
 }
 
-int psp_v13_0_update_spirom(struct psp_context *psp, uint64_t fw_pri_mc_addr)
+static int psp_v13_0_update_spirom(struct psp_context *psp,
+                                  uint64_t fw_pri_mc_addr)
 {
        struct amdgpu_device *adev = psp->adev;
        int ret;
@@ -529,6 +533,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 +542,13 @@ int psp_v13_0_update_spirom(struct psp_context *psp, uint64_t fw_pri_mc_addr)
        return 0;
 }
 
+static 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 +566,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)