diff --git a/src/soc/amd/common/block/include/amdblocks/psp.h b/src/soc/amd/common/block/include/amdblocks/psp.h index a1c1152af9..91c96e1b0c 100644 --- a/src/soc/amd/common/block/include/amdblocks/psp.h +++ b/src/soc/amd/common/block/include/amdblocks/psp.h @@ -67,6 +67,12 @@ enum psp_blob_type { BLOB_SMU_FW2, }; +/* + * Notify PSP that the system is entering a sleep state. sleep_state uses the + * same definition as Pm1Cnt[SlpTyp], typically 0, 1, 3, 4, 5. + */ +void psp_notify_sx_info(u8 sleep_type); + int psp_load_named_blob(enum psp_blob_type type, const char *name); #endif /* __AMD_PSP_H__ */ diff --git a/src/soc/amd/common/block/psp/psp_def.h b/src/soc/amd/common/block/psp/psp_def.h index 63ca3abb0a..7772ca6bda 100644 --- a/src/soc/amd/common/block/psp/psp_def.h +++ b/src/soc/amd/common/block/psp/psp_def.h @@ -9,18 +9,19 @@ #include /* x86 to PSP commands */ -#define MBOX_BIOS_CMD_DRAM_INFO 0x01 -#define MBOX_BIOS_CMD_SMM_INFO 0x02 -#define MBOX_BIOS_CMD_SX_INFO 0x03 -#define MBOX_BIOS_CMD_RSM_INFO 0x04 -#define MBOX_BIOS_CMD_PSP_QUERY 0x05 -#define MBOX_BIOS_CMD_BOOT_DONE 0x06 -#define MBOX_BIOS_CMD_CLEAR_S3_STS 0x07 -#define MBOX_BIOS_CMD_S3_DATA_INFO 0x08 -#define MBOX_BIOS_CMD_NOP 0x09 -#define MBOX_BIOS_CMD_SMU_FW 0x19 -#define MBOX_BIOS_CMD_SMU_FW2 0x1a -#define MBOX_BIOS_CMD_ABORT 0xfe +#define MBOX_BIOS_CMD_DRAM_INFO 0x01 +#define MBOX_BIOS_CMD_SMM_INFO 0x02 +#define MBOX_BIOS_CMD_SX_INFO 0x03 +#define MBOX_BIOS_CMD_SX_INFO_SLEEP_TYPE_MAX 0x07 +#define MBOX_BIOS_CMD_RSM_INFO 0x04 +#define MBOX_BIOS_CMD_PSP_QUERY 0x05 +#define MBOX_BIOS_CMD_BOOT_DONE 0x06 +#define MBOX_BIOS_CMD_CLEAR_S3_STS 0x07 +#define MBOX_BIOS_CMD_S3_DATA_INFO 0x08 +#define MBOX_BIOS_CMD_NOP 0x09 +#define MBOX_BIOS_CMD_SMU_FW 0x19 +#define MBOX_BIOS_CMD_SMU_FW2 0x1a +#define MBOX_BIOS_CMD_ABORT 0xfe /* generic PSP interface status, v1 */ #define PSPV1_STATUS_INITIALIZED BIT(0) diff --git a/src/soc/amd/common/block/psp/psp_smm.c b/src/soc/amd/common/block/psp/psp_smm.c index cc15738881..4ae2277cab 100644 --- a/src/soc/amd/common/block/psp/psp_smm.c +++ b/src/soc/amd/common/block/psp/psp_smm.c @@ -76,3 +76,31 @@ int psp_notify_smm(void) return cmd_status; } + +/* Notify PSP the system is going to a sleep state. */ +void psp_notify_sx_info(u8 sleep_type) +{ + int cmd_status; + struct mbox_cmd_sx_info_buffer *buffer; + + /* PSP verifies that this buffer is at the address specified in psp_notify_smm() */ + buffer = (struct mbox_cmd_sx_info_buffer *)c2p_buffer.buffer; + memset(buffer, 0, sizeof(*buffer)); + buffer->header.size = sizeof(*buffer); + + if (sleep_type > MBOX_BIOS_CMD_SX_INFO_SLEEP_TYPE_MAX) { + printk(BIOS_ERR, "PSP: BUG: invalid sleep type 0x%x requested\n", sleep_type); + return; + } + + printk(BIOS_DEBUG, "PSP: Prepare to enter sleep state %d... ", sleep_type); + + buffer->sleep_type = sleep_type; + + set_smm_flag(); + cmd_status = send_psp_command(MBOX_BIOS_CMD_SX_INFO, buffer); + clear_smm_flag(); + + /* buffer's status shouldn't change but report it if it does */ + psp_print_cmd_status(cmd_status, (struct mbox_default_buffer *)buffer); +}