blob: ec23940f2bba823affbc802f71e932cef22955d9 [file] [log] [blame]
Jonathan Zhang3ed903f2023-01-25 11:37:27 -08001/* SPDX-License-Identifier: GPL-2.0-only */
Patrick Rudolphe357ac32024-02-23 09:47:24 +01002#include <acpi/acpigen_pci.h>
Jonathan Zhang3ed903f2023-01-25 11:37:27 -08003#include <arch/ioapic.h>
4#include <console/console.h>
5#include <console/debug.h>
6#include <cpu/x86/lapic.h>
7#include <device/pci.h>
8#include <device/pci_ids.h>
9#include <device/pciexp.h>
Patrick Rudolph40e07482024-02-23 09:23:41 +010010#include <intelblocks/acpi.h>
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080011#include <intelblocks/gpio.h>
12#include <intelblocks/lpc_lib.h>
13#include <intelblocks/p2sb.h>
14#include <intelblocks/pcr.h>
15#include <intelblocks/tco.h>
16#include <soc/acpi.h>
17#include <soc/chip_common.h>
18#include <soc/crashlog.h>
19#include <soc/numa.h>
20#include <soc/p2sb.h>
21#include <soc/pch.h>
22#include <soc/soc_pch.h>
23#include <soc/pci_devs.h>
24#include <soc/ramstage.h>
25#include <soc/soc_util.h>
26#include <soc/util.h>
27#include <soc/xhci.h>
28
29__weak void mainboard_silicon_init_params(FSPS_UPD *params)
30{
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080031}
32
33/* UPD parameters to be initialized before SiliconInit */
34void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd)
35{
36 mainboard_silicon_init_params(silupd);
37}
38
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080039static struct device_operations cpu_bus_ops = {
40 .read_resources = noop_read_resources,
41 .set_resources = noop_set_resources,
42 .init = mp_cpu_bus_init,
43 .acpi_fill_ssdt = generate_cpu_entries,
44};
45
46struct pci_operations soc_pci_ops = {
47 .set_subsystem = pci_dev_set_subsystem,
48};
49
50static void chip_enable_dev(struct device *dev)
51{
52 /* Set the operations if it is a special bus type */
53 if (dev->path.type == DEVICE_PATH_DOMAIN) {
Shuo Liu255f9272023-03-29 20:14:11 +080054 /* domain ops are assigned at their creation */
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080055 } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
56 dev->ops = &cpu_bus_ops;
57 } else if (dev->path.type == DEVICE_PATH_GPIO) {
58 block_gpio_enable(dev);
59 }
60}
61
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080062static void set_pcu_locks(void)
63{
Patrick Rudolph106d7b32024-01-18 09:14:03 +010064 struct device *dev = NULL;
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080065
Patrick Rudolph106d7b32024-01-18 09:14:03 +010066 while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR0_DEVID, dev))) {
67 printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev));
68 pci_or_config32(dev, PCU_CR0_P_STATE_LIMITS, P_STATE_LIMITS_LOCK);
69 pci_or_config32(dev, PCU_CR0_PACKAGE_RAPL_LIMIT_UPR,
70 PKG_PWR_LIM_LOCK_UPR);
71 pci_or_config32(dev, PCU_CR0_TURBO_ACTIVATION_RATIO,
72 TURBO_ACTIVATION_RATIO_LOCK);
73 }
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080074
Patrick Rudolph106d7b32024-01-18 09:14:03 +010075 dev = NULL;
76 while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR2_DEVID, dev))) {
77 printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev));
78 pci_or_config32(dev, PCU_CR2_DRAM_POWER_INFO_UPR,
79 DRAM_POWER_INFO_LOCK_UPR);
80 pci_or_config32(dev, PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR,
81 PP_PWR_LIM_LOCK_UPR);
82 }
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080083
Patrick Rudolph106d7b32024-01-18 09:14:03 +010084 dev = NULL;
85 while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR3_DEVID, dev))) {
86 printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev));
87 pci_or_config32(dev, PCU_CR3_CONFIG_TDP_CONTROL, TDP_LOCK);
88 }
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080089
Patrick Rudolph106d7b32024-01-18 09:14:03 +010090 dev = NULL;
91 while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR6_DEVID, dev))) {
92 printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev));
93 pci_or_config32(dev, PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_UPR,
94 PLT_PWR_LIM_LOCK_UPR);
95 pci_or_config32(dev, PCU_CR6_PLATFORM_POWER_INFO_CFG_UPR,
96 PLT_PWR_INFO_LOCK_UPR);
Jonathan Zhang3ed903f2023-01-25 11:37:27 -080097 }
98}
99
100static void chip_final(void *data)
101{
102 /* Lock SBI */
103 pci_or_config32(PCH_DEV_P2SB, P2SBC, SBILOCK);
104
105 /* LOCK PAM */
106 pci_or_config32(pcidev_path_on_root(PCI_DEVFN(0, 0)), 0x80, 1 << 0);
107
108 set_pcu_locks();
109 tco_lockdown();
110
111 p2sb_hide();
112
113 /* Accessing xHCI CSR needs to be done after PCI enumeration. */
114 lock_oc_cfg(false);
115 mainboard_override_usb_oc();
116 lock_oc_cfg(true);
117 /* Disable CPU Crashlog to avoid conflict between CPU Crashlog and BMC ACD. */
118 disable_cpu_crashlog();
119
120 set_bios_init_completion();
121}
122
123static void chip_init(void *data)
124{
125 printk(BIOS_DEBUG, "coreboot: calling fsp_silicon_init\n");
126 fsp_silicon_init();
Shuo Liu255f9272023-03-29 20:14:11 +0800127
128 attach_iio_stacks();
129
Jonathan Zhang3ed903f2023-01-25 11:37:27 -0800130 override_hpet_ioapic_bdf();
131 pch_enable_ioapic();
132 pch_lock_dmictl();
133 p2sb_unhide();
134 lock_gpio(false);
135 mainboard_override_fsp_gpio();
136 lock_gpio(true);
137}
138
139struct chip_operations soc_intel_xeon_sp_spr_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +0900140 .name = "Intel SapphireRapids-SP",
141 .enable_dev = chip_enable_dev,
Jonathan Zhang3ed903f2023-01-25 11:37:27 -0800142 .init = chip_init,
143 .final = chip_final,
144};
145
146void lock_gpio(bool lock)
147{
148 if (lock) {
149 pcr_write32(gpio_get_pad_portid(GPPC_B0), PAD_CFG_LOCK_B, 0xffffffff);
150 pcr_write32(gpio_get_pad_portid(GPP_D0), PAD_CFG_LOCK_D, 0xffffffff);
151 } else {
152 pcr_write32(gpio_get_pad_portid(GPPC_B0), PAD_CFG_LOCK_B, 0);
153 pcr_write32(gpio_get_pad_portid(GPP_D0), PAD_CFG_LOCK_D, 0);
154 }
155}
156
157/* Root Complex Event Collector */
158static void rcec_init(struct device *dev)
159{
160 /* Set up RCEC EA extended capability, section 7.9.10 of PCIe 5.0 spec */
161 const unsigned int rcecea_cap =
162 pciexp_find_extended_cap(dev, PCIE_EXT_CAP_RCECEA_ID, 0);
163 if (!rcecea_cap)
164 return;
165
166 pci_devfn_t ecrc_bdf = PCI_BDF(dev);
167 uint32_t ecrc_bus = (ecrc_bdf >> 20) & 0xFFF;
168 uint32_t ecrc_dev = (ecrc_bdf >> 15) & 0x1F;
169
170 /*
171 * Find all CXL devices, and match them with RCEC.
172 * With CXL 1.1, the bus# of CXL device (RCiEP) is 1 bigger than
173 * the bus# of RCEC.
174 */
175 uint32_t ep_bus;
176 uint8_t i;
177 for (i = 0; i < pds.num_pds; i++) {
178 if (pds.pds[i].pd_type == PD_TYPE_PROCESSOR)
179 continue;
Patrick Rudolphf25d58c2024-01-31 11:31:55 +0100180 ep_bus = PCI_BDF(pds.pds[i].dev) >> 20;
Jonathan Zhang3ed903f2023-01-25 11:37:27 -0800181 if (ep_bus == ecrc_bus + 1)
182 break;
183 }
184 if (i == pds.num_pds)
185 return;
186
187 printk(BIOS_DEBUG, "ep_bus: %x, ecrc_dev: %x\n", ep_bus, ecrc_dev);
188 u32 rcecea_bitmap = 0x1 << ecrc_dev;
189 u32 rcecea_busnum = (ep_bus << 8) | (ep_bus << 16);
190 pci_write_config32(dev, rcecea_cap + PCI_RCECEA_BITMAP, rcecea_bitmap);
191 pci_write_config32(dev, rcecea_cap + PCI_RCECEA_BUSNUM, rcecea_busnum);
192}
193
194#define SPR_IEH 0x0b23
195
196static const unsigned short rcec_ids[] = {
197 SPR_IEH,
198 0
199};
200
201static struct device_operations rcec_ops = {
202 .read_resources = pci_dev_read_resources,
203 .set_resources = pci_dev_set_resources,
204 .enable_resources = pci_dev_enable_resources,
205 .init = rcec_init,
206 .ops_pci = &soc_pci_ops,
207};
208
209static const struct pci_driver rcec_driver __pci_driver = {
210 .ops = &rcec_ops,
211 .vendor = PCI_VID_INTEL,
212 .devices = rcec_ids,
213};