Commit 09fffcd9 authored by Andrey Grodzovsky's avatar Andrey Grodzovsky Committed by Alex Deucher

drm/amdgpu/psp: Add VBIOS flash handler

Add psp vbflash function for psp v13.

v2: fix warnings
Signed-off-by: default avatarAndrey Grodzovsky <andrey.grodzovsky@amd.com>
Signed-off-by: default avatarLikun Gao <Likun.Gao@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent bce04f21
...@@ -129,6 +129,7 @@ struct psp_funcs ...@@ -129,6 +129,7 @@ struct psp_funcs
void (*ring_set_wptr)(struct psp_context *psp, uint32_t value); void (*ring_set_wptr)(struct psp_context *psp, uint32_t value);
int (*load_usbc_pd_fw)(struct psp_context *psp, uint64_t fw_pri_mc_addr); 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 (*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);
}; };
#define AMDGPU_XGMI_MAX_CONNECTED_NODES 64 #define AMDGPU_XGMI_MAX_CONNECTED_NODES 64
...@@ -417,6 +418,10 @@ struct amdgpu_psp_funcs { ...@@ -417,6 +418,10 @@ struct amdgpu_psp_funcs {
((psp)->funcs->read_usbc_pd_fw ? \ ((psp)->funcs->read_usbc_pd_fw ? \
(psp)->funcs->read_usbc_pd_fw((psp), fw_ver) : -EINVAL) (psp)->funcs->read_usbc_pd_fw((psp), fw_ver) : -EINVAL)
#define psp_update_spirom(psp, fw_pri_mc_addr) \
((psp)->funcs->update_spirom ? \
(psp)->funcs->update_spirom((psp), fw_pri_mc_addr) : -EINVAL)
extern const struct amd_ip_funcs psp_ip_funcs; extern const struct amd_ip_funcs psp_ip_funcs;
extern const struct amdgpu_ip_block_version psp_v3_1_ip_block; extern const struct amdgpu_ip_block_version psp_v3_1_ip_block;
......
...@@ -50,6 +50,15 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin"); ...@@ -50,6 +50,15 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin");
/* Read USB-PD from LFB */ /* Read USB-PD from LFB */
#define GFX_CMD_USB_PD_USE_LFB 0x480 #define GFX_CMD_USB_PD_USE_LFB 0x480
/* VBIOS gfl defines */
#define MBOX_READY_MASK 0x80000000
#define MBOX_STATUS_MASK 0x0000FFFF
#define MBOX_COMMAND_MASK 0x00FF0000
#define MBOX_READY_FLAG 0x80000000
#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO 0x2
#define C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI 0x3
#define C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE 0x4
static int psp_v13_0_init_microcode(struct psp_context *psp) static int psp_v13_0_init_microcode(struct psp_context *psp)
{ {
struct amdgpu_device *adev = psp->adev; struct amdgpu_device *adev = psp->adev;
...@@ -465,6 +474,68 @@ static int psp_v13_0_read_usbc_pd_fw(struct psp_context *psp, uint32_t *fw_ver) ...@@ -465,6 +474,68 @@ static int psp_v13_0_read_usbc_pd_fw(struct psp_context *psp, uint32_t *fw_ver)
return ret; return ret;
} }
static int psp_v13_0_exec_spi_cmd(struct psp_context *psp, int cmd)
{
uint32_t reg_status = 0, reg_val = 0;
struct amdgpu_device *adev = psp->adev;
int ret;
/* clear MBX ready (MBOX_READY_MASK bit is 0) and set update command */
reg_val |= (cmd << 16);
WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_115, reg_val);
/* Ring the doorbell */
WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_73, 1);
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115),
MBOX_READY_FLAG, MBOX_READY_MASK, false);
if (ret) {
dev_err(adev->dev, "SPI cmd %x timed out, ret = %d", cmd, ret);
return ret;
}
reg_status = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_115);
if ((reg_status & 0xFFFF) != 0) {
dev_err(adev->dev, "SPI cmd %x failed, fail status = %04x\n",
cmd, reg_status & 0xFFFF);
return -EIO;
}
return 0;
}
int psp_v13_0_update_spirom(struct psp_context *psp, uint64_t fw_pri_mc_addr)
{
struct amdgpu_device *adev = psp->adev;
int ret;
/* Confirm PSP is ready to start */
ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_115),
MBOX_READY_FLAG, MBOX_READY_MASK, false);
if (ret) {
dev_err(adev->dev, "PSP Not ready to start processing, ret = %d", ret);
return ret;
}
WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, lower_32_bits(fw_pri_mc_addr));
ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_LO);
if (ret)
return ret;
WREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_116, upper_32_bits(fw_pri_mc_addr));
ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_ROM_IMAGE_ADDR_HI);
if (ret)
return ret;
ret = psp_v13_0_exec_spi_cmd(psp, C2PMSG_CMD_SPI_UPDATE_FLASH_IMAGE);
if (ret)
return ret;
return 0;
}
static const struct psp_funcs psp_v13_0_funcs = { static const struct psp_funcs psp_v13_0_funcs = {
.init_microcode = psp_v13_0_init_microcode, .init_microcode = psp_v13_0_init_microcode,
.bootloader_load_kdb = psp_v13_0_bootloader_load_kdb, .bootloader_load_kdb = psp_v13_0_bootloader_load_kdb,
...@@ -481,7 +552,8 @@ static const struct psp_funcs psp_v13_0_funcs = { ...@@ -481,7 +552,8 @@ static const struct psp_funcs psp_v13_0_funcs = {
.ring_get_wptr = psp_v13_0_ring_get_wptr, .ring_get_wptr = psp_v13_0_ring_get_wptr,
.ring_set_wptr = psp_v13_0_ring_set_wptr, .ring_set_wptr = psp_v13_0_ring_set_wptr,
.load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw, .load_usbc_pd_fw = psp_v13_0_load_usbc_pd_fw,
.read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw .read_usbc_pd_fw = psp_v13_0_read_usbc_pd_fw,
.update_spirom = psp_v13_0_update_spirom
}; };
void psp_v13_0_set_psp_funcs(struct psp_context *psp) void psp_v13_0_set_psp_funcs(struct psp_context *psp)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment