blob: 5df8b7193aacbc74ae8018060e49714beedcddc2 [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
17#include <cbmem.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +020018#include <cf9_reset.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020019#include <console/console.h>
20#include <cpu/x86/mtrr.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020021#include <device/pci_ops.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020022#include <soc/fiamux.h>
23#include <soc/iomap.h>
24#include <soc/pci_devs.h>
25#include <soc/pcr.h>
26#include <soc/pmc.h>
27#include <soc/romstage.h>
28#include <soc/smbus.h>
29#include <soc/smm.h>
30#include <soc/soc_util.h>
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010031#include <soc/hob_mem.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020032
Aaron Durbin64031672018-04-21 14:45:32 -060033void __weak mainboard_config_gpios(void) {}
Mariusz Szafranskia4041332017-08-02 17:28:17 +020034
35#if IS_ENABLED(CONFIG_DISPLAY_HOBS)
36static void display_fsp_smbios_memory_info_hob(void)
37{
Mariusz Szafranskia4041332017-08-02 17:28:17 +020038 const FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
39
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010040 /* Get the memory info HOB */
41 memory_info_hob = soc_get_fsp_smbios_memory_info_hob();
Subrata Banik6ee716e2018-02-08 16:50:21 +053042
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010043 if (memory_info_hob == NULL)
Subrata Banik6ee716e2018-02-08 16:50:21 +053044 return;
Mariusz Szafranskia4041332017-08-02 17:28:17 +020045
Julien Viard de Galbert2d0aaa72018-02-26 18:32:59 +010046 soc_display_fsp_smbios_memory_info_hob(memory_info_hob);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020047}
48#endif
49
50static void early_pmc_init(void)
51{
52 /* PMC (B0:D31:F2). */
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020053 pci_devfn_t dev = PCH_PMC_DEV;
Mariusz Szafranskia4041332017-08-02 17:28:17 +020054
55 /* Is PMC present */
56 if (pci_read_config16(dev, 0) == 0xffff) {
57 printk(BIOS_ERR, "PMC controller (B0:D31:F2) does not present!\n");
58 return;
59 }
60
61 uint32_t pwrm_base =
62 pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
63 if (!pwrm_base) {
64 printk(BIOS_ERR, "PWRM base address is not configured!\n");
65 return;
66 }
67
68 /* Workaround for sighting report (doc#: 560805) v1.86.
69 42. System Might Hang In AC Power Loss
70 Problem :
71 When removing and reapplying AC power to the board,
72 the system might hang at serial output
73 'RESET required : change of frequency'
74 due to PMC ROM change on B0.
75 Implication :
76 1. This issue is only shown in B0 stepping.
77 2. This issue does not impact a system without an RTC battery.
78 Alternative workaround :
79 Remove RTC battery on the board if possible.
80 Status : Plan Fix.
81 */
82 if (silicon_stepping() == SILICON_REV_DENVERTON_B0) {
83 if (!(pci_read_config32(dev, PMC_GEN_PMCON_B)
84 & PMC_GEN_PMCON_B_RTC_PWR_STS)) {
85 if (read32((void *)(pwrm_base + 0x124))
86 & ((1 << 11) | (1 << 12))) {
87 /* Performs a global reset */
88 printk(BIOS_DEBUG,
89 "Requesting Global Reset...\n");
90 pci_write_config32(dev, PMC_ETR3,
91 pci_read_config32(dev, PMC_ETR3)
92 | PMC_ETR3_CF9GR);
Patrick Rudolphf677d172018-10-01 19:17:11 +020093 full_reset();
Mariusz Szafranskia4041332017-08-02 17:28:17 +020094 }
95 }
96 }
97}
98
99static void early_tco_init(void)
100{
101 /* SMBUS (B0:D31:F4). */
Elyes HAOUAS68c851b2018-06-12 22:06:09 +0200102 pci_devfn_t dev = PCI_DEV(0, SMBUS_DEV, SMBUS_FUNC);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200103
104 /* Configure TCO base address */
105 if (pci_read_config16(dev, TCOBASE) == 0xffff) {
106 printk(BIOS_ERR, "SMBus controller (B0:D31:F4) does not present!\n");
107 return;
108 }
109 uint16_t tco_ctl = pci_read_config16(dev, TCOCTL);
110 if (tco_ctl & TCOBASE_LOCK) {
111 printk(BIOS_ERR, "TCO base register already has been locked!\n");
112 } else {
113 pci_write_config16(dev, TCOCTL, tco_ctl & (~TCOBASE_EN));
114 pci_write_config16(dev, TCOBASE, DEFAULT_TCO_BASE | 0x1);
115 pci_write_config16(dev, TCOCTL, tco_ctl | TCOBASE_EN);
116 }
117
118 uint16_t tco_base = pci_read_config16(dev, TCOBASE) & MASK_TCOBASE;
119 printk(BIOS_DEBUG, "TCO base address set to 0x%x!\n", tco_base);
120
121 /* Disable the TCO timer expiration from causing a system reset */
122 MMIO32_OR(PCH_PCR_ADDRESS(PID_SMB, PCR_SMBUS_GC),
123 (uint32_t)PCR_SMBUS_GC_NR);
124
125 /* Halt the TCO timer */
126 uint16_t reg16 = inw(tco_base + TCO1_CNT);
127 reg16 |= TCO_TMR_HLT;
128 outw(reg16, tco_base + TCO1_CNT);
129
130 /* Clear the Second TCO status bit */
131 reg16 = inw(tco_base + TCO2_STS);
132 reg16 |= TCO2_STS_SECOND_TO;
133 outw(reg16, tco_base + TCO2_STS);
134}
135
136asmlinkage void car_stage_entry(void)
137{
138
139 struct postcar_frame pcf;
140 uintptr_t top_of_ram;
141
142#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
143 void *smm_base;
144 size_t smm_size;
145 uintptr_t tseg_base;
146#endif
147
148 console_init();
149
150 printk(BIOS_DEBUG, "FSP TempRamInit was successful...\n");
151
152 mainboard_config_gpios();
153 early_tco_init();
154 early_pmc_init();
155
156 fsp_memory_init(false);
157
158#if IS_ENABLED(CONFIG_DISPLAY_HOBS)
159 display_fsp_smbios_memory_info_hob();
160#endif
161
162 if (postcar_frame_init(&pcf, 1 * KiB))
163 die("Unable to initialize postcar frame.\n");
164
165 /*
166 * We need to make sure ramstage will be run cached. At this point exact
167 * location of ramstage in cbmem is not known. Instruct postcar to cache
168 * 16 megs under cbmem top which is a safe bet to cover ramstage.
169 */
170 top_of_ram = (uintptr_t)cbmem_top();
171 postcar_frame_add_mtrr(&pcf, top_of_ram - 16 * MiB, 16 * MiB,
172 MTRR_TYPE_WRBACK);
173
174 /* Cache the memory-mapped boot media. */
Nico Huber6ea67752018-05-27 14:37:52 +0200175 postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT);
176
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200177#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)
178 /*
179 * Cache the TSEG region at the top of ram. This region is
180 * not restricted to SMM mode until SMM has been relocated.
181 * By setting the region to cacheable it provides faster access
182 * when relocating the SMM handler as well as using the TSEG
183 * region for other purposes.
184 */
185 smm_region(&smm_base, &smm_size);
186 tseg_base = (uintptr_t)smm_base;
187 postcar_frame_add_mtrr(&pcf, tseg_base, smm_size, MTRR_TYPE_WRBACK);
188#endif
189
190 run_postcar_phase(&pcf);
191}
192
193static void soc_memory_init_params(FSP_M_CONFIG *m_cfg)
194{
195 FSPM_UPD *mupd = container_of(m_cfg, FSPM_UPD, FspmConfig);
196 size_t num;
197 uint16_t supported_hsio_lanes;
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200198 BL_HSIO_INFORMATION *hsio_config;
199
200 /* Set the parameters for MemoryInit */
201 m_cfg->PcdEnableIQAT = IS_ENABLED(CONFIG_IQAT_ENABLE);
202
203 /* if ME HECI communication is disabled, apply default one*/
204 if (mupd->FspmConfig.PcdMeHeciCommunication == 0) {
205
206 /* Configure FIA MUX PCD */
207 /* Assume the validating silicon has max lanes. */
208 supported_hsio_lanes = BL_ME_FIA_MUX_LANE_NUM_MAX;
209
Julien Viard de Galbertf5281952017-11-06 13:19:58 +0100210 num = mainboard_get_hsio_config(&hsio_config);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200211
212 if (get_fiamux_hsio_info(supported_hsio_lanes, num,
213 &hsio_config))
214 die("HSIO Configuration is invalid, please correct "
215 "it!");
216
217 /* Check the requested FIA MUX Configuration */
218 if (!(&hsio_config->FiaConfig)) {
219 die("Requested FIA MUX Configuration is invalid,"
220 " please correct it!");
221 }
222
223 mupd->FspmConfig.PcdHsioLanesNumber =
224 (uint32_t)hsio_config->NumLanesSupported;
225 mupd->FspmConfig.PcdFiaMuxConfigPtr =
226 (uint32_t)&hsio_config->FiaConfig;
227 }
228}
229
Aaron Durbin64031672018-04-21 14:45:32 -0600230__weak void mainboard_memory_init_params(FSPM_UPD *mupd)
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200231{
232 /* Do nothing */
233}
234
235void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
236{
237 FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
238
239 soc_memory_init_params(m_cfg);
240
241 mainboard_memory_init_params(mupd);
242}