soc/intel/apollolake: Hook Up SataPortEnable to devicetree
[coreboot.git] / src / soc / intel / apollolake / chip.c
blobac8dfdf568d5de39045ceaeb3cef2ff5480adc18
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <acpi/acpi.h>
4 #include <bootsplash.h>
5 #include <bootstate.h>
6 #include <console/console.h>
7 #include <cpu/x86/mp.h>
8 #include <device/mmio.h>
9 #include <device/device.h>
10 #include <device/pci.h>
11 #include <device/pci_ops.h>
12 #include <intelblocks/acpi.h>
13 #include <intelblocks/cfg.h>
14 #include <intelblocks/fast_spi.h>
15 #include <intelblocks/msr.h>
16 #include <intelblocks/p2sb.h>
17 #include <intelblocks/power_limit.h>
18 #include <intelblocks/xdci.h>
19 #include <fsp/api.h>
20 #include <fsp/util.h>
21 #include <intelblocks/cpulib.h>
22 #include <intelblocks/gpio.h>
23 #include <intelblocks/itss.h>
24 #include <intelblocks/pmclib.h>
25 #include <intelblocks/systemagent.h>
26 #include <option.h>
27 #include <soc/cpu.h>
28 #include <soc/heci.h>
29 #include <soc/intel/common/vbt.h>
30 #include <soc/iomap.h>
31 #include <soc/itss.h>
32 #include <soc/msr.h>
33 #include <soc/pci_devs.h>
34 #include <soc/pm.h>
35 #include <soc/systemagent.h>
36 #include <spi-generic.h>
37 #include <timer.h>
38 #include <soc/ramstage.h>
39 #include <soc/soc_chip.h>
40 #include <types.h>
42 #include "chip.h"
44 #define DUAL_ROLE_CFG0 0x80d8
45 #define SW_VBUS_VALID_MASK (1 << 24)
46 #define SW_IDPIN_EN_MASK (1 << 21)
47 #define SW_IDPIN_MASK (1 << 20)
48 #define SW_IDPIN_HOST (0 << 20)
49 #define DUAL_ROLE_CFG1 0x80dc
50 #define DRD_MODE_MASK (1 << 29)
51 #define DRD_MODE_HOST (1 << 29)
53 #define CFG_XHCLKGTEN 0x8650
54 /* Naking USB2.0 EPs for Backbone Clock Gating and PLL Shutdown */
55 #define NUEFBCGPS (1 << 28)
56 /* SRAM Power Gate Enable */
57 #define SRAMPGTEN (1 << 27)
58 /* SS Link PLL Shutdown Enable */
59 #define SSLSE (1 << 26)
60 /* USB2 PLL Shutdown Enable */
61 #define USB2PLLSE (1 << 25)
62 /* IOSF Sideband Trunk Clock Gating Enable */
63 #define IOSFSTCGE (1 << 24)
64 /* BIT[23:20] HS Backbone PXP Trunk Clock Gate Enable */
65 #define HSTCGE (1 << 23 | 1 << 22)
66 /* BIT[19:16] SS Backbone PXP Trunk Clock Gate Enable */
67 #define SSTCGE (1 << 19 | 1 << 18 | 1 << 17)
68 /* XHC Ignore_EU3S */
69 #define XHCIGEU3S (1 << 15)
70 /* XHC Frame Timer Clock Shutdown Enable */
71 #define XHCFTCLKSE (1 << 14)
72 /* XHC Backbone PXP Trunk Clock Gate In Presence of ISOCH EP */
73 #define XHCBBTCGIPISO (1 << 13)
74 /* XHC HS Backbone PXP Trunk Clock Gate U2 non RWE */
75 #define XHCHSTCGU2NRWE (1 << 12)
76 /* BIT[11:10] XHC USB2 PLL Shutdown Lx Enable */
77 #define XHCUSB2PLLSDLE (1 << 11 | 1 << 10)
78 /* BIT[9:8] HS Backbone PXP PLL Shutdown Ux Enable */
79 #define HSUXDMIPLLSE (1 << 9)
80 /* BIT[7:5] SS Backbone PXP PLL shutdown Ux Enable */
81 #define SSPLLSUE (1 << 6)
82 /* XHC Backbone Local Clock Gating Enable */
83 #define XHCBLCGE (1 << 4)
84 /* HS Link Trunk Clock Gating Enable */
85 #define HSLTCGE (1 << 3)
86 /* SS Link Trunk Clock Gating Enable */
87 #define SSLTCGE (1 << 2)
88 /* IOSF Backbone Trunk Clock Gating Enable */
89 #define IOSFBTCGE (1 << 1)
90 /* IOSF Gasket Backbone Local Clock Gating Enable */
91 #define IOSFGBLCGE (1 << 0)
93 #define CFG_XHCPMCTRL 0x80a4
94 /* BIT[7:4] LFPS periodic sampling for USB3 Ports */
95 #define LFPS_PM_DISABLE_MASK 0xFFFFFF0F
97 const char *soc_acpi_name(const struct device *dev)
99 if (dev->path.type == DEVICE_PATH_DOMAIN)
100 return "PCI0";
102 if (dev->path.type == DEVICE_PATH_USB) {
103 switch (dev->path.usb.port_type) {
104 case 0:
105 /* Root Hub */
106 return "RHUB";
107 case 2:
108 /* USB2 ports */
109 switch (dev->path.usb.port_id) {
110 case 0: return "HS01";
111 case 1: return "HS02";
112 case 2: return "HS03";
113 case 3: return "HS04";
114 case 4: return "HS05";
115 case 5: return "HS06";
116 case 6: return "HS07";
117 case 7: return "HS08";
118 case 8:
119 if (CONFIG(SOC_INTEL_GEMINILAKE))
120 return "HS09";
122 break;
123 case 3:
124 /* USB3 ports */
125 switch (dev->path.usb.port_id) {
126 case 0: return "SS01";
127 case 1: return "SS02";
128 case 2: return "SS03";
129 case 3: return "SS04";
130 case 4: return "SS05";
131 case 5: return "SS06";
133 break;
135 return NULL;
138 if (dev->path.type != DEVICE_PATH_PCI)
139 return NULL;
141 switch (dev->path.pci.devfn) {
142 /* DSDT: acpi/northbridge.asl */
143 case SA_DEVFN_ROOT:
144 return "MCHC";
145 /* DSDT: acpi/xhci.asl */
146 case PCH_DEVFN_XHCI:
147 return "XHCI";
148 /* DSDT: acpi/pch_hda.asl */
149 case PCH_DEVFN_HDA:
150 return "HDAS";
151 /* DSDT: acpi/lpss.asl */
152 case PCH_DEVFN_UART0:
153 return "URT1";
154 case PCH_DEVFN_UART1:
155 return "URT2";
156 case PCH_DEVFN_UART2:
157 return "URT3";
158 case PCH_DEVFN_UART3:
159 return "URT4";
160 case PCH_DEVFN_SPI0:
161 return "SPI1";
162 case PCH_DEVFN_SPI1:
163 return "SPI2";
164 case PCH_DEVFN_SPI2:
165 return "SPI3";
166 case PCH_DEVFN_PWM:
167 return "PWM";
168 case PCH_DEVFN_I2C0:
169 return "I2C0";
170 case PCH_DEVFN_I2C1:
171 return "I2C1";
172 case PCH_DEVFN_I2C2:
173 return "I2C2";
174 case PCH_DEVFN_I2C3:
175 return "I2C3";
176 case PCH_DEVFN_I2C4:
177 return "I2C4";
178 case PCH_DEVFN_I2C5:
179 return "I2C5";
180 case PCH_DEVFN_I2C6:
181 return "I2C6";
182 case PCH_DEVFN_I2C7:
183 return "I2C7";
184 /* Storage */
185 case PCH_DEVFN_SDCARD:
186 return "SDCD";
187 case PCH_DEVFN_EMMC:
188 return "EMMC";
189 case PCH_DEVFN_SDIO:
190 return "SDIO";
191 /* PCIe */
192 case PCH_DEVFN_PCIE1:
193 return "RP03";
194 case PCH_DEVFN_PCIE5:
195 return "RP01";
198 return NULL;
201 static struct device_operations pci_domain_ops = {
202 .read_resources = pci_domain_read_resources,
203 .set_resources = pci_domain_set_resources,
204 .scan_bus = pci_domain_scan_bus,
205 .acpi_name = &soc_acpi_name,
206 .acpi_fill_ssdt = ssdt_set_above_4g_pci,
209 static struct device_operations cpu_bus_ops = {
210 .read_resources = noop_read_resources,
211 .set_resources = noop_set_resources,
212 .init = apollolake_init_cpus,
213 .acpi_fill_ssdt = generate_cpu_entries,
216 static void enable_dev(struct device *dev)
218 /* Set the operations if it is a special bus type */
219 if (dev->path.type == DEVICE_PATH_DOMAIN)
220 dev->ops = &pci_domain_ops;
221 else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
222 dev->ops = &cpu_bus_ops;
223 else if (dev->path.type == DEVICE_PATH_GPIO)
224 block_gpio_enable(dev);
228 * If the PCIe root port at function 0 is disabled,
229 * the PCIe root ports might be coalesced after FSP silicon init.
230 * The below function will swap the devfn of the first enabled device
231 * in devicetree and function 0 resides a pci device
232 * so that it won't confuse coreboot.
234 static void pcie_update_device_tree(unsigned int devfn0, int num_funcs)
236 struct device *func0;
237 unsigned int devfn;
238 int i;
239 unsigned int inc = PCI_DEVFN(0, 1);
241 func0 = pcidev_path_on_root(devfn0);
242 if (func0 == NULL)
243 return;
245 /* No more functions if function 0 is disabled. */
246 if (pci_read_config32(func0, PCI_VENDOR_ID) == 0xffffffff)
247 return;
249 devfn = devfn0 + inc;
252 * Increase function by 1.
253 * Then find first enabled device to replace func0
254 * as that port was move to func0.
256 for (i = 1; i < num_funcs; i++, devfn += inc) {
257 struct device *dev = pcidev_path_on_root(devfn);
258 if (dev == NULL)
259 continue;
261 if (!dev->enabled)
262 continue;
263 /* Found the first enabled device in given dev number */
264 func0->path.pci.devfn = dev->path.pci.devfn;
265 dev->path.pci.devfn = devfn0;
266 break;
270 static void pcie_override_devicetree_after_silicon_init(void)
272 pcie_update_device_tree(PCH_DEVFN_PCIE1, 4);
273 pcie_update_device_tree(PCH_DEVFN_PCIE5, 2);
276 /* Overwrites the SCI IRQ if another IRQ number is given by device tree. */
277 static void set_sci_irq(void)
279 struct soc_intel_apollolake_config *cfg;
280 uint32_t scis;
282 cfg = config_of_soc();
284 /* Change only if a device tree entry exists. */
285 if (cfg->sci_irq) {
286 scis = soc_read_sci_irq_select();
287 scis &= ~SCI_IRQ_SEL;
288 scis |= (cfg->sci_irq << SCI_IRQ_ADJUST) & SCI_IRQ_SEL;
289 soc_write_sci_irq_select(scis);
293 static void soc_init(void *data)
295 struct soc_power_limits_config *soc_config;
296 config_t *config;
298 /* Snapshot the current GPIO IRQ polarities. FSP is setting a
299 * default policy that doesn't honor boards' requirements. */
300 itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
303 * Clear the GPI interrupt status and enable registers. These
304 * registers do not get reset to default state when booting from S5.
306 gpi_clear_int_cfg();
308 fsp_silicon_init();
310 /* Restore GPIO IRQ polarities back to previous settings. */
311 itss_restore_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
313 /* override 'enabled' setting in device tree if needed */
314 pcie_override_devicetree_after_silicon_init();
317 * Keep the P2SB device visible so it and the other devices are
318 * visible in coreboot for driver support and PCI resource allocation.
319 * There is a UPD setting for this, but it's more consistent to use
320 * hide and unhide symmetrically.
322 p2sb_unhide();
324 config = config_of_soc();
325 /* Set RAPL MSR for Package power limits */
326 soc_config = &config->power_limits_config;
327 set_power_limits(MOBILE_SKU_PL1_TIME_SEC, soc_config);
330 * FSP-S routes SCI to IRQ 9. With the help of this function you can
331 * select another IRQ for SCI.
333 set_sci_irq();
336 static void soc_final(void *data)
338 /* Make sure payload/OS can't trigger global reset */
339 pmc_global_reset_disable_and_lock();
342 static void disable_dev(struct device *dev, FSP_S_CONFIG *silconfig)
344 switch (dev->path.pci.devfn) {
345 case PCH_DEVFN_NPK:
347 * Disable this device in the parse_devicetree_setting() function
348 * in romstage.c
350 break;
351 case PCH_DEVFN_ISH:
352 silconfig->IshEnable = 0;
353 break;
354 case PCH_DEVFN_SATA:
355 silconfig->EnableSata = 0;
356 break;
357 case PCH_DEVFN_PCIE5:
358 silconfig->PcieRootPortEn[0] = 0;
359 silconfig->PcieRpHotPlug[0] = 0;
360 break;
361 case PCH_DEVFN_PCIE6:
362 silconfig->PcieRootPortEn[1] = 0;
363 silconfig->PcieRpHotPlug[1] = 0;
364 break;
365 case PCH_DEVFN_PCIE1:
366 silconfig->PcieRootPortEn[2] = 0;
367 silconfig->PcieRpHotPlug[2] = 0;
368 break;
369 case PCH_DEVFN_PCIE2:
370 silconfig->PcieRootPortEn[3] = 0;
371 silconfig->PcieRpHotPlug[3] = 0;
372 break;
373 case PCH_DEVFN_PCIE3:
374 silconfig->PcieRootPortEn[4] = 0;
375 silconfig->PcieRpHotPlug[4] = 0;
376 break;
377 case PCH_DEVFN_PCIE4:
378 silconfig->PcieRootPortEn[5] = 0;
379 silconfig->PcieRpHotPlug[5] = 0;
380 break;
381 case PCH_DEVFN_XHCI:
382 silconfig->Usb30Mode = 0;
383 break;
384 case PCH_DEVFN_XDCI:
385 silconfig->UsbOtg = 0;
386 break;
387 case PCH_DEVFN_I2C0:
388 silconfig->I2c0Enable = 0;
389 break;
390 case PCH_DEVFN_I2C1:
391 silconfig->I2c1Enable = 0;
392 break;
393 case PCH_DEVFN_I2C2:
394 silconfig->I2c2Enable = 0;
395 break;
396 case PCH_DEVFN_I2C3:
397 silconfig->I2c3Enable = 0;
398 break;
399 case PCH_DEVFN_I2C4:
400 silconfig->I2c4Enable = 0;
401 break;
402 case PCH_DEVFN_I2C5:
403 silconfig->I2c5Enable = 0;
404 break;
405 case PCH_DEVFN_I2C6:
406 silconfig->I2c6Enable = 0;
407 break;
408 case PCH_DEVFN_I2C7:
409 silconfig->I2c7Enable = 0;
410 break;
411 case PCH_DEVFN_UART0:
412 silconfig->Hsuart0Enable = 0;
413 break;
414 case PCH_DEVFN_UART1:
415 silconfig->Hsuart1Enable = 0;
416 break;
417 case PCH_DEVFN_UART2:
418 silconfig->Hsuart2Enable = 0;
419 break;
420 case PCH_DEVFN_UART3:
421 silconfig->Hsuart3Enable = 0;
422 break;
423 case PCH_DEVFN_SPI0:
424 silconfig->Spi0Enable = 0;
425 break;
426 case PCH_DEVFN_SPI1:
427 silconfig->Spi1Enable = 0;
428 break;
429 case PCH_DEVFN_SPI2:
430 silconfig->Spi2Enable = 0;
431 break;
432 case PCH_DEVFN_SDCARD:
433 silconfig->SdcardEnabled = 0;
434 break;
435 case PCH_DEVFN_EMMC:
436 silconfig->eMMCEnabled = 0;
437 break;
438 case PCH_DEVFN_SDIO:
439 silconfig->SdioEnabled = 0;
440 break;
441 case PCH_DEVFN_SMBUS:
442 silconfig->SmbusEnable = 0;
443 break;
444 #if !CONFIG(SOC_INTEL_GEMINILAKE)
445 case SA_DEVFN_IPU:
446 silconfig->IpuEn = 0;
447 break;
448 #else
449 case PCH_DEVFN_CNVI:
450 silconfig->CnviMode = 0;
451 break;
452 case PCH_DEVFN_UFS:
453 silconfig->UfsEnabled = 0;
454 break;
455 #endif
456 case PCH_DEVFN_HDA:
457 silconfig->HdaEnable = 0;
458 break;
459 default:
460 printk(BIOS_WARNING, "PCI:%02x.%01x: Could not disable the device\n",
461 PCI_SLOT(dev->path.pci.devfn),
462 PCI_FUNC(dev->path.pci.devfn));
463 break;
467 static void parse_devicetree(FSP_S_CONFIG *silconfig)
469 struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT);
471 if (!dev) {
472 printk(BIOS_ERR, "Could not find root device\n");
473 return;
475 /* Only disable bus 0 devices. */
476 for (dev = dev->bus->children; dev; dev = dev->sibling) {
477 if (!dev->enabled)
478 disable_dev(dev, silconfig);
482 static void apl_fsp_silicon_init_params_cb(struct soc_intel_apollolake_config
483 *cfg, FSP_S_CONFIG *silconfig)
485 #if !CONFIG(SOC_INTEL_GEMINILAKE) /* GLK FSP does not have these fields in FspsUpd.h yet */
486 uint8_t port;
488 for (port = 0; port < APOLLOLAKE_USB2_PORT_MAX; port++) {
489 if (cfg->usb_config_override) {
490 if (!cfg->usb2_port[port].enable)
491 continue;
493 silconfig->PortUsb20Enable[port] = 1;
494 silconfig->PortUs20bOverCurrentPin[port] = cfg->usb2_port[port].oc_pin;
497 if (cfg->usb2eye[port].Usb20PerPortTxPeHalf != 0)
498 silconfig->PortUsb20PerPortTxPeHalf[port] =
499 cfg->usb2eye[port].Usb20PerPortTxPeHalf;
501 if (cfg->usb2eye[port].Usb20PerPortPeTxiSet != 0)
502 silconfig->PortUsb20PerPortPeTxiSet[port] =
503 cfg->usb2eye[port].Usb20PerPortPeTxiSet;
505 if (cfg->usb2eye[port].Usb20PerPortTxiSet != 0)
506 silconfig->PortUsb20PerPortTxiSet[port] =
507 cfg->usb2eye[port].Usb20PerPortTxiSet;
509 if (cfg->usb2eye[port].Usb20HsSkewSel != 0)
510 silconfig->PortUsb20HsSkewSel[port] =
511 cfg->usb2eye[port].Usb20HsSkewSel;
513 if (cfg->usb2eye[port].Usb20IUsbTxEmphasisEn != 0)
514 silconfig->PortUsb20IUsbTxEmphasisEn[port] =
515 cfg->usb2eye[port].Usb20IUsbTxEmphasisEn;
517 if (cfg->usb2eye[port].Usb20PerPortRXISet != 0)
518 silconfig->PortUsb20PerPortRXISet[port] =
519 cfg->usb2eye[port].Usb20PerPortRXISet;
521 if (cfg->usb2eye[port].Usb20HsNpreDrvSel != 0)
522 silconfig->PortUsb20HsNpreDrvSel[port] =
523 cfg->usb2eye[port].Usb20HsNpreDrvSel;
526 if (cfg->usb_config_override) {
527 for (port = 0; port < APOLLOLAKE_USB3_PORT_MAX; port++) {
528 if (!cfg->usb3_port[port].enable)
529 continue;
531 silconfig->PortUsb30Enable[port] = 1;
532 silconfig->PortUs30bOverCurrentPin[port] = cfg->usb3_port[port].oc_pin;
535 #endif
538 static void glk_fsp_silicon_init_params_cb(
539 struct soc_intel_apollolake_config *cfg, FSP_S_CONFIG *silconfig)
541 #if CONFIG(SOC_INTEL_GEMINILAKE)
542 uint8_t port;
545 * UsbPerPortCtl was retired in Fsp 2.0.0+, so PDO programming must be
546 * enabled to configure individual ports in what Fsp thinks is PEI.
548 silconfig->UsbPdoProgramming = cfg->usb_config_override;
550 for (port = 0; port < APOLLOLAKE_USB2_PORT_MAX; port++) {
551 if (cfg->usb_config_override) {
552 silconfig->PortUsb20Enable[port] = cfg->usb2_port[port].enable;
553 silconfig->PortUs20bOverCurrentPin[port] = cfg->usb2_port[port].oc_pin;
556 if (!cfg->usb2eye[port].Usb20OverrideEn)
557 continue;
559 silconfig->Usb2AfePehalfbit[port] =
560 cfg->usb2eye[port].Usb20PerPortTxPeHalf;
561 silconfig->Usb2AfePetxiset[port] =
562 cfg->usb2eye[port].Usb20PerPortPeTxiSet;
563 silconfig->Usb2AfeTxiset[port] =
564 cfg->usb2eye[port].Usb20PerPortTxiSet;
565 silconfig->Usb2AfePredeemp[port] =
566 cfg->usb2eye[port].Usb20IUsbTxEmphasisEn;
569 if (cfg->usb_config_override) {
570 for (port = 0; port < APOLLOLAKE_USB3_PORT_MAX; port++) {
571 silconfig->PortUsb30Enable[port] = cfg->usb3_port[port].enable;
572 silconfig->PortUs30bOverCurrentPin[port] = cfg->usb3_port[port].oc_pin;
576 silconfig->Gmm = is_devfn_enabled(SA_GLK_DEVFN_GMM);
578 /* On Geminilake, we need to override the default FSP PCIe de-emphasis
579 * settings using the device tree settings. This is because PCIe
580 * de-emphasis is enabled by default and Thunderpeak PCIe WiFi detection
581 * requires de-emphasis disabled. If we make this change common to both
582 * Apollolake and Geminilake, then we need to add mainboard device tree
583 * de-emphasis settings of 1 to Apollolake systems.
585 memcpy(silconfig->PcieRpSelectableDeemphasis,
586 cfg->pcie_rp_deemphasis_enable,
587 sizeof(silconfig->PcieRpSelectableDeemphasis));
589 * FSP does not know what the clock requirements are for the
590 * device on SPI bus, hence it should not modify what coreboot
591 * has set up. Hence skipping in FSP.
593 silconfig->SkipSpiPCP = 1;
596 * FSP provides UPD interface to execute IPC command. In order to
597 * improve boot performance, configure PmicPmcIpcCtrl for PMC to program
598 * PMIC PCH_PWROK delay.
600 silconfig->PmicPmcIpcCtrl = cfg->PmicPmcIpcCtrl;
603 * Options to disable XHCI Link Compliance Mode.
605 silconfig->DisableComplianceMode = cfg->DisableComplianceMode;
608 * Options to change USB3 ModPhy setting for Integrated Filter value.
610 silconfig->ModPhyIfValue = cfg->ModPhyIfValue;
613 * Options to bump USB3 LDO voltage with 40mv.
615 silconfig->ModPhyVoltageBump = cfg->ModPhyVoltageBump;
618 * Options to adjust PMIC Vdd2 voltage.
620 silconfig->PmicVdd2Voltage = cfg->PmicVdd2Voltage;
622 /* FSP should let coreboot set subsystem IDs, which are read/write-once */
623 silconfig->SiSVID = 0;
624 silconfig->SiSSID = 0;
625 silconfig->HgSubSystemId = 0;
626 #endif
629 void __weak mainboard_devtree_update(struct device *dev)
631 /* Override dev tree settings per board */
634 void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
636 FSP_S_CONFIG *silconfig = &silupd->FspsConfig;
637 struct soc_intel_apollolake_config *cfg;
638 struct device *dev;
640 /* Load VBT before devicetree-specific config. */
641 silconfig->GraphicsConfigPtr = (uintptr_t)vbt_get();
643 dev = pcidev_path_on_root(SA_DEVFN_ROOT);
644 cfg = config_of(dev);
646 mainboard_devtree_update(dev);
648 /* Parse device tree and disable unused device*/
649 parse_devicetree(silconfig);
651 memcpy(silconfig->PcieRpClkReqNumber, cfg->pcie_rp_clkreq_pin,
652 sizeof(silconfig->PcieRpClkReqNumber));
654 memcpy(silconfig->PcieRpHotPlug, cfg->pcie_rp_hotplug_enable,
655 sizeof(silconfig->PcieRpHotPlug));
657 switch (cfg->serirq_mode) {
658 case SERIRQ_QUIET:
659 silconfig->SirqEnable = 1;
660 silconfig->SirqMode = 0;
661 break;
662 case SERIRQ_CONTINUOUS:
663 silconfig->SirqEnable = 1;
664 silconfig->SirqMode = 1;
665 break;
666 case SERIRQ_OFF:
667 default:
668 silconfig->SirqEnable = 0;
669 break;
672 if (cfg->emmc_tx_cmd_cntl != 0)
673 silconfig->EmmcTxCmdCntl = cfg->emmc_tx_cmd_cntl;
674 if (cfg->emmc_tx_data_cntl1 != 0)
675 silconfig->EmmcTxDataCntl1 = cfg->emmc_tx_data_cntl1;
676 if (cfg->emmc_tx_data_cntl2 != 0)
677 silconfig->EmmcTxDataCntl2 = cfg->emmc_tx_data_cntl2;
678 if (cfg->emmc_rx_cmd_data_cntl1 != 0)
679 silconfig->EmmcRxCmdDataCntl1 = cfg->emmc_rx_cmd_data_cntl1;
680 if (cfg->emmc_rx_strobe_cntl != 0)
681 silconfig->EmmcRxStrobeCntl = cfg->emmc_rx_strobe_cntl;
682 if (cfg->emmc_rx_cmd_data_cntl2 != 0)
683 silconfig->EmmcRxCmdDataCntl2 = cfg->emmc_rx_cmd_data_cntl2;
684 if (cfg->emmc_host_max_speed != 0)
685 silconfig->eMMCHostMaxSpeed = cfg->emmc_host_max_speed;
687 memcpy(silconfig->SataPortsHotPlug, cfg->SataPortsHotPlug,
688 sizeof(silconfig->SataPortsHotPlug));
690 silconfig->LPSS_S0ixEnable = cfg->lpss_s0ix_enable;
692 /* Disable monitor mwait since it is broken due to a hardware bug
693 * without a fix. Specific to Apollolake.
695 if (!CONFIG(SOC_INTEL_GEMINILAKE))
696 silconfig->MonitorMwaitEnable = 0;
698 silconfig->SkipMpInit = !CONFIG(USE_INTEL_FSP_MP_INIT);
700 /* Disable setting of EISS bit in FSP. */
701 silconfig->SpiEiss = 0;
703 /* Disable FSP from locking access to the RTC NVRAM */
704 silconfig->RtcLock = 0;
706 /* Enable Audio clk gate and power gate */
707 silconfig->HDAudioClkGate = cfg->hdaudio_clk_gate_enable;
708 silconfig->HDAudioPwrGate = cfg->hdaudio_pwr_gate_enable;
709 /* BIOS config lockdown Audio clk and power gate */
710 silconfig->BiosCfgLockDown = cfg->hdaudio_bios_config_lockdown;
711 if (CONFIG(SOC_INTEL_GEMINILAKE))
712 glk_fsp_silicon_init_params_cb(cfg, silconfig);
713 else
714 apl_fsp_silicon_init_params_cb(cfg, silconfig);
716 silconfig->UsbOtg = xdci_can_enable(PCH_DEVFN_XDCI);
718 silconfig->VmxEnable = CONFIG(ENABLE_VMX);
720 /* Enable enhanced C-states */
721 silconfig->C1e = cfg->enhanced_cstates;
723 /* Set VTD feature according to devicetree */
724 silconfig->VtdEnable = get_uint_option("vtd", cfg->enable_vtd);
726 silconfig->PeiGraphicsPeimInit = CONFIG(RUN_FSP_GOP) && is_devfn_enabled(SA_DEVFN_IGD);
728 silconfig->PavpEnable = CONFIG(PAVP);
730 /* SATA config */
731 if (is_devfn_enabled(PCH_DEVFN_SATA)) {
732 silconfig->SataSalpSupport = !(cfg->DisableSataSalpSupport);
733 memcpy(silconfig->SataPortsEnable, cfg->SataPortsEnable,
734 sizeof(silconfig->SataPortsEnable));
737 /* 8254 Timer */
738 bool use_8254 = get_uint_option("legacy_8254_timer", CONFIG(USE_LEGACY_8254_TIMER));
739 silconfig->Timer8254ClkSetting = use_8254;
741 /* FSP should let coreboot set subsystem IDs, which are read/write-once */
742 silconfig->SubSystemVendorId = 0;
743 silconfig->SubSystemId = 0;
745 mainboard_silicon_init_params(silconfig);
748 struct chip_operations soc_intel_apollolake_ops = {
749 CHIP_NAME("Intel Apollolake SOC")
750 .enable_dev = &enable_dev,
751 .init = &soc_init,
752 .final = &soc_final
755 static void soc_enable_untrusted_mode(void *unused)
758 * Set Bit 6 (ENABLE_IA_UNTRUSTED_MODE) of MSR 0x120
759 * UCODE_PCR_POWER_MISC MSR to enter IA Untrusted Mode.
761 msr_set(MSR_POWER_MISC, ENABLE_IA_UNTRUSTED);
764 static void drop_privilege_all(void)
766 /* Drop privilege level on all the CPUs */
767 if (mp_run_on_all_cpus(&soc_enable_untrusted_mode, NULL) != CB_SUCCESS)
768 printk(BIOS_ERR, "failed to enable untrusted mode\n");
771 static void configure_xhci_host_mode_port0(void)
773 uint32_t *cfg0;
774 uint32_t *cfg1;
775 const struct resource *res;
776 uint32_t reg;
777 struct stopwatch sw;
778 struct device *xhci_dev = PCH_DEV_XHCI;
780 printk(BIOS_INFO, "Putting xHCI port 0 into host mode.\n");
781 res = find_resource(xhci_dev, PCI_BASE_ADDRESS_0);
782 cfg0 = (void *)(uintptr_t)(res->base + DUAL_ROLE_CFG0);
783 cfg1 = (void *)(uintptr_t)(res->base + DUAL_ROLE_CFG1);
784 reg = read32(cfg0);
785 if (!(reg & SW_IDPIN_EN_MASK))
786 return;
788 reg &= ~(SW_IDPIN_MASK | SW_VBUS_VALID_MASK);
789 write32(cfg0, reg);
791 stopwatch_init_msecs_expire(&sw, 10);
792 /* Wait for the host mode status bit. */
793 while ((read32(cfg1) & DRD_MODE_MASK) != DRD_MODE_HOST) {
794 if (stopwatch_expired(&sw)) {
795 printk(BIOS_ERR, "Timed out waiting for host mode.\n");
796 return;
800 printk(BIOS_INFO, "xHCI port 0 host switch over took %lu ms\n",
801 stopwatch_duration_msecs(&sw));
804 static int check_xdci_enable(void)
806 return is_dev_enabled(pcidev_path_on_root(PCH_DEVFN_XDCI));
809 static void disable_xhci_lfps_pm(void)
811 struct soc_intel_apollolake_config *cfg;
813 cfg = config_of_soc();
815 if (cfg->disable_xhci_lfps_pm) {
816 void *addr;
817 const struct resource *res;
818 uint32_t reg;
819 struct device *xhci_dev = PCH_DEV_XHCI;
821 res = find_resource(xhci_dev, PCI_BASE_ADDRESS_0);
822 addr = (void *)(uintptr_t)(res->base + CFG_XHCPMCTRL);
823 reg = read32(addr);
824 printk(BIOS_DEBUG, "XHCI PM: control reg=0x%x.\n", reg);
825 if (reg) {
826 reg &= LFPS_PM_DISABLE_MASK;
827 write32(addr, reg);
828 printk(BIOS_INFO, "XHCI PM: Disable xHCI LFPS as configured in devicetree.\n");
833 void platform_fsp_notify_status(enum fsp_notify_phase phase)
835 if (phase == END_OF_FIRMWARE) {
838 * Before hiding P2SB device and dropping privilege level,
839 * dump CSE status and disable HECI1 interface.
841 heci_cse_lockdown();
843 /* Hide the P2SB device to align with previous behavior. */
844 p2sb_hide();
847 * As per guidelines BIOS is recommended to drop CPU privilege
848 * level to IA_UNTRUSTED. After that certain device registers
849 * and MSRs become inaccessible supposedly increasing system
850 * security.
852 drop_privilege_all();
855 * When USB OTG is set, GLK FSP enables xHCI SW ID pin and
856 * configures USB-C as device mode. Force USB-C into host mode.
858 if (check_xdci_enable())
859 configure_xhci_host_mode_port0();
862 * Override GLK xhci clock gating register(XHCLKGTEN) to
863 * mitigate USB device suspend and resume failure.
865 if (CONFIG(SOC_INTEL_GEMINILAKE)) {
866 uint32_t *cfg;
867 const struct resource *res;
868 uint32_t reg;
869 struct device *xhci_dev = PCH_DEV_XHCI;
871 res = find_resource(xhci_dev, PCI_BASE_ADDRESS_0);
872 cfg = (void *)(uintptr_t)(res->base + CFG_XHCLKGTEN);
873 reg = SRAMPGTEN | SSLSE | USB2PLLSE | IOSFSTCGE |
874 HSTCGE | HSUXDMIPLLSE | SSTCGE | XHCFTCLKSE |
875 XHCBBTCGIPISO | XHCUSB2PLLSDLE | SSPLLSUE |
876 XHCBLCGE | HSLTCGE | SSLTCGE | IOSFBTCGE |
877 IOSFGBLCGE;
878 write32(cfg, reg);
881 /* Disable XHCI LFPS power management if the option in dev tree is set. */
882 disable_xhci_lfps_pm();
887 * spi_flash init() needs to run unconditionally on every boot (including
888 * resume) to allow write protect to be disabled for eventlog and nvram
889 * updates. This needs to be done as early as possible in ramstage. Thus, add a
890 * callback for entry into BS_PRE_DEVICE.
892 static void spi_flash_init_cb(void *unused)
894 fast_spi_init();
897 __weak
898 void mainboard_silicon_init_params(FSP_S_CONFIG *silconfig)
900 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
903 /* Handle FSP logo params */
904 void soc_load_logo(FSPS_UPD *supd)
906 bmp_load_logo(&supd->FspsConfig.LogoPtr, &supd->FspsConfig.LogoSize);
909 BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_flash_init_cb, NULL);