soc/amd/common: factor out SMN access function from SMU code

The SMU mailbox interface gets accessed over the SMN register space, so
factor out those access functions into a separate common code SMN access
building block.

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: Iabac181972c02ae641da99f47b2aa9aa28dae333
Reviewed-on: https://review.coreboot.org/c/coreboot/+/51399
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com>
This commit is contained in:
Felix Held 2021-03-10 22:55:22 +01:00
parent 5a702653cd
commit e995684fa1
7 changed files with 52 additions and 23 deletions

View File

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef AMD_BLOCK_SMN_H
#define AMD_BLOCK_SMN_H
#include <types.h>
uint32_t smn_read32(uint32_t reg);
void smn_write32(uint32_t reg, uint32_t val);
#endif /* AMD_BLOCK_SMN_H */

View File

@ -6,10 +6,6 @@
#include <types.h> #include <types.h>
#include <soc/smu.h> /* SoC-dependent definitions for SMU access */ #include <soc/smu.h> /* SoC-dependent definitions for SMU access */
/* SMU registers accessed indirectly using an index/data pair in D0F00 config space */
#define SMU_INDEX_ADDR 0xb8 /* 32 bit */
#define SMU_DATA_ADDR 0xbc /* 32 bit */
/* Arguments indexed locations are contiguous; the number is SoC-dependent */ /* Arguments indexed locations are contiguous; the number is SoC-dependent */
#define REG_ADDR_MESG_ARG(x) (REG_ADDR_MESG_ARGS_BASE + ((x) * sizeof(uint32_t))) #define REG_ADDR_MESG_ARG(x) (REG_ADDR_MESG_ARGS_BASE + ((x) * sizeof(uint32_t)))

View File

@ -0,0 +1,4 @@
config SOC_AMD_COMMON_BLOCK_SMN
bool
help
Select this option to add functions to access the SMN register space to the build.

View File

@ -0,0 +1,8 @@
ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_SMN),y)
bootblock-y += smn.c
romstage-y += smn.c
ramstage-y += smn.c
smm-y += smn.c
endif # CONFIG_SOC_AMD_COMMON_BLOCK_SMN

View File

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <amdblocks/smn.h>
#include <device/pci_ops.h>
#include <soc/pci_devs.h>
#include <types.h>
/* SMN registers accessed indirectly using an index/data pair in D0F00 config space */
#define SMN_INDEX_ADDR 0xb8 /* 32 bit */
#define SMN_DATA_ADDR 0xbc /* 32 bit */
uint32_t smn_read32(uint32_t reg)
{
pci_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg);
return pci_read_config32(SOC_GNB_DEV, SMN_DATA_ADDR);
}
void smn_write32(uint32_t reg, uint32_t val)
{
pci_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg);
pci_write_config32(SOC_GNB_DEV, SMN_DATA_ADDR, val);
}

View File

@ -1,4 +1,5 @@
config SOC_AMD_COMMON_BLOCK_SMU config SOC_AMD_COMMON_BLOCK_SMU
bool bool
select SOC_AMD_COMMON_BLOCK_SMN
help help
Select this option to add functions to communicate with the SMU to the build. Select this option to add functions to communicate with the SMU to the build.

View File

@ -2,24 +2,11 @@
#include <timer.h> #include <timer.h>
#include <console/console.h> #include <console/console.h>
#include <device/pci_ops.h> #include <amdblocks/smn.h>
#include <amdblocks/smu.h> #include <amdblocks/smu.h>
#include <soc/pci_devs.h>
#include <soc/smu.h> #include <soc/smu.h>
#include <types.h> #include <types.h>
static uint32_t smu_read32(uint32_t reg)
{
pci_write_config32(SOC_GNB_DEV, SMU_INDEX_ADDR, reg);
return pci_read_config32(SOC_GNB_DEV, SMU_DATA_ADDR);
}
static void smu_write32(uint32_t reg, uint32_t val)
{
pci_write_config32(SOC_GNB_DEV, SMU_INDEX_ADDR, reg);
pci_write_config32(SOC_GNB_DEV, SMU_DATA_ADDR, val);
}
#define SMU_MESG_RESP_TIMEOUT 0x00 #define SMU_MESG_RESP_TIMEOUT 0x00
#define SMU_MESG_RESP_OK 0x01 #define SMU_MESG_RESP_OK 0x01
@ -33,7 +20,7 @@ static int32_t smu_poll_response(bool print_command_duration)
stopwatch_init_msecs_expire(&sw, timeout_ms); stopwatch_init_msecs_expire(&sw, timeout_ms);
do { do {
result = smu_read32(REG_ADDR_MESG_RESP); result = smn_read32(REG_ADDR_MESG_RESP);
if (result) { if (result) {
if (print_command_duration) if (print_command_duration)
printk(BIOS_SPEW, "SMU command consumed %ld usecs\n", printk(BIOS_SPEW, "SMU command consumed %ld usecs\n",
@ -59,14 +46,14 @@ enum cb_err send_smu_message(enum smu_message_id message_id, struct smu_payload
return CB_ERR; return CB_ERR;
/* clear response register */ /* clear response register */
smu_write32(REG_ADDR_MESG_RESP, 0); smn_write32(REG_ADDR_MESG_RESP, 0);
/* populate arguments */ /* populate arguments */
for (i = 0 ; i < SMU_NUM_ARGS ; i++) for (i = 0 ; i < SMU_NUM_ARGS ; i++)
smu_write32(REG_ADDR_MESG_ARG(i), arg->msg[i]); smn_write32(REG_ADDR_MESG_ARG(i), arg->msg[i]);
/* send message to SMU */ /* send message to SMU */
smu_write32(REG_ADDR_MESG_ID, message_id); smn_write32(REG_ADDR_MESG_ID, message_id);
/* wait until SMU has processed the message and check if it was successful */ /* wait until SMU has processed the message and check if it was successful */
if (smu_poll_response(true) != SMU_MESG_RESP_OK) if (smu_poll_response(true) != SMU_MESG_RESP_OK)
@ -74,7 +61,7 @@ enum cb_err send_smu_message(enum smu_message_id message_id, struct smu_payload
/* copy returned values */ /* copy returned values */
for (i = 0 ; i < SMU_NUM_ARGS ; i++) for (i = 0 ; i < SMU_NUM_ARGS ; i++)
arg->msg[i] = smu_read32(REG_ADDR_MESG_ARG(i)); arg->msg[i] = smn_read32(REG_ADDR_MESG_ARG(i));
return CB_SUCCESS; return CB_SUCCESS;
} }