blob: 53c51f488ce5b818026605b60d482bf224cde7d8 [file] [log] [blame]
Mariusz Szafranskia4041332017-08-02 17:28:17 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2016 - 2017 Intel Corp.
Julien Viard de Galbertf5281952017-11-06 13:19:58 +01005 * Copyright (C) 2017 Online SAS.
Mariusz Szafranskia4041332017-08-02 17:28:17 +02006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
Kyösti Mälkki6e2d0c12019-06-28 10:08:51 +030017#include <arch/cpu.h>
Kyösti Mälkkibdaec072019-03-02 23:18:29 +020018#include <arch/io.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020019#include <cbmem.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +020020#include <cf9_reset.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020021#include <console/console.h>
22#include <cpu/x86/mtrr.h>
Kyösti Mälkkib2a5f0b2019-08-04 19:54:32 +030023#include <cpu/x86/smm.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020024#include <device/pci_ops.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020025#include <soc/fiamux.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020026#include <device/mmio.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020027#include <soc/iomap.h>
28#include <soc/pci_devs.h>
29#include <soc/pcr.h>
30#include <soc/pmc.h>
31#include <soc/romstage.h>
32#include <soc/smbus.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020033#include <soc/soc_util.h>
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010034#include <soc/hob_mem.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020035
Aaron Durbin64031672018-04-21 14:45:32 -060036void __weak mainboard_config_gpios(void) {}
Mariusz Szafranskia4041332017-08-02 17:28:17 +020037
Julius Wernercd49cce2019-03-05 16:53:33 -080038#if CONFIG(DISPLAY_HOBS)
Mariusz Szafranskia4041332017-08-02 17:28:17 +020039static void display_fsp_smbios_memory_info_hob(void)
40{
Mariusz Szafranskia4041332017-08-02 17:28:17 +020041 const FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
42
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010043 /* Get the memory info HOB */
44 memory_info_hob = soc_get_fsp_smbios_memory_info_hob();
Subrata Banik6ee716e2018-02-08 16:50:21 +053045
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010046 if (memory_info_hob == NULL)
Subrata Banik6ee716e2018-02-08 16:50:21 +053047 return;
Mariusz Szafranskia4041332017-08-02 17:28:17 +020048
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010049 soc_display_fsp_smbios_memory_info_hob(memory_info_hob);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020050}
51#endif
52
53static void early_pmc_init(void)
54{
55 /* PMC (B0:D31:F2). */
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020056 pci_devfn_t dev = PCH_PMC_DEV;
Mariusz Szafranskia4041332017-08-02 17:28:17 +020057
58 /* Is PMC present */
59 if (pci_read_config16(dev, 0) == 0xffff) {
60 printk(BIOS_ERR, "PMC controller (B0:D31:F2) does not present!\n");
61 return;
62 }
63
64 uint32_t pwrm_base =
65 pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
66 if (!pwrm_base) {
67 printk(BIOS_ERR, "PWRM base address is not configured!\n");
68 return;
69 }
70
71 /* Workaround for sighting report (doc#: 560805) v1.86.
72 42. System Might Hang In AC Power Loss
73 Problem :
74 When removing and reapplying AC power to the board,
75 the system might hang at serial output
76 'RESET required : change of frequency'
77 due to PMC ROM change on B0.
78 Implication :
79 1. This issue is only shown in B0 stepping.
80 2. This issue does not impact a system without an RTC battery.
81 Alternative workaround :
82 Remove RTC battery on the board if possible.
83 Status : Plan Fix.
84 */
85 if (silicon_stepping() == SILICON_REV_DENVERTON_B0) {
86 if (!(pci_read_config32(dev, PMC_GEN_PMCON_B)
87 & PMC_GEN_PMCON_B_RTC_PWR_STS)) {
88 if (read32((void *)(pwrm_base + 0x124))
89 & ((1 << 11) | (1 << 12))) {
90 /* Performs a global reset */
91 printk(BIOS_DEBUG,
92 "Requesting Global Reset...\n");
93 pci_write_config32(dev, PMC_ETR3,
94 pci_read_config32(dev, PMC_ETR3)
95 | PMC_ETR3_CF9GR);
Patrick Rudolphf677d172018-10-01 19:17:11 +020096 full_reset();
Mariusz Szafranskia4041332017-08-02 17:28:17 +020097 }
98 }
99 }
100}
101
102static void early_tco_init(void)
103{
104 /* SMBUS (B0:D31:F4). */
Elyes HAOUAS68c851b2018-06-12 22:06:09 +0200105 pci_devfn_t dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200106
107 /* Configure TCO base address */
108 if (pci_read_config16(dev, TCOBASE) == 0xffff) {
109 printk(BIOS_ERR, "SMBus controller (B0:D31:F4) does not present!\n");
110 return;
111 }
112 uint16_t tco_ctl = pci_read_config16(dev, TCOCTL);
113 if (tco_ctl & TCOBASE_LOCK) {
114 printk(BIOS_ERR, "TCO base register already has been locked!\n");
115 } else {
116 pci_write_config16(dev, TCOCTL, tco_ctl & (~TCOBASE_EN));
117 pci_write_config16(dev, TCOBASE, DEFAULT_TCO_BASE | 0x1);
118 pci_write_config16(dev, TCOCTL, tco_ctl | TCOBASE_EN);
119 }
120
121 uint16_t tco_base = pci_read_config16(dev, TCOBASE) & MASK_TCOBASE;
122 printk(BIOS_DEBUG, "TCO base address set to 0x%x!\n", tco_base);
123
124 /* Disable the TCO timer expiration from causing a system reset */
125 MMIO32_OR(PCH_PCR_ADDRESS(PID_SMB, PCR_SMBUS_GC),
126 (uint32_t)PCR_SMBUS_GC_NR);
127
128 /* Halt the TCO timer */
129 uint16_t reg16 = inw(tco_base + TCO1_CNT);
130 reg16 |= TCO_TMR_HLT;
131 outw(reg16, tco_base + TCO1_CNT);
132
133 /* Clear the Second TCO status bit */
134 reg16 = inw(tco_base + TCO2_STS);
135 reg16 |= TCO2_STS_SECOND_TO;
136 outw(reg16, tco_base + TCO2_STS);
137}
138
139asmlinkage void car_stage_entry(void)
140{
141
142 struct postcar_frame pcf;
143 uintptr_t top_of_ram;
Kyösti Mälkki14222d82019-08-05 15:10:18 +0300144 uintptr_t smm_base;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200145 size_t smm_size;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200146
147 console_init();
148
149 printk(BIOS_DEBUG, "FSP TempRamInit was successful...\n");
150
151 mainboard_config_gpios();
152 early_tco_init();
153 early_pmc_init();
154
155 fsp_memory_init(false);
156
Julius Wernercd49cce2019-03-05 16:53:33 -0800157#if CONFIG(DISPLAY_HOBS)
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200158 display_fsp_smbios_memory_info_hob();
159#endif
160
Kyösti Mälkki6e2d0c12019-06-28 10:08:51 +0300161 if (postcar_frame_init(&pcf, 0))
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200162 die("Unable to initialize postcar frame.\n");
163
164 /*
165 * We need to make sure ramstage will be run cached. At this point exact
166 * location of ramstage in cbmem is not known. Instruct postcar to cache
167 * 16 megs under cbmem top which is a safe bet to cover ramstage.
168 */
169 top_of_ram = (uintptr_t)cbmem_top();
170 postcar_frame_add_mtrr(&pcf, top_of_ram - 16 * MiB, 16 * MiB,
171 MTRR_TYPE_WRBACK);
172
173 /* Cache the memory-mapped boot media. */
Nico Huber6ea67752018-05-27 14:37:52 +0200174 postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT);
175
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200176 /*
177 * Cache the TSEG region at the top of ram. This region is
178 * not restricted to SMM mode until SMM has been relocated.
179 * By setting the region to cacheable it provides faster access
180 * when relocating the SMM handler as well as using the TSEG
181 * region for other purposes.
182 */
Kyösti Mälkkib4905622019-07-12 08:02:35 +0300183 if (CONFIG(HAVE_SMI_HANDLER)) {
184 smm_region(&smm_base, &smm_size);
Kyösti Mälkki14222d82019-08-05 15:10:18 +0300185 postcar_frame_add_mtrr(&pcf, smm_base, smm_size, MTRR_TYPE_WRBACK);
Kyösti Mälkkib4905622019-07-12 08:02:35 +0300186 }
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200187
188 run_postcar_phase(&pcf);
189}
190
191static void soc_memory_init_params(FSP_M_CONFIG *m_cfg)
192{
193 FSPM_UPD *mupd = container_of(m_cfg, FSPM_UPD, FspmConfig);
194 size_t num;
195 uint16_t supported_hsio_lanes;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200196 BL_HSIO_INFORMATION *hsio_config;
197
198 /* Set the parameters for MemoryInit */
Julius Wernercd49cce2019-03-05 16:53:33 -0800199 m_cfg->PcdEnableIQAT = CONFIG(IQAT_ENABLE);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200200
201 /* if ME HECI communication is disabled, apply default one*/
202 if (mupd->FspmConfig.PcdMeHeciCommunication == 0) {
203
204 /* Configure FIA MUX PCD */
205 /* Assume the validating silicon has max lanes. */
206 supported_hsio_lanes = BL_ME_FIA_MUX_LANE_NUM_MAX;
207
Julien Viard de Galbertf5281952017-11-06 13:19:58 +0100208 num = mainboard_get_hsio_config(&hsio_config);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200209
210 if (get_fiamux_hsio_info(supported_hsio_lanes, num,
211 &hsio_config))
212 die("HSIO Configuration is invalid, please correct "
213 "it!");
214
215 /* Check the requested FIA MUX Configuration */
216 if (!(&hsio_config->FiaConfig)) {
217 die("Requested FIA MUX Configuration is invalid,"
218 " please correct it!");
219 }
220
221 mupd->FspmConfig.PcdHsioLanesNumber =
222 (uint32_t)hsio_config->NumLanesSupported;
223 mupd->FspmConfig.PcdFiaMuxConfigPtr =
224 (uint32_t)&hsio_config->FiaConfig;
225 }
226}
227
Aaron Durbin64031672018-04-21 14:45:32 -0600228__weak void mainboard_memory_init_params(FSPM_UPD *mupd)
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200229{
230 /* Do nothing */
231}
232
233void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
234{
235 FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
236
237 soc_memory_init_params(m_cfg);
238
239 mainboard_memory_init_params(mupd);
240}