diff options
Diffstat (limited to 'src/soc/amd')
-rw-r--r-- | src/soc/amd/common/block/psp/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/bootblock/bootblock.c | 33 | ||||
-rw-r--r-- | src/soc/amd/stoneyridge/chip.c | 9 |
3 files changed, 41 insertions, 2 deletions
diff --git a/src/soc/amd/common/block/psp/Makefile.inc b/src/soc/amd/common/block/psp/Makefile.inc index eebba16e6a..d5f93869c8 100644 --- a/src/soc/amd/common/block/psp/Makefile.inc +++ b/src/soc/amd/common/block/psp/Makefile.inc @@ -1,2 +1,3 @@ +bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_PSP) += psp.c diff --git a/src/soc/amd/stoneyridge/bootblock/bootblock.c b/src/soc/amd/stoneyridge/bootblock/bootblock.c index 461f32dbff..abe06fbd24 100644 --- a/src/soc/amd/stoneyridge/bootblock/bootblock.c +++ b/src/soc/amd/stoneyridge/bootblock/bootblock.c @@ -24,7 +24,10 @@ #include <bootblock_common.h> #include <agesawrapper.h> #include <agesawrapper_call.h> +#include <soc/pci_devs.h> +#include <soc/northbridge.h> #include <soc/southbridge.h> +#include <amdblocks/psp.h> asmlinkage void bootblock_c_entry(uint64_t base_timestamp) { @@ -74,6 +77,33 @@ void bootblock_soc_early_init(void) configure_stoneyridge_uart(); } +/* + * This step is in bootblock because the SMU FW1 must be loaded prior to + * issuing any reset to the system. Set up just enough to get the command + * to the PSP. A side effect of placing this step here is we will always + * load a RO version of FW1 and never a RW version. + * + * todo: If AMD develops a more robust methodology, move this function to + * romstage. + */ +static void load_smu_fw1(void) +{ + u32 base, limit; + + /* Open a posted hole from 0x80000000 : 0xfed00000-1 */ + base = 0x80000000; + base = (0x80000000 >> 8) | MMIO_WE | MMIO_RE; + limit = (ALIGN_DOWN(HPET_BASE_ADDRESS - 1, 64 * KiB) >> 8); + pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_LIMIT0_LO, limit); + pci_write_config32(SOC_ADDR_DEV, D18F1_MMIO_BASE0_LO, base); + + /* Preload a value into "BAR3" and enable it */ + pci_write_config32(SOC_PSP_DEV, PSP_MAILBOX_BAR, PSP_MAILBOX_BAR3_BASE); + pci_write_config32(SOC_PSP_DEV, PSP_BAR_ENABLES, PSP_MAILBOX_BAR_EN); + + psp_load_named_blob(MBOX_BIOS_CMD_SMU_FW, "smu_fw"); +} + void bootblock_soc_init(void) { if (IS_ENABLED(CONFIG_STONEYRIDGE_UART)) @@ -83,6 +113,9 @@ void bootblock_soc_init(void) u32 val = cpuid_eax(1); printk(BIOS_DEBUG, "Family_Model: %08x\n", val); + if (boot_cpu() && IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW)) + load_smu_fw1(); + post_code(0x37); AGESAWRAPPER(amdinitreset); diff --git a/src/soc/amd/stoneyridge/chip.c b/src/soc/amd/stoneyridge/chip.c index 622e72c274..8e4ab2ee88 100644 --- a/src/soc/amd/stoneyridge/chip.c +++ b/src/soc/amd/stoneyridge/chip.c @@ -23,6 +23,7 @@ #include <soc/cpu.h> #include <soc/northbridge.h> #include <soc/southbridge.h> +#include <amdblocks/psp.h> #include <agesawrapper.h> #include <agesawrapper_call.h> @@ -78,10 +79,14 @@ struct chip_operations soc_amd_stoneyridge_ops = { .final = &soc_final }; -static void do_initenv(void *unused) +static void earliest_ramstage(void *unused) { post_code(0x46); + if (IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW)) + psp_load_named_blob(MBOX_BIOS_CMD_SMU_FW2, "smu_fw2"); + + post_code(0x47); AGESAWRAPPER(amdinitenv); } -BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, do_initenv, NULL); +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, earliest_ramstage, NULL); |