soc/intel: Replace config_of_path() with config_of_soc()
[coreboot.git] / src / soc / intel / cannonlake / fsp_params.c
blobb580620d70f09b45281016cf2bbf143a2dae060f
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2018-2019 Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <console/console.h>
17 #include <device/device.h>
18 #include <device/pci.h>
19 #include <fsp/api.h>
20 #include <fsp/util.h>
21 #include <intelblocks/lpss.h>
22 #include <intelblocks/xdci.h>
23 #include <intelpch/lockdown.h>
24 #include <soc/intel/common/vbt.h>
25 #include <soc/pci_devs.h>
26 #include <soc/ramstage.h>
27 #include <string.h>
29 #include "chip.h"
31 static const pci_devfn_t serial_io_dev[] = {
32 PCH_DEVFN_I2C0,
33 PCH_DEVFN_I2C1,
34 PCH_DEVFN_I2C2,
35 PCH_DEVFN_I2C3,
36 PCH_DEVFN_I2C4,
37 PCH_DEVFN_I2C5,
38 PCH_DEVFN_GSPI0,
39 PCH_DEVFN_GSPI1,
40 PCH_DEVFN_GSPI2,
41 PCH_DEVFN_UART0,
42 PCH_DEVFN_UART1,
43 PCH_DEVFN_UART2
47 * Given an enum for PCH_SERIAL_IO_MODE, 1 needs to be subtracted to get the FSP
48 * UPD expected value for Serial IO since valid enum index starts from 1.
50 #define PCH_SERIAL_IO_INDEX(x) ((x) - 1)
52 static uint8_t get_param_value(const config_t *config, uint32_t dev_offset)
54 struct device *dev;
56 dev = pcidev_path_on_root(serial_io_dev[dev_offset]);
57 if (!dev || !dev->enabled)
58 return PCH_SERIAL_IO_INDEX(PchSerialIoDisabled);
60 if ((config->SerialIoDevMode[dev_offset] >= PchSerialIoMax) ||
61 (config->SerialIoDevMode[dev_offset] == PchSerialIoNotInitialized))
62 return PCH_SERIAL_IO_INDEX(PchSerialIoPci);
65 * Correct Enum index starts from 1, so subtract 1 while returning value
67 return PCH_SERIAL_IO_INDEX(config->SerialIoDevMode[dev_offset]);
70 #if CONFIG(SOC_INTEL_COMETLAKE)
71 static void parse_devicetree_param(const config_t *config, FSP_S_CONFIG *params)
73 uint32_t dev_offset = 0;
74 uint32_t i = 0;
76 for (i = 0; i < CONFIG_SOC_INTEL_I2C_DEV_MAX; i++, dev_offset++) {
77 params->SerialIoI2cMode[i] =
78 get_param_value(config, dev_offset);
81 for (i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++,
82 dev_offset++) {
83 params->SerialIoSpiMode[i] =
84 get_param_value(config, dev_offset);
87 for (i = 0; i < SOC_INTEL_CML_UART_DEV_MAX; i++, dev_offset++) {
88 params->SerialIoUartMode[i] =
89 get_param_value(config, dev_offset);
92 #else
93 static void parse_devicetree_param(const config_t *config, FSP_S_CONFIG *params)
95 for (int i = 0; i < ARRAY_SIZE(serial_io_dev); i++)
96 params->SerialIoDevMode[i] = get_param_value(config, i);
98 #endif
100 static void parse_devicetree(FSP_S_CONFIG *params)
102 const config_t *config = config_of_soc();
104 parse_devicetree_param(config, params);
107 /* Ignore LTR value for GBE devices */
108 static void ignore_gbe_ltr(void)
110 uint8_t reg8;
111 uint8_t *pmcbase = pmc_mmio_regs();
113 reg8 = read8(pmcbase + LTR_IGN);
114 reg8 |= IGN_GBE;
115 write8(pmcbase + LTR_IGN, reg8);
118 static void configure_gspi_cs(int idx, const config_t *config,
119 uint8_t *polarity, uint8_t *enable,
120 uint8_t *defaultcs)
122 struct spi_cfg cfg;
124 /* If speed_mhz is set, infer that the port should be configured */
125 if (config->common_soc_config.gspi[idx].speed_mhz != 0) {
126 if (gspi_get_soc_spi_cfg(idx, &cfg) == 0) {
127 if (cfg.cs_polarity == SPI_POLARITY_LOW)
128 *polarity = 0;
129 else
130 *polarity = 1;
132 if (defaultcs != NULL)
133 *defaultcs = 0;
134 if (enable != NULL)
135 *enable = 1;
140 /* UPD parameters to be initialized before SiliconInit */
141 void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
143 int i;
144 FSP_S_CONFIG *params = &supd->FspsConfig;
145 FSP_S_TEST_CONFIG *tconfig = &supd->FspsTestConfig;
146 struct device *dev;
148 config_t *config = config_of_soc();
150 /* Parse device tree and enable/disable devices */
151 parse_devicetree(params);
153 /* Load VBT before devicetree-specific config. */
154 params->GraphicsConfigPtr = (uintptr_t)vbt_get();
156 /* Set USB OC pin to 0 first */
157 for (i = 0; i < ARRAY_SIZE(params->Usb2OverCurrentPin); i++) {
158 params->Usb2OverCurrentPin[i] = 0;
161 for (i = 0; i < ARRAY_SIZE(params->Usb3OverCurrentPin); i++) {
162 params->Usb3OverCurrentPin[i] = 0;
165 mainboard_silicon_init_params(params);
167 /* Set PsysPmax if it is available from DT */
168 if (config->psys_pmax) {
169 printk(BIOS_DEBUG, "psys_pmax = %dW\n", config->psys_pmax);
170 /* PsysPmax is in unit of 1/8 Watt */
171 tconfig->PsysPmax = config->psys_pmax * 8;
174 /* Unlock upper 8 bytes of RTC RAM */
175 params->PchLockDownRtcMemoryLock = 0;
177 /* SATA */
178 dev = pcidev_path_on_root(PCH_DEVFN_SATA);
179 if (!dev)
180 params->SataEnable = 0;
181 else {
182 params->SataEnable = dev->enabled;
183 params->SataMode = config->SataMode;
184 params->SataSalpSupport = config->SataSalpSupport;
185 memcpy(params->SataPortsEnable, config->SataPortsEnable,
186 sizeof(params->SataPortsEnable));
187 memcpy(params->SataPortsDevSlp, config->SataPortsDevSlp,
188 sizeof(params->SataPortsDevSlp));
189 #if CONFIG(SOC_INTEL_COMETLAKE)
190 memcpy(params->SataPortsDevSlpResetConfig,
191 config->SataPortsDevSlpResetConfig,
192 sizeof(params->SataPortsDevSlpResetConfig));
193 #endif
196 /* Lan */
197 dev = pcidev_path_on_root(PCH_DEVFN_GBE);
198 if (!dev)
199 params->PchLanEnable = 0;
200 else {
201 params->PchLanEnable = dev->enabled;
202 if (config->s0ix_enable) {
203 params->SlpS0WithGbeSupport = 1;
204 params->PchPmSlpS0VmRuntimeControl = 0;
205 params->PchPmSlpS0Vm070VSupport = 0;
206 params->PchPmSlpS0Vm075VSupport = 0;
207 ignore_gbe_ltr();
211 /* Audio */
212 params->PchHdaDspEnable = config->PchHdaDspEnable;
213 params->PchHdaIDispCodecDisconnect = config->PchHdaIDispCodecDisconnect;
214 params->PchHdaAudioLinkHda = config->PchHdaAudioLinkHda;
215 params->PchHdaAudioLinkDmic0 = config->PchHdaAudioLinkDmic0;
216 params->PchHdaAudioLinkDmic1 = config->PchHdaAudioLinkDmic1;
217 params->PchHdaAudioLinkSsp0 = config->PchHdaAudioLinkSsp0;
218 params->PchHdaAudioLinkSsp1 = config->PchHdaAudioLinkSsp1;
219 params->PchHdaAudioLinkSsp2 = config->PchHdaAudioLinkSsp2;
220 params->PchHdaAudioLinkSndw1 = config->PchHdaAudioLinkSndw1;
221 params->PchHdaAudioLinkSndw2 = config->PchHdaAudioLinkSndw2;
222 params->PchHdaAudioLinkSndw3 = config->PchHdaAudioLinkSndw3;
223 params->PchHdaAudioLinkSndw4 = config->PchHdaAudioLinkSndw4;
225 /* eDP device */
226 params->DdiPortEdp = config->DdiPortEdp;
228 /* HPD of DDI ports */
229 params->DdiPortBHpd = config->DdiPortBHpd;
230 params->DdiPortCHpd = config->DdiPortCHpd;
231 params->DdiPortDHpd = config->DdiPortDHpd;
232 params->DdiPortFHpd = config->DdiPortFHpd;
234 /* DDC of DDI ports */
235 params->DdiPortBDdc = config->DdiPortBDdc;
236 params->DdiPortCDdc = config->DdiPortCDdc;
237 params->DdiPortDDdc = config->DdiPortDDdc;
238 params->DdiPortFDdc = config->DdiPortFDdc;
240 /* WOL */
241 params->PchPmPcieWakeFromDeepSx = config->LanWakeFromDeepSx;
242 params->PchPmWolEnableOverride = config->WolEnableOverride;
244 /* S0ix */
245 params->PchPmSlpS0Enable = config->s0ix_enable;
247 /* disable Legacy PME */
248 memset(params->PcieRpPmSci, 0, sizeof(params->PcieRpPmSci));
250 /* Legacy 8254 timer support */
251 params->Enable8254ClockGating = !CONFIG_USE_LEGACY_8254_TIMER;
252 params->Enable8254ClockGatingOnS3 = 1;
254 /* USB */
255 for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
256 params->PortUsb20Enable[i] = config->usb2_ports[i].enable;
257 params->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin;
258 params->Usb2AfePetxiset[i] = config->usb2_ports[i].pre_emp_bias;
259 params->Usb2AfeTxiset[i] = config->usb2_ports[i].tx_bias;
260 params->Usb2AfePredeemp[i] =
261 config->usb2_ports[i].tx_emp_enable;
262 params->Usb2AfePehalfbit[i] = config->usb2_ports[i].pre_emp_bit;
265 for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
266 params->PortUsb30Enable[i] = config->usb3_ports[i].enable;
267 params->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin;
268 if (config->usb3_ports[i].tx_de_emp) {
269 params->Usb3HsioTxDeEmphEnable[i] = 1;
270 params->Usb3HsioTxDeEmph[i] =
271 config->usb3_ports[i].tx_de_emp;
273 if (config->usb3_ports[i].tx_downscale_amp) {
274 params->Usb3HsioTxDownscaleAmpEnable[i] = 1;
275 params->Usb3HsioTxDownscaleAmp[i] =
276 config->usb3_ports[i].tx_downscale_amp;
280 /* Enable xDCI controller if enabled in devicetree and allowed */
281 dev = pcidev_path_on_root(PCH_DEVFN_USBOTG);
282 if (dev) {
283 if (!xdci_can_enable())
284 dev->enabled = 0;
285 params->XdciEnable = dev->enabled;
286 } else
287 params->XdciEnable = 0;
289 /* Set Debug serial port */
290 params->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE;
291 #if !CONFIG(SOC_INTEL_COMETLAKE)
292 params->SerialIoEnableDebugUartAfterPost = CONFIG_INTEL_LPSS_UART_FOR_CONSOLE;
293 #endif
295 /* Enable CNVi Wifi if enabled in device tree */
296 dev = pcidev_path_on_root(PCH_DEVFN_CNViWIFI);
297 #if CONFIG(SOC_INTEL_COMETLAKE)
298 if (dev)
299 params->CnviMode = dev->enabled;
300 else
301 params->CnviMode = 0;
302 #else
303 if (dev)
304 params->PchCnviMode = dev->enabled;
305 else
306 params->PchCnviMode = 0;
307 #endif
308 /* PCI Express */
309 for (i = 0; i < ARRAY_SIZE(config->PcieClkSrcUsage); i++) {
310 if (config->PcieClkSrcUsage[i] == 0)
311 config->PcieClkSrcUsage[i] = PCIE_CLK_NOTUSED;
313 memcpy(params->PcieClkSrcUsage, config->PcieClkSrcUsage,
314 sizeof(config->PcieClkSrcUsage));
315 memcpy(params->PcieClkSrcClkReq, config->PcieClkSrcClkReq,
316 sizeof(config->PcieClkSrcClkReq));
317 memcpy(params->PcieRpLtrEnable, config->PcieRpLtrEnable,
318 sizeof(config->PcieRpLtrEnable));
319 memcpy(params->PcieRpHotPlug, config->PcieRpHotPlug,
320 sizeof(config->PcieRpHotPlug));
322 /* eMMC and SD */
323 dev = pcidev_path_on_root(PCH_DEVFN_EMMC);
324 if (!dev)
325 params->ScsEmmcEnabled = 0;
326 else {
327 params->ScsEmmcEnabled = dev->enabled;
328 params->ScsEmmcHs400Enabled = config->ScsEmmcHs400Enabled;
329 params->PchScsEmmcHs400DllDataValid = config->EmmcHs400DllNeed;
330 if (config->EmmcHs400DllNeed == 1) {
331 params->PchScsEmmcHs400RxStrobeDll1 =
332 config->EmmcHs400RxStrobeDll1;
333 params->PchScsEmmcHs400TxDataDll =
334 config->EmmcHs400TxDataDll;
338 dev = pcidev_path_on_root(PCH_DEVFN_SDCARD);
339 if (!dev) {
340 params->ScsSdCardEnabled = 0;
341 } else {
342 params->ScsSdCardEnabled = dev->enabled;
343 params->SdCardPowerEnableActiveHigh =
344 CONFIG(MB_HAS_ACTIVE_HIGH_SD_PWR_ENABLE);
345 #if CONFIG(SOC_INTEL_COMETLAKE)
346 params->ScsSdCardWpPinEnabled = config->ScsSdCardWpPinEnabled;
347 #endif
350 dev = pcidev_path_on_root(PCH_DEVFN_UFS);
351 if (!dev)
352 params->ScsUfsEnabled = 0;
353 else
354 params->ScsUfsEnabled = dev->enabled;
356 params->Heci3Enabled = config->Heci3Enabled;
357 #if !CONFIG(HECI_DISABLE_USING_SMM)
358 params->Heci1Disabled = !config->HeciEnabled;
359 #endif
360 params->Device4Enable = config->Device4Enable;
362 /* VrConfig Settings for 5 domains
363 * 0 = System Agent, 1 = IA Core, 2 = Ring,
364 * 3 = GT unsliced, 4 = GT sliced */
365 for (i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++)
366 fill_vr_domain_config(params, i, &config->domain_vr_config[i]);
368 /* Acoustic Noise Mitigation */
369 params->AcousticNoiseMitigation = config->AcousticNoiseMitigation;
370 params->SlowSlewRateForIa = config->SlowSlewRateForIa;
371 params->SlowSlewRateForGt = config->SlowSlewRateForGt;
372 params->SlowSlewRateForSa = config->SlowSlewRateForSa;
373 params->SlowSlewRateForFivr = config->SlowSlewRateForFivr;
374 params->FastPkgCRampDisableIa = config->FastPkgCRampDisableIa;
375 params->FastPkgCRampDisableGt = config->FastPkgCRampDisableGt;
376 params->FastPkgCRampDisableSa = config->FastPkgCRampDisableSa;
377 params->FastPkgCRampDisableFivr = config->FastPkgCRampDisableFivr;
379 /* Power Optimizer */
380 params->SataPwrOptEnable = config->satapwroptimize;
382 /* Disable PCH ACPI timer */
383 params->EnableTcoTimer = !config->PmTimerDisabled;
385 /* Apply minimum assertion width settings if non-zero */
386 if (config->PchPmSlpS3MinAssert)
387 params->PchPmSlpS3MinAssert = config->PchPmSlpS3MinAssert;
388 if (config->PchPmSlpS4MinAssert)
389 params->PchPmSlpS4MinAssert = config->PchPmSlpS4MinAssert;
390 if (config->PchPmSlpSusMinAssert)
391 params->PchPmSlpSusMinAssert = config->PchPmSlpSusMinAssert;
392 if (config->PchPmSlpAMinAssert)
393 params->PchPmSlpAMinAssert = config->PchPmSlpAMinAssert;
395 /* Set TccActivationOffset */
396 tconfig->TccActivationOffset = config->tcc_offset;
398 /* Unlock all GPIO pads */
399 tconfig->PchUnlockGpioPads = config->PchUnlockGpioPads;
402 * GSPI Chip Select parameters
403 * The GSPI driver assumes that CS0 is the used chip-select line,
404 * therefore only CS0 is configured below.
406 #if CONFIG(SOC_INTEL_COMETLAKE)
407 configure_gspi_cs(0, config, &params->SerialIoSpi0CsPolarity[0],
408 &params->SerialIoSpi0CsEnable[0],
409 &params->SerialIoSpiDefaultCsOutput[0]);
410 configure_gspi_cs(1, config, &params->SerialIoSpi1CsPolarity[0],
411 &params->SerialIoSpi1CsEnable[0],
412 &params->SerialIoSpiDefaultCsOutput[1]);
413 configure_gspi_cs(2, config, &params->SerialIoSpi2CsPolarity[0],
414 &params->SerialIoSpi2CsEnable[0],
415 &params->SerialIoSpiDefaultCsOutput[2]);
416 #else
417 for (i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++)
418 configure_gspi_cs(i, config,
419 &params->SerialIoSpiCsPolarity[0], NULL, NULL);
420 #endif
422 /* Chipset Lockdown */
423 if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) {
424 tconfig->PchLockDownGlobalSmi = 0;
425 tconfig->PchLockDownBiosInterface = 0;
426 params->PchLockDownBiosLock = 0;
427 params->PchLockDownRtcMemoryLock = 0;
428 #if CONFIG(SOC_INTEL_COMETLAKE)
430 * Skip SPI Flash Lockdown from inside FSP.
431 * Making this config "0" means FSP won't set the FLOCKDN bit
432 * of SPIBAR + 0x04 (i.e., Bit 15 of BIOS_HSFSTS_CTL).
433 * So, it becomes coreboot's responsibility to set this bit
434 * before end of POST for security concerns.
436 params->SpiFlashCfgLockDown = 0;
437 #endif
438 } else {
439 tconfig->PchLockDownGlobalSmi = 1;
440 tconfig->PchLockDownBiosInterface = 1;
441 params->PchLockDownBiosLock = 1;
442 params->PchLockDownRtcMemoryLock = 1;
443 #if CONFIG(SOC_INTEL_COMETLAKE)
445 * Enable SPI Flash Lockdown from inside FSP.
446 * Making this config "1" means FSP will set the FLOCKDN bit
447 * of SPIBAR + 0x04 (i.e., Bit 15 of BIOS_HSFSTS_CTL).
449 params->SpiFlashCfgLockDown = 1;
450 #endif
454 /* Mainboard GPIO Configuration */
455 __weak void mainboard_silicon_init_params(FSP_S_CONFIG *params)
457 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
460 /* Return list of SOC LPSS controllers */
461 const pci_devfn_t *soc_lpss_controllers_list(size_t *size)
463 *size = ARRAY_SIZE(serial_io_dev);
464 return serial_io_dev;