aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/amd/common/block/psp/Makefile.inc1
-rw-r--r--src/soc/amd/stoneyridge/bootblock/bootblock.c33
-rw-r--r--src/soc/amd/stoneyridge/chip.c9
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);