blob: 2f3a5cc1e7b77ffbef4b6a71a82f26acee480e0e [file] [log] [blame]
Angel Pons80d92382020-04-05 15:47:00 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Mariusz Szafranskia4041332017-08-02 17:28:17 +02002
Kyösti Mälkkia963acd2019-08-16 20:34:25 +03003#include <arch/romstage.h>
Kyösti Mälkkibdaec072019-03-02 23:18:29 +02004#include <arch/io.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +02005#include <cf9_reset.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +02006#include <console/console.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02007#include <device/pci_ops.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +02008#include <soc/fiamux.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02009#include <device/mmio.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020010#include <soc/iomap.h>
11#include <soc/pci_devs.h>
12#include <soc/pcr.h>
13#include <soc/pmc.h>
14#include <soc/romstage.h>
15#include <soc/smbus.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020016#include <soc/soc_util.h>
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010017#include <soc/hob_mem.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020018
Aaron Durbin64031672018-04-21 14:45:32 -060019void __weak mainboard_config_gpios(void) {}
Mariusz Szafranskia4041332017-08-02 17:28:17 +020020
Julius Wernercd49cce2019-03-05 16:53:33 -080021#if CONFIG(DISPLAY_HOBS)
Mariusz Szafranskia4041332017-08-02 17:28:17 +020022static void display_fsp_smbios_memory_info_hob(void)
23{
Mariusz Szafranskia4041332017-08-02 17:28:17 +020024 const FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
25
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010026 /* Get the memory info HOB */
27 memory_info_hob = soc_get_fsp_smbios_memory_info_hob();
Subrata Banik6ee716e2018-02-08 16:50:21 +053028
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010029 if (memory_info_hob == NULL)
Subrata Banik6ee716e2018-02-08 16:50:21 +053030 return;
Mariusz Szafranskia4041332017-08-02 17:28:17 +020031
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010032 soc_display_fsp_smbios_memory_info_hob(memory_info_hob);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020033}
34#endif
35
36static void early_pmc_init(void)
37{
38 /* PMC (B0:D31:F2). */
Subrata Banik7848aa92022-02-15 20:49:01 +053039 pci_devfn_t dev = PCH_DEV_PMC;
Mariusz Szafranskia4041332017-08-02 17:28:17 +020040
41 /* Is PMC present */
42 if (pci_read_config16(dev, 0) == 0xffff) {
43 printk(BIOS_ERR, "PMC controller (B0:D31:F2) does not present!\n");
44 return;
45 }
46
47 uint32_t pwrm_base =
48 pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
49 if (!pwrm_base) {
50 printk(BIOS_ERR, "PWRM base address is not configured!\n");
51 return;
52 }
53
54 /* Workaround for sighting report (doc#: 560805) v1.86.
55 42. System Might Hang In AC Power Loss
56 Problem :
57 When removing and reapplying AC power to the board,
58 the system might hang at serial output
59 'RESET required : change of frequency'
60 due to PMC ROM change on B0.
61 Implication :
62 1. This issue is only shown in B0 stepping.
63 2. This issue does not impact a system without an RTC battery.
64 Alternative workaround :
65 Remove RTC battery on the board if possible.
66 Status : Plan Fix.
67 */
68 if (silicon_stepping() == SILICON_REV_DENVERTON_B0) {
Subrata Banik7848aa92022-02-15 20:49:01 +053069 if (!(pci_read_config32(dev, GEN_PMCON_B)
70 & GEN_PMCON_B_RTC_PWR_STS)) {
Mariusz Szafranskia4041332017-08-02 17:28:17 +020071 if (read32((void *)(pwrm_base + 0x124))
72 & ((1 << 11) | (1 << 12))) {
73 /* Performs a global reset */
74 printk(BIOS_DEBUG,
75 "Requesting Global Reset...\n");
Subrata Banik7848aa92022-02-15 20:49:01 +053076 pci_write_config32(dev, ETR3,
77 pci_read_config32(dev, ETR3)
78 | ETR3_CF9GR);
Patrick Rudolphf677d172018-10-01 19:17:11 +020079 full_reset();
Mariusz Szafranskia4041332017-08-02 17:28:17 +020080 }
81 }
82 }
83}
84
85static void early_tco_init(void)
86{
87 /* SMBUS (B0:D31:F4). */
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020088 pci_devfn_t dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020089
90 /* Configure TCO base address */
91 if (pci_read_config16(dev, TCOBASE) == 0xffff) {
92 printk(BIOS_ERR, "SMBus controller (B0:D31:F4) does not present!\n");
93 return;
94 }
95 uint16_t tco_ctl = pci_read_config16(dev, TCOCTL);
96 if (tco_ctl & TCOBASE_LOCK) {
97 printk(BIOS_ERR, "TCO base register already has been locked!\n");
98 } else {
99 pci_write_config16(dev, TCOCTL, tco_ctl & (~TCOBASE_EN));
100 pci_write_config16(dev, TCOBASE, DEFAULT_TCO_BASE | 0x1);
101 pci_write_config16(dev, TCOCTL, tco_ctl | TCOBASE_EN);
102 }
103
104 uint16_t tco_base = pci_read_config16(dev, TCOBASE) & MASK_TCOBASE;
105 printk(BIOS_DEBUG, "TCO base address set to 0x%x!\n", tco_base);
106
107 /* Disable the TCO timer expiration from causing a system reset */
108 MMIO32_OR(PCH_PCR_ADDRESS(PID_SMB, PCR_SMBUS_GC),
109 (uint32_t)PCR_SMBUS_GC_NR);
110
111 /* Halt the TCO timer */
112 uint16_t reg16 = inw(tco_base + TCO1_CNT);
113 reg16 |= TCO_TMR_HLT;
114 outw(reg16, tco_base + TCO1_CNT);
115
116 /* Clear the Second TCO status bit */
117 reg16 = inw(tco_base + TCO2_STS);
118 reg16 |= TCO2_STS_SECOND_TO;
119 outw(reg16, tco_base + TCO2_STS);
120}
121
Kyösti Mälkkicd7a70f2019-08-17 20:51:08 +0300122void mainboard_romstage_entry(void)
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200123{
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200124 printk(BIOS_DEBUG, "FSP TempRamInit was successful...\n");
125
126 mainboard_config_gpios();
127 early_tco_init();
128 early_pmc_init();
129
130 fsp_memory_init(false);
131
Julius Wernercd49cce2019-03-05 16:53:33 -0800132#if CONFIG(DISPLAY_HOBS)
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200133 display_fsp_smbios_memory_info_hob();
134#endif
Kyösti Mälkkicd7a70f2019-08-17 20:51:08 +0300135}
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200136
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200137static void soc_memory_init_params(FSP_M_CONFIG *m_cfg)
138{
139 FSPM_UPD *mupd = container_of(m_cfg, FSPM_UPD, FspmConfig);
140 size_t num;
141 uint16_t supported_hsio_lanes;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200142 BL_HSIO_INFORMATION *hsio_config;
143
144 /* Set the parameters for MemoryInit */
Julius Wernercd49cce2019-03-05 16:53:33 -0800145 m_cfg->PcdEnableIQAT = CONFIG(IQAT_ENABLE);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200146
147 /* if ME HECI communication is disabled, apply default one*/
148 if (mupd->FspmConfig.PcdMeHeciCommunication == 0) {
149
150 /* Configure FIA MUX PCD */
151 /* Assume the validating silicon has max lanes. */
152 supported_hsio_lanes = BL_ME_FIA_MUX_LANE_NUM_MAX;
153
Julien Viard de Galbertf5281952017-11-06 13:19:58 +0100154 num = mainboard_get_hsio_config(&hsio_config);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200155
156 if (get_fiamux_hsio_info(supported_hsio_lanes, num,
157 &hsio_config))
158 die("HSIO Configuration is invalid, please correct "
159 "it!");
160
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200161 mupd->FspmConfig.PcdHsioLanesNumber =
162 (uint32_t)hsio_config->NumLanesSupported;
163 mupd->FspmConfig.PcdFiaMuxConfigPtr =
164 (uint32_t)&hsio_config->FiaConfig;
165 }
166}
167
Aaron Durbin64031672018-04-21 14:45:32 -0600168__weak void mainboard_memory_init_params(FSPM_UPD *mupd)
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200169{
170 /* Do nothing */
171}
172
173void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
174{
175 FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
176
177 soc_memory_init_params(m_cfg);
178
179 mainboard_memory_init_params(mupd);
180}