blob: 8c6fde521a4c594688f14e12ff50356e0d50d58c [file] [log] [blame]
Angel Ponsae593872020-04-04 18:50:57 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Marc Jones24484842017-05-04 21:17:45 -06002
3#include <stdint.h>
Marshall Dawsona5f225f2017-08-18 10:07:07 -06004#include <assert.h>
Marshall Dawson9df969a2017-07-25 18:46:46 -06005#include <console/console.h>
Marshall Dawson154239a2017-11-02 09:49:30 -06006#include <cpu/x86/msr.h>
Elyes HAOUAS400ce552018-10-12 10:54:30 +02007#include <cpu/amd/msr.h>
Marshall Dawson154239a2017-11-02 09:49:30 -06008#include <cpu/x86/mtrr.h>
Marshall Dawson9df969a2017-07-25 18:46:46 -06009#include <smp/node.h>
10#include <bootblock_common.h>
Richard Spiegel0ad74ac2017-12-08 16:53:29 -070011#include <amdblocks/agesawrapper.h>
12#include <amdblocks/agesawrapper_call.h>
Michał Żygowski200d2132019-12-06 12:07:52 +010013#include <amdblocks/amd_pci_mmconf.h>
Michał Żygowski5a662022019-12-02 17:02:00 +010014#include <amdblocks/biosram.h>
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -070015#include <amdblocks/i2c.h>
Marshall Dawsonf5e057c2017-10-12 16:10:14 -060016#include <soc/pci_devs.h>
Marshall Dawsond85c4af2018-03-28 19:48:42 -060017#include <soc/cpu.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060018#include <soc/southbridge.h>
Aaron Durbin51e4c1a2018-01-24 17:42:51 -070019#include <timestamp.h>
Richard Spiegel6d61db02018-04-04 10:35:21 -070020#include <halt.h>
Marc Jones24484842017-05-04 21:17:45 -060021
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -070022#include "chip.h"
23
Marshall Dawsonc4be1752018-05-07 09:59:10 -060024#if CONFIG_PI_AGESA_TEMP_RAM_BASE < 0x100000
25#error "Error: CONFIG_PI_AGESA_TEMP_RAM_BASE must be >= 1MB"
26#endif
27#if CONFIG_PI_AGESA_CAR_HEAP_BASE < 0x100000
28#error "Error: CONFIG_PI_AGESA_CAR_HEAP_BASE must be >= 1MB"
29#endif
30
Felix Held916cd502021-08-04 17:22:36 +020031/* Table to switch SCL pins to outputs to initially reset the I2C peripherals */
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -070032static const struct soc_i2c_scl_pin i2c_scl_pins[] = {
Felix Held7bbde762021-09-08 00:37:30 +020033 I2C_RESET_SCL_PIN(I2C0_SCL_PIN, GPIO_I2C0_SCL),
34 I2C_RESET_SCL_PIN(I2C1_SCL_PIN, GPIO_I2C1_SCL),
35 I2C_RESET_SCL_PIN(I2C2_SCL_PIN, GPIO_I2C2_SCL),
36 I2C_RESET_SCL_PIN(I2C3_SCL_PIN, GPIO_I2C3_SCL),
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -070037};
38
Marshall Dawsonc4be1752018-05-07 09:59:10 -060039/* Set the MMIO Configuration Base Address, Bus Range, and misc MTRRs. */
Marshall Dawson154239a2017-11-02 09:49:30 -060040static void amd_initmmio(void)
41{
Marshall Dawson154239a2017-11-02 09:49:30 -060042 msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
43 int mtrr;
44
Marshall Dawson154239a2017-11-02 09:49:30 -060045 /*
46 * todo: AGESA currently writes variable MTRRs. Once that is
47 * corrected, un-hardcode this MTRR.
Marshall Dawsonc4be1752018-05-07 09:59:10 -060048 *
49 * Be careful not to use get_free_var_mtrr/set_var_mtrr pairs
50 * where all cores execute the path. Both cores within a compute
51 * unit share MTRRs. Programming core0 has the appearance of
52 * modifying core1 too. Using the pair again will create
53 * duplicate copies.
Marshall Dawson154239a2017-11-02 09:49:30 -060054 */
Marshall Dawsond85c4af2018-03-28 19:48:42 -060055 mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_FLASH;
Marshall Dawson154239a2017-11-02 09:49:30 -060056 set_var_mtrr(mtrr, FLASH_BASE_ADDR, CONFIG_ROM_SIZE, MTRR_TYPE_WRPROT);
Marshall Dawsonc4be1752018-05-07 09:59:10 -060057
58 mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_CAR_HEAP;
59 set_var_mtrr(mtrr, CONFIG_PI_AGESA_CAR_HEAP_BASE,
60 CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_WRBACK);
61
62 mtrr = (mtrr_cap.lo & MTRR_CAP_VCNT) - SOC_EARLY_VMTRR_TEMPRAM;
63 set_var_mtrr(mtrr, CONFIG_PI_AGESA_TEMP_RAM_BASE,
64 CONFIG_PI_AGESA_HEAP_SIZE, MTRR_TYPE_UNCACHEABLE);
Marshall Dawson154239a2017-11-02 09:49:30 -060065}
66
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -070067static void reset_i2c_peripherals(void)
68{
69 const struct soc_amd_stoneyridge_config *cfg = config_of_soc();
70 struct soc_i2c_peripheral_reset_info reset_info;
71
72 reset_info.i2c_scl_reset_mask = cfg->i2c_scl_reset & GPIO_I2C_MASK;
73 reset_info.i2c_scl = i2c_scl_pins;
74 reset_info.num_pins = ARRAY_SIZE(i2c_scl_pins);
75 sb_reset_i2c_peripherals(&reset_info);
76}
77
Richard Spiegel6d61db02018-04-04 10:35:21 -070078asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
Marc Jones24484842017-05-04 21:17:45 -060079{
Michał Żygowski200d2132019-12-06 12:07:52 +010080 enable_pci_mmconf();
Marshall Dawson9df969a2017-07-25 18:46:46 -060081 amd_initmmio();
Richard Spiegel6d61db02018-04-04 10:35:21 -070082 /*
83 * Call lib/bootblock.c main with BSP, shortcut for APs
84 */
85 if (!boot_cpu()) {
86 void (*ap_romstage_entry)(void) =
87 (void (*)(void))get_ap_entry_ptr();
Marshall Dawson9df969a2017-07-25 18:46:46 -060088
Richard Spiegel6d61db02018-04-04 10:35:21 -070089 ap_romstage_entry(); /* execution does not return */
90 halt();
91 }
Marshall Dawson9df969a2017-07-25 18:46:46 -060092
Richard Spiegel6d61db02018-04-04 10:35:21 -070093 /* TSC cannot be relied upon. Override the TSC value passed in. */
Kyösti Mälkki101ef0b2019-08-18 06:58:42 +030094 bootblock_main_with_basetime(timestamp_get());
Richard Spiegel6d61db02018-04-04 10:35:21 -070095}
96
97void bootblock_soc_early_init(void)
98{
Richard Spiegel5401aa22018-09-11 11:36:38 -070099 /*
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -0700100 * This call (sb_reset_i2c_peripherals) was originally early at
Richard Spiegel5401aa22018-09-11 11:36:38 -0700101 * bootblock_c_entry, but had to be moved here. There was an
102 * unexplained delay in the middle of the i2c transaction when
103 * we had it in bootblock_c_entry. Moving it to this point
104 * (or adding delays) fixes the issue. It seems like the processor
105 * just pauses but we don't know why.
106 */
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -0700107 reset_i2c_peripherals();
Marshall Dawson9df969a2017-07-25 18:46:46 -0600108 bootblock_fch_early_init();
Marshall Dawson9df969a2017-07-25 18:46:46 -0600109 post_code(0x90);
Marshall Dawson9df969a2017-07-25 18:46:46 -0600110}
111
112void bootblock_soc_init(void)
113{
Felix Held91ef9252021-01-12 23:44:05 +0100114 if (CONFIG(AMD_SOC_CONSOLE_UART))
Marshall Dawsona5f225f2017-08-18 10:07:07 -0600115 assert(CONFIG_UART_FOR_CONSOLE >= 0
116 && CONFIG_UART_FOR_CONSOLE <= 1);
117
Marshall Dawson9df969a2017-07-25 18:46:46 -0600118 u32 val = cpuid_eax(1);
119 printk(BIOS_DEBUG, "Family_Model: %08x\n", val);
120
Raul E Rangeld820f4b82018-08-13 10:39:03 -0600121 bootblock_fch_init();
122
Aaron Durbinde3e84c2018-01-29 17:44:58 -0700123 /* Initialize any early i2c buses. */
124 i2c_soc_early_init();
Marc Jones24484842017-05-04 21:17:45 -0600125}