Blob Blame History Raw
From 5ba589709506d79efa3a04f61b0169e06cc08995 Mon Sep 17 00:00:00 2001
From: Likun Gao <Likun.Gao@amd.com>
Date: Thu, 5 May 2022 15:45:06 -0400
Subject: drm/amdgpu: add sysfs to shows psp vbflash status
Git-commit: dfc53681de592d31a6de894c9b9afb14634ec6aa
Patch-mainline: v5.19-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225

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>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 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  | 18 ++++++++++++++++--
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 78320f2566e5..d01050808626 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..d6d79e97def9 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) {
@@ -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)
-- 
2.38.1