soc/mediatek/mt8196: Initialize SSPM
[coreboot.git] / src / soc / intel / snowridge / chip.c
blobf08161e7e8d3efa5dace30ca080fc3561238f0cb
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi.h>
4 #include <cbfs.h>
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/pci_def.h>
8 #include <device/pci_ops.h>
9 #include <device/resource.h>
10 #include <fsp/api.h>
11 #include <intelblocks/acpi.h>
12 #include <intelblocks/irq.h>
13 #include <ramstage.h>
14 #include <soc/acpi.h>
15 #include <soc/pci_devs.h>
16 #include <stdbool.h>
17 #include <stdint.h>
19 #include "chip.h"
20 #include "common/fsp_hob.h"
22 static void soc_silicon_init_params(FSPS_UPD *supd)
24 const struct microcode *microcode_file;
25 size_t microcode_len;
27 microcode_file = cbfs_map("cpu_microcode_blob.bin", &microcode_len);
28 if (microcode_file && (microcode_len != 0)) {
29 supd->FspsConfig.PcdCpuMicrocodePatchBase = (UINT32)microcode_file;
30 supd->FspsConfig.PcdCpuMicrocodePatchSize = (UINT32)microcode_len;
34 /* UPD parameters to be initialized before SiliconInit */
35 void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
37 soc_silicon_init_params(supd);
38 mainboard_silicon_init_params(supd);
41 static void chip_domain_resource_table_init(config_t *chip_info)
43 memset(&chip_info->domain, 0, sizeof(chip_info->domain));
44 /**
45 * Valid resource range meets base <= limit.
47 for (int i = 0; i < MAX_DOMAIN; i++) {
48 chip_info->domain[i].bus_base = UINT8_MAX;
49 chip_info->domain[i].io_base = UINT16_MAX;
50 chip_info->domain[i].mem32_base = UINT32_MAX;
51 chip_info->domain[i].mem64_base = UINT64_MAX;
55 static void chip_domain_resource_table_load(config_t *chip_info)
57 const BL_IIO_UDS *hob = fsp_hob_get_iio_uds_data();
58 if (!hob)
59 die("FSP HOB IIO UDS DATA not found!\n");
61 /**
62 * Assert for `numofIIO` and `BL_MAX_LOGIC_IIO_STACK` so the following loop effects.
64 assert(hob->PlatformData.numofIIO == 1);
65 assert(BL_MAX_LOGIC_IIO_STACK);
67 const BL_STACK_RES *stack_res = hob->PlatformData.IIO_resource[0].StackRes;
68 for (int i = 0; i < BL_MAX_LOGIC_IIO_STACK; i++) {
69 struct snr_domain *domain = &chip_info->domain[i];
70 domain->personality = stack_res[i].Personality;
72 /**
73 * SNR FSP uses specific enumerations for different type of stacks, see
74 * vendorcode/intel/fsp/fsp2_0/snowridge/FspmUpd.h.
76 if (stack_res[i].Personality >= BL_TYPE_DISABLED)
77 continue;
79 if (stack_res[i].BusBase > stack_res[i].BusLimit)
80 die("Incorrect bus base 0x%02x and limit 0x%02x for domain %d",
81 stack_res[i].BusBase, stack_res[i].BusLimit, i);
83 domain->bus_base = stack_res[i].BusBase;
84 domain->bus_limit = stack_res[i].BusLimit;
86 /**
87 * Stack with `BL_TYPE_RESERVED` personality has valid bus range but no IO and MMIO resources.
89 if (stack_res[i].Personality == BL_TYPE_RESERVED)
90 continue;
92 domain->enabled = true;
94 /**
95 * Only non-zero resource base is valid.
97 if (stack_res[i].PciResourceIoBase) {
98 if (stack_res[i].PciResourceIoBase > stack_res[i].PciResourceIoLimit)
99 die("Incorrect IO base 0x%04x and limit 0x%04x for domain %d",
100 stack_res[i].PciResourceIoBase,
101 stack_res[i].PciResourceIoLimit, i);
103 domain->io_base = stack_res[i].PciResourceIoBase;
104 domain->io_limit = stack_res[i].PciResourceIoLimit;
107 if (stack_res[i].PciResourceMem32Base) {
108 if (stack_res[i].PciResourceMem32Base >
109 stack_res[i].PciResourceMem32Limit)
110 die("Incorrect Mem32 base 0x%08x and limit 0x%08x for domain %d",
111 stack_res[i].PciResourceMem32Base,
112 stack_res[i].PciResourceMem32Limit, i);
114 domain->mem32_base = stack_res[i].PciResourceMem32Base;
115 domain->mem32_limit = stack_res[i].PciResourceMem32Limit;
118 if (stack_res[i].PciResourceMem64Base) {
119 if (stack_res[i].PciResourceMem64Base >
120 stack_res[i].PciResourceMem64Limit)
121 die("Incorrect Mem64 base 0x%16llx and limit 0x%16llx for domain %d",
122 stack_res[i].PciResourceMem64Base,
123 stack_res[i].PciResourceMem64Limit, i);
125 domain->mem64_base = stack_res[i].PciResourceMem64Base;
126 domain->mem64_limit = stack_res[i].PciResourceMem64Limit;
131 static void chip_cfg_domain_resource_table_split(config_t *chip_info, int base_domain_index,
132 int addtional_domain_index)
134 assert(base_domain_index < MAX_DOMAIN);
135 assert(addtional_domain_index < MAX_DOMAIN);
137 struct snr_domain *base_domain = &chip_info->domain[base_domain_index];
138 struct snr_domain *addtional_domain = &chip_info->domain[addtional_domain_index];
139 memcpy(addtional_domain, base_domain, sizeof(*addtional_domain));
142 * Base + (Limit - Base) / 2 to avoid overflow.
144 if (base_domain->bus_base < base_domain->bus_limit) {
145 base_domain->bus_limit = base_domain->bus_base +
146 (base_domain->bus_limit - base_domain->bus_base) / 2;
147 addtional_domain->bus_base = base_domain->bus_limit + 1;
150 if (base_domain->io_base < base_domain->io_limit) {
151 base_domain->io_limit = base_domain->io_base +
152 (base_domain->io_limit - base_domain->io_base) / 2;
153 addtional_domain->io_base = base_domain->io_limit + 1;
156 if (base_domain->mem32_base < base_domain->mem32_limit) {
157 base_domain->mem32_limit =
158 base_domain->mem32_base +
159 (base_domain->mem32_limit - base_domain->mem32_base) / 2;
160 addtional_domain->mem32_base = base_domain->mem32_limit + 1;
163 if (base_domain->mem64_base < base_domain->mem64_limit) {
164 base_domain->mem64_limit =
165 base_domain->mem64_base +
166 (base_domain->mem64_limit - base_domain->mem64_base) / 2;
167 addtional_domain->mem64_base = base_domain->mem64_limit + 1;
171 static void chip_domain_resource_table_handle_multi_root(config_t *chip_info)
174 * Split domains that have more than 1 root bus.
176 int addtional_domain = BL_MAX_LOGIC_IIO_STACK;
177 chip_cfg_domain_resource_table_split(chip_info, 7,
178 addtional_domain++); /**< Domain 8 (Ubox1). */
180 if (chip_info->domain[2].enabled)
181 chip_cfg_domain_resource_table_split(
182 chip_info, 2,
183 addtional_domain++); /**< Domain 2 (S2) has an extra root bus for Intel DLB. */
186 static void chip_domain_resource_table_dump(config_t *chip_info)
188 printk(BIOS_DEBUG,
189 "---------------------------------------------------------------------------------------------------------------------\n"
190 "| Domain | Enabled | Bus Base/Limit | IO Base/Limit | Mem32 Base/Limit | Mem64 Base/Limit |\n"
191 "---------------------------------------------------------------------------------------------------------------------\n");
192 for (int i = 0; i < MAX_DOMAIN; i++) {
193 struct snr_domain *domain = &chip_info->domain[i];
194 printk(BIOS_DEBUG,
195 "| %2u | %c(0x%02x) | 0x%02x/0x%02x | 0x%04x/0x%04x | 0x%08x/0x%08x | 0x%016llx/0x%016llx |\n",
196 i, domain->enabled ? 'Y' : 'N', domain->personality, domain->bus_base,
197 domain->bus_limit, domain->io_base, domain->io_limit, domain->mem32_base,
198 domain->mem32_limit, domain->mem64_base, domain->mem64_limit);
200 printk(BIOS_DEBUG,
201 "---------------------------------------------------------------------------------------------------------------------\n");
204 static void chip_domain_resource_table_fill(config_t *chip_info)
206 chip_domain_resource_table_init(chip_info);
207 chip_domain_resource_table_load(chip_info);
208 chip_domain_resource_table_handle_multi_root(chip_info);
209 chip_domain_resource_table_dump(chip_info);
212 static void devicetree_domain_definition_update(config_t *chip_info)
214 struct device *dev = NULL;
215 int domain;
218 * Check static domain id agaginst dynamic and fill domain device.
220 while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)) != NULL) {
221 domain = dev_get_domain_id(dev);
222 if (domain >= MAX_DOMAIN)
223 die("Incorrect domain[%d] in devicetree\n", domain);
225 chip_info->domain[domain].dev = dev;
227 printk(BIOS_SPEW, "%s -> domain[%d] defined in devicetree\n", dev_path(dev),
228 domain);
231 if (!chip_info->domain[0].dev)
232 die("Please add domain 0 to device tree!\n");
234 for (domain = 0; domain < MAX_DOMAIN; domain++) {
235 if (!chip_info->domain[domain].enabled) {
236 if (chip_info->domain[domain].dev &&
237 chip_info->domain[domain].dev->enabled) {
238 printk(BIOS_WARNING,
239 "Domain[%d] is disabled, reserved or not existed but defined in device tree!\n",
240 domain);
241 dev_set_enabled(chip_info->domain[domain].dev, false);
243 continue;
246 if (!chip_info->domain[domain].dev)
247 die("Domain[%d] is enabled but not defined in device tree!\n", domain);
249 dev = chip_info->domain[domain].dev;
251 printk(BIOS_SPEW, "Domain[%d] is enabled, updating PCI root bus to 0x%02x\n",
252 domain, chip_info->domain[domain].bus_base);
254 /* Use same bus number for secondary and subordinate before PCI enumeration. */
255 dev->downstream->secondary = dev->downstream->subordinate =
256 chip_info->domain[domain].bus_base;
257 dev->downstream->max_subordinate = chip_info->domain[domain].bus_limit;
261 static void soc_init_pre_device(void *chip_info)
263 fsp_silicon_init();
265 chip_domain_resource_table_fill((config_t *)chip_info);
267 devicetree_domain_definition_update((config_t *)chip_info);
270 static void domain_read_resources(struct device *dev)
272 struct resource *res;
273 uint8_t index = 0;
274 const uint8_t domain = dev->path.domain.domain_id;
275 const config_t *chip_info = dev->chip_info;
277 printk(BIOS_DEBUG, "Reading resources for %s\n", dev_path(dev));
280 * Allocate IO resource.
282 if (chip_info->domain[domain].io_limit >= chip_info->domain[domain].io_base) {
283 res = new_resource(dev, index++);
284 if (!res)
285 die("Allocate resource for %s failed!\n", dev_path(dev));
287 res->base = chip_info->domain[domain].io_base;
288 res->limit = chip_info->domain[domain].io_limit;
289 res->size = res->limit - res->base + 1;
290 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED;
291 printk(BIOS_SPEW, "IO Base/Limit: 0x%04llx/0x%04llx\n", res->base, res->limit);
295 * Allocate Mem32 resource.
297 if (chip_info->domain[domain].mem32_limit >= chip_info->domain[domain].mem32_base) {
298 res = new_resource(dev, index++);
299 if (!res)
300 die("Allocate resource for %s failed!\n", dev_path(dev));
302 res->base = chip_info->domain[domain].mem32_base;
303 res->limit = chip_info->domain[domain].mem32_limit;
304 res->size = res->limit - res->base + 1;
305 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
306 printk(BIOS_SPEW, "Mem32 Base/Limit: 0x%08llx/0x%08llx\n", res->base,
307 res->limit);
311 * Allocate Mem64 resource.
313 if (chip_info->domain[domain].mem64_limit >= chip_info->domain[domain].mem64_base) {
314 res = new_resource(dev, index++);
315 if (!res)
316 die("Allocate resource for %s failed!\n", dev_path(dev));
318 res->base = chip_info->domain[domain].mem64_base;
319 res->limit = chip_info->domain[domain].mem64_limit;
320 res->size = res->limit - res->base + 1;
321 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_PCI64 |
322 IORESOURCE_ABOVE_4G;
323 printk(BIOS_SPEW, "Mem64 Base/Limit: 0x%016llx/0x%016llx\n", res->base,
324 res->size);
327 printk(BIOS_DEBUG, "Reading resources for %s done\n", dev_path(dev));
330 static void domain_set_resources(struct device *dev)
332 printk(BIOS_DEBUG, "Setting resources for %s\n", dev_path(dev));
334 pci_domain_set_resources(dev);
336 printk(BIOS_DEBUG, "Setting resources for %s done\n", dev_path(dev));
339 static void domain_scan_bus(struct device *dev)
341 printk(BIOS_DEBUG, "Scanning %s\n", dev_path(dev));
343 pci_host_bridge_scan_bus(dev);
345 printk(BIOS_DEBUG, "Scanning %s done\n", dev_path(dev));
348 const char *soc_acpi_name(const struct device *dev)
350 if (dev->path.type == DEVICE_PATH_DOMAIN)
351 switch (dev_get_domain_id(dev)) {
352 case 0:
353 return "PCI0";
354 case 1:
355 return "PCI1";
356 case 2:
357 return "PCI2";
358 case 3:
359 return "PCI3";
360 case 4:
361 return "PCI4";
362 case 5:
363 return "PCI5";
364 case 6:
365 return "PCI6";
366 case 7:
367 return "PCI7";
368 case 8:
369 return "PCI8";
370 case 9:
371 return "PCI9";
372 default:
373 return NULL;
376 return NULL;
379 static struct device_operations pci_domain_ops = {
380 .read_resources = domain_read_resources,
381 .set_resources = domain_set_resources,
382 .scan_bus = domain_scan_bus,
383 .acpi_fill_ssdt = domain_fill_ssdt,
384 .acpi_name = soc_acpi_name,
387 static struct device_operations cpu_bus_ops = {
388 .read_resources = noop_read_resources,
389 .set_resources = noop_set_resources,
390 .acpi_fill_ssdt = generate_cpu_entries,
393 static void southcluster_enable_dev(struct device *dev)
395 if (!dev->enabled) {
396 printk(BIOS_DEBUG, "Disable %s\n", dev_path(dev));
398 * Mark the device as hidden so that coreboot won't complain about leftover static
399 * device.
401 dev->hidden = true;
402 pci_and_config16(dev, PCI_COMMAND,
403 ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER));
404 } else {
405 printk(BIOS_DEBUG, "Enable %s\n", dev_path(dev));
406 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR);
410 static void soc_enable_dev(struct device *dev)
412 if (dev->path.type == DEVICE_PATH_DOMAIN) {
413 printk(BIOS_SPEW, "Set domain operation for %s\n", dev_path(dev));
414 dev->ops = &pci_domain_ops;
415 } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
416 printk(BIOS_SPEW, "Set CPU cluster operation for %s\n", dev_path(dev));
417 dev->ops = &cpu_bus_ops;
418 } else if (dev->path.type == DEVICE_PATH_PCI) {
420 * For a static PCH device, if it's enabled, set the SERR bits, otherwise
421 * disable the ability of issuing and responding to IO and memory requests.
423 if (is_dev_on_domain0(dev) && is_pci(dev) && is_pch_slot(dev->path.pci.devfn))
424 southcluster_enable_dev(dev);
428 struct chip_operations soc_intel_snowridge_ops = {
429 .name = "Intel Snowridge",
430 .init = &soc_init_pre_device,
431 .enable_dev = &soc_enable_dev,