diff options
Diffstat (limited to 'src/soc/intel')
62 files changed, 5074 insertions, 0 deletions
diff --git a/src/soc/intel/snowridge/Kconfig b/src/soc/intel/snowridge/Kconfig new file mode 100644 index 0000000000..ad77f9a1ea --- /dev/null +++ b/src/soc/intel/snowridge/Kconfig @@ -0,0 +1,259 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_SNOWRIDGE + bool + help + Intel Snow Ridge SoC support + + select BOOT_DEVICE_SUPPORTS_WRITES + + ## Arch + select ARCH_X86 + + ## CPU + select SSE + select SUPPORT_CPU_UCODE_IN_CBFS + select MICROCODE_BLOB_NOT_IN_BLOB_REPO + select CPU_INTEL_COMMON + select CPU_INTEL_FIRMWARE_INTERFACE_TABLE + select PARALLEL_MP + select PARALLEL_MP_AP_WORK + select UDELAY_TSC + select TSC_MONOTONIC_TIMER + select TSC_SYNC_MFENCE + select HAVE_SMI_HANDLER + + ## ACPI + select ACPI_INTEL_HARDWARE_SLEEP_VALUES + + ## Device + select USE_DDR4 + + ## Drivers + select CACHE_MRC_SETTINGS + select UART_OVERRIDE_REFCLK + + ## FSP 2.0 + select PLATFORM_USES_FSP2_0 + select FSP_CAR + select FSP_USES_CB_STACK + select FSP_M_XIP + select FSP_T_XIP + select SOC_INTEL_COMMON_FSP_RESET + + ## SoC + select SOC_INTEL_COMMON + select SOC_INTEL_COMMON_BASECODE + select SOC_INTEL_COMMON_BLOCK + select SOC_INTEL_COMMON_BLOCK_ACPI + select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG + select SOC_INTEL_COMMON_BLOCK_CPU + select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT + select SOC_INTEL_COMMON_BLOCK_CPU_SMMRELOCATE + select USE_INTEL_FSP_MP_INIT + select SOC_INTEL_COMMON_BLOCK_FAST_SPI + select SOC_INTEL_COMMON_BLOCK_GPIO + select SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG + select SOC_INTEL_COMMON_BLOCK_GPMR + select USE_SOC_GPMR_DEFS + select SOC_INTEL_COMMON_BLOCK_IMC + select SOC_INTEL_COMMON_BLOCK_IRQ + select SOC_INTEL_COMMON_BLOCK_ITSS + select SOC_INTEL_COMMON_BLOCK_LPC + select SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR + select SOC_INTEL_COMMON_BLOCK_MEMINIT + select SOC_INTEL_COMMON_BLOCK_P2SB + select SOC_INTEL_COMMON_BLOCK_PCR + select SOC_INTEL_COMMON_BLOCK_PMC + select SOC_INTEL_COMMON_BLOCK_RTC + select SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION + select PMC_GLOBAL_RESET_ENABLE_LOCK + select SOC_INTEL_COMMON_BLOCK_SMBUS + select SOC_INTEL_COMMON_BLOCK_TCO + select SOC_INTEL_COMMON_BLOCK_TCO_ENABLE_THROUGH_SMBUS + select SOC_INTEL_COMMON_BLOCK_SA_SERVER + select SOC_INTEL_COMMON_BLOCK_SMM + select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP + select SOC_INTEL_COMMON_BLOCK_SMM_ESPI_DISABLE + select SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE + select SOC_INTEL_COMMON_BLOCK_SPI + select SOC_INTEL_COMMON_BLOCK_TIMER + select SOC_INTEL_COMMON_BLOCK_XHCI + select SOC_INTEL_COMMON_IBL_BASE # Select this one to add intelpch to including path. + select SOC_INTEL_COMMON_PCH_LOCKDOWN + select SOC_INTEL_COMMON_RESET + + ## Southbridge + select INTEL_DESCRIPTOR_MODE_CAPABLE + + ## Vendorcode + select UDK_202005_BINDING + +if SOC_INTEL_SNOWRIDGE + +config CHIPSET_DEVICETREE + default "soc/intel/snowridge/chipset.cb" + +config MAX_CPUS + default 16 + +config HEAP_SIZE + default 0x100000 + +config PRERAM_CBFS_CACHE_SIZE + default 0x0 + +config C_ENV_BOOTBLOCK_SIZE + default 0x8000 + +# CAR memory layout on Snow Ridge hardware: +# CAR base address - 0xfe800000 +# CAR size - 0x7ff00 (512KB - 0x100) +# FSP: +# FSP reserved base - 0xfe800000 +# FSP reserved size - 0x40000 +# remaining: +# DCACHE base - 0xfe840000 +# DCACHE size - 0x3ff00 + +config DCACHE_RAM_BASE + default 0xfe840000 + +config DCACHE_RAM_SIZE + default 0x3ff00 if FSP_CAR + +config DCACHE_BSP_STACK_SIZE + default 0x1C400 + help + The amount of anticipated stack usage in CAR by bootblock and other stages. + In the case of FSP_USES_CB_STACK, the default value will be sum of FSP-M + stack requirement (112KiB) and CB romstage stack requirement (~1KiB). + +config CPU_INTEL_NUM_FIT_ENTRIES + default 24 + help + Number of microcode files. + +config ECAM_MMCONF_BASE_ADDRESS + default 0x80000000 + +config ECAM_MMCONF_BUS_NUMBER + default 256 + +config ALWAYS_ALLOW_ABOVE_4G_ALLOCATION + default y + +config MAX_SOCKET + int + default 1 + +config FSP_HEADER_PATH + default "src/vendorcode/intel/fsp/fsp2_0/snowridge" if !FSP_USE_REPO + +config FSP_TEMP_RAM_SIZE + default 0x20000 + help + The amount of anticipated heap usage in CAR by FSP. Refer to platform FSP + integration guide document to know the exact FSP requirement for heap setup. + +config FSP_T_LOCATION + hex "Intel FSP-T (temp ram init) binary location" + depends on ADD_FSP_BINARIES && FSP_CAR + default 0xffe20000 + help + The memory location of the Intel FSP-T binary for this platform. + +config FSP_M_ADDR + hex "Intel FSP-M (memory init) binary location" + depends on ADD_FSP_BINARIES + default 0xffe27000 + help + The memory location of the Intel FSP-M binary for this platform. + +config FSP_S_ADDR + hex "Intel FSP-S (silicon init) binary location" + depends on ADD_FSP_BINARIES + default 0xffdb5000 + help + The memory location of the Intel FSP-S binary for this platform. + +config DIMMS_PER_CHANNEL + default 2 + +config DATA_BUS_WIDTH + default 128 + +config MRC_CHANNEL_WIDTH + default 64 + +## Private settings +config KTI_CACHE_IN_FMAP + bool + default y + help + Save KTI cache data to flash and load it on following boots. + +if KTI_CACHE_IN_FMAP + +config KTI_CACHE_FMAP_NAME + string + default "RW_KTI_CACHE" + +config KTI_CACHE_SIZE + hex + default 0x1000 + help + Size should be aligned to sector size. + +endif # KTI_CACHE_IN_FMAP + +config HSUART_DEV + hex + default 0x1a + +choice + prompt "UART mode selection" + default HIGH_SPEED_UART + +config LEGACY_UART + bool "Enable legacy UART" + select DRIVERS_UART_8250IO + +config HIGH_SPEED_UART + bool "Enable High-Speed UART" + select DRIVERS_UART_8250MEM +endchoice + +config CONSOLE_UART_BASE_ADDRESS + hex "Temporary MMIO Base Address for HSUART" + default 0xfe032000 + depends on HIGH_SPEED_UART + help + This option allows you to select temporary MMIO Base Address for HSUART. + It should be selected from 8M temporary MMIO address space starting at + 0xfe000000. It will be used until coreboot resource allocation overwrite it + with new allocated value. + +config PCR_BASE_ADDRESS + hex + default 0xfd000000 + help + This option allows you to select MMIO Base Address of sideband bus. + +config IED_REGION_SIZE + hex + default 0x400000 + +config SMM_RESERVED_SIZE + hex + default 0x200000 + +config CPU_BCLK_MHZ + int + default 100 + +config ENABLE_VTD + bool "Enable Intel Virtualization Technology" + default y + +endif # SOC_INTEL_SNOWRIDGE diff --git a/src/soc/intel/snowridge/Makefile.mk b/src/soc/intel/snowridge/Makefile.mk new file mode 100644 index 0000000000..07f39231f0 --- /dev/null +++ b/src/soc/intel/snowridge/Makefile.mk @@ -0,0 +1,62 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(CONFIG_SOC_INTEL_SNOWRIDGE),y) + +subdirs-y += ../../../cpu/intel/microcode +subdirs-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += ../../../cpu/intel/turbo + +all-$(CONFIG_HIGH_SPEED_UART) += common/uart8250mem.c +all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += common/gpio.c +all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PMC) += common/pmclib.c +all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SPI) += common/spi.c + +bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += bootblock/bootblock.c +bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += bootblock/early_uart_init.c + +romstage-y += ../../../cpu/intel/car/romstage.c +romstage-y += common/fsp_hob.c +romstage-y += common/kti_cache.c +romstage-y += romstage/gpio_snr.c +romstage-y += romstage/romstage.c +romstage-$(CONFIG_DISPLAY_HOBS) += common/hob_display.c +romstage-$(CONFIG_DISPLAY_UPD_DATA) += common/upd_display.c +romstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += common/reset.c +romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SA_SERVER) += common/systemagent_early.c + +ramstage-y += common/fsp_hob.c +ramstage-y += common/kti_cache.c +ramstage-y += chip.c +ramstage-y += finalize.c +ramstage-$(CONFIG_DISPLAY_HOBS) += common/hob_display.c +ramstage-$(CONFIG_DISPLAY_UPD_DATA) += common/upd_display.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += common/reset.c +ramstage-$(CONFIG_PCI) += dlb.c +ramstage-$(CONFIG_PCI) += heci.c +ramstage-$(CONFIG_PCI) += lpc.c +ramstage-$(CONFIG_PCI) += nis.c +ramstage-$(CONFIG_PCI) += pcie_rp.c +ramstage-$(CONFIG_PCI) += qat.c +ramstage-$(CONFIG_PCI) += sata.c +ramstage-$(CONFIG_PCI) += sriov.c +ramstage-$(CONFIG_PCI) += systemagent.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI) += acpi.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += cpu.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ITSS) += itss.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SA_SERVER) += common/systemagent_early.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown.c + +smm-$(CONFIG_ARCH_RAMSTAGE_X86_32) += smihandler.c +smm-$(CONFIG_HIGH_SPEED_UART) += common/uart8250mem.c +smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += common/gpio.c +smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PMC) += common/pmclib.c +smm-$(CONFIG_SPI_FLASH_SMM) += common/spi.c + +CPPFLAGS_common += -I$(src)/soc/intel/snowridge/include/ + +## Set FSP binary blobs memory location + +$(call strip_quotes,$(CONFIG_FSP_T_CBFS))-position := $(CONFIG_FSP_T_LOCATION) --xip +$(call strip_quotes,$(CONFIG_FSP_M_CBFS))-position := $(CONFIG_FSP_M_ADDR) --xip +$(call strip_quotes,$(CONFIG_FSP_S_CBFS))-position := $(CONFIG_FSP_S_ADDR) --xip + +endif ## CONFIG_SOC_INTEL_SNOWRIDGE diff --git a/src/soc/intel/snowridge/acpi.c b/src/soc/intel/snowridge/acpi.c new file mode 100644 index 0000000000..552f7ba816 --- /dev/null +++ b/src/soc/intel/snowridge/acpi.c @@ -0,0 +1,481 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpi.h> +#include <acpi/acpi_device.h> +#include <acpi/acpigen.h> +#include <acpi/acpigen_pci.h> +#include <arch/hpet.h> +#include <arch/ioapic.h> +#include <assert.h> +#include <cbmem.h> +#include <commonlib/bsd/helpers.h> +#include <console/console.h> +#include <device/mmio.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pci_type.h> +#include <intelblocks/acpi.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/p2sb.h> +#include <intelblocks/systemagent_server.h> +#include <soc/acpi.h> +#include <soc/iomap.h> +#include <soc/irq.h> +#include <soc/itss.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/systemagent.h> +#include <southbridge/intel/common/acpi_pirq_gen.h> +#include <static.h> +#include <string.h> + +uint32_t soc_read_sci_irq_select(void) +{ + return read32p(PCH_PWRM_BASE_ADDRESS + ACTL); +} + +int soc_madt_sci_irq_polarity(int sci) +{ + if (sci >= 20) + return MP_IRQ_POLARITY_LOW; + + return MP_IRQ_POLARITY_HIGH; +} + +void soc_fill_fadt(acpi_fadt_t *fadt) +{ + /** + * The default field value is 0 if it's not set when calling this function. + */ + + fadt->pm2_cnt_blk = ACPI_BASE_ADDRESS + PM2_CNT; + fadt->pm_tmr_blk = ACPI_BASE_ADDRESS + PM1_TMR; + fadt->pm2_cnt_len = 1; + fadt->pm_tmr_len = 4; + + fadt->duty_offset = 1; + fadt->duty_width = 0; + + fill_fadt_extended_pm_io(fadt); +} + +void soc_power_states_generation(int core_id, int cores_per_package) +{ + generate_p_state_entries(core_id, cores_per_package); +} + +static void acpigen_write_pci_prt(const struct device *dev) +{ + unsigned int map_count = 0; + struct slot_pin_irq_map *pin_irq_map = + calloc(MAX_SLOTS * PCI_INT_MAX, sizeof(struct slot_pin_irq_map)); + if (!pin_irq_map) + return; + + struct device *child = NULL; + while ((child = dev_bus_each_child(dev->downstream, child))) { + if (!is_enabled_pci(child)) + continue; + + enum pci_pin pin = pci_read_config8(child, PCI_INTERRUPT_PIN); + if (pin < PCI_INT_A || pin > PCI_INT_D) + continue; + + pin_irq_map[map_count].slot = PCI_SLOT(child->path.pci.devfn); + pin_irq_map[map_count].pin = pin; + + /* `pic_pirq` is actually `enum pirq` type. */ + pin_irq_map[map_count].pic_pirq = itss_soc_get_dev_pirq(child); + if (pin_irq_map[map_count].pic_pirq == PIRQ_INVALID) + continue; + + /* PIRQA-H is hardwired to IRQ16-23. */ + pin_irq_map[map_count].apic_gsi = + PCH_IRQ16 + pirq_idx(pin_irq_map[map_count].pic_pirq); + + printk(BIOS_SPEW, "%s, slot_pin_irq_map[%2d]: {0x%2x, %s, PIRQ%c, IRQ%d}\n", + dev_path(child), map_count, pin_irq_map[map_count].slot, + pin_to_str(pin_irq_map[map_count].pin), + (unsigned int)pirq_idx(pin_irq_map[map_count].pic_pirq) + 'A', + pin_irq_map[map_count].apic_gsi); + + map_count++; + } + + size_t pirq_routes; + const uint8_t *legacy_pirq_routing = lpc_get_pic_pirq_routing(&pirq_routes); + struct pic_pirq_map pirq_map = {.type = PIRQ_GSI}; + for (size_t i = 0; i < PIRQ_COUNT && i < pirq_routes; i++) + pirq_map.gsi[i] = legacy_pirq_routing[i]; + + intel_write_pci_PRT(acpi_device_path(dev), pin_irq_map, map_count, &pirq_map); + free(pin_irq_map); +} + +void domain_fill_ssdt(const struct device *dev) +{ + const char *acpi_scope = acpi_device_scope(dev); + const char *acpi_name = acpi_device_name(dev); + printk(BIOS_DEBUG, "%s ACPI scope: '%s', name: '%s'\n", __func__, acpi_scope, + acpi_name); + + /** + * PCH domain is defined in uncore.asl. + * + * Generating accelerator domains dynamically since they are SKU-dependent. + */ + if (!is_domain0(dev)) { + /** + * Device (PCIx) + * { + * Method (_STA) { Return (status) } + * Name (_HID, EISAID ("PNP0A08")) // PCI Express Bus + * Name (_CID, EISAID ("PNP0A03")) // PCI Bus + * Name (_UID, "PCIx") + * Name (_PXM, 0) + * Method (_OSC, 4) { Return (\_SB.DOSC (Arg0, Arg1, Arg2, Arg3)) } + * } + */ + acpigen_write_scope(acpi_scope); + acpigen_write_device(acpi_name); + + acpigen_write_STA(dev->enabled ? ACPI_STATUS_DEVICE_ALL_ON : + ACPI_STATUS_DEVICE_ALL_OFF); + + acpigen_write_name("_HID"); + acpigen_emit_eisaid("PNP0A08"); + + acpigen_write_name("_CID"); + acpigen_emit_eisaid("PNP0A03"); + + acpigen_write_name("_UID"); + acpigen_write_string(acpi_name); + + acpigen_write_name("_PXM"); + acpigen_write_integer(0); + + acpigen_write_method("_OSC", 4); + acpigen_write_return_namestr("\\_SB.DOSC"); + acpigen_emit_byte(ARG0_OP); + acpigen_emit_byte(ARG1_OP); + acpigen_emit_byte(ARG2_OP); + acpigen_emit_byte(ARG3_OP); + acpigen_write_method_end(); + + acpigen_write_device_end(); + acpigen_write_scope_end(); + } + + pci_domain_fill_ssdt(dev); + + acpigen_write_pci_prt(dev); +} + +void pcie_rp_fill_ssdt(const struct device *dev) +{ + const char *acpi_scope = acpi_device_scope(dev); + const char *acpi_name = acpi_device_name(dev); + printk(BIOS_DEBUG, "%s ACPI scope: '%s', name: '%s'\n", __func__, acpi_scope, + acpi_name); + + acpigen_write_scope(acpi_scope); + acpigen_write_device(acpi_name); + acpigen_write_STA(dev->enabled ? ACPI_STATUS_DEVICE_ALL_ON : + ACPI_STATUS_DEVICE_ALL_OFF); + acpigen_write_ADR_pci_device(dev); + acpigen_write_device_end(); + acpigen_write_scope_end(); + + acpigen_write_pci_prt(dev); +} + +unsigned long acpi_create_srat_lapics(unsigned long current) +{ + for (struct device *cpu = DEV_PTR(cpu_bus)->downstream->children; cpu != NULL; + cpu = cpu->next) { + if (!is_enabled_cpu(cpu)) + continue; + + printk(BIOS_DEBUG, + "SRAT: APIC ID = 0x%02x, package ID = 0x%02x, node ID = 0x%02x, core ID = 0x%02x, thread ID = 0x%02x\n", + cpu->path.apic.apic_id, cpu->path.apic.package_id, + cpu->path.apic.node_id, cpu->path.apic.core_id, + cpu->path.apic.thread_id); + current += acpi_create_srat_lapic((acpi_srat_lapic_t *)current, + cpu->path.apic.node_id, + cpu->path.apic.apic_id); + } + + return current; +} + +static unsigned long acpi_fill_srat(unsigned long current) +{ + const uint32_t low_mem_end = sa_server_get_tolud(); + const uint64_t hi_mem_end = sa_server_get_touud(), mem_4G = 4ull * GiB; + + current = acpi_create_srat_lapics(current); + + current += acpi_create_srat_mem((acpi_srat_mem_t *)current, 0, 0, low_mem_end >> 10, + ACPI_SRAT_MEMORY_ENABLED); + + if (hi_mem_end > mem_4G) + current += acpi_create_srat_mem((acpi_srat_mem_t *)current, 0, mem_4G >> 10, + (hi_mem_end - mem_4G) >> 10, + ACPI_SRAT_MEMORY_ENABLED); + + return current; +} + +static unsigned long acpi_create_drhd(unsigned long current, struct device *dev) +{ + unsigned long tmp = current; + const struct device *dev_domain = dev_get_domain(dev); + if (!dev_domain->enabled) + return current; + + /** + * Bit 0 of VTBAR is read-write and it indicates whether VT-d base address is enabled. + */ + uint32_t vtd_base = pci_read_config32(dev, VTBAR); + if (!(vtd_base & VTD_CHIPSET_BASE_ADDRESS_ENABLE)) + return current; + + vtd_base = ALIGN_DOWN(vtd_base, 4 * KiB); + + const uint32_t pcie_seg = dev->upstream->segment_group; + if (is_dev_on_domain0(dev)) { + printk(BIOS_DEBUG, + "[DMA Remapping Hardware Unit Definition] Flags: 0x%x, PCI Segment: 0x%x, Register Base Address: 0x%x\n", + DRHD_INCLUDE_PCI_ALL, pcie_seg, vtd_base); + current += acpi_create_dmar_drhd_4k(current, DRHD_INCLUDE_PCI_ALL, pcie_seg, + vtd_base); + + union p2sb_bdf ioapic_bdf = p2sb_get_ioapic_bdf(); + printk(BIOS_DEBUG, "[IOAPIC] PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", + ioapic_bdf.bus, ioapic_bdf.dev, ioapic_bdf.fn); + current += acpi_create_dmar_ds_ioapic_from_hw( + current, IO_APIC_ADDR, ioapic_bdf.bus, ioapic_bdf.dev, ioapic_bdf.fn); + + uint16_t num_hpets = (read32p(HPET_BASE_ADDRESS) >> HPET_NUM_TIM_CAP_SHIFT) & + HPET_NUM_TIM_CAP_MASK; + if (num_hpets && num_hpets != HPET_NUM_TIM_CAP_MASK) { + if (read32p(HPET_BASE_ADDRESS + HPET_TMR0_CNF_CAP) & + HPET_TIMER_FSB_EN_CNF_MASK) { + union p2sb_bdf hpet_bdf = p2sb_get_hpet_bdf(); + printk(BIOS_DEBUG, + "[MSI_CAPABLE_HPET] Enumeration ID: 0x%x, PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", + 0, hpet_bdf.bus, hpet_bdf.dev, hpet_bdf.fn); + current += acpi_create_dmar_ds_msi_hpet( + current, 0, hpet_bdf.bus, hpet_bdf.dev, hpet_bdf.fn); + } + } + } else { + printk(BIOS_DEBUG, + "[DMA Remapping Hardware Unit Definition] Flags: 0x%x, PCI Segment: 0x%x, Register Base Address: 0x%x\n", + 0, pcie_seg, vtd_base); + current += acpi_create_dmar_drhd_4k(current, 0, pcie_seg, vtd_base); + + if (dev == DEV_PTR(dlb_sa)) { + if (DEV_PTR(dlb)) { + printk(BIOS_DEBUG, "[PCI Endpoint Device] %s\n", + dev_path(DEV_PTR(dlb))); + current += acpi_create_dmar_ds_pci( + current, PCI_DEV2BUS(PCI_BDF(DEV_PTR(dlb))), + PCI_SLOT(DEV_PTR(dlb)->path.pci.devfn), + PCI_FUNC(DEV_PTR(dlb)->path.pci.devfn)); + } + } else { + struct device *pci_bridge = NULL; + while ((pci_bridge = dev_bus_each_child(dev_get_domain(dev)->downstream, + pci_bridge))) { + if (pci_bridge->vendor != PCI_VID_INTEL) + continue; + + switch (pci_bridge->device) { + case PCI_DID_INTEL_SNR_CPU_PCIE_RPA: + case PCI_DID_INTEL_SNR_CPU_PCIE_RPB: + case PCI_DID_INTEL_SNR_CPU_PCIE_RPC: + case PCI_DID_INTEL_SNR_CPU_PCIE_RPD: + case PCI_DID_INTEL_SNR_VRP4_NIS: + case PCI_DID_INTEL_SNR_VRP5_QAT_1_8: + printk(BIOS_DEBUG, "[PCI Sub-hierarchy] %s\n", + dev_path(pci_bridge)); + current += acpi_create_dmar_ds_pci_br( + current, dev->upstream->secondary, + PCI_SLOT(pci_bridge->path.pci.devfn), + PCI_FUNC(pci_bridge->path.pci.devfn)); + break; + default: + continue; + } + } + } + } + + if (current != tmp) + acpi_dmar_drhd_fixup(tmp, current); + + return current; +} + +static unsigned long acpi_create_rmrr(unsigned long current) +{ + const uint32_t MEM_BLK_COUNT = 0x140, MEM_BLK_SIZE = 32; + uint32_t size = ALIGN_UP(MEM_BLK_COUNT * MEM_BLK_SIZE, 0x1000); + const struct cbmem_entry *entry; + void *ptr; + unsigned long tmp = current; + struct device *dev = PCH_DEV_XHCI; + + entry = cbmem_entry_find(CBMEM_ID_STORAGE_DATA); + if (!entry) { + ptr = cbmem_add(CBMEM_ID_STORAGE_DATA, size); + if (!ptr) { + printk(BIOS_ERR, "Failed to allocate reserved memory in cbmem!\n"); + return current; + } + + memset(ptr, 0, size); + } else { + ptr = cbmem_entry_start(entry); + size = cbmem_entry_size(entry); + } + + printk(BIOS_DEBUG, + "[Reserved Memory Region Reporting] PCI Segment: 0x%x, Base: %p, Limit: %p\n", + dev->upstream->segment_group, ptr, ptr + size - 1); + current += acpi_create_dmar_rmrr(current, dev->upstream->segment_group, (uintptr_t)ptr, + (uintptr_t)(ptr + size - 1)); + + printk(BIOS_DEBUG, "[PCI Endpoint Device] %s\n", dev_path(dev)); + current += acpi_create_dmar_ds_pci(current, PCI_DEV2BUS(PCI_BDF(dev)), + PCI_SLOT(dev->path.pci.devfn), + PCI_FUNC(dev->path.pci.devfn)); + + if (current != tmp) + acpi_dmar_rmrr_fixup(tmp, current); + + return current; +} + +static unsigned long acpi_create_atsr(unsigned long current, struct device *dev) +{ + unsigned long tmp = current; + + /** + * Bit 0 of VTBAR is read-write and it indicates whether VT-d base address is enabled. + */ + uint32_t vtd_base = pci_read_config32(dev, VTBAR); + if (!(vtd_base & VTD_CHIPSET_BASE_ADDRESS_ENABLE)) + return current; + + vtd_base = ALIGN_DOWN(vtd_base, 4 * KiB); + + uint64_t vtd_ext_cap = read64p(vtd_base + VTD_ECAP); + if (!(vtd_ext_cap & DEVICE_TLB)) + return current; + + printk(BIOS_DEBUG, "Domain 1 VT-d BAR: 0x%x, Extended Capability: 0x%llx\n", vtd_base, + vtd_ext_cap); + + bool first = true; + struct device *cpu_pcie_rp = NULL; + while ((cpu_pcie_rp = + dev_bus_each_child(dev_get_domain(dev)->downstream, cpu_pcie_rp))) { + if (cpu_pcie_rp->vendor != PCI_VID_INTEL) + continue; + + switch (cpu_pcie_rp->device) { + case PCI_DID_INTEL_SNR_CPU_PCIE_RPA: + case PCI_DID_INTEL_SNR_CPU_PCIE_RPB: + case PCI_DID_INTEL_SNR_CPU_PCIE_RPC: + case PCI_DID_INTEL_SNR_CPU_PCIE_RPD: + break; + default: + continue; + } + + if (first) { + const uint32_t pcie_seg = dev->upstream->segment_group; + printk(BIOS_DEBUG, + "[Root Port ATS Capability] Flags: 0x%x, PCI Segment: 0x%x\n", 0, + pcie_seg); + current += acpi_create_dmar_atsr(current, 0, pcie_seg); + first = false; + } + + printk(BIOS_DEBUG, "[PCI Sub-hierarchy] %s\n", dev_path(cpu_pcie_rp)); + current += acpi_create_dmar_ds_pci_br(current, + PCI_DEV2BUS(PCI_BDF(cpu_pcie_rp)), + PCI_SLOT(cpu_pcie_rp->path.pci.devfn), + PCI_FUNC(cpu_pcie_rp->path.pci.devfn)); + } + + if (tmp != current) + acpi_dmar_atsr_fixup(tmp, current); + + return current; +} + +static unsigned long acpi_fill_dmar(unsigned long current) +{ + assert(DEV_PTR(pch_sa)); + + /** + * Domain 0 hosts all PCH peripherals, and DRHD entry for this domain should be at last, + * thus we search from `DEV_PTR(pch_sa)` here. + */ + struct device *dev = DEV_PTR(pch_sa); + while ((dev = dev_find_device(PCI_VID_INTEL, PCI_DID_INTEL_SNR_ID, dev)) != NULL) + current = acpi_create_drhd(current, dev); + + current = acpi_create_drhd(current, DEV_PTR(pch_sa)); + + current = acpi_create_rmrr(current); + + /* Only CPU PCIe root ports support address translation services (ATS). */ + assert(DEV_PTR(cpu_sa)); + current = acpi_create_atsr(current, DEV_PTR(cpu_sa)); + + return current; +} + +unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current, + struct acpi_rsdp *rsdp) +{ + acpi_srat_t *srat; + acpi_dmar_t *dmar; + + /** + * Write only when calling from system agent in domain 0. + */ + if (!sa_server_is_on_pch_domain(dev)) + return current; + + /* SRAT */ + printk(BIOS_DEBUG, "ACPI: * SRAT at 0x%08lx\n", current); + srat = (acpi_srat_t *)current; + acpi_create_srat(srat, acpi_fill_srat); + acpi_add_table(rsdp, srat); + current += srat->header.length; + current = acpi_align_current(current); + + printk(BIOS_DEBUG, "ACPI: * DMAR at 0x%08lx\n", current); + dmar = (acpi_dmar_t *)current; + acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar); + acpi_add_table(rsdp, dmar); + current += dmar->header.length; + + return current; +} + +/** + * To use ACPI in common block, this function should be defined. + */ +const acpi_cstate_t *soc_get_cstate_map(size_t *entries) +{ + *entries = 0; + return NULL; +} diff --git a/src/soc/intel/snowridge/acpi/southcluster.asl b/src/soc/intel/snowridge/acpi/southcluster.asl new file mode 100644 index 0000000000..e2df596c05 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/southcluster.asl @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/ioapic.h> +#include <cpu/x86/lapic_def.h> +#include <soc/iomap.h> + +Scope (\_SB.PCI0) +{ + /* PCH Reserved resources. */ + Device (PCHR) + { + Name (_HID, EisaId ("PNP0C02")) + Name (_CRS, ResourceTemplate () + { + Memory32Fixed (ReadWrite, RESERVED_BASE_ADDRESS, RESERVED_BASE_SIZE) + }) + } + + Device (APIC) + { + Name (_HID, EisaId ("PNP0003")) + Name (_CRS, ResourceTemplate () + { + /* IO APIC */ + Memory32Fixed (ReadOnly, IO_APIC_ADDR, 0x00100000) + /* Local APIC */ + Memory32Fixed (ReadOnly, LAPIC_DEFAULT_BASE, 0x00100000) + }) + } + + #include <soc/intel/common/block/acpi/acpi/lpc.asl> + + Device (PMC) + { + Name (_HID, EISAID ("PNP0C02")) + Name (_DDN, "PCH PMC") + Name (_UID, "PMC") + + Name (_CRS, ResourceTemplate + { + IO (Decode16, ACPI_BASE_ADDRESS, ACPI_BASE_ADDRESS, 0x1, 0x80) + Memory32Fixed (ReadOnly, PCH_PWRM_BASE_ADDRESS, 0x10000) + }) + } +} diff --git a/src/soc/intel/snowridge/acpi/uncore.asl b/src/soc/intel/snowridge/acpi/uncore.asl new file mode 100644 index 0000000000..5d06926d81 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/uncore.asl @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/itss.h> +#include <intelblocks/pcr.h> +#include <soc/pcr_ids.h> + +#define PCI_HOST_BRIDGE_OSC_UUID "33db4d5b-1ff7-401c-9657-7441c03dd766" + +Scope (\_SB) +{ + Method (DOSC, 4) + { + If (Arg0 != ToUUID (PCI_HOST_BRIDGE_OSC_UUID)) + { + CreateDWordField (Arg3, 0, DW1) + DW1 |= 4 // Unrecognized UUID + } + Return (Arg3) + } + + Device (PCI0) + { + Method (_STA) + { + Return (0xf) + } + Name (_HID, EISAID ("PNP0A08")) // PCI Express Bus + Name (_CID, EISAID ("PNP0A03")) // PCI Bus + Name (_UID, "PCI0") + Name (_PXM, 0) + Method (_OSC, 4) + { + Return (\_SB.DOSC (Arg0, Arg1, Arg2, Arg3)) + } + } +} diff --git a/src/soc/intel/snowridge/bootblock/bootblock.c b/src/soc/intel/snowridge/bootblock/bootblock.c new file mode 100644 index 0000000000..8e6c0def99 --- /dev/null +++ b/src/soc/intel/snowridge/bootblock/bootblock.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootblock_common.h> +#include <console/console.h> +#include <fsp/util.h> +#include <intelblocks/fast_spi.h> +#include <intelblocks/tco.h> +#include <soc/iomap.h> + +#include <FsptUpd.h> + +#include "bootblock.h" + +const FSPT_UPD temp_ram_init_params = { + .FspUpdHeader = { + .Signature = 0x545F445055434F53ULL, + .Revision = 1, + .Reserved = {0}, + }, + .FsptCoreUpd = { + .MicrocodeRegionBase = 0, + .MicrocodeRegionLength = 0, + .CodeRegionBase = 0xffe00000, + .CodeRegionLength = 0x200000, + .Reserved1 = {0}, + }, + .ReservedTempRamInitUpd = {0}, + .UnusedUpdSpace0 = {0}, + .UpdTerminator = 0x55AA, +}; + +asmlinkage void bootblock_c_entry(uint64_t base_timestamp) +{ + bootblock_main_with_basetime(base_timestamp); +} + +void bootblock_soc_early_init(void) +{ + if (CONFIG(DRIVERS_UART)) + early_uart_init(); +} + +void bootblock_soc_init(void) +{ + if (CONFIG(BOOTBLOCK_CONSOLE)) + printk(BIOS_DEBUG, "FSP TempRamInit successful...\n"); + + if (CONFIG(FSP_CAR)) + report_fspt_output(); + + tco_configure(); + tco_reset_status(); + + fast_spi_early_init(SPI_BASE_ADDRESS); +} diff --git a/src/soc/intel/snowridge/bootblock/bootblock.h b/src/soc/intel/snowridge/bootblock/bootblock.h new file mode 100644 index 0000000000..2cc732085a --- /dev/null +++ b/src/soc/intel/snowridge/bootblock/bootblock.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_BOOTBLOCK_H_ +#define _SOC_SNOWRIDGE_BOOTBLOCK_H_ + +void early_uart_init(void); + +void early_tco_init(void); + +#endif // _SOC_SNOWRIDGE_BOOTBLOCK_H_ diff --git a/src/soc/intel/snowridge/bootblock/early_uart_init.c b/src/soc/intel/snowridge/bootblock/early_uart_init.c new file mode 100644 index 0000000000..9f56ceba01 --- /dev/null +++ b/src/soc/intel/snowridge/bootblock/early_uart_init.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <soc/pci_devs.h> +#include <stdint.h> + +#include "../common/uart8250mem.h" +#include "bootblock.h" + +static void pci_early_hsuart_device_enable(uint8_t func, uint16_t io_base) +{ + register uint16_t cmd_stat_reg; + + pci_or_config32(PCH_DEV_UART(func), UART_IOBA, io_base); + + /** + * Enable memory/io space and allow to initiate a transaction as a master. + */ + cmd_stat_reg = pci_read_config16(PCH_DEV_UART(func), PCI_COMMAND); + cmd_stat_reg |= PCI_COMMAND_MASTER | PCI_COMMAND_IO; + +#if CONFIG_CONSOLE_UART_BASE_ADDRESS != 0 + /* Decode MMIO at MEMBA (BAR1). */ + pci_write_config32(PCH_DEV_UART(func), UART_MEMBA, + CONFIG_CONSOLE_UART_BASE_ADDRESS + SIZE_OF_HSUART_RES * func); + cmd_stat_reg |= PCI_COMMAND_MEMORY; +#endif + + pci_write_config16(PCH_DEV_UART(func), PCI_COMMAND, cmd_stat_reg); + +#if CONFIG_TTYS0_BAUD > 115200 +#if CONFIG_CONSOLE_UART_BASE_ADDRESS && CONFIG(ECAM_MMCONF_SUPPORT) +#define UCMR_OFFSET 0x34 + /** + * Change UART baseclock to 24 x 1.8432MHz -> 44.2368MHz, use + * `HIGH_SPEED_CLK_MULT` (24) times faster base clock. + */ + write32p(CONFIG_CONSOLE_UART_BASE_ADDRESS + UCMR_OFFSET, + read32p(CONFIG_CONSOLE_UART_BASE_ADDRESS + UCMR_OFFSET) * HIGH_SPEED_CLK_MULT); +#else +#error MMIO access is required for baudrates above 115200. +#endif +#endif +} + +void early_uart_init(void) +{ + static const uint16_t legacy_uart_io_port_tab[] = {0x3F8, 0x2F8, 0x3E8, 0x2E8}; + register int i; + + for (i = SNOWRIDGE_UARTS_TO_INIT - 1; i >= 0; --i) { + pci_early_hsuart_device_enable(i, legacy_uart_io_port_tab[i]); + } +} diff --git a/src/soc/intel/snowridge/chip.c b/src/soc/intel/snowridge/chip.c new file mode 100644 index 0000000000..f08161e7e8 --- /dev/null +++ b/src/soc/intel/snowridge/chip.c @@ -0,0 +1,432 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpi.h> +#include <cbfs.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <device/resource.h> +#include <fsp/api.h> +#include <intelblocks/acpi.h> +#include <intelblocks/irq.h> +#include <ramstage.h> +#include <soc/acpi.h> +#include <soc/pci_devs.h> +#include <stdbool.h> +#include <stdint.h> + +#include "chip.h" +#include "common/fsp_hob.h" + +static void soc_silicon_init_params(FSPS_UPD *supd) +{ + const struct microcode *microcode_file; + size_t microcode_len; + + microcode_file = cbfs_map("cpu_microcode_blob.bin", µcode_len); + if (microcode_file && (microcode_len != 0)) { + supd->FspsConfig.PcdCpuMicrocodePatchBase = (UINT32)microcode_file; + supd->FspsConfig.PcdCpuMicrocodePatchSize = (UINT32)microcode_len; + } +} + +/* UPD parameters to be initialized before SiliconInit */ +void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) +{ + soc_silicon_init_params(supd); + mainboard_silicon_init_params(supd); +} + +static void chip_domain_resource_table_init(config_t *chip_info) +{ + memset(&chip_info->domain, 0, sizeof(chip_info->domain)); + /** + * Valid resource range meets base <= limit. + */ + for (int i = 0; i < MAX_DOMAIN; i++) { + chip_info->domain[i].bus_base = UINT8_MAX; + chip_info->domain[i].io_base = UINT16_MAX; + chip_info->domain[i].mem32_base = UINT32_MAX; + chip_info->domain[i].mem64_base = UINT64_MAX; + } +} + +static void chip_domain_resource_table_load(config_t *chip_info) +{ + const BL_IIO_UDS *hob = fsp_hob_get_iio_uds_data(); + if (!hob) + die("FSP HOB IIO UDS DATA not found!\n"); + + /** + * Assert for `numofIIO` and `BL_MAX_LOGIC_IIO_STACK` so the following loop effects. + */ + assert(hob->PlatformData.numofIIO == 1); + assert(BL_MAX_LOGIC_IIO_STACK); + + const BL_STACK_RES *stack_res = hob->PlatformData.IIO_resource[0].StackRes; + for (int i = 0; i < BL_MAX_LOGIC_IIO_STACK; i++) { + struct snr_domain *domain = &chip_info->domain[i]; + domain->personality = stack_res[i].Personality; + + /** + * SNR FSP uses specific enumerations for different type of stacks, see + * vendorcode/intel/fsp/fsp2_0/snowridge/FspmUpd.h. + */ + if (stack_res[i].Personality >= BL_TYPE_DISABLED) + continue; + + if (stack_res[i].BusBase > stack_res[i].BusLimit) + die("Incorrect bus base 0x%02x and limit 0x%02x for domain %d", + stack_res[i].BusBase, stack_res[i].BusLimit, i); + + domain->bus_base = stack_res[i].BusBase; + domain->bus_limit = stack_res[i].BusLimit; + + /** + * Stack with `BL_TYPE_RESERVED` personality has valid bus range but no IO and MMIO resources. + */ + if (stack_res[i].Personality == BL_TYPE_RESERVED) + continue; + + domain->enabled = true; + + /** + * Only non-zero resource base is valid. + */ + if (stack_res[i].PciResourceIoBase) { + if (stack_res[i].PciResourceIoBase > stack_res[i].PciResourceIoLimit) + die("Incorrect IO base 0x%04x and limit 0x%04x for domain %d", + stack_res[i].PciResourceIoBase, + stack_res[i].PciResourceIoLimit, i); + + domain->io_base = stack_res[i].PciResourceIoBase; + domain->io_limit = stack_res[i].PciResourceIoLimit; + } + + if (stack_res[i].PciResourceMem32Base) { + if (stack_res[i].PciResourceMem32Base > + stack_res[i].PciResourceMem32Limit) + die("Incorrect Mem32 base 0x%08x and limit 0x%08x for domain %d", + stack_res[i].PciResourceMem32Base, + stack_res[i].PciResourceMem32Limit, i); + + domain->mem32_base = stack_res[i].PciResourceMem32Base; + domain->mem32_limit = stack_res[i].PciResourceMem32Limit; + } + + if (stack_res[i].PciResourceMem64Base) { + if (stack_res[i].PciResourceMem64Base > + stack_res[i].PciResourceMem64Limit) + die("Incorrect Mem64 base 0x%16llx and limit 0x%16llx for domain %d", + stack_res[i].PciResourceMem64Base, + stack_res[i].PciResourceMem64Limit, i); + + domain->mem64_base = stack_res[i].PciResourceMem64Base; + domain->mem64_limit = stack_res[i].PciResourceMem64Limit; + } + } +} + +static void chip_cfg_domain_resource_table_split(config_t *chip_info, int base_domain_index, + int addtional_domain_index) +{ + assert(base_domain_index < MAX_DOMAIN); + assert(addtional_domain_index < MAX_DOMAIN); + + struct snr_domain *base_domain = &chip_info->domain[base_domain_index]; + struct snr_domain *addtional_domain = &chip_info->domain[addtional_domain_index]; + memcpy(addtional_domain, base_domain, sizeof(*addtional_domain)); + + /** + * Base + (Limit - Base) / 2 to avoid overflow. + */ + if (base_domain->bus_base < base_domain->bus_limit) { + base_domain->bus_limit = base_domain->bus_base + + (base_domain->bus_limit - base_domain->bus_base) / 2; + addtional_domain->bus_base = base_domain->bus_limit + 1; + } + + if (base_domain->io_base < base_domain->io_limit) { + base_domain->io_limit = base_domain->io_base + + (base_domain->io_limit - base_domain->io_base) / 2; + addtional_domain->io_base = base_domain->io_limit + 1; + } + + if (base_domain->mem32_base < base_domain->mem32_limit) { + base_domain->mem32_limit = + base_domain->mem32_base + + (base_domain->mem32_limit - base_domain->mem32_base) / 2; + addtional_domain->mem32_base = base_domain->mem32_limit + 1; + } + + if (base_domain->mem64_base < base_domain->mem64_limit) { + base_domain->mem64_limit = + base_domain->mem64_base + + (base_domain->mem64_limit - base_domain->mem64_base) / 2; + addtional_domain->mem64_base = base_domain->mem64_limit + 1; + } +} + +static void chip_domain_resource_table_handle_multi_root(config_t *chip_info) +{ + /** + * Split domains that have more than 1 root bus. + */ + int addtional_domain = BL_MAX_LOGIC_IIO_STACK; + chip_cfg_domain_resource_table_split(chip_info, 7, + addtional_domain++); /**< Domain 8 (Ubox1). */ + + if (chip_info->domain[2].enabled) + chip_cfg_domain_resource_table_split( + chip_info, 2, + addtional_domain++); /**< Domain 2 (S2) has an extra root bus for Intel DLB. */ +} + +static void chip_domain_resource_table_dump(config_t *chip_info) +{ + printk(BIOS_DEBUG, + "---------------------------------------------------------------------------------------------------------------------\n" + "| Domain | Enabled | Bus Base/Limit | IO Base/Limit | Mem32 Base/Limit | Mem64 Base/Limit |\n" + "---------------------------------------------------------------------------------------------------------------------\n"); + for (int i = 0; i < MAX_DOMAIN; i++) { + struct snr_domain *domain = &chip_info->domain[i]; + printk(BIOS_DEBUG, + "| %2u | %c(0x%02x) | 0x%02x/0x%02x | 0x%04x/0x%04x | 0x%08x/0x%08x | 0x%016llx/0x%016llx |\n", + i, domain->enabled ? 'Y' : 'N', domain->personality, domain->bus_base, + domain->bus_limit, domain->io_base, domain->io_limit, domain->mem32_base, + domain->mem32_limit, domain->mem64_base, domain->mem64_limit); + } + printk(BIOS_DEBUG, + "---------------------------------------------------------------------------------------------------------------------\n"); +} + +static void chip_domain_resource_table_fill(config_t *chip_info) +{ + chip_domain_resource_table_init(chip_info); + chip_domain_resource_table_load(chip_info); + chip_domain_resource_table_handle_multi_root(chip_info); + chip_domain_resource_table_dump(chip_info); +} + +static void devicetree_domain_definition_update(config_t *chip_info) +{ + struct device *dev = NULL; + int domain; + + /** + * Check static domain id agaginst dynamic and fill domain device. + */ + while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)) != NULL) { + domain = dev_get_domain_id(dev); + if (domain >= MAX_DOMAIN) + die("Incorrect domain[%d] in devicetree\n", domain); + + chip_info->domain[domain].dev = dev; + + printk(BIOS_SPEW, "%s -> domain[%d] defined in devicetree\n", dev_path(dev), + domain); + } + + if (!chip_info->domain[0].dev) + die("Please add domain 0 to device tree!\n"); + + for (domain = 0; domain < MAX_DOMAIN; domain++) { + if (!chip_info->domain[domain].enabled) { + if (chip_info->domain[domain].dev && + chip_info->domain[domain].dev->enabled) { + printk(BIOS_WARNING, + "Domain[%d] is disabled, reserved or not existed but defined in device tree!\n", + domain); + dev_set_enabled(chip_info->domain[domain].dev, false); + } + continue; + } + + if (!chip_info->domain[domain].dev) + die("Domain[%d] is enabled but not defined in device tree!\n", domain); + + dev = chip_info->domain[domain].dev; + + printk(BIOS_SPEW, "Domain[%d] is enabled, updating PCI root bus to 0x%02x\n", + domain, chip_info->domain[domain].bus_base); + + /* Use same bus number for secondary and subordinate before PCI enumeration. */ + dev->downstream->secondary = dev->downstream->subordinate = + chip_info->domain[domain].bus_base; + dev->downstream->max_subordinate = chip_info->domain[domain].bus_limit; + } +} + +static void soc_init_pre_device(void *chip_info) +{ + fsp_silicon_init(); + + chip_domain_resource_table_fill((config_t *)chip_info); + + devicetree_domain_definition_update((config_t *)chip_info); +} + +static void domain_read_resources(struct device *dev) +{ + struct resource *res; + uint8_t index = 0; + const uint8_t domain = dev->path.domain.domain_id; + const config_t *chip_info = dev->chip_info; + + printk(BIOS_DEBUG, "Reading resources for %s\n", dev_path(dev)); + + /** + * Allocate IO resource. + */ + if (chip_info->domain[domain].io_limit >= chip_info->domain[domain].io_base) { + res = new_resource(dev, index++); + if (!res) + die("Allocate resource for %s failed!\n", dev_path(dev)); + + res->base = chip_info->domain[domain].io_base; + res->limit = chip_info->domain[domain].io_limit; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED; + printk(BIOS_SPEW, "IO Base/Limit: 0x%04llx/0x%04llx\n", res->base, res->limit); + } + + /** + * Allocate Mem32 resource. + */ + if (chip_info->domain[domain].mem32_limit >= chip_info->domain[domain].mem32_base) { + res = new_resource(dev, index++); + if (!res) + die("Allocate resource for %s failed!\n", dev_path(dev)); + + res->base = chip_info->domain[domain].mem32_base; + res->limit = chip_info->domain[domain].mem32_limit; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED; + printk(BIOS_SPEW, "Mem32 Base/Limit: 0x%08llx/0x%08llx\n", res->base, + res->limit); + } + + /** + * Allocate Mem64 resource. + */ + if (chip_info->domain[domain].mem64_limit >= chip_info->domain[domain].mem64_base) { + res = new_resource(dev, index++); + if (!res) + die("Allocate resource for %s failed!\n", dev_path(dev)); + + res->base = chip_info->domain[domain].mem64_base; + res->limit = chip_info->domain[domain].mem64_limit; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_PCI64 | + IORESOURCE_ABOVE_4G; + printk(BIOS_SPEW, "Mem64 Base/Limit: 0x%016llx/0x%016llx\n", res->base, + res->size); + } + + printk(BIOS_DEBUG, "Reading resources for %s done\n", dev_path(dev)); +} + +static void domain_set_resources(struct device *dev) +{ + printk(BIOS_DEBUG, "Setting resources for %s\n", dev_path(dev)); + + pci_domain_set_resources(dev); + + printk(BIOS_DEBUG, "Setting resources for %s done\n", dev_path(dev)); +} + +static void domain_scan_bus(struct device *dev) +{ + printk(BIOS_DEBUG, "Scanning %s\n", dev_path(dev)); + + pci_host_bridge_scan_bus(dev); + + printk(BIOS_DEBUG, "Scanning %s done\n", dev_path(dev)); +} + +const char *soc_acpi_name(const struct device *dev) +{ + if (dev->path.type == DEVICE_PATH_DOMAIN) + switch (dev_get_domain_id(dev)) { + case 0: + return "PCI0"; + case 1: + return "PCI1"; + case 2: + return "PCI2"; + case 3: + return "PCI3"; + case 4: + return "PCI4"; + case 5: + return "PCI5"; + case 6: + return "PCI6"; + case 7: + return "PCI7"; + case 8: + return "PCI8"; + case 9: + return "PCI9"; + default: + return NULL; + } + + return NULL; +} + +static struct device_operations pci_domain_ops = { + .read_resources = domain_read_resources, + .set_resources = domain_set_resources, + .scan_bus = domain_scan_bus, + .acpi_fill_ssdt = domain_fill_ssdt, + .acpi_name = soc_acpi_name, +}; + +static struct device_operations cpu_bus_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .acpi_fill_ssdt = generate_cpu_entries, +}; + +static void southcluster_enable_dev(struct device *dev) +{ + if (!dev->enabled) { + printk(BIOS_DEBUG, "Disable %s\n", dev_path(dev)); + /** + * Mark the device as hidden so that coreboot won't complain about leftover static + * device. + */ + dev->hidden = true; + pci_and_config16(dev, PCI_COMMAND, + ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); + } else { + printk(BIOS_DEBUG, "Enable %s\n", dev_path(dev)); + pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR); + } +} + +static void soc_enable_dev(struct device *dev) +{ + if (dev->path.type == DEVICE_PATH_DOMAIN) { + printk(BIOS_SPEW, "Set domain operation for %s\n", dev_path(dev)); + dev->ops = &pci_domain_ops; + } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { + printk(BIOS_SPEW, "Set CPU cluster operation for %s\n", dev_path(dev)); + dev->ops = &cpu_bus_ops; + } else if (dev->path.type == DEVICE_PATH_PCI) { + /** + * For a static PCH device, if it's enabled, set the SERR bits, otherwise + * disable the ability of issuing and responding to IO and memory requests. + */ + if (is_dev_on_domain0(dev) && is_pci(dev) && is_pch_slot(dev->path.pci.devfn)) + southcluster_enable_dev(dev); + } +} + +struct chip_operations soc_intel_snowridge_ops = { + .name = "Intel Snowridge", + .init = &soc_init_pre_device, + .enable_dev = &soc_enable_dev, +}; diff --git a/src/soc/intel/snowridge/chip.h b/src/soc/intel/snowridge/chip.h new file mode 100644 index 0000000000..27d792a7be --- /dev/null +++ b/src/soc/intel/snowridge/chip.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_CHIP_H_ +#define _SOC_SNOWRIDGE_CHIP_H_ + +#include <fsp/soc_binding.h> +#include <intelblocks/cfg.h> +#include <stdint.h> + +/** + * @brief Total number of domains. SNR needs two additional domains to handle + * additional root bus in stack 2 (Intel Dynamic Load Balancer) and 7 (UBox1). + */ +#define MAX_DOMAIN (BL_MAX_SOCKET * BL_MAX_LOGIC_IIO_STACK + 2) + +struct snr_domain { + uint8_t enabled; + uint8_t personality; + uint8_t bus_base; + uint8_t bus_limit; + uint16_t io_base; + uint16_t io_limit; + uint32_t mem32_base; + uint32_t mem32_limit; + uint64_t mem64_base; + uint64_t mem64_limit; + struct device *dev; +}; + +struct soc_intel_snowridge_config { + struct soc_intel_common_config common_soc_config; + + uint32_t tcc_offset; /**< Needed by `common/block/cpulib.c`. */ + uint8_t eist_enable; + + struct snr_domain domain[MAX_DOMAIN]; +}; + +typedef struct soc_intel_snowridge_config config_t; + +#endif // _SOC_SNOWRIDGE_CHIP_H_ diff --git a/src/soc/intel/snowridge/chipset.cb b/src/soc/intel/snowridge/chipset.cb new file mode 100644 index 0000000000..7632b33eac --- /dev/null +++ b/src/soc/intel/snowridge/chipset.cb @@ -0,0 +1,214 @@ +## SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/snowridge + + register "common_soc_config" = "{ + .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, + }" + + # Enable Enhanced Intel SpeedStep + register "eist_enable" = "1" + + device cpu_cluster 0 alias cpu_bus on end + + device domain 0 on # S0 personality: 0x01 (UBOX_IIO) + # + # S0 hosts all the PCH peripherals and some of the CPU Complex peripherals. + # + device pci 00.0 alias pch_sa on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S0 + device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S0 + device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S0 + device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S0 + device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S0 + # + # Not found + # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S0 + # + device pci 01.0 on end # 0x0b00 - DMA Channel 0 + device pci 01.1 on end # 0x0b00 - DMA Channel 1 + device pci 01.2 on end # 0x0b00 - DMA Channel 2 + device pci 01.3 on end # 0x0b00 - DMA Channel 3 + device pci 01.4 on end # 0x0b00 - DMA Channel 4 + device pci 01.5 on end # 0x0b00 - DMA Channel 5 + device pci 01.6 on end # 0x0b00 - DMA Channel 6 + device pci 01.7 on end # 0x0b00 - DMA Channel 7 + device pci 02.0 on end # 0x09a6 - PECI Out-Of-Band Management Services Module (OOBMSM) + device pci 02.1 on end # 0x09a7 - PECI OOB-MSM - Discovery + device pci 02.2 hidden end # 0x09a8 - Reserved + device pci 02.4 on end # 0x3456 - CPU Complex Intel Trace Hub + # + # QAT v.17 is SKU dependent, let coreboot autodetect it. + # device pci 06.0 on end # 0x18da - Intel QAT v1.7 + # + device pci 07.0 on end # 0x18b3 - SATA Controller 0 + # + # Let coreboot autodetect when something is plugged in. + # device pci 09.0 on end # 0x18a4 - PCH PCIe Cluster 0, Root Port 0 + # device pci 0a.0 on end # 0x18a5 - PCH PCIe Cluster 0, Root Port 1 + # device pci 0b.0 on end # 0x18a6 - PCH PCIe Cluster 0, Root Port 2 + # device pci 0c.0 on end # 0x18a7 - PCH PCIe Cluster 0, Root Port 3 + # + device pci 0e.0 on end # 0x18f3 - SATA Controller 2 + device pci 0f.0 on end # 0x18ac - Host (DMA) SMBus + # + # Let coreboot autodetect when something is plugged in. + # device pci 14.0 on end # 0x18ad - PCH PCIe Cluster 2, Root Port 8 + # device pci 15.0 on end # 0x18ae - PCH PCIe Cluster 2, Root Port 9 + # device pci 16.0 on end # 0x18af - PCH PCIe Cluster 2, Root Port 10 + # device pci 17.0 on end # 0x18a2 - PCH PCIe Cluster 2, Root Port 11 + # + device pci 18.0 on end # 0x18d3 - Intel ME - HECI 1 + device pci 18.1 hidden end # 0x18d4 - Reserved + device pci 18.2 hidden end # 0x18ea - Reserved + device pci 18.3 hidden end # 0x18d5 - Reserved + device pci 18.4 hidden end # 0x18d6 - Reserved + device pci 18.6 hidden end # 0x18d7 - Reserved + device pci 1a.0 on end # 0x18d8 - HSUART 0 + device pci 1a.1 on end # 0x18d8 - HSUART 1 + device pci 1a.2 on end # 0x18d8 - HSUART 2 + device pci 1a.3 hidden end # 0x18d9 - Reserved + # + # Not found + # device pci 1a.4 on end # 0x18ec - Reserved + # device pci 1b.0 on end # 0x18e5 - Reserved + # device pci 1b.1 on end # 0x18e6 - Reserved + # device pci 1b.2 on end # 0x18e7 - Reserved + # device pci 1b.3 on end # 0x18e8 - Reserved + # device pci 1b.4 on end # 0x18e9 - Reserved + # device pci 1b.6 on end # 0x18eb - Reserved + # + device pci 1c.0 on end # 0x18db - eMMC Controller + device pci 1d.0 on end # 0x0998 - Satellite IEH - PCH + device pci 1e.0 on end # 0x18d0 - USB Controller + # + # Not found + # device pci 1e.2 on end # 0x18e3 - PCM/SRAM + # + device pci 1f.0 on end # 0x18dc - LPC/eSPI Controller + device pci 1f.1 on end # 0x18dd - PH Bridge Control - P2SB + device pci 1f.2 hidden end # 0x18de - PCH PMC + device pci 1f.4 on end # 0x18df - Legacy SMBus + device pci 1f.5 on end # 0x18e0 - SPI Controller + device pci 1f.7 on end # 0x18e1 - PCH Intel Trace Hub + end # D0 S0 + device domain 1 on # S1 personality: 0x01 (UBOX_IIO) + # + # S1 hosts the CPU Complex PCIe Root Ports + # + device pci 00.0 alias cpu_sa on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S1 + device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S1 + device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S1 + device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S1 + device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S1 + # + # Not found + # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S1 + # + # Let coreboot autodetect when something is plugged in. + # device pci 04.0 on end # 0x334a - CPU PCIe Root Port - A link widths: x16, x8, x4, x2, x1 + # device pci 05.0 on end # 0x334b - CPU PCIe Root Port - B link widths: x4, x2, x1 + # device pci 06.0 on end # 0x334c - CPU PCIe Root Port - C link widths: x8, x4, x2, x1 + # device pci 07.0 on end # 0x334d - CPU PCIe Root Port - D link widths: x4, x2, x1 + # + end # D1 S1 + device domain 2 on # S2 personality: 0x05 (NAC) + device pci 00.0 alias dlb_sa on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S2 + device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S2 + device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S2 + device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S2 + device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S2 + # + # Not found + # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S2 + # + end # D2 S2 + device domain 3 on # S3 personality: 0x05 (NAC) + # + # S3 hosts the VRP to the Network Interface and Scheduler (NIS) + # + device pci 00.0 on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S3 + device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S3 + device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S3 + device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S3 + device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S3 + # + # Not found + # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S3 + # + device pci 04.0 alias nis_vrp on # 0x18d1 - VRP to Network Interface and Scheduler (NIS) + # + # NIS devices are SKU dependent, let coreboot autodetect them. + # + end + end # D3 S3 + device domain 4 on # S4 personality: 0x05 (NAC) + # + # S4 hosts the Intel QAT v1.8 accelerator and the iRC-NAC + # + device pci 00.0 on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S4 + device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S4 + device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S4 + device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S4 + device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S4 + # + # Not found + # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S4 + # + device pci 05.0 alias qat_1_8_vrp on # 0x18da - VRP for Intel QAT v1.8 accelerator + device pci 00.0 on end # 0x18a0 - Intel QAT v1.8 accelerator + end + device pci 06.0 on end # 0x18e2 - NAC Intelligent Reset Controller (iRC) + end # D4 S4 + device domain 5 off # Personality: 0x12 (None) + end # D5 S5 + device domain 6 off # Personality: 0x08 (Reserved) + end # D6 S6 + device domain 7 on # Personality: 0x00 (Ubox) U0 + # + # U0 is the second-highest bus number assigned to the device + # U0 hosts the Ubox, Serial Presence Detect (SPD) SMBus, + # Virtual Pin Port (VPP) SMBus, the Memory Controller, and DDRIO + # + device pci 00.0 on end # 0x3460 - Ubox - Noncoherent Events (NCEVENTS) + device pci 00.1 on end # 0x3451 - Ubox - Register Access Control Unit (RACU) + device pci 00.2 on end # 0x3452 - Ubox - Noncoherent Decode (NCDECS) + device pci 00.3 on end # 0x0998 - Ubox - Global I/O Error Handler (Global IEH) + device pci 00.5 on end # 0x3455 - Ubox - Error Handling + device pci 0b.0 on end # 0x3448 - Ubox - SPD0 SMBus + device pci 0b.1 on end # 0x3449 - Ubox - SPD1 SMBus. Note: SoC does not pin out it. + device pci 0b.2 hidden end # 0x344b - Ubox - Reserved + device pci 0c.0 on end # 0x344a - Ubox - IMC + device pci 1a.0 on end # 0x2880 - Ubox - DDRIO + end # D7 U0 + device domain 8 on # U1 - additional root bus 0xFF for domain/stack 7 + # + # U1 is the highest bus number assigned to the device + # U1 hosts the Cache and Home Agent (CHA) and Power Control Unit (PCU) + # + device pci 00.0 on end # 0x344c - CHA0_GRP1 - Mesh Credit Configuration + device pci 00.1 on end # 0x344c - CHA1_GRP1 - Mesh Credit Configuration + device pci 00.2 on end # 0x344c - CHA2_GRP1 - Mesh Credit Configuration + device pci 00.3 on end # 0x344c - CHA3_GRP1 - Mesh Credit Configuration + device pci 00.4 on end # 0x344c - CHA4_GRP1 - Mesh Credit Configuration + device pci 00.5 on end # 0x344c - CHA5_GRP1 - Mesh Credit Configuration + device pci 0a.0 on end # 0x344d - CHA0_GRP0 - IMC Channel Mapping + device pci 0a.1 on end # 0x344d - CHA1_GRP0 - IMC Channel Mapping + device pci 0a.2 on end # 0x344d - CHA2_GRP0 - IMC Channel Mapping + device pci 0a.3 on end # 0x344d - CHA3_GRP0 - IMC Channel Mapping + device pci 0a.4 on end # 0x344d - CHA4_GRP0 - IMC Channel Mapping + device pci 0a.5 on end # 0x344d - CHA5_GRP0 - IMC Channel Mapping + device pci 1d.0 on end # 0x344f - CHAALL0 - Multicast DRAM Rules + device pci 1d.1 on end # 0x3457 - CHAALL1 - Multicast MMIO Rules + device pci 1e.0 on end # 0x3458 - Power Control Unit (PCU) + device pci 1e.1 on end # 0x3459 - PCU + device pci 1e.2 on end # 0x345a - PCU + device pci 1e.3 on end # 0x345b - PCU + device pci 1e.4 on end # 0x345c - PCU + device pci 1e.5 on end # 0x345d - PCU + device pci 1e.6 on end # 0x345e - PCU + device pci 1e.7 on end # 0x345f - PCU + end # D8 U1 + device domain 9 on # Additional root bus 0xE7 for domain/stack 2 + device pci 0.0 alias dlb on end # 0x270b - Intel DLB 1.0 + end +end #chip diff --git a/src/soc/intel/snowridge/common/fsp_hob.c b/src/soc/intel/snowridge/common/fsp_hob.c new file mode 100644 index 0000000000..426e6c3cf9 --- /dev/null +++ b/src/soc/intel/snowridge/common/fsp_hob.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <fsp/util.h> + +#include "fsp_hob.h" + +const guid_t fsp_hob_fia_override_status_guid = { + .b = {0xc1, 0x94, 0x8d, 0x61, 0xde, 0x0e, 0xe3, 0x4e, 0x98, 0x4F, 0xB2, 0x07, 0x6B, + 0x05, 0x50, 0xFB} +}; + +const guid_t fsp_hob_iio_uds_data_guid = { + .b = {0xbd, 0x74, 0x6b, 0x83, 0xf3, 0xc2, 0x28, 0x4d, 0xa3, 0xb8, 0x91, 0x33, 0x10, + 0x52, 0x52, 0x9b} +}; + +const guid_t fsp_hob_kti_cache_guid = { + .b = {0xd6, 0xd3, 0x45, 0xac, 0x6e, 0xa3, 0xa6, 0x43, 0xad, 0x17, 0x0a, 0x45, 0xbb, + 0x47, 0xbe, 0xd6} +}; + +const guid_t fsp_hob_smbios_memory_info_guid = { + .b = {0x8c, 0x10, 0xa1, 0x01, 0xee, 0x9d, 0x84, 0x49, 0x88, 0xc3, 0xee, 0xe8, 0xc4, + 0x9e, 0xfb, 0x89} +}; + +static const void *fsp_hob_get(const guid_t *guid, size_t *hob_size) +{ + return fsp_find_extension_hob_by_guid(guid->b, hob_size); +} + +const BL_IIO_UDS *fsp_hob_get_iio_uds_data(void) +{ + size_t unused; + + return fsp_hob_get(&fsp_hob_iio_uds_data_guid, &unused); +} + +const void *fsp_hob_get_kti_cache(size_t *hob_size) +{ + return fsp_hob_get(&fsp_hob_kti_cache_guid, hob_size); +} + +const FSP_SMBIOS_MEMORY_INFO *fsp_hob_get_memory_info(void) +{ + size_t unused; + + return fsp_hob_get(&fsp_hob_smbios_memory_info_guid, &unused); +} diff --git a/src/soc/intel/snowridge/common/fsp_hob.h b/src/soc/intel/snowridge/common/fsp_hob.h new file mode 100644 index 0000000000..e5c96bdd27 --- /dev/null +++ b/src/soc/intel/snowridge/common/fsp_hob.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_FSP_HOB_H_ +#define _SOC_SNOWRIDGE_FSP_HOB_H_ + +#include <fsp/soc_binding.h> +#include <stddef.h> +#include <stdint.h> +#include <uuid.h> + +extern const guid_t fsp_hob_fia_override_status_guid; +extern const guid_t fsp_hob_iio_uds_data_guid; +extern const guid_t fsp_hob_kti_cache_guid; +extern const guid_t fsp_hob_smbios_memory_info_guid; + +const BL_IIO_UDS *fsp_hob_get_iio_uds_data(void); +const void *fsp_hob_get_kti_cache(size_t *hob_size); +const FSP_SMBIOS_MEMORY_INFO *fsp_hob_get_memory_info(void); + +#endif // _SOC_SNOWRIDGE_FSP_HOB_H_ diff --git a/src/soc/intel/snowridge/common/gpio.c b/src/soc/intel/snowridge/common/gpio.c new file mode 100644 index 0000000000..8bf5edf50e --- /dev/null +++ b/src/soc/intel/snowridge/common/gpio.c @@ -0,0 +1,314 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/gpio.h> +#include <soc/gpio_snr.h> +#include <soc/pcr_ids.h> + +static const struct pad_group snr_community_west2_groups[] = { + INTEL_GPP(GPIO_WEST2_0, GPIO_WEST2_0, GPIO_WEST2_23), +}; + +static const struct pad_group snr_community_west3_groups[] = { + INTEL_GPP(GPIO_WEST3_0, GPIO_WEST3_0, GPIO_WEST3_23), +}; + +static const struct pad_group snr_community_west01_groups[] = { + INTEL_GPP(GPIO_WEST01_0, GPIO_WEST01_0, GPIO_WEST01_22), +}; + +static const struct pad_group snr_community_west5_groups[] = { + INTEL_GPP(GPIO_WEST5_0, GPIO_WEST5_0, GPIO_WEST5_18), +}; + +static const struct pad_group snr_community_westb_groups[] = { + INTEL_GPP(GPIO_WESTB_0, GPIO_WESTB_0, GPIO_WESTB_11), +}; + +static const struct pad_group snr_community_westd_peci_groups[] = { + INTEL_GPP(GPIO_WESTD_PECI_0, GPIO_WESTD_PECI_0, GPIO_WESTD_PECI_0), +}; + +static const struct pad_group snr_community_east2_groups[] = { + INTEL_GPP(GPIO_EAST2_0, GPIO_EAST2_0, GPIO_EAST2_23), +}; + +static const struct pad_group snr_community_east3_groups[] = { + INTEL_GPP(GPIO_EAST3_0, GPIO_EAST3_0, GPIO_EAST3_9), +}; + +static const struct pad_group snr_community_east0_groups[] = { + INTEL_GPP(GPIO_EAST0_0, GPIO_EAST0_0, GPIO_EAST0_22), +}; + +static const struct pad_group snr_community_emmc_groups[] = { + INTEL_GPP(GPIO_EMMC_0, GPIO_EMMC_0, GPIO_EMMC_10), +}; + +static const struct pad_community snr_gpio_communities[] = { + { + .name = "GPIO_WEST2", + .acpi_path = "\\_SB.GPO0", + .num_gpi_regs = GPIO_WEST2_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_WEST2_0, + .last_pad = GPIO_WEST2_23, + .pad_own_reg_0 = GPIO_WEST2_PAD_OWN, + .host_own_reg_0 = GPIO_WEST2_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_WEST2_GPI_IS, + .gpi_int_en_reg_0 = GPIO_WEST2_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_WEST2_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_WEST2_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_WEST2_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_WEST2_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_WEST2_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_WEST2_NMI_EN, + .pad_cfg_base = GPIO_WEST2_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_WEST2_PADCFGLOCK, + .gpi_status_offset = 0, + .port = PID_GPIOCOM1, + .groups = snr_community_west2_groups, + .num_groups = ARRAY_SIZE(snr_community_west2_groups), + }, + { + .name = "GPIO_WEST3", + .acpi_path = "\\_SB.GPO1", + .num_gpi_regs = GPIO_WEST3_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_WEST3_0, + .last_pad = GPIO_WEST3_23, + .pad_own_reg_0 = GPIO_WEST3_PAD_OWN, + .host_own_reg_0 = GPIO_WEST3_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_WEST3_GPI_IS, + .gpi_int_en_reg_0 = GPIO_WEST3_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_WEST3_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_WEST3_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_WEST3_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_WEST3_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_WEST3_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_WEST3_NMI_EN, + .pad_cfg_base = GPIO_WEST3_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_WEST3_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS, + .port = PID_GPIOCOM1, + .groups = snr_community_west3_groups, + .num_groups = ARRAY_SIZE(snr_community_west3_groups), + }, + { + .name = "GPIO_WEST01", + .acpi_path = "\\_SB.GPO2", + .num_gpi_regs = GPIO_WEST01_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_WEST01_0, + .last_pad = GPIO_WEST01_22, + .pad_own_reg_0 = GPIO_WEST01_PAD_OWN, + .host_own_reg_0 = GPIO_WEST01_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_WEST01_GPI_IS, + .gpi_int_en_reg_0 = GPIO_WEST01_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_WEST01_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_WEST01_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_WEST01_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_WEST01_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_WEST01_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_WEST01_NMI_EN, + .pad_cfg_base = GPIO_WEST01_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_WEST01_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS, + .port = PID_GPIOCOM1, + .groups = snr_community_west01_groups, + .num_groups = ARRAY_SIZE(snr_community_west01_groups), + }, + { + .name = "GPIO_WEST5", + .acpi_path = "\\_SB.GPO3", + .num_gpi_regs = GPIO_WEST5_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_WEST5_0, + .last_pad = GPIO_WEST5_18, + .pad_own_reg_0 = GPIO_WEST5_PAD_OWN, + .host_own_reg_0 = GPIO_WEST5_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_WEST5_GPI_IS, + .gpi_int_en_reg_0 = GPIO_WEST5_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_WEST5_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_WEST5_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_WEST5_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_WEST5_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_WEST5_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_WEST5_NMI_EN, + .pad_cfg_base = GPIO_WEST5_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_WEST5_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + + GPIO_WEST01_GPI_STATUS_REGS, + .port = PID_GPIOCOM1, + .groups = snr_community_west5_groups, + .num_groups = ARRAY_SIZE(snr_community_west5_groups), + }, + { + .name = "GPIO_WESTB", + .acpi_path = "\\_SB.GPO4", + .num_gpi_regs = GPIO_WESTB_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_WESTB_0, + .last_pad = GPIO_WESTB_11, + .pad_own_reg_0 = GPIO_WESTB_PAD_OWN, + .host_own_reg_0 = GPIO_WESTB_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_WESTB_GPI_IS, + .gpi_int_en_reg_0 = GPIO_WESTB_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_WESTB_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_WESTB_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_WESTB_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_WESTB_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_WESTB_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_WESTB_NMI_EN, + .pad_cfg_base = GPIO_WESTB_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_WESTB_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + + GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS, + .port = PID_GPIOCOM1, + .groups = snr_community_westb_groups, + .num_groups = ARRAY_SIZE(snr_community_westb_groups), + }, + { + .name = "GPIO_WESTD_PECI", + .acpi_path = "\\_SB.GPO5", + .num_gpi_regs = GPIO_WESTD_PECI_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_WESTD_PECI_0, + .last_pad = GPIO_WESTD_PECI_0, + .pad_own_reg_0 = GPIO_WESTD_PECI_PAD_OWN, + .host_own_reg_0 = GPIO_WESTD_PECI_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_WESTD_PECI_GPI_IS, + .gpi_int_en_reg_0 = GPIO_WESTD_PECI_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_WESTD_PECI_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_WESTD_PECI_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_WESTD_PECI_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_WESTD_PECI_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_WESTD_PECI_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_WESTD_PECI_NMI_EN, + .pad_cfg_base = GPIO_WESTD_PECI_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_WESTD_PECI_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + + GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS + + GPIO_WESTB_GPI_STATUS_REGS, + .port = PID_GPIOCOM1, + .groups = snr_community_westd_peci_groups, + .num_groups = ARRAY_SIZE(snr_community_westd_peci_groups), + }, + { + .name = "GPIO_EAST2", + .acpi_path = "\\_SB.GPO11", + .num_gpi_regs = GPIO_EAST2_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_EAST2_0, + .last_pad = GPIO_EAST2_23, + .pad_own_reg_0 = GPIO_EAST2_PAD_OWN, + .host_own_reg_0 = GPIO_EAST2_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_EAST2_GPI_IS, + .gpi_int_en_reg_0 = GPIO_EAST2_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_EAST2_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_EAST2_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_EAST2_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_EAST2_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_EAST2_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_EAST2_NMI_EN, + .pad_cfg_base = GPIO_EAST2_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_EAST2_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + + GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS + + GPIO_WESTB_GPI_STATUS_REGS + + GPIO_WESTD_PECI_GPI_STATUS_REGS, + .port = PID_GPIOCOM0, + .groups = snr_community_east2_groups, + .num_groups = ARRAY_SIZE(snr_community_east2_groups), + }, + { + .name = "GPIO_EAST3", + .acpi_path = "\\_SB.GPO12", + .num_gpi_regs = GPIO_EAST3_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_EAST3_0, + .last_pad = GPIO_EAST3_9, + .pad_own_reg_0 = GPIO_EAST3_PAD_OWN, + .host_own_reg_0 = GPIO_EAST3_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_EAST3_GPI_IS, + .gpi_int_en_reg_0 = GPIO_EAST3_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_EAST3_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_EAST3_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_EAST3_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_EAST3_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_EAST3_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_EAST3_NMI_EN, + .pad_cfg_base = GPIO_EAST3_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_EAST3_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + + GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS + + GPIO_WESTB_GPI_STATUS_REGS + + GPIO_WESTD_PECI_GPI_STATUS_REGS + + GPIO_EAST2_GPI_STATUS_REGS, + .port = PID_GPIOCOM0, + .groups = snr_community_east3_groups, + .num_groups = ARRAY_SIZE(snr_community_east3_groups), + }, + { + .name = "GPIO_EAST0", + .acpi_path = "\\_SB.GPO13", + .num_gpi_regs = GPIO_EAST0_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_EAST0_0, + .last_pad = GPIO_EAST0_22, + .pad_own_reg_0 = GPIO_EAST0_PAD_OWN, + .host_own_reg_0 = GPIO_EAST0_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_EAST0_GPI_IS, + .gpi_int_en_reg_0 = GPIO_EAST0_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_EAST0_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_EAST0_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_EAST0_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_EAST0_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_EAST0_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_EAST0_NMI_EN, + .pad_cfg_base = GPIO_EAST0_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_EAST0_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + + GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS + + GPIO_WESTB_GPI_STATUS_REGS + + GPIO_WESTD_PECI_GPI_STATUS_REGS + + GPIO_EAST2_GPI_STATUS_REGS + GPIO_EAST3_GPI_STATUS_REGS, + .port = PID_GPIOCOM0, + .groups = snr_community_east0_groups, + .num_groups = ARRAY_SIZE(snr_community_east0_groups), + }, + { + .name = "GPIO_EMMC", + .acpi_path = "\\_SB.GPO14", + .num_gpi_regs = GPIO_EMMC_GPI_STATUS_REGS, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .first_pad = GPIO_EMMC_0, + .last_pad = GPIO_EMMC_10, + .pad_own_reg_0 = GPIO_EMMC_PAD_OWN, + .host_own_reg_0 = GPIO_EMMC_HOSTSW_OWN, + .gpi_int_sts_reg_0 = GPIO_EMMC_GPI_IS, + .gpi_int_en_reg_0 = GPIO_EMMC_GPI_IE, + .gpi_smi_sts_reg_0 = GPIO_EMMC_SMI_STS, + .gpi_smi_en_reg_0 = GPIO_EMMC_SMI_EN, + .gpi_gpe_sts_reg_0 = GPIO_EMMC_GPI_GPE_STS, + .gpi_gpe_en_reg_0 = GPIO_EMMC_GPI_GPE_EN, + .gpi_nmi_sts_reg_0 = GPIO_EMMC_NMI_STS, + .gpi_nmi_en_reg_0 = GPIO_EMMC_NMI_EN, + .pad_cfg_base = GPIO_EMMC_PADCFG_OFFSET, + .pad_cfg_lock_offset = GPIO_EMMC_PADCFGLOCK, + .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + + GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS + + GPIO_WESTB_GPI_STATUS_REGS + + GPIO_WESTD_PECI_GPI_STATUS_REGS + + GPIO_EAST2_GPI_STATUS_REGS + GPIO_EAST3_GPI_STATUS_REGS + + GPIO_EAST0_GPI_STATUS_REGS, + .port = PID_GPIOCOM0, + .groups = snr_community_emmc_groups, + .num_groups = ARRAY_SIZE(snr_community_emmc_groups), + } +}; + +const struct pad_community *soc_gpio_get_community(size_t *num_communities) +{ + *num_communities = ARRAY_SIZE(snr_gpio_communities); + return snr_gpio_communities; +} diff --git a/src/soc/intel/snowridge/common/hob_display.c b/src/soc/intel/snowridge/common/hob_display.c new file mode 100644 index 0000000000..eaed9c674b --- /dev/null +++ b/src/soc/intel/snowridge/common/hob_display.c @@ -0,0 +1,312 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <fsp/debug.h> +#include <fsp/soc_binding.h> +#include <fsp/util.h> +#include <lib.h> +#include <uuid.h> + +#include "fsp_hob.h" + +struct guid_name_map { + const guid_t *guid; + const char *name; +}; + +static const struct guid_name_map guid_names[] = { + {&fsp_hob_fia_override_status_guid, "FSP_HOB_FIA_OVERRIDE_STATUS_GUID"}, + {&fsp_hob_iio_uds_data_guid, "FSP_HOB_IIO_UDS_DATA_GUID" }, + {&fsp_hob_kti_cache_guid, "FSP_HOB_KTI_HOST_NVRAM_DATA_GUID"}, + {&fsp_hob_smbios_memory_info_guid, "FSP_HOB_SMBIOS_MEMORY_INFO_GUID" }, +}; + +const char *soc_get_guid_name(const uint8_t *guid) +{ + size_t index; + + /* Compare the GUID values in this module */ + for (index = 0; index < ARRAY_SIZE(guid_names); index++) + if (fsp_guid_compare(guid, guid_names[index].guid->b)) + return guid_names[index].name; + + return NULL; +} + +static void soc_display_fsp_iio_uds_data_hob(const BL_IIO_UDS *hob) +{ + if (!hob) { + return; + } + + printk(BIOS_DEBUG, "IIO UDS\n"); + printk(BIOS_DEBUG, "\t Platform Data\n"); + printk(BIOS_DEBUG, "\t\t PlatGlobalIoBase: 0x%x\n", hob->PlatformData.PlatGlobalIoBase); + printk(BIOS_DEBUG, "\t\t PlatGlobalIoLimit: 0x%x\n", + hob->PlatformData.PlatGlobalIoLimit); + printk(BIOS_DEBUG, "\t\t PlatGlobalMmio32Base: 0x%x\n", + hob->PlatformData.PlatGlobalMmio32Base); + printk(BIOS_DEBUG, "\t\t PlatGlobalMmio32Limit: 0x%x\n", + hob->PlatformData.PlatGlobalMmio32Limit); + printk(BIOS_DEBUG, "\t\t PlatGlobalMmio64Base: 0x%llx\n", + hob->PlatformData.PlatGlobalMmio64Base); + printk(BIOS_DEBUG, "\t\t PlatGlobalMmio64Limit: 0x%llx\n", + hob->PlatformData.PlatGlobalMmio64Limit); + for (int socket = 0; socket < BL_MAX_SOCKET; socket++) { + const BL_QPI_CPU_DATA *cpu_qpi_info = &hob->PlatformData.CpuQpiInfo[socket]; + printk(BIOS_DEBUG, "\t\t CpuQpiInfo[%d]\n", socket); + printk(BIOS_DEBUG, "\t\t\t Valid: 0x%x\n", cpu_qpi_info->Valid); + for (int bar = 0; bar < BL_TYPE_MAX_MMIO_BAR; bar++) { + printk(BIOS_DEBUG, "\t\t\t MmioBar[%d]: 0x%x\n", bar, + cpu_qpi_info->MmioBar[bar]); + } + printk(BIOS_DEBUG, "\t\t\t PcieSegment: 0x%x\n", cpu_qpi_info->PcieSegment); + printk(BIOS_DEBUG, "\t\t\t SegMmcfgBase: 0x%llx\n", + cpu_qpi_info->SegMmcfgBase.Data); + printk(BIOS_DEBUG, "\t\t\t stackPresentBitmap: 0x%x\n", + cpu_qpi_info->stackPresentBitmap); + printk(BIOS_DEBUG, "\t\t\t M2PciePresentBitmap: 0x%x\n", + cpu_qpi_info->M2PciePresentBitmap); + printk(BIOS_DEBUG, "\t\t\t TotM3Kti: 0x%x\n", cpu_qpi_info->TotM3Kti); + printk(BIOS_DEBUG, "\t\t\t TotCha: 0x%x\n", cpu_qpi_info->TotCha); + for (int cha = 0; cha < BL_MAX_CHA_MAP; cha++) { + printk(BIOS_DEBUG, "\t\t\t ChaList[%d]: 0x%x\n", cha, + cpu_qpi_info->ChaList[cha]); + } + printk(BIOS_DEBUG, "\t\t\t SocId: 0x%x\n", cpu_qpi_info->SocId); + for (int peer = 0; peer < BL_MAX_FW_KTI_PORTS; peer++) { + const BL_QPI_PEER_DATA *peer_info = &cpu_qpi_info->PeerInfo[peer]; + printk(BIOS_DEBUG, "\t\t\t PeerInfo[%d]\n", peer); + printk(BIOS_DEBUG, "\t\t\t\t Valid: 0x%x\n", peer_info->Valid); + printk(BIOS_DEBUG, "\t\t\t\t PeerSocId: 0x%x\n", peer_info->PeerSocId); + printk(BIOS_DEBUG, "\t\t\t\t PeerSocType: 0x%x\n", + peer_info->PeerSocType); + printk(BIOS_DEBUG, "\t\t\t\t PeerPort: 0x%x\n", peer_info->PeerPort); + } + } + for (int socket = 0; socket < BL_MAX_SOCKET; socket++) { + const BL_QPI_IIO_DATA *iio_qpi_info = &hob->PlatformData.IioQpiInfo[socket]; + printk(BIOS_DEBUG, "\t\t IioQpiInfo[%d]\n", socket); + printk(BIOS_DEBUG, "\t\t\t SocId: 0x%x\n", iio_qpi_info->SocId); + for (int peer = 0; peer < BL_MAX_SOCKET; peer++) { + const BL_QPI_PEER_DATA *peer_info = &iio_qpi_info->PeerInfo[peer]; + printk(BIOS_DEBUG, "\t\t\t PeerInfo[%d]\n", peer); + printk(BIOS_DEBUG, "\t\t\t\t Valid: 0x%x\n", peer_info->Valid); + printk(BIOS_DEBUG, "\t\t\t\t PeerSocId: 0x%x\n", peer_info->PeerSocId); + printk(BIOS_DEBUG, "\t\t\t\t PeerSocType: 0x%x\n", + peer_info->PeerSocType); + printk(BIOS_DEBUG, "\t\t\t\t PeerPort: 0x%x\n", peer_info->PeerPort); + } + } + printk(BIOS_DEBUG, "\t\t MemTsegSize: 0x%x\n", hob->PlatformData.MemTsegSize); + printk(BIOS_DEBUG, "\t\t MemIedSize: 0x%x\n", hob->PlatformData.MemIedSize); + printk(BIOS_DEBUG, "\t\t PciExpressBase: 0x%llx\n", hob->PlatformData.PciExpressBase); + printk(BIOS_DEBUG, "\t\t PciExpressSize: 0x%x\n", hob->PlatformData.PciExpressSize); + printk(BIOS_DEBUG, "\t\t MemTolm: 0x%x\n", hob->PlatformData.MemTolm); + for (uint8_t socket = 0; socket < hob->PlatformData.numofIIO; socket++) { + const BL_IIO_RESOURCE_INSTANCE *iio_res = + &hob->PlatformData.IIO_resource[socket]; + printk(BIOS_DEBUG, "\t\t IIO_resource[%d]\n", socket); + printk(BIOS_DEBUG, "\t\t\t Valid: 0x%x\n", iio_res->Valid); + printk(BIOS_DEBUG, "\t\t\t SocketID: 0x%x\n", iio_res->SocketID); + printk(BIOS_DEBUG, "\t\t\t BusBase: 0x%x\n", iio_res->BusBase); + printk(BIOS_DEBUG, "\t\t\t BusLimit: 0x%x\n", iio_res->BusLimit); + printk(BIOS_DEBUG, "\t\t\t PciResourceIoBase: 0x%x\n", + iio_res->PciResourceIoBase); + printk(BIOS_DEBUG, "\t\t\t PciResourceIoLimit: 0x%x\n", + iio_res->PciResourceIoLimit); + printk(BIOS_DEBUG, "\t\t\t IoApicBase: 0x%x\n", iio_res->IoApicBase); + printk(BIOS_DEBUG, "\t\t\t IoApicLimit: 0x%x\n", iio_res->IoApicLimit); + printk(BIOS_DEBUG, "\t\t\t Mmio32Base: 0x%x\n", iio_res->Mmio32Base); + printk(BIOS_DEBUG, "\t\t\t Mmio32Limit: 0x%x\n", iio_res->Mmio32Limit); + printk(BIOS_DEBUG, "\t\t\t Mmio64Base: 0x%llx\n", iio_res->Mmio64Base); + printk(BIOS_DEBUG, "\t\t\t Mmio64Limit: 0x%llx\n", iio_res->Mmio64Limit); + for (int stack = 0; stack < BL_MAX_LOGIC_IIO_STACK; stack++) { + const BL_STACK_RES *stack_res = &iio_res->StackRes[stack]; + printk(BIOS_DEBUG, "\t\t\t StackRes[%d]\n", stack); + printk(BIOS_DEBUG, "\t\t\t\t Personality: 0x%x\n", + stack_res->Personality); + printk(BIOS_DEBUG, "\t\t\t\t BusBase: 0x%x\n", stack_res->BusBase); + printk(BIOS_DEBUG, "\t\t\t\t BusLimit: 0x%x\n", stack_res->BusLimit); + printk(BIOS_DEBUG, "\t\t\t\t PciResourceIoBase: 0x%x\n", + stack_res->PciResourceIoBase); + printk(BIOS_DEBUG, "\t\t\t\t PciResourceIoLimit: 0x%x\n", + stack_res->PciResourceIoLimit); + printk(BIOS_DEBUG, "\t\t\t\t IoApicBase: 0x%x\n", + stack_res->IoApicBase); + printk(BIOS_DEBUG, "\t\t\t\t IoApicLimit: 0x%x\n", + stack_res->IoApicLimit); + printk(BIOS_DEBUG, "\t\t\t\t Mmio32Base: 0x%x\n", + stack_res->Mmio32Base); + printk(BIOS_DEBUG, "\t\t\t\t Mmio32Limit: 0x%x\n", + stack_res->Mmio32Limit); + printk(BIOS_DEBUG, "\t\t\t\t Mmio64Base: 0x%llx\n", + stack_res->Mmio64Base); + printk(BIOS_DEBUG, "\t\t\t\t Mmio64Limit: 0x%llx\n", + stack_res->Mmio64Limit); + printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem32Base: 0x%x\n", + stack_res->PciResourceMem32Base); + printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem32Limit: 0x%x\n", + stack_res->PciResourceMem32Limit); + printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem64Base: 0x%llx\n", + stack_res->PciResourceMem64Base); + printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem64Limit: 0x%llx\n", + stack_res->PciResourceMem64Limit); + printk(BIOS_DEBUG, "\t\t\t\t VtdBarAddress: 0x%x\n", + stack_res->VtdBarAddress); + printk(BIOS_DEBUG, "\t\t\t\t Mmio32MinSize: 0x%x\n", + stack_res->Mmio32MinSize); + } + printk(BIOS_DEBUG, "\t\t\t RcBaseAddress: 0x%x\n", iio_res->RcBaseAddress); + printk(BIOS_DEBUG, "\t\t\t PcieInfo\n"); + for (int port = 0; port < BL_NUMBER_PORTS_PER_SOCKET; port++) { + const BL_IIO_PORT_INFO *port_info = &iio_res->PcieInfo.PortInfo[port]; + printk(BIOS_DEBUG, "\t\t\t\t PortInfo[%d]\n", port); + printk(BIOS_DEBUG, "\t\t\t\t\t Device: 0x%x, Function: 0x%x\n", + port_info->Device, port_info->Function); + } + printk(BIOS_DEBUG, "\t\t\t DmaDeviceCount: 0x%x\n", iio_res->DmaDeviceCount); + } + printk(BIOS_DEBUG, "\t\t numofIIO: 0x%x\n", hob->PlatformData.numofIIO); + printk(BIOS_DEBUG, "\t\t MaxBusNumber: 0x%x\n", hob->PlatformData.MaxBusNumber); + for (int socket = 0; socket < BL_MAX_SOCKET; socket++) { + printk(BIOS_DEBUG, "\t\t packageBspApicID[%d]: 0x%x\n", socket, + hob->PlatformData.packageBspApicID[socket]); + } + printk(BIOS_DEBUG, "\t\t EVMode: 0x%x\n", hob->PlatformData.EVMode); + printk(BIOS_DEBUG, "\t\t Pci64BitResourceAllocation: %d\n", + hob->PlatformData.Pci64BitResourceAllocation); + for (int socket = 0; socket < BL_MAX_SOCKET; socket++) { + printk(BIOS_DEBUG, "\t\t SkuPersonality[%d]: 0x%x\n", socket, + hob->PlatformData.SkuPersonality[socket]); + } + for (int iio = 0; iio < BL_MaxIIO; iio++) { + for (int iio_stack = 0; iio_stack < BL_MAX_IIO_STACK; iio_stack++) { + printk(BIOS_DEBUG, "\t\t VMDStackEnable[%d][%d]: 0x%x\n", iio, + iio_stack, hob->PlatformData.VMDStackEnable[iio][iio_stack]); + } + } + printk(BIOS_DEBUG, "\t\t IoGranularity: 0x%x\n", hob->PlatformData.IoGranularity); + printk(BIOS_DEBUG, "\t\t MmiolGranularity: 0x%x\n", hob->PlatformData.MmiolGranularity); + printk(BIOS_DEBUG, "\t\t MmiohGranularity: 0x%llx\n", + hob->PlatformData.MmiohGranularity.Data); + printk(BIOS_DEBUG, "\t\t RemoteRequestThreshold: 0x%x\n", + hob->PlatformData.RemoteRequestThreshold); + printk(BIOS_DEBUG, "\t\t UboxMmioSize: 0x%x\n", hob->PlatformData.UboxMmioSize); + printk(BIOS_DEBUG, "\t\t MaxAddressBits: 0x%x\n", hob->PlatformData.MaxAddressBits); + + printk(BIOS_DEBUG, "\t System Status\n"); + printk(BIOS_DEBUG, "\t\t CurrentUpiiLinkSpeed: 0x%x\n", + hob->SystemStatus.CurrentUpiiLinkSpeed); + printk(BIOS_DEBUG, "\t\t CurrentUpiLinkFrequency: 0x%x\n", + hob->SystemStatus.CurrentUpiLinkFrequency); + printk(BIOS_DEBUG, "\t\t OutKtiCpuSktHotPlugEn: 0x%x\n", + hob->SystemStatus.OutKtiCpuSktHotPlugEn); + for (int socket = 0; socket < BL_MAX_SOCKET; socket++) + printk(BIOS_DEBUG, "\t\t OutKtiPerLinkL1En: 0x%x\n", + hob->SystemStatus.OutKtiPerLinkL1En[socket]); + printk(BIOS_DEBUG, "\t\t IsocEnable: 0x%x\n", hob->SystemStatus.IsocEnable); + printk(BIOS_DEBUG, "\t\t meRequestedSize: 0x%x\n", hob->SystemStatus.meRequestedSize); + printk(BIOS_DEBUG, "\t\t ieRequestedSize: 0x%x\n", hob->SystemStatus.ieRequestedSize); + printk(BIOS_DEBUG, "\t\t DmiVc1: 0x%x\n", hob->SystemStatus.DmiVc1); + printk(BIOS_DEBUG, "\t\t DmiVcm: 0x%x\n", hob->SystemStatus.DmiVcm); + printk(BIOS_DEBUG, "\t\t CpuPCPSInfo: 0x%x\n", hob->SystemStatus.CpuPCPSInfo); + printk(BIOS_DEBUG, "\t\t cpuSubType: 0x%x\n", hob->SystemStatus.cpuSubType); + printk(BIOS_DEBUG, "\t\t SystemRasType: 0x%x\n", hob->SystemStatus.SystemRasType); + printk(BIOS_DEBUG, "\t\t numCpus: 0x%x\n", hob->SystemStatus.numCpus); + printk(BIOS_DEBUG, "\t\t tolmLimit: 0x%x\n", hob->SystemStatus.tolmLimit); + printk(BIOS_DEBUG, "\t\t tohmLimit: 0x%x\n", hob->SystemStatus.tohmLimit); + printk(BIOS_DEBUG, "\t\t RcVersion\n"); + printk(BIOS_DEBUG, "\t\t\t Major: 0x%x\n", hob->SystemStatus.RcVersion.Major); + printk(BIOS_DEBUG, "\t\t\t Minor: 0x%x\n", hob->SystemStatus.RcVersion.Minor); + printk(BIOS_DEBUG, "\t\t\t Revision: 0x%x\n", hob->SystemStatus.RcVersion.Revision); + printk(BIOS_DEBUG, "\t\t\t BuildNumber: 0x%x\n", + hob->SystemStatus.RcVersion.BuildNumber); + printk(BIOS_DEBUG, "\t\t MsrTraceEnable: 0x%x\n", hob->SystemStatus.MsrTraceEnable); + printk(BIOS_DEBUG, "\t\t DdrXoverMode: 0x%x\n", hob->SystemStatus.DdrXoverMode); + printk(BIOS_DEBUG, "\t\t bootMode: 0x%x\n", hob->SystemStatus.bootMode); + printk(BIOS_DEBUG, "\t\t OutClusterOnDieEn: 0x%x\n", + hob->SystemStatus.OutClusterOnDieEn); + printk(BIOS_DEBUG, "\t\t OutSncEn: 0x%x\n", hob->SystemStatus.OutSncEn); + printk(BIOS_DEBUG, "\t\t OutNumOfCluster: 0x%x\n", hob->SystemStatus.OutNumOfCluster); + for (int socket = 0; socket < BL_MAX_SOCKET; socket++) { + for (int imc = 0; imc < BL_MAX_IMC; imc++) { + printk(BIOS_DEBUG, "\t\t imcEnabled[%d][%d]: 0x%x\n", socket, imc, + hob->SystemStatus.imcEnabled[socket][imc]); + } + } + printk(BIOS_DEBUG, "\t\t LlcSizeReg: 0x%x\n", hob->SystemStatus.LlcSizeReg); + for (int socket = 0; socket < BL_MAX_SOCKET; socket++) { + for (int ch = 0; ch < BL_MAX_CH; ch++) { + printk(BIOS_DEBUG, "\t\t chEnabled[%d][%d]: 0x%x\n", socket, ch, + hob->SystemStatus.chEnabled[socket][ch]); + } + } + for (int node = 0; node < BL_MC_MAX_NODE; node++) { + printk(BIOS_DEBUG, "\t\t memNode[%d]: 0x%x\n", node, + hob->SystemStatus.memNode[node]); + } + printk(BIOS_DEBUG, "\t\t IoDcMode: 0x%x\n", hob->SystemStatus.IoDcMode); + printk(BIOS_DEBUG, "\t\t DfxRstCplBitsEn: 0x%x\n", hob->SystemStatus.DfxRstCplBitsEn); +} + +static void soc_display_fsp_fia_override_status(const BL_FIA_OVERRIDE_STATUS_HOB *hob) +{ + if (!hob) + return; + printk(BIOS_DEBUG, "FIA Override Status\n"); + printk(BIOS_DEBUG, "\t FiaMuxConfigGetStatus: 0x%08x\n", hob->FiaMuxConfigGetStatus); + printk(BIOS_DEBUG, "\t FiaMuxConfigSetStatus: 0x%08x\n", hob->FiaMuxConfigSetStatus); + printk(BIOS_DEBUG, "\t FiaMuxConfigSetRequired: 0x%08x\n", + hob->FiaMuxConfigSetRequired); +} + +static void soc_display_fsp_smbios_memory_info(const FSP_SMBIOS_MEMORY_INFO *hob) +{ + if (!hob) + return; + + printk(BIOS_DEBUG, "SMBIOS Memory Info\n"); + printk(BIOS_DEBUG, "\t Revision: 0x%x\n", hob->Revision); + printk(BIOS_DEBUG, "\t DataWidth: 0x%x\n", hob->DataWidth); + printk(BIOS_DEBUG, "\t MemoryType: 0x%x\n", hob->MemoryType); + printk(BIOS_DEBUG, "\t MemoryFrequencyInMHz: 0x%x\n", hob->MemoryFrequencyInMHz); + printk(BIOS_DEBUG, "\t ErrorCorrectionType: 0x%x\n", hob->ErrorCorrectionType); + printk(BIOS_DEBUG, "\t ChannelCount: 0x%x\n", hob->ChannelCount); + for (uint8_t channel = 0; channel < hob->ChannelCount; channel++) { + const CHANNEL_INFO *channel_info = &hob->ChannelInfo[channel]; + printk(BIOS_DEBUG, "\t ChannelInfo[%d]\n", channel); + printk(BIOS_DEBUG, "\t\t ChannelId: 0x%x\n", channel_info->ChannelId); + printk(BIOS_DEBUG, "\t\t DimmCount: 0x%x\n", channel_info->DimmCount); + for (uint8_t dimm = 0; dimm < channel_info->DimmCount; dimm++) { + const DIMM_INFO *dimm_info = &channel_info->DimmInfo[dimm]; + printk(BIOS_DEBUG, "\t\t\t DimmInfo[%d]\n", dimm); + printk(BIOS_DEBUG, "\t\t\t\t DimmId: 0x%x\n", dimm_info->DimmId); + printk(BIOS_DEBUG, "\t\t\t\t SizeInMb: 0x%x\n", dimm_info->SizeInMb); + printk(BIOS_DEBUG, "\t\t\t\t MfgId: 0x%x\n", dimm_info->MfgId); + printk(BIOS_DEBUG, "\t\t\t\t ModulePartNum: %s\n", + dimm_info->ModulePartNum); + } + } +} + +void soc_display_hob(const struct hob_header *hob) +{ + uint8_t *guid; + + if (hob->type != HOB_TYPE_GUID_EXTENSION) + return; + + guid = (uint8_t *)fsp_hob_header_to_resource(hob); + if (fsp_guid_compare(guid, fsp_hob_iio_uds_data_guid.b)) + soc_display_fsp_iio_uds_data_hob( + (const BL_IIO_UDS *)(guid + sizeof(fsp_hob_iio_uds_data_guid))); + else if (fsp_guid_compare(guid, fsp_hob_fia_override_status_guid.b)) + soc_display_fsp_fia_override_status( + (const BL_FIA_OVERRIDE_STATUS_HOB + *)(guid + sizeof(fsp_hob_fia_override_status_guid))); + else if (fsp_guid_compare(guid, fsp_hob_smbios_memory_info_guid.b)) + soc_display_fsp_smbios_memory_info( + (const FSP_SMBIOS_MEMORY_INFO + *)(guid + sizeof(fsp_hob_smbios_memory_info_guid))); +} diff --git a/src/soc/intel/snowridge/common/kti_cache.c b/src/soc/intel/snowridge/common/kti_cache.c new file mode 100644 index 0000000000..f3d72b638d --- /dev/null +++ b/src/soc/intel/snowridge/common/kti_cache.c @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boot_device.h> +#include <bootstate.h> +#include <commonlib/bsd/ipchksum.h> +#include <stdlib.h> +#include <commonlib/region.h> +#include <console/console.h> +#include <fmap.h> +#include <lib.h> +#include <spi-generic.h> +#include <spi_flash.h> +#include <string.h> + +#include "fsp_hob.h" +#include "kti_cache.h" + +struct kti_metadata { + uint16_t data_size; + uint16_t data_checksum; +} __packed; + +void *kti_cache_load(size_t *size) +{ + struct region region; + struct region_device read_rdev; + struct kti_metadata md; + void *data; + uint16_t checksum; + + if (fmap_locate_area(CONFIG_KTI_CACHE_FMAP_NAME, ®ion) != 0) { + printk(BIOS_ERR, "Region %s doesn't exist!\n", CONFIG_KTI_CACHE_FMAP_NAME); + return NULL; + } + + if (boot_device_ro_subregion(®ion, &read_rdev) < 0) + return NULL; + + if (rdev_readat(&read_rdev, &md, 0, sizeof(struct kti_metadata)) < 0) { + printk(BIOS_ERR, "Couldn't read KTI metadata\n"); + return NULL; + } + + if (md.data_size == 0xFFFF) { + printk(BIOS_INFO, "KTI cache not found!\n"); + return NULL; + } + + data = rdev_mmap(&read_rdev, sizeof(struct kti_metadata), md.data_size); + if (data == NULL) { + printk(BIOS_ERR, "Map KTI cache failed.\n"); + return NULL; + } + + checksum = ipchksum(data, md.data_size); + rdev_munmap(&read_rdev, data); + if (checksum != md.data_checksum) { + printk(BIOS_ERR, "KTI cache checksum mismatch: %x vs %x\n", md.data_checksum, + checksum); + return NULL; + } + + if (size) + *size = md.data_size; + + return data; +} + +static void kti_cache_protect(void) +{ + struct region region; + + if (fmap_locate_area(CONFIG_KTI_CACHE_FMAP_NAME, ®ion) < 0) { + return; + } + + if (spi_flash_ctrlr_protect_region(boot_device_spi_flash(), ®ion, WRITE_PROTECT) < + 0) { + printk(BIOS_ERR, "Set Flash Protected Range for %s failed.\n", + CONFIG_KTI_CACHE_FMAP_NAME); + return; + } + + printk(BIOS_INFO, "Enable Flash Protected Range on %s.\n", CONFIG_KTI_CACHE_FMAP_NAME); +} + +static void kti_cache_save(void *unused) +{ + size_t kti_data_size; + const void *kti_data; + struct kti_metadata *md; + struct region region; + struct region_device write_rdev; + + printk(BIOS_INFO, "Save KTI starts...\n"); + + kti_data = fsp_hob_get_kti_cache(&kti_data_size); + if (!kti_data) { + printk(BIOS_WARNING, "Couldn't find KTI cache hob!\n"); + return; + } + + hexdump(kti_data, kti_data_size); + + md = malloc(sizeof(struct kti_metadata) + kti_data_size); + if (md == NULL) { + printk(BIOS_ERR, "Allocate KTI metadata failed!\n"); + return; + } + + memset(md, 0, sizeof(struct kti_metadata)); + md->data_size = kti_data_size; + md->data_checksum = ipchksum(kti_data, kti_data_size); + memcpy(md + 1, kti_data, kti_data_size); + + if (fmap_locate_area(CONFIG_KTI_CACHE_FMAP_NAME, ®ion) != 0) + goto ret; + + if (boot_device_rw_subregion(®ion, &write_rdev) < 0) + goto ret; + + if (rdev_eraseat(&write_rdev, 0, region_device_sz(&write_rdev)) < 0) { + printk(BIOS_ERR, "Erase stale KTI cache failed.\n"); + goto ret; + } + + if (rdev_writeat(&write_rdev, md, 0, sizeof(struct kti_metadata) + kti_data_size) < 0) { + printk(BIOS_ERR, "Write KTI cache failed.\n"); + goto ret; + } + + kti_cache_protect(); + + printk(BIOS_INFO, "Save KTI ends.\n"); + +ret: + free(md); +} + +/** + * Ensures kti data is stored into SPI after PCI enumeration is done during + * BS_DEV_ENUMERATE-BS_ON_EXIT and lock down SPI protected ranges during + * BS_DEV_RESOURCES-BS_ON_EXIT. + */ +BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_EXIT, kti_cache_save, NULL); diff --git a/src/soc/intel/snowridge/common/kti_cache.h b/src/soc/intel/snowridge/common/kti_cache.h new file mode 100644 index 0000000000..0c8d923e33 --- /dev/null +++ b/src/soc/intel/snowridge/common/kti_cache.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_KTI_CACHE_H_ +#define _SOC_SNOWRIDGE_KTI_CACHE_H_ + +#include <stddef.h> + +void *kti_cache_load(size_t *size); + +#endif // _SOC_SNOWRIDGE_KTI_CACHE_H_ diff --git a/src/soc/intel/snowridge/common/pmclib.c b/src/soc/intel/snowridge/common/pmclib.c new file mode 100644 index 0000000000..ae995ca67c --- /dev/null +++ b/src/soc/intel/snowridge/common/pmclib.c @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/mmio.h> +#include <intelblocks/pmclib.h> +#include <soc/iomap.h> +#include <soc/pm.h> +#include <soc/pmc.h> + +const char *const *soc_smi_sts_array(size_t *a) +{ + static const char *const smi_sts_bits[] = { + [BIOS_STS_BIT] = "BIOS", + [LEGACY_USB_STS_BIT] = "LEGACY_USB", + [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI", + [APM_STS_BIT] = "APM", + [SWSMI_TMR_STS_BIT] = "SWSMI_TMR", + [PM1_STS_BIT] = "PM1", + [GPE0_STS_BIT] = "GPE0", + [GPIO_STS_BIT] = "GPI", + [MCSMI_STS_BIT] = "MCSMI", + [DEVMON_STS_BIT] = "DEVMON", + [TCO_STS_BIT] = "TCO", + [PERIODIC_STS_BIT] = "PERIODIC", + [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI", + [SMBUS_SMI_STS_BIT] = "SMBUS_SMI", + [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI", + [MONITOR_STS_BIT] = "MONITOR", + [SPI_SMI_STS_BIT] = "SPI", + [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK", + [ESPI_SMI_STS_BIT] = "ESPI_SMI", + }; + + *a = ARRAY_SIZE(smi_sts_bits); + return smi_sts_bits; +} + +const char *const *soc_tco_sts_array(size_t *a) +{ + static const char *const tco_sts_bits[] = { + [0] = "NMI2SMI", + [1] = "SW_TCO", + [2] = "TCO_INT", + [3] = "TIMEOUT", + [7] = "NEWCENTURY", + [8] = "BIOSWR", + [9] = "DMISCI", + [10] = "DMISMI", + [12] = "DMISERR", + [13] = "SLVSEL", + [16] = "INTRD_DET", + [17] = "SECOND_TO", + [18] = "BOOT", + [20] = "SMLINK_SLV" + }; + + *a = ARRAY_SIZE(tco_sts_bits); + return tco_sts_bits; +} + +const char *const *soc_std_gpe_sts_array(size_t *a) +{ + static const char *const gpe_sts_bits[] = { + [1] = "HOTPLUG", + [2] = "SWGPE", + [6] = "TCO_SCI", + [7] = "SMB_WAK", + [9] = "PCI_EXP", + [10] = "BATLOW", + [11] = "PME", + [12] = "ME", + [13] = "PME_B0", + [14] = "eSPI", + [15] = "GPIO Tier-2", + [16] = "LAN_WAKE", + [18] = "WADT" + }; + + *a = ARRAY_SIZE(gpe_sts_bits); + return gpe_sts_bits; +} + +void pmc_soc_set_afterg3_en(bool on) +{ + uintptr_t pmc_bar = soc_read_pmc_base(); + uint8_t reg8 = read32p(pmc_bar + GEN_PMCON_A); + + if (on) + reg8 &= ~SLEEP_AFTER_POWER_FAIL; + else + reg8 |= SLEEP_AFTER_POWER_FAIL; + + write32p(pmc_bar + GEN_PMCON_A, reg8); +} + +uintptr_t soc_read_pmc_base(void) +{ + return PCH_PWRM_BASE_ADDRESS; +} + +uint32_t *soc_pmc_etr_addr(void) +{ + return (uint32_t *)(soc_read_pmc_base() + ETR); +} diff --git a/src/soc/intel/snowridge/common/reset.c b/src/soc/intel/snowridge/common/reset.c new file mode 100644 index 0000000000..dc2c5642e0 --- /dev/null +++ b/src/soc/intel/snowridge/common/reset.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cf9_reset.h> +#include <console/console.h> +#include <soc/intel/common/reset.h> + +void do_global_reset(void) +{ + do_full_reset(); +} diff --git a/src/soc/intel/snowridge/common/spi.c b/src/soc/intel/snowridge/common/spi.c new file mode 100644 index 0000000000..7fbb9115b8 --- /dev/null +++ b/src/soc/intel/snowridge/common/spi.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/spi.h> + +int spi_soc_devfn_to_bus(unsigned int devfn) +{ + return -1; +} diff --git a/src/soc/intel/snowridge/common/systemagent_early.c b/src/soc/intel/snowridge/common/systemagent_early.c new file mode 100644 index 0000000000..56bddad500 --- /dev/null +++ b/src/soc/intel/snowridge/common/systemagent_early.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/systemagent_server.h> +#include <soc/systemagent.h> + +uint32_t sa_server_soc_reg_to_pci_offset(enum sa_server_reg reg) +{ + switch (reg) { + case MMCFG_BASE_REG: + return PCIE_MMCFG_BASE; + case MMCFG_LIMIT_REG: + return PCIE_MMCFG_LIMIT; + case TSEG_BASE_REG: + return TSEG; + case TSEG_LIMIT_REG: + return TSEG_LIMIT; + case TOCM_REG: + return TOCM; + case TOUUD_REG: + return TOUUD; + case TOLUD_REG: + return TOLUD; + case MMIO_L_REG: + return MMIOL; + case VT_BAR_REG: + return VTBAR; + case DPR_REG: + return DPR; + default: + return 0; + } +} diff --git a/src/soc/intel/snowridge/common/uart8250mem.c b/src/soc/intel/snowridge/common/uart8250mem.c new file mode 100644 index 0000000000..51d0604ac8 --- /dev/null +++ b/src/soc/intel/snowridge/common/uart8250mem.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/uart.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <soc/pci_devs.h> + +#include "uart8250mem.h" + +uintptr_t uart_platform_base(unsigned int idx) +{ + uint32_t reg32 = pci_read_config32(PCH_DEV_UART(idx), UART_MEMBA); + + reg32 &= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK; + + return reg32; +} + +unsigned int uart_platform_refclk(void) +{ + unsigned int ret = 115200 * 16; + + /** + * Base uart clock is HIGH_SPEED_CLK_MULT (24) * 1.8432Mhz if using baudrates > 115200. + */ + if (CONFIG_TTYS0_BAUD > 115200) + ret *= HIGH_SPEED_CLK_MULT; + + return ret; +} diff --git a/src/soc/intel/snowridge/common/uart8250mem.h b/src/soc/intel/snowridge/common/uart8250mem.h new file mode 100644 index 0000000000..2c5b6fb516 --- /dev/null +++ b/src/soc/intel/snowridge/common/uart8250mem.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_UART_H_ +#define _SOC_SNOWRIDGE_UART_H_ + +#define UART_IOBA 0x10 +#define UART_MEMBA 0x14 + +#if CONFIG_CONSOLE_UART_BASE_ADDRESS != 0 +#define SIZE_OF_HSUART_RES 256 +#endif + +#define SNOWRIDGE_UARTS_TO_INIT 3 +#define HIGH_SPEED_CLK_MULT 24 + +#endif /* _SOC_SNOWRIDGE_UART_H_ */ diff --git a/src/soc/intel/snowridge/common/upd_display.c b/src/soc/intel/snowridge/common/upd_display.c new file mode 100644 index 0000000000..3c7f44bcef --- /dev/null +++ b/src/soc/intel/snowridge/common/upd_display.c @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <fsp/debug.h> +#include <lib.h> + +#define DISPLAY_UPD(field) \ + fsp_display_upd_value(#field, sizeof(old->field), old->field, new->field) + +void soc_display_fspm_upd_params(const FSPM_UPD *fspm_old_upd, const FSPM_UPD *fspm_new_upd) +{ + const FSP_M_CONFIG *old = &fspm_old_upd->FspmConfig; + const FSP_M_CONFIG *new = &fspm_new_upd->FspmConfig; + + printk(BIOS_SPEW, "UPD values for FspMemoryInit:\n"); + + DISPLAY_UPD(PcdEnableBiosSsaRMT); + DISPLAY_UPD(PcdEnableBiosSsaRMTonFCB); + DISPLAY_UPD(PcdBiosSsaPerBitMargining); + DISPLAY_UPD(PcdBiosSsaDisplayTables); + DISPLAY_UPD(PcdBiosSsaPerDisplayPlots); + DISPLAY_UPD(PcdBiosSsaLoopCount); + DISPLAY_UPD(PcdBiosSsaBacksideMargining); + DISPLAY_UPD(PcdBiosSsaEarlyReadIdMargining); + DISPLAY_UPD(PcdBiosSsaStepSizeOverride); + DISPLAY_UPD(PcdBiosSsaRxDqs); + DISPLAY_UPD(PcdBiosSsaRxVref); + DISPLAY_UPD(PcdBiosSsaTxDq); + DISPLAY_UPD(PcdBiosSsaTxVref); + DISPLAY_UPD(PcdBiosSsaCmdAll); + DISPLAY_UPD(PcdBiosSsaCmdVref); + DISPLAY_UPD(PcdBiosSsaCtlAll); + DISPLAY_UPD(PcdBiosSsaEridDelay); + DISPLAY_UPD(PcdBiosSsaEridVref); + DISPLAY_UPD(PcdBiosSsaDebugMessages); + DISPLAY_UPD(PcdEccSupport); + DISPLAY_UPD(PcdFastBoot); + DISPLAY_UPD(PcdMemTest); + DISPLAY_UPD(PcdMemTurnaroundOpt); + DISPLAY_UPD(PcdDdrFreq); + DISPLAY_UPD(PcdCommandTiming); + DISPLAY_UPD(PcdCustomRefreshRate); + DISPLAY_UPD(PcdTsegSize); + DISPLAY_UPD(PcdHsuartDevice); + DISPLAY_UPD(PcdHeciCommunication); + DISPLAY_UPD(PcdVtdSupport); + DISPLAY_UPD(PcdPchUsb3Port); + DISPLAY_UPD(PcdPchUsb2Port); + DISPLAY_UPD(PcdPchUsb3PortOc); + DISPLAY_UPD(PcdPchUsb2PortOc); + DISPLAY_UPD(PcdUsb2PeTxiSet); + DISPLAY_UPD(PcdUsb2TxiSet); + DISPLAY_UPD(PcdUsb2PreDeEmp); + DISPLAY_UPD(PcdUsb2PreEmpHalfBit); + DISPLAY_UPD(PcdIIOPciePortBifurcation); + DISPLAY_UPD(PcdIIoPcieRLinkDeEmphasis); + DISPLAY_UPD(PcdIIoPciePort1ADeEmphasis); + DISPLAY_UPD(PcdIIoPciePort1BDeEmphasis); + DISPLAY_UPD(PcdIIoPciePort1CDeEmphasis); + DISPLAY_UPD(PcdIIoPciePort1DDeEmphasis); + DISPLAY_UPD(PcdIIoPcieLinkSpeedRLink); + DISPLAY_UPD(PcdIIoPciePort1ALinkSpeed); + DISPLAY_UPD(PcdIIoPciePort1BLinkSpeed); + DISPLAY_UPD(PcdIIoPciePort1CLinkSpeed); + DISPLAY_UPD(PcdIIoPciePort1DLinkSpeed); + DISPLAY_UPD(PcdIIoPcieRLinkAspm); + DISPLAY_UPD(PcdIIoPciePort1AAspm); + DISPLAY_UPD(PcdIIoPciePort1BAspm); + DISPLAY_UPD(PcdIIoPciePort1CAspm); + DISPLAY_UPD(PcdIIoPciePort1DAspm); + DISPLAY_UPD(PcdBifurcationPcie0); + DISPLAY_UPD(PcdBifurcationPcie2); + DISPLAY_UPD(PcdMemoryThermalThrottling); + DISPLAY_UPD(PcdFiaMuxOverride); + DISPLAY_UPD(FiaMuxCfgInvalidate); + DISPLAY_UPD(PcdPchTraceHubMode); + DISPLAY_UPD(PcdPchTraceHubMemReg0Size); + DISPLAY_UPD(PcdPchTraceHubMemReg1Size); + DISPLAY_UPD(PcdFiaLaneConfigPtr); + DISPLAY_UPD(PcdKtiBufferPtr); + DISPLAY_UPD(PcdMemSpdPtr); + + hexdump(fspm_new_upd, sizeof(*fspm_new_upd)); +} + +void soc_display_fsps_upd_params(const FSPS_UPD *fsps_old_upd, const FSPS_UPD *fsps_new_upd) +{ + const FSP_S_CONFIG *old = &fsps_old_upd->FspsConfig; + const FSP_S_CONFIG *new = &fsps_new_upd->FspsConfig; + + printk(BIOS_SPEW, "UPD values for FspSiliconInit:\n"); + + DISPLAY_UPD(PcdCpuMicrocodePatchBase); + DISPLAY_UPD(PcdCpuMicrocodePatchSize); + DISPLAY_UPD(PcdEnableSATA); + DISPLAY_UPD(PcdEmmc); + DISPLAY_UPD(PcdEmmcHS400Support); + DISPLAY_UPD(PcdPcieRootPort0LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort1LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort2LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort3LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort8LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort9LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort10LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort11LinkSpeed); + DISPLAY_UPD(PcdPcieRootPort0Aspm); + DISPLAY_UPD(PcdPcieRootPort1Aspm); + DISPLAY_UPD(PcdPcieRootPort2Aspm); + DISPLAY_UPD(PcdPcieRootPort3Aspm); + DISPLAY_UPD(PcdPcieRootPort8Aspm); + DISPLAY_UPD(PcdPcieRootPort9Aspm); + DISPLAY_UPD(PcdPcieRootPort10Aspm); + DISPLAY_UPD(PcdPcieRootPort11Aspm); + DISPLAY_UPD(PcdPcieRootPort0ConnectionType); + DISPLAY_UPD(PcdPcieRootPort1ConnectionType); + DISPLAY_UPD(PcdPcieRootPort2ConnectionType); + DISPLAY_UPD(PcdPcieRootPort3ConnectionType); + DISPLAY_UPD(PcdPcieRootPort8ConnectionType); + DISPLAY_UPD(PcdPcieRootPort9ConnectionType); + DISPLAY_UPD(PcdPcieRootPort10ConnectionType); + DISPLAY_UPD(PcdPcieRootPort11ConnectionType); + DISPLAY_UPD(PcdPcieRootPort0HotPlug); + DISPLAY_UPD(PcdPcieRootPort1HotPlug); + DISPLAY_UPD(PcdPcieRootPort2HotPlug); + DISPLAY_UPD(PcdPcieRootPort3HotPlug); + DISPLAY_UPD(PcdPcieRootPort8HotPlug); + DISPLAY_UPD(PcdPcieRootPort9HotPlug); + DISPLAY_UPD(PcdPcieRootPort10HotPlug); + DISPLAY_UPD(PcdPcieRootPort11HotPlug); + DISPLAY_UPD(PcdEMMCDLLConfigPtr); + + hexdump(fsps_new_upd, sizeof(*fsps_new_upd)); +} diff --git a/src/soc/intel/snowridge/cpu.c b/src/soc/intel/snowridge/cpu.c new file mode 100644 index 0000000000..29050aa9ab --- /dev/null +++ b/src/soc/intel/snowridge/cpu.c @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cpu/intel/common/common.h> +#include <cpu/intel/smm_reloc.h> +#include <cpu/intel/turbo.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/smm.h> +#include <device/device.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/mp_init.h> +#include <intelblocks/msr.h> +#include <soc/msr.h> +#include <soc/soc_chip.h> +#include <static.h> + +static void configure_misc(void) +{ + msr_t msr; + config_t *conf = config_of_soc(); + + msr = rdmsr(IA32_MISC_ENABLE); + msr.lo |= FAST_STRINGS_ENABLE_BIT; + msr.lo |= (1 << 3); /**< Enable TM1, TM2 and EMTTM. */ + wrmsr(IA32_MISC_ENABLE, msr); + + cpu_set_eist(conf->eist_enable); + + msr.lo = 0; + msr.hi = 0; + wrmsr(IA32_THERM_INTERRUPT, msr); + + msr.lo = 1 << 4; + msr.hi = 0; + wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr); + + msr = rdmsr(MSR_POWER_CTL); + msr.lo |= (1 << 0); /**< Enable bi-directional PROCHOT as an input. */ + msr.lo |= (1 << 23); /**< Lock it. */ + wrmsr(MSR_POWER_CTL, msr); +} + +void soc_core_init(struct device *dev) +{ + /** + * This should only be done on a cold boot. Also, some these banks are core + * vs package scope. + */ + mca_configure(); + + enable_lapic_tpr(); + + configure_misc(); + + configure_dca_cap(); + + set_energy_perf_bias(ENERGY_POLICY_NORMAL); + + enable_turbo(); +} + +static void post_mp_init(void) +{ + cpu_set_max_ratio(); + + /** + * Now that all APs have been relocated as well as the BSP, let SMI start flowing. + */ + global_smi_enable(); +} + +static const struct mp_ops mp_ops = { + /** + * Skip Pre MP init MTRR programming as MTRRs are mirrored from BSP that are set prior + * to ramstage. Real MTRRs programming are being done after resource allocation. + */ + + .get_cpu_count = get_cpu_count, +#if CONFIG(HAVE_SMI_HANDLER) + .get_smm_info = smm_info, +#endif + .get_microcode_info = get_microcode_info, + .pre_mp_smm_init = smm_initialize, + .per_cpu_smm_trigger = smm_relocate, + .relocation_handler = smm_relocation_handler, + .post_mp_init = post_mp_init, +}; + +void mp_init_cpus(struct bus *cpu_bus) +{ + if (mp_init_with_smm(cpu_bus, &mp_ops)) + die_with_post_code(POSTCODE_HW_INIT_FAILURE, "mp_init_with_smm failed!\n"); + + configure_tcc_thermal_target(); +} + +bool cpu_soc_is_in_untrusted_mode(void) +{ + msr_t msr; + + msr = rdmsr(MSR_BIOS_DONE); + return !!(msr.lo & ENABLE_IA_UNTRUSTED); +} diff --git a/src/soc/intel/snowridge/dlb.c b/src/soc/intel/snowridge/dlb.c new file mode 100644 index 0000000000..6e25c4064a --- /dev/null +++ b/src/soc/intel/snowridge/dlb.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +#include "ramstage.h" + +static struct device_operations snr_dlb_ops = { + .read_resources = pciexp_pf_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .final = pci_dev_request_bus_master, + .ops_pci = &pci_dev_ops_pci, +}; + +static const struct pci_driver snr_dlb_driver __pci_driver = { + .ops = &snr_dlb_ops, + .vendor = PCI_VID_INTEL, + .device = PCI_DID_INTEL_SNR_DLB +}; diff --git a/src/soc/intel/snowridge/finalize.c b/src/soc/intel/snowridge/finalize.c new file mode 100644 index 0000000000..476b2c1f3d --- /dev/null +++ b/src/soc/intel/snowridge/finalize.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootstate.h> +#include <commonlib/console/post_codes.h> +#include <console/console.h> +#include <cpu/x86/smm.h> + +static void soc_finalize(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + apm_control(APM_CNT_FINALIZE); + + /* Indicate finalize step with post code */ + post_code(POSTCODE_OS_BOOT); +} + +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL); diff --git a/src/soc/intel/snowridge/heci.c b/src/soc/intel/snowridge/heci.c new file mode 100644 index 0000000000..3bc9d5f21f --- /dev/null +++ b/src/soc/intel/snowridge/heci.c @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <device/resource.h> + +static void heci_read_resources(struct device *dev) +{ + struct resource *res = NULL; + + pci_dev_read_resources(dev); + + /** + * Clear `IORESOURCE_PCI64` since we want this device to remain under 4G as it is used + * by FSP Notify. + */ + res = find_resource(dev, PCI_BASE_ADDRESS_0); + res->limit = 0xffffffff; + res->flags &= ~IORESOURCE_PCI64; +} + +static struct device_operations snr_heci_ops = { + .read_resources = heci_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .ops_pci = &pci_dev_ops_pci, +}; + +static const struct pci_driver snr_heci_driver __pci_driver = { + .ops = &snr_heci_ops, + .vendor = PCI_VID_INTEL, + .device = PCI_DID_INTEL_SNR_HECI1, +}; diff --git a/src/soc/intel/snowridge/include/soc/acpi.h b/src/soc/intel/snowridge/include/soc/acpi.h new file mode 100644 index 0000000000..9bb36c3b82 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/acpi.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_ACPI_H_ +#define _SOC_SNOWRIDGE_ACPI_H_ + +#include <acpi/acpi.h> +#include <device/device.h> + +void domain_fill_ssdt(const struct device *dev); +void pcie_rp_fill_ssdt(const struct device *dev); + +#endif // _SOC_SNOWRIDGE_ACPI_H_ diff --git a/src/soc/intel/snowridge/include/soc/cpu.h b/src/soc/intel/snowridge/include/soc/cpu.h new file mode 100644 index 0000000000..eaf0a01770 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/cpu.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_CPU_H_ +#define _SOC_SNOWRIDGE_CPU_H_ + +/** + * @brief Required by `src/soc/intel/common/block`. + */ + +#endif // _SOC_SNOWRIDGE_CPU_H_ diff --git a/src/soc/intel/snowridge/include/soc/gpio.h b/src/soc/intel/snowridge/include/soc/gpio.h new file mode 100644 index 0000000000..1166aed4fd --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/gpio.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_GPIO_H_ +#define _SOC_SNOWRIDGE_GPIO_H_ + +#include "gpio_defs.h" + +#define GPIO_MAX_NUM_PER_GROUP 32 + +#define GPIO_WEST2_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_WEST2_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_WEST3_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_WEST3_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_WEST01_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_WEST01_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_WEST5_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_WEST5_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_WESTB_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_WESTB_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_WESTD_PECI_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_WESTD_PECI_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_EAST2_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_EAST2_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_EAST3_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_EAST3_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_EAST0_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_EAST0_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_EMMC_GPI_STATUS_REGS \ + (ALIGN_UP(GPIO_EMMC_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define GPIO_MISCCFG 0x10 /**< Miscellaneous Configuration. */ +#define GPIO_NUM_PAD_CFG_REGS 4 /**< DW0, DW1 and DW2 but 16-bytes aligned. */ + +#define NUM_GPI_STATUS_REGS \ + (GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + \ + GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS + \ + GPIO_WESTB_GPI_STATUS_REGS + GPIO_WESTD_PECI_GPI_STATUS_REGS + \ + GPIO_EAST2_GPI_STATUS_REGS + GPIO_EAST3_GPI_STATUS_REGS + \ + GPIO_EAST0_GPI_STATUS_REGS + GPIO_EMMC_GPI_STATUS_REGS) + +/** + * @brief SNR doesn't support dynamic GPIO PM hence GPIO community MISCCFG register doesn't + * have PM bits. + */ +#define MISCCFG_GPIO_PM_CONFIG_BITS 0 + +/** + * @note Actually `intelblocks/gpio.h` has already included this file, but to support those + * file that include this file directly, we need include `intelblocks/gpio.h` recursively. + */ +#include <intelblocks/gpio.h> + +#endif // _SOC_SNOWRIDGE_GPIO_H_ diff --git a/src/soc/intel/snowridge/include/soc/gpio_defs.h b/src/soc/intel/snowridge/include/soc/gpio_defs.h new file mode 100644 index 0000000000..8f21c22a11 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/gpio_defs.h @@ -0,0 +1,179 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_GPIO_DEFS_H_ +#define _SOC_SNOWRIDGE_GPIO_DEFS_H_ + +enum gpio_pad_own_t { + GPIO_PAD_OWN_HOST = 0x00, + GPIO_PAD_OWN_ME = 0x03 +}; + +/** + * The following sets of macros are used when defining pad_community in + * src/soc/intel/snowridge/common/gpio.c. + */ + +#define GPIO_WEST2_PAD_OWN 0x0020 +#define GPIO_WEST2_HOSTSW_OWN 0x0120 +#define GPIO_WEST2_GPI_IS 0x0200 +#define GPIO_WEST2_GPI_IE 0x0230 +#define GPIO_WEST2_GPI_GPE_STS 0x0260 +#define GPIO_WEST2_GPI_GPE_EN 0x0290 +#define GPIO_WEST2_SMI_STS 0x02c0 +#define GPIO_WEST2_SMI_EN 0x02f0 +#define GPIO_WEST2_NMI_STS 0x0320 +#define GPIO_WEST2_NMI_EN 0x0350 +#define GPIO_WEST2_PADCFGLOCK 0x00c0 +#define GPIO_WEST2_PADCFGLOCKTX 0x00c4 +#define GPIO_WEST2_PAD_NUM 24 + +#define GPIO_WEST3_PAD_OWN 0x002c +#define GPIO_WEST3_HOSTSW_OWN 0x0124 +#define GPIO_WEST3_GPI_IS 0x0204 +#define GPIO_WEST3_GPI_IE 0x0234 +#define GPIO_WEST3_GPI_GPE_STS 0x0264 +#define GPIO_WEST3_GPI_GPE_EN 0x0294 +#define GPIO_WEST3_SMI_STS 0x02c4 +#define GPIO_WEST3_SMI_EN 0x02f4 +#define GPIO_WEST3_NMI_STS 0x0324 +#define GPIO_WEST3_NMI_EN 0x0354 +#define GPIO_WEST3_PADCFGLOCK 0x00c8 +#define GPIO_WEST3_PADCFGLOCKTX 0x00cc +#define GPIO_WEST3_PAD_NUM 16 + +#define GPIO_WEST01_PAD_OWN 0x0038 +#define GPIO_WEST01_HOSTSW_OWN 0x0128 +#define GPIO_WEST01_GPI_IS 0x0208 +#define GPIO_WEST01_GPI_IE 0x0238 +#define GPIO_WEST01_GPI_GPE_STS 0x0268 +#define GPIO_WEST01_GPI_GPE_EN 0x0298 +#define GPIO_WEST01_SMI_STS 0x02c8 +#define GPIO_WEST01_SMI_EN 0x02f8 +#define GPIO_WEST01_NMI_STS 0x0328 +#define GPIO_WEST01_NMI_EN 0x0358 +#define GPIO_WEST01_PADCFGLOCK 0x00d0 +#define GPIO_WEST01_PADCFGLOCKTX 0x00d4 +#define GPIO_WEST01_PAD_NUM 23 + +#define GPIO_WEST5_PAD_OWN 0x0044 +#define GPIO_WEST5_HOSTSW_OWN 0x012c +#define GPIO_WEST5_GPI_IS 0x020c +#define GPIO_WEST5_GPI_IE 0x023c +#define GPIO_WEST5_GPI_GPE_STS 0x026c +#define GPIO_WEST5_GPI_GPE_EN 0x029c +#define GPIO_WEST5_SMI_STS 0x02cc +#define GPIO_WEST5_SMI_EN 0x02fc +#define GPIO_WEST5_NMI_STS 0x032c +#define GPIO_WEST5_NMI_EN 0x035c +#define GPIO_WEST5_PADCFGLOCK 0x00d8 +#define GPIO_WEST5_PADCFGLOCKTX 0x00dc +#define GPIO_WEST5_PAD_NUM 13 + +#define GPIO_WESTB_PAD_OWN 0x0060 /**< Reserved. */ +#define GPIO_WESTB_HOSTSW_OWN 0x013c +#define GPIO_WESTB_GPI_IS 0x021c +#define GPIO_WESTB_GPI_IE 0x024c +#define GPIO_WESTB_GPI_GPE_STS 0x027c +#define GPIO_WESTB_GPI_GPE_EN 0x02ac +#define GPIO_WESTB_SMI_STS 0x02dc +#define GPIO_WESTB_SMI_EN 0x030c +#define GPIO_WESTB_NMI_STS 0x033c +#define GPIO_WESTB_NMI_EN 0x036c +#define GPIO_WESTB_PADCFGLOCK 0x00f8 +#define GPIO_WESTB_PADCFGLOCKTX 0x00fc +#define GPIO_WESTB_PAD_NUM 4 + +#define GPIO_WESTD_PECI_PAD_OWN 0x0074 +#define GPIO_WESTD_PECI_HOSTSW_OWN 0x0144 +#define GPIO_WESTD_PECI_GPI_IS 0x0224 +#define GPIO_WESTD_PECI_GPI_IE 0x0254 +#define GPIO_WESTD_PECI_GPI_GPE_STS 0x0284 +#define GPIO_WESTD_PECI_GPI_GPE_EN 0x02b4 +#define GPIO_WESTD_PECI_SMI_STS 0x02e4 +#define GPIO_WESTD_PECI_SMI_EN 0x0314 +#define GPIO_WESTD_PECI_NMI_STS 0x0344 +#define GPIO_WESTD_PECI_NMI_EN 0x0374 +#define GPIO_WESTD_PECI_PADCFGLOCK 0x0108 +#define GPIO_WESTD_PECI_PADCFGLOCKTX 0x010c +#define GPIO_WESTD_PECI_PAD_NUM 1 + +#define GPIO_EAST2_PAD_OWN 0x0020 +#define GPIO_EAST2_HOSTSW_OWN 0x0120 +#define GPIO_EAST2_GPI_IS 0x0200 +#define GPIO_EAST2_GPI_IE 0x0230 +#define GPIO_EAST2_GPI_GPE_STS 0x0260 +#define GPIO_EAST2_GPI_GPE_EN 0x0290 +#define GPIO_EAST2_SMI_STS 0x02c0 +#define GPIO_EAST2_SMI_EN 0x02f0 +#define GPIO_EAST2_NMI_STS 0x0320 +#define GPIO_EAST2_NMI_EN 0x0350 +#define GPIO_EAST2_PADCFGLOCK 0x00c0 +#define GPIO_EAST2_PADCFGLOCKTX 0x00c4 +#define GPIO_EAST2_PAD_NUM 23 + +#define GPIO_EAST3_PAD_OWN 0x002c +#define GPIO_EAST3_HOSTSW_OWN 0x0124 +#define GPIO_EAST3_GPI_IS 0x0204 +#define GPIO_EAST3_GPI_IE 0x0234 +#define GPIO_EAST3_GPI_GPE_STS 0x0264 +#define GPIO_EAST3_GPI_GPE_EN 0x0294 +#define GPIO_EAST3_SMI_STS 0x02c4 +#define GPIO_EAST3_SMI_EN 0x02f4 +#define GPIO_EAST3_NMI_STS 0x0324 +#define GPIO_EAST3_NMI_EN 0x0354 +#define GPIO_EAST3_PADCFGLOCK 0x00c8 +#define GPIO_EAST3_PADCFGLOCKTX 0x00cc +#define GPIO_EAST3_PAD_NUM 10 + +#define GPIO_EAST0_PAD_OWN 0x0034 /**< Reserved. */ +#define GPIO_EAST0_HOSTSW_OWN 0x0128 +#define GPIO_EAST0_GPI_IS 0x0208 +#define GPIO_EAST0_GPI_IE 0x0238 +#define GPIO_EAST0_GPI_GPE_STS 0x0268 +#define GPIO_EAST0_GPI_GPE_EN 0x0298 +#define GPIO_EAST0_SMI_STS 0x02c8 +#define GPIO_EAST0_SMI_EN 0x02f8 +#define GPIO_EAST0_NMI_STS 0x0328 +#define GPIO_EAST0_NMI_EN 0x0358 +#define GPIO_EAST0_PADCFGLOCK 0x00d0 +#define GPIO_EAST0_PADCFGLOCKTX 0x00d4 +#define GPIO_EAST0_PAD_NUM 8 + +#define GPIO_EMMC_PAD_OWN 0x0040 +#define GPIO_EMMC_HOSTSW_OWN 0x012c +#define GPIO_EMMC_GPI_IS 0x020c +#define GPIO_EMMC_GPI_IE 0x023c +#define GPIO_EMMC_GPI_GPE_STS 0x026c +#define GPIO_EMMC_GPI_GPE_EN 0x029c +#define GPIO_EMMC_SMI_STS 0x02cc +#define GPIO_EMMC_SMI_EN 0x02fc +#define GPIO_EMMC_NMI_STS 0x032c +#define GPIO_EMMC_NMI_EN 0x035c +#define GPIO_EMMC_PADCFGLOCK 0x00d8 +#define GPIO_EMMC_PADCFGLOCKTX 0x00dc +#define GPIO_EMMC_PAD_NUM 11 + +/** + * @brief GPIO west community. + */ +#define GPIO_WEST2_PADCFG_OFFSET 0x800 +#define GPIO_WEST3_PADCFG_OFFSET 0x980 +#define GPIO_WEST01_PADCFG_OFFSET 0xb00 +#define GPIO_WEST5_PADCFG_OFFSET 0xc70 +#define GPIO_WESTB_PADCFG_OFFSET 0xf00 /**< Reserved. */ +#define GPIO_WESTD_PECI_PADCFG_OFFSET 0x1100 + +/** + * @brief GPIO east community. + */ +#define GPIO_EAST2_PADCFG_OFFSET 0x800 +#define GPIO_EAST3_PADCFG_OFFSET 0x980 +#define GPIO_EAST0_PADCFG_OFFSET 0xa30 /**< Reserved. */ +#define GPIO_EMMC_PADCFG_OFFSET 0xba0 + +#define TOTAL_PADS \ + (GPIO_WEST2_PAD_NUM + GPIO_WEST3_PAD_NUM + GPIO_WEST01_PAD_NUM + GPIO_WEST5_PAD_NUM + \ + GPIO_WESTB_PAD_NUM + GPIO_WESTD_PECI_PAD_NUM + GPIO_EAST2_PAD_NUM + \ + GPIO_EAST3_PAD_NUM + GPIO_EAST0_PAD_NUM + GPIO_EMMC_PAD_NUM) + +#endif // _SOC_SNOWRIDGE_GPIO_DEFS_H_ diff --git a/src/soc/intel/snowridge/include/soc/gpio_snr.h b/src/soc/intel/snowridge/include/soc/gpio_snr.h new file mode 100644 index 0000000000..d986b1af2e --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/gpio_snr.h @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_GPIO_SNR_H_ +#define _SOC_SNOWRIDGE_GPIO_SNR_H_ + +#include <intelblocks/gpio.h> + +enum snr_pad_host_sw_owner_t { GPIO_HOSTSW_OWN_DEFAULT, GPIO_HOSTSW_OWN_ACPI, GPIO_HOSTSW_OWN_DRIVER }; + +struct snr_pad_config { + struct pad_config cfg; + uint32_t pad_config_mask[GPIO_NUM_PAD_CFG_REGS]; + enum snr_pad_host_sw_owner_t hostsw_own; +}; + +/** + * @note Intel common block uses the fourth bits in DW1 to indicate GPIO host software ownership. + */ +#define SNR_PAD_CFG_STRUCT1(__pad, __config0, __mask0, __config1, __mask1, __hostsw_own) \ + { \ + .cfg = _PAD_CFG_STRUCT(__pad, __config0, __config1), \ + .pad_config_mask[0] = __mask0, .pad_config_mask[1] = __mask1 | BIT(4), \ + .hostsw_own = __hostsw_own, \ + } + +#define SNR_PAD_CFG_STRUCT0(__pad, __config0, __mask0, __hostsw_own) \ + SNR_PAD_CFG_STRUCT1(__pad, __config0, __mask0, 0, 0, __hostsw_own) + +/** + * @brief GPIO pad format: + * 31 24 16 8 0 + * --------------------------------------------------- + * | | Community Index | Group Index | Pad Number | + * --------------------------------------------------- + */ + +#define SNR_GPIO_DEF(COMMUNITY, PAD) ((uint32_t)(((COMMUNITY & 0xff) << 16) | (PAD & 0xff))) +#define SNR_GPIO_COMMUNITY(GPIO_PAD) ((GPIO_PAD >> 16) & 0xff) +#define SNR_GPIO_PAD(GPIO_PAD) (GPIO_PAD & 0xff) + +enum { + GPIO_COMM_WEST2 = 0, + GPIO_COMM_WEST3, + GPIO_COMM_WEST01, + GPIO_COMM_WEST5, + GPIO_COMM_WESTB, + GPIO_COMM_WESTD_PECI, + GPIO_COMM_EAST2, + GPIO_COMM_EAST3, + GPIO_COMM_EAST0, + GPIO_COMM_EMMC +}; + +#define GPIO_WEST2_0 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x0) /**< GBE_SDP_TIMESYNC0. */ +#define GPIO_WEST2_1 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x1) /**< GBE_SDP_TIMESYNC1. */ +#define GPIO_WEST2_2 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x2) /**< GBE_SDP_TIMESYNC2. */ +#define GPIO_WEST2_3 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x3) /**< GBE_SDP_TIMESYNC3. */ +#define GPIO_WEST2_4 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x4) /**< GBE0_I2C_CLK. */ +#define GPIO_WEST2_5 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x5) /**< GBE0_I2C_DATA. */ +#define GPIO_WEST2_6 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x6) /**< GBE1_I2C_CLK. */ +#define GPIO_WEST2_7 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x7) /**< GBE1_I2C_DATA. */ +#define GPIO_WEST2_8 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x8) /**< GBE2_I2C_CLK. */ +#define GPIO_WEST2_9 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x9) /**< GBE2_I2C_DATA. */ +#define GPIO_WEST2_10 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xa) /**< GBE3_I2C_CLK. */ +#define GPIO_WEST2_11 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xb) /**< GBE3_I2C_DATA. */ +#define GPIO_WEST2_12 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xc) /**< GBE0_LED0. */ +#define GPIO_WEST2_13 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xd) /**< GBE0_LED1. */ +#define GPIO_WEST2_14 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xe) /**< GBE0_LED2. */ +#define GPIO_WEST2_15 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xf) /**< GBE1_LED0. */ +#define GPIO_WEST2_16 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x10) /**< GBE1_LED1. */ +#define GPIO_WEST2_17 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x11) /**< GBE1_LED2. */ +#define GPIO_WEST2_18 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x12) /**< GBE2_LED0. */ +#define GPIO_WEST2_19 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x13) /**< GBE2_LED1. */ +#define GPIO_WEST2_20 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x14) /**< GBE2_LED2. */ +#define GPIO_WEST2_21 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x15) /**< GBE3_LED0. */ +#define GPIO_WEST2_22 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x16) /**< GBE3_LED1. */ +#define GPIO_WEST2_23 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x17) /**< GBE3_LED2. */ +#define GPIO_WEST3_0 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x0) /**< NCSI_RXD0. */ +#define GPIO_WEST3_1 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x1) /**< NCSI_CLK_IN. */ +#define GPIO_WEST3_2 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x2) /**< NCSI_RXD1. */ +#define GPIO_WEST3_3 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x3) /**< NCSI_CRS_DV. */ +#define GPIO_WEST3_4 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x4) /**< NCSI_ARB_IN. */ +#define GPIO_WEST3_5 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x5) /**< NCSI_TX_EN. */ +#define GPIO_WEST3_6 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x6) /**< NCSI_TXD0. */ +#define GPIO_WEST3_7 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x7) /**< NCSI_TXD1. */ +#define GPIO_WEST3_8 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x8) /**< NCSI_ARB_OUT. */ +#define GPIO_WEST3_9 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x9) /**< GBE_SMB_CLK. */ +#define GPIO_WEST3_10 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0xa) /**< GBE_SMB_DATA. */ +#define GPIO_WEST3_11 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0xb) /**< GBE_SMB_ALRT_N. */ +#define GPIO_WEST3_20 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x14) /**< UART0_RXD. */ +#define GPIO_WEST3_21 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x15) /**< UART0_TXD. */ +#define GPIO_WEST3_22 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x16) /**< UART1_RXD. */ +#define GPIO_WEST3_23 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x17) /**< UART1_TXD. */ +#define GPIO_WEST01_0 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x0) /**< CPU_GP_0. */ +#define GPIO_WEST01_1 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x1) /**< CPU_GP_1. */ +#define GPIO_WEST01_2 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x2) /**< CPU_GP_2. */ +#define GPIO_WEST01_3 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x3) /**< CPU_GP_3. */ +#define GPIO_WEST01_4 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x4) /**< FAN_PWM_0. */ +#define GPIO_WEST01_5 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x5) /**< FAN_PWM_1. */ +#define GPIO_WEST01_6 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x6) /**< FAN_PWM_2. */ +#define GPIO_WEST01_7 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x7) /**< FAN_PWM_3. */ +#define GPIO_WEST01_8 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x8) /**< FAN_TACH_0. */ +#define GPIO_WEST01_9 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x9) /**< FAN_TACH_1. */ +#define GPIO_WEST01_10 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xa) /**< FAN_TACH_2. */ +#define GPIO_WEST01_11 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xb) /**< FAN_TACH_3. */ +#define GPIO_WEST01_12 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xc) /**< ME_SMB0_CLK. */ +#define GPIO_WEST01_13 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xd) /**< ME_SMB0_DATA. */ +#define GPIO_WEST01_14 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xe) /**< ME_SMB0_ALRT_N. */ +#define GPIO_WEST01_15 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xf) /**< ME_SMB1_CLK. */ +#define GPIO_WEST01_16 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x10) /**< ME_SMB1_DATA. */ +#define GPIO_WEST01_17 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x11) /**< ME_SMB1_ALRT_N. */ +#define GPIO_WEST01_18 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x12) /**< ME_SMB2_CLK. */ +#define GPIO_WEST01_19 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x13) /**< ME_SMB2_DATA. */ +#define GPIO_WEST01_20 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x14) /**< ME_SMB2_ALRT_N. */ +#define GPIO_WEST01_21 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x15) /**< GBE_MNG_I2C_CLK. */ +#define GPIO_WEST01_22 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x16) /**< GBE_MNG_I2C_DATA. */ +#define GPIO_WEST5_0 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x0) /**< IE_UART_RXD. */ +#define GPIO_WEST5_1 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x1) /**< IE_UART_TXD. */ +#define GPIO_WEST5_2 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x2) /**< VPP_SMB_CLK. */ +#define GPIO_WEST5_3 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x3) /**< VPP_SMB_DATA. */ +#define GPIO_WEST5_4 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x4) /**< VPP_SMB_ALRT_N. */ +#define GPIO_WEST5_5 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x5) /**< PCIE_CLKREQ0_N. */ +#define GPIO_WEST5_6 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x6) /**< PCIE_CLKREQ1_N. */ +#define GPIO_WEST5_7 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x7) /**< PCIE_CLKREQ2_N. */ +#define GPIO_WEST5_8 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x8) /**< PCIE_CLKREQ3_N. */ +#define GPIO_WEST5_15 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0xf) /**< FLEX_CLK_SE0. */ +#define GPIO_WEST5_16 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x10) /**< FLEX_CLK_SE1. */ +#define GPIO_WEST5_17 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x11) /**< FLEX_CLK1_50. */ +#define GPIO_WEST5_18 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x12) /**< FLEX_CLK2_50. */ +#define GPIO_WESTB_0 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0x0) /**< Reserved. */ +#define GPIO_WESTB_8 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0x8) /**< DBG_SPARE0. */ +#define GPIO_WESTB_9 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0x9) /**< DBG_SPARE1. */ +#define GPIO_WESTB_10 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0xa) /**< DBG_SPARE2. */ +#define GPIO_WESTB_11 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0xb) /**< DBG_SPARE3. */ +#define GPIO_WESTD_PECI_0 SNR_GPIO_DEF(GPIO_COMM_WESTD_PECI, 0x0) /**< PECI_PCH. For P5900. */ +#define GPIO_EAST2_0 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x0) /**< USB_OC0_N. */ +#define GPIO_EAST2_1 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x1) /**< GPIO_0. */ +#define GPIO_EAST2_2 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x2) /**< GPIO_1. */ +#define GPIO_EAST2_3 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x3) /**< GPIO_2. */ +#define GPIO_EAST2_4 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x4) /**< GPIO_3. */ +#define GPIO_EAST2_5 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x5) /**< GPIO_4. */ +#define GPIO_EAST2_6 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x6) /**< GPIO_5. */ +#define GPIO_EAST2_7 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x7) /**< GPIO_6. */ +#define GPIO_EAST2_8 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x8) /**< GPIO_7. */ +#define GPIO_EAST2_9 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x9) /**< GPIO_8. */ +#define GPIO_EAST2_10 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xa) /**< GPIO_9. */ +#define GPIO_EAST2_11 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xb) /**< GPIO_10. */ +#define GPIO_EAST2_12 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xc) /**< GPIO_11. */ +#define GPIO_EAST2_13 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xd) /**< GPIO_12. */ +#define GPIO_EAST2_14 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xe) /**< PECI_SMB_DATA. */ +#define GPIO_EAST2_15 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xf) /**< SATA0_LED_N. */ +#define GPIO_EAST2_17 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x11) /**< SATA_PDETECT0. */ +#define GPIO_EAST2_18 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x12) /**< SATA_PDETECT1. */ +#define GPIO_EAST2_19 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x13) /**< SATA0_SDOUT. */ +#define GPIO_EAST2_20 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x14) /**< SATA1_SDOUT. */ +#define GPIO_EAST2_21 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x15) /**< SATA2_LED_N. */ +#define GPIO_EAST2_22 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x16) /**< SATA_PDETECT2. */ +#define GPIO_EAST2_23 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x17) /**< SATA2_SDOUT. */ +#define GPIO_EAST3_0 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x0) /**< ESPI_IO0. For P5900. */ +#define GPIO_EAST3_1 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x1) /**< ESPI_IO1. */ +#define GPIO_EAST3_2 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x2) /**< ESPI_IO2. */ +#define GPIO_EAST3_3 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x3) /**< ESPI_IO3. */ +#define GPIO_EAST3_4 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x4) /**< ESPI_CLK. */ +#define GPIO_EAST3_5 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x5) /**< ESPI_RST_N. */ +#define GPIO_EAST3_6 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x6) /**< ESPI_CS0_N. */ +#define GPIO_EAST3_7 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x7) /**< ESPI_ALRT0_N. */ +#define GPIO_EAST3_8 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x8) /**< ESPI_CS1_N. */ +#define GPIO_EAST3_9 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x9) /**< ESPI_ALRT1_N. */ +#define GPIO_EAST0_0 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x0) /**< Reserved. */ +#define GPIO_EAST0_10 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0xa) /**< ADR_COMPLETE. */ +#define GPIO_EAST0_11 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0xb) /**< ADR_TRIGGER_N. */ +#define GPIO_EAST0_13 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0xd) /**< PMU_SLP_S3_N. */ +#define GPIO_EAST0_18 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x12) /**< SUS_STAT_N. Not documented. */ +#define GPIO_EAST0_19 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x13) /**< PMU_I2C_CLK. */ +#define GPIO_EAST0_20 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x14) /**< PMU_I2C_DATA. */ +#define GPIO_EAST0_21 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x15) /**< PECI_SMB_CLK. */ +#define GPIO_EAST0_22 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x16) /**< PECI_SMB_ALRT_N. */ +#define GPIO_EMMC_0 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x0) /**< EMMC_CMD. */ +#define GPIO_EMMC_1 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x1) /**< EMMC_STROBE. */ +#define GPIO_EMMC_2 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x2) /**< EMMC_CLK. */ +#define GPIO_EMMC_3 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x3) /**< EMMC_D0. */ +#define GPIO_EMMC_4 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x4) /**< EMMC_D1. */ +#define GPIO_EMMC_5 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x5) /**< EMMC_D2. */ +#define GPIO_EMMC_6 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x6) /**< EMMC_D3. */ +#define GPIO_EMMC_7 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x7) /**< EMMC_D4. */ +#define GPIO_EMMC_8 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x8) /**< EMMC_D5. */ +#define GPIO_EMMC_9 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x9) /**< EMMC_D6. */ +#define GPIO_EMMC_10 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0xa) /**< EMMC_D7. */ + +void gpio_configure_snr_pads(struct snr_pad_config *gpio, size_t num); + +#endif // _SOC_SNOWRIDGE_GPIO_SNR_H_ diff --git a/src/soc/intel/snowridge/include/soc/iomap.h b/src/soc/intel/snowridge/include/soc/iomap.h new file mode 100644 index 0000000000..11a06aceab --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/iomap.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_IOMAP_H_ +#define _SOC_SNOWRIDGE_IOMAP_H_ + +#define TCO_BASE_ADDRESS 0x400 + +/** + * @brief PMC PciCfgSpace is not PCI compliant. Intel FSP will hide the PMC controller to avoid + * external software or OS from corrupting the BAR addresses. Intel® FSP will program the PMC + * controller I/O and MMIO BARs with the following addresses. Use these addresses in the + * bootloader code instead of reading from the PMC controller. This process takes place during + * Intel FSP-S, @sa SnowRidge FSP Integration Guide. + */ +#define ACPI_BASE_ADDRESS 0x00000500 +#define PCH_PWRM_BASE_ADDRESS 0xfe000000 + +#define SPI_BASE_ADDRESS 0xfe010000 +#define SPI_BASE_SIZE 0x00001000 + +#define RESERVED_BASE_ADDRESS 0xfc000000 /**< PCH reserved. */ +#define RESERVED_BASE_SIZE 0x02c00000 + +#endif // _SOC_SNOWRIDGE_IOMAP_H_ diff --git a/src/soc/intel/snowridge/include/soc/irq.h b/src/soc/intel/snowridge/include/soc/irq.h new file mode 100644 index 0000000000..18d9f89e83 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/irq.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _SOC_SNOWRIDGE_IRQ_H_ +#define _SOC_SNOWRIDGE_IRQ_H_ + +#define PCH_IRQ10 10 +#define PCH_IRQ11 11 +#define PCH_IRQ16 16 + +#define PCH_REDIR_ETR 120 + +#define PCH_IOAPIC_ID 8 + +#endif // _SOC_SNOWRIDGE_IRQ_H_ diff --git a/src/soc/intel/snowridge/include/soc/itss.h b/src/soc/intel/snowridge/include/soc/itss.h new file mode 100644 index 0000000000..916c2510ad --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/itss.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_ITSS_H_ +#define _SOC_SNOWRIDGE_ITSS_H_ + +#include <device/device.h> +#include <southbridge/intel/common/acpi_pirq_gen.h> + +enum pirq itss_soc_get_dev_pirq(struct device *dev); + +#endif // _SOC_SNOWRIDGE_ITSS_H_ diff --git a/src/soc/intel/snowridge/include/soc/lpc.h b/src/soc/intel/snowridge/include/soc/lpc.h new file mode 100644 index 0000000000..bea9a035a0 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/lpc.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_LPC_H_ +#define _SOC_SNOWRIDGE_LPC_H_ + +#endif // _SOC_SNOWRIDGE_LPC_H_ diff --git a/src/soc/intel/snowridge/include/soc/msr.h b/src/soc/intel/snowridge/include/soc/msr.h new file mode 100644 index 0000000000..b45050b794 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/msr.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_MSR_H_ +#define _SOC_SNOWRIDGE_MSR_H_ + +#include <intelblocks/msr.h> + +/** + * @brief Force serialized SMM relocation by hardcoding `SMM_CPU_SVRSTR` feature as not supported. + */ +#ifdef SMM_CPU_SVRSTR_MASK +#undef SMM_CPU_SVRSTR_MASK +#endif +#define SMM_CPU_SVRSTR_MASK 0 + +#define MSR_BIOS_DONE 0x151 +#define ENABLE_IA_UNTRUSTED BIT(0) + +#endif // _SOC_SNOWRIDGE_MSR_H_ diff --git a/src/soc/intel/snowridge/include/soc/nvs.h b/src/soc/intel/snowridge/include/soc/nvs.h new file mode 100644 index 0000000000..7b0950386e --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/nvs.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_NVS_H_ +#define _SOC_SNOWRIDGE_NVS_H_ + +#include <intelblocks/nvs.h> + +#endif // _SOC_SNOWRIDGE_NVS_H_ diff --git a/src/soc/intel/snowridge/include/soc/p2sb.h b/src/soc/intel/snowridge/include/soc/p2sb.h new file mode 100644 index 0000000000..e70a3aaf04 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/p2sb.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_P2SB_H_ +#define _SOC_SNOWRIDGE_P2SB_H_ + +#include <commonlib/bsd/helpers.h> + +#define PCH_P2SB_EPMASK0 0x220 + +#define P2SB_BAR CONFIG_PCR_BASE_ADDRESS +#define P2SB_SIZE (16 * MiB) + +#define HPTC_OFFSET 0x60 +#define HPTC_ADDR_ENABLE_BIT BIT(7) + +#endif /* _SOC_SNOWRIDGE_P2SB_H_ */ diff --git a/src/soc/intel/snowridge/include/soc/pci_devs.h b/src/soc/intel/snowridge/include/soc/pci_devs.h new file mode 100644 index 0000000000..ca50bf8eb1 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pci_devs.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_PCI_DEVS_H_ +#define _SOC_SNOWRIDGE_PCI_DEVS_H_ + +#include <device/pci_def.h> + +#if defined(__SIMPLE_DEVICE__) +#include <device/pci_type.h> +#define _SA_DEV(slot, func) PCI_DEV(0x00, slot, func) +#define _PCH_DEV(slot, func) PCI_DEV(0x00, slot, func) +#define _UBOX0_DEV(slot, func) PCI_DEV(0xFE, slot, func) +#define _UBOX1_DEV(slot, func) PCI_DEV(0xFF, slot, func) +#else +#include <device/device.h> +#define _SA_DEV(slot, func) pcidev_path_on_bus(0, PCI_DEVFN(slot, func)) +#define _PCH_DEV(slot, func) pcidev_path_on_bus(0, PCI_DEVFN(slot, func)) +#define _UBOX0_DEV(slot, func) pcidev_path_on_bus(0xFE, PCI_DEVFN(slot, func)) +#define _UBOX1_DEV(slot, func) pcidev_path_on_bus(0xFF, PCI_DEVFN(slot, func)) +#endif + +/* Stack S0. */ +#define SA_DEV_ROOT _SA_DEV(0x00, 0) +#define PCH_DEVFN_QAT_1_7 PCI_DEVFN(0x06, 0) +#define PCH_DEVFN_PCIE_RP0 PCI_DEVFN(0x09, 0) +#define PCH_DEVFN_PCIE_RP1 PCI_DEVFN(0x0a, 0) +#define PCH_DEVFN_PCIE_RP2 PCI_DEVFN(0x0b, 0) +#define PCH_DEVFN_PCIE_RP3 PCI_DEVFN(0x0c, 0) +#define PCH_DEVFN_PCIE_RP8 PCI_DEVFN(0x14, 0) +#define PCH_DEVFN_PCIE_RP9 PCI_DEVFN(0x15, 0) +#define PCH_DEVFN_PCIE_RP10 PCI_DEVFN(0x16, 0) +#define PCH_DEVFN_PCIE_RP11 PCI_DEVFN(0x17, 0) +#define PCH_DEV_UART(func) _PCH_DEV(0x1a, func) + +#define MIN_PCH_SLOT PCI_SLOT(PCH_DEVFN_QAT_1_7) + +/** + * @note To use common block xhci, `PCH_DEVFN_XHCI` need to be defined as `PCI_DEV` not + * `PCI_DEVFN`. Actually they are same for this SoC. + */ +#define PCH_DEVFN_XHCI PCI_DEV(0x0, 0x1e, 0) +#define PCH_DEV_XHCI _PCH_DEV(0x1e, 0) + +#define PCH_DEVFN_LPC PCI_DEVFN(0x1f, 0) +#define PCH_DEV_LPC _PCH_DEV(0x1f, 0) +#define PCH_DEVFN_P2SB PCI_DEVFN(0x1f, 1) +#define PCH_DEV_P2SB _PCH_DEV(0x1f, 1) +#define PCH_DEVFN_PMC PCI_DEVFN(0x1f, 2) +#define PCH_DEVFN_SMBUS PCI_DEVFN(0x1f, 4) +#define PCH_DEV_SMBUS _PCH_DEV(0x1f, 4) +#define PCH_DEVFN_SPI PCI_DEVFN(0x1f, 5) +#define PCH_DEV_SPI _PCH_DEV(0x1f, 5) + +/* Stack S1. */ +#define CPU_DEVFN_PCIE_RPA PCI_DEVFN(0x04, 0) +#define CPU_DEVFN_PCIE_RPB PCI_DEVFN(0x05, 0) +#define CPU_DEVFN_PCIE_RPC PCI_DEVFN(0x06, 0) +#define CPU_DEVFN_PCIE_RPD PCI_DEVFN(0x07, 0) + +/* Stack S2. */ +#define DLB_DEVFN PCI_DEVFN(0x00, 0) + +/* Stack S3. */ +#define NIS_DEVFN PCI_DEVFN(0x04, 0) + +/* Stack S4. */ +#define QAT_1_8_DEVFN PCI_DEVFN(0x05, 0) + +/* Stack U0. */ +#define UBOX_DEV_RACU _UBOX0_DEV(0x00, 1) +#define UBOX_DEV_NCDECS _UBOX0_DEV(0x00, 2) + +/* Stack U1. */ +#define CHAALL_DEV(func) _UBOX1_DEV(0x1d, func) + +/** + * Before calling FspMemoryInit(), the bus number for UBox 0 is 0x1E. + */ +#define IMC_SPD_DEV PCI_DEV(0x1e, 0x0b, 0) + +#endif // _SOC_SNOWRIDGE_PCI_DEVS_H_ diff --git a/src/soc/intel/snowridge/include/soc/pcr_gpmr.h b/src/soc/intel/snowridge/include/soc/pcr_gpmr.h new file mode 100644 index 0000000000..c2879271c6 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pcr_gpmr.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_GPMR_H_ +#define _SOC_SNOWRIDGE_GPMR_H_ + +#define GPMR_LPCLGIR1 0xe30 +#define GPMR_DMICTL 0xefc +#define GPMR_DMICTL_SRLOCK BIT(31) + +#define GPMR_LPCGMR 0xe40 +#define GPMR_GCS 0xe4c +#define GPMR_GCS_BILD BIT(0) + +#define GPMR_LPCIOD 0xe70 +#define GPMR_LPCIOE 0xe74 +#define GPMR_TCOBASE 0xe78 +#define GPMR_TCOEN BIT(1) + +#endif // _SOC_SNOWRIDGE_GPMR_H_ diff --git a/src/soc/intel/snowridge/include/soc/pcr_ids.h b/src/soc/intel/snowridge/include/soc/pcr_ids.h new file mode 100644 index 0000000000..94f1f17b11 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pcr_ids.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_PCR_IDS_H_ +#define _SOC_SNOWRIDGE_PCR_IDS_H_ + +#define PID_PCIE2_P0 0x71 +#define PID_PSTH 0x89 +#define PID_ESPISPI 0x93 +#define PID_USB2 0xA7 +#define PID_PCIE0_P0 0xB4 +#define PID_MODPHY1 0xBA +#define PID_MODPHY2 0xBB +#define PID_GPIOCOM1 0xC2 /**< GPIO Community West. */ +#define PID_GPIOCOM0 0xC5 /**< GPIO Community East. */ +#define PID_CC 0xCC +#define PID_SMB 0xCF +#define PID_ITSS 0xD0 +#define PID_LPC 0xD2 +#define PID_RTC 0xD1 +#define PID_DMI 0x4D + +#endif // _SOC_SNOWRIDGE_PCR_IDS_H_ diff --git a/src/soc/intel/snowridge/include/soc/pm.h b/src/soc/intel/snowridge/include/soc/pm.h new file mode 100644 index 0000000000..fe5c292c0d --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pm.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_PM_H_ +#define _SOC_SNOWRIDGE_PM_H_ + +#include <acpi/acpi.h> +#include <intelpch/gpe.h> +#include <stdint.h> +#include <soc/iomap.h> +#include <soc/pmc.h> + +#define PM1_STS 0x00 +#define WAK_STS BIT(15) +#define PWRBTN_STS BIT(8) +#define PM1_EN 0x02 +#define PWRBTN_EN BIT(8) +#define GBL_EN BIT(5) +#define PM1_CNT 0x04 +#define SCI_EN BIT(0) +#define PM1_TMR 0x08 +#define SMI_EN 0x30 +#define XHCI_SMI_EN BIT(31) +#define ME_SMI_EN BIT(30) +#define ESPI_SMI_EN BIT(28) +#define GPIO_UNLOCK_SMI_EN BIT(27) +#define SDX_SMI_EN BIT(25) +#define THERM_SMI_EN BIT(18) +#define LEGACY_USB2_EN BIT(17) +#define PERIODIC_EN BIT(14) +#define TCO_SMI_EN BIT(13) +#define MCSMI_EN BIT(11) +#define BIOS_RLS BIT(7) +#define SWSMI_TMR_EN BIT(6) +#define APMC_EN BIT(5) +#define SLP_SMI_EN BIT(4) +#define LEGACY_USB_EN BIT(3) +#define BIOS_EN BIT(2) +#define EOS BIT(1) +#define GBL_SMI_EN BIT(0) +#define SMI_STS 0x34 +#define SMI_STS_BITS 32 +#define XHCI_SMI_STS_BIT 31 +#define ME_SMI_STS_BIT 30 +#define ESPI_SMI_STS_BIT 28 +#define GPIO_UNLOCK_SMI_STS_BIT 27 +#define SPI_SMI_STS_BIT 26 +#define SCC_SMI_STS_BIT 25 +#define INTERNAL_TT_STS_BIT 22 +#define MONITOR_STS_BIT 21 +#define PCI_EXP_SMI_STS_BIT 20 +#define RTC_UIP_SMI_STS_BIT 19 +#define THERMAL_SMI_STS_BIT 18 +#define LEGACY_USB2_STS_BIT 17 +#define SMBUS_SMI_STS_BIT 16 +#define SERIRQ_SMI_STS_BIT 15 +#define PERIODIC_STS_BIT 14 +#define TCO_STS_BIT 13 +#define DEVMON_STS_BIT 12 +#define MCSMI_STS_BIT 11 +#define GPIO_STS_BIT 10 +#define GPE0_STS_BIT 9 +#define PM1_STS_BIT 8 +#define SWSMI_TMR_STS_BIT 6 +#define APM_STS_BIT 5 +#define SMI_ON_SLP_EN_STS_BIT 4 +#define LEGACY_USB_STS_BIT 3 +#define BIOS_STS_BIT 2 +#define PM2_CNT 0x50 + +#define GPE0_REG_MAX 4 +#define GPE0_STS(x) (0x60 + ((x) * 4)) +#define GPE_31_0 0 /**< 0x60 = GPE[31:0]. */ +#define GPE_63_32 1 /**< 0x64 = GPE[63:32]. */ +#define GPE_95_64 2 /**< 0x68 = GPE[95:64]. */ +#define GPE_STD 3 /**< 0x6c = Standard GPE. */ + +#define GPE0_EN(x) (0x70 + ((x) * 4)) +#define WADT_EN BIT(18) +#define USB_CON_DSX_EN BIT(17) +#define LANWAKE_EN BIT(16) +#define GPIO_T2_EN BIT(15) +#define ESPI_EN BIT(14) +#define PME_B0_EN BIT(13) +#define ME_SCI_EN BIT(12) +#define PME_EN BIT(11) +#define BATLOW_EN BIT(10) +#define PCI_EXP_EN BIT(9) +#define TCOSCI_EN BIT(6) +#define THERM_EN BIT(4) +#define SWGPE_EN BIT(2) +#define HOT_PLUG_EN BIT(1) + +/** + * @brief Enable SMI generation: + * - on APMC writes (io 0xb2) + * - on writes to SLP_EN (sleep states) + * - on writes to GBL_RLS (bios commands) + * - on eSPI events (does nothing on LPC systems) + * No SMIs: + * - on TCO events, unless enabled in common code + * - on microcontroller writes (io 0x62/0x66) + */ +#define ENABLE_SMI_PARAMS (APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS) + +#define PSS_RATIO_STEP 2 +#define PSS_MAX_ENTRIES 8 +#define PSS_LATENCY_TRANSITION 10 +#define PSS_LATENCY_BUSMASTER 10 + +struct chipset_power_state { + uint16_t pm1_sts; + uint16_t pm1_en; + uint32_t pm1_cnt; + uint32_t gpe0_sts[4]; + uint32_t gpe0_en[4]; + + uint32_t prev_sleep_state; +} __packed; + +/** + * @brief Return base address of Power Management Controller memory mapped registers, definition + * is not needed. + * + * @return uint8_t* + */ +uint8_t *pmc_mmio_regs(void); + +#endif // _SOC_SNOWRIDGE_PM_H_ diff --git a/src/soc/intel/snowridge/include/soc/pmc.h b/src/soc/intel/snowridge/include/soc/pmc.h new file mode 100644 index 0000000000..01873d3d93 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pmc.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_PMC_H_ +#define _SOC_SNOWRIDGE_PMC_H_ + +#define GEN_PMCON_A 0x1020 +#define GBL_RST_STS BIT(24) +#define MS4V BIT(18) +#define SUS_PWR_FLR BIT(16) +#define PWR_FLR BIT(14) +#define PER_SMI_SEL_MASK (3 << 1) +#define SMI_RATE_64S (0 << 1) +#define SMI_RATE_32S BIT(1) +#define SMI_RATE_16S (2 << 1) +#define SMI_RATE_8S (3 << 1) +#define SLEEP_AFTER_POWER_FAIL BIT(0) +#define GEN_PMCON_B 0x1024 +#define SLP_STR_POL_LOCK BIT(18) +#define ACPI_BASE_LOCK BIT(17) +#define SMI_LOCK BIT(4) +#define ETR 0x1048 +#define CF9_LOCK BIT(31) +#define CF9_GLB_RST BIT(20) +#define PRSTS 0x1810 +#define PMSYNC_TPR_CFG 0x18C4 +#define PCH2CPU_TPR_CFG_LOCK BIT(31) +#define GPIO_GPE_CFG 0x1920 +#define GPE0_DWX_MASK 0xf +#define GPE0_DW_SHIFT(x) (4 * (x)) +#define ACTL 0x1BD8 +#define SCI_IRQ_SEL (7 << 0) +#define SCI_IRQ_ADJUST 0 +#define SCIS_IRQ9 0 +#define SCIS_IRQ10 1 +#define SCIS_IRQ11 2 +#define SCIS_IRQ20 4 +#define SCIS_IRQ21 5 +#define SCIS_IRQ22 6 +#define SCIS_IRQ23 7 + +#endif // _SOC_SNOWRIDGE_PMC_H_ diff --git a/src/soc/intel/snowridge/include/soc/sata.h b/src/soc/intel/snowridge/include/soc/sata.h new file mode 100644 index 0000000000..b52cffe389 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/sata.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_SATA_H_ +#define _SOC_SNOWRIDGE_SATA_H_ + +#define SATA_ABAR 0x24 +#define SATA_MAP 0x90 +#define SATA_MAP_AHCI (0 << 6) +#define SATA_MAP_RAID (1 << 6) + +#define SATA_GHC 0x04 +#define SATA_GHC_AE BIT(31) + +#endif // _SOC_SNOWRIDGE_SATA_H_ diff --git a/src/soc/intel/snowridge/include/soc/smbus.h b/src/soc/intel/snowridge/include/soc/smbus.h new file mode 100644 index 0000000000..20b7897843 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/smbus.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_SMBUS_H_ +#define _SOC_SNOWRIDGE_SMBUS_H_ + +#include <intelpch/smbus.h> + +#endif // _SOC_SNOWRIDGE_SMBUS_H_ diff --git a/src/soc/intel/snowridge/include/soc/soc_chip.h b/src/soc/intel/snowridge/include/soc/soc_chip.h new file mode 100644 index 0000000000..713291c9b4 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/soc_chip.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_SOC_CHIP_H_ +#define _SOC_SNOWRIDGE_SOC_CHIP_H_ + +#include "../../chip.h" + +#endif // _SOC_SNOWRIDGE_SOC_CHIP_H_ diff --git a/src/soc/intel/snowridge/include/soc/systemagent.h b/src/soc/intel/snowridge/include/soc/systemagent.h new file mode 100644 index 0000000000..532f71773e --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/systemagent.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_SYSTEMAGENT_H_ +#define _SOC_SNOWRIDGE_SYSTEMAGENT_H_ + +#define PCIE_MMCFG_BASE 0x90 +#define PCIE_MMCFG_LIMIT 0x98 +#define TSEG 0xA8 +#define TSEG_LIMIT 0xAC +#define TOCM 0xC0 +#define TOUUD 0xC8 +#define TOLUD 0xD0 +#define MMIOL 0xD8 + +#define VTBAR 0x180 +#define VTD_CHIPSET_BASE_ADDRESS_ENABLE BIT(0) + +#define DPR 0x290 + +#define VTD_ECAP 0x10 +#define DEVICE_TLB BIT(2) + +#endif // _SOC_SNOWRIDGE_SYSTEMAGENT_H_ diff --git a/src/soc/intel/snowridge/itss.c b/src/soc/intel/snowridge/itss.c new file mode 100644 index 0000000000..07f5b1d788 --- /dev/null +++ b/src/soc/intel/snowridge/itss.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/pci.h> +#include <device/pci_ops.h> +#include <device/pci_type.h> +#include <intelblocks/itss.h> +#include <soc/itss.h> +#include <soc/pci_devs.h> +#include <static.h> + +#include "ramstage.h" + +uint32_t itss_soc_get_on_chip_dev_pir(struct device *dev) +{ + /* Check if device is on chip. */ + if (dev->upstream->dev->path.type != DEVICE_PATH_DOMAIN) + return 0; + + if (!is_pci(dev)) + return 0; + + const unsigned int devfn = dev->path.pci.devfn; + switch (dev_get_domain_id(dev)) { + case 0: + return PCI_ITSS_PIR(PCI_SLOT(devfn)); + case 3: + if (devfn == NIS_DEVFN) + return PCI_ITSS_PIR(25); + break; + case 4: + if (devfn == QAT_1_8_DEVFN) + return PCI_ITSS_PIR(5); + break; + } + + printk(BIOS_WARNING, "Unknown PIR for %s\n", dev_path(dev)); + return 0; +} + +enum pirq itss_soc_get_dev_pirq(struct device *dev) +{ + enum pci_pin dev_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN); + if (dev_pin < PCI_INT_A || dev_pin > PCI_INT_D) + return PIRQ_INVALID; + + struct device *bridge; + enum pci_pin swizzle_pin; + if (is_dev_on_domain0(dev)) { + /** + * Get the pin asserting from bridge to root. + * This function only applies for devices in domain 0. + */ + swizzle_pin = get_pci_irq_pins(dev, &bridge); + if (swizzle_pin < PCI_INT_A || swizzle_pin > PCI_INT_D) + return PIRQ_INVALID; + + /* Device attached to PCH PCIe Root Port need further swizzle. */ + if (is_pci_bridge(bridge) && bridge != dev) + swizzle_pin = pciexp_get_rp_irq_pin(bridge, swizzle_pin); + } else if (dev->upstream->dev == DEV_PTR(nis_vrp)) { + bridge = DEV_PTR(nis_vrp); + swizzle_pin = (dev_pin - 1 + PCI_SLOT(dev->path.pci.devfn)) % 4 + 1; + } else if (dev->upstream->dev == DEV_PTR(qat_1_8_vrp)) { + bridge = DEV_PTR(qat_1_8_vrp); + swizzle_pin = (dev_pin - 1 + PCI_SLOT(dev->path.pci.devfn)) % 4 + 1; + } else { + bridge = dev; + swizzle_pin = dev_pin; + } + + if (bridge != dev) { + /** + * We can't print `dev` path and `bridge` path in a single `printk()` due to + * restriction of `dev_path()`. + */ + printk(BIOS_DEBUG, "%s %s swizzled to ", dev_path(dev), pin_to_str(dev_pin)); + printk(BIOS_DEBUG, "%s %s.\n", dev_path(bridge), pin_to_str(swizzle_pin)); + } + + return itss_get_on_chip_dev_pirq(bridge, swizzle_pin); +} diff --git a/src/soc/intel/snowridge/lockdown.c b/src/soc/intel/snowridge/lockdown.c new file mode 100644 index 0000000000..b74b74ca4b --- /dev/null +++ b/src/soc/intel/snowridge/lockdown.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/pci_ops.h> +#include <intelblocks/cfg.h> +#include <intelblocks/pmclib.h> +#include <intelpch/lockdown.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/pmc.h> + +#define SMM_FEATURE_CONTROL 0x8c +#define SMM_CODE_CHK_EN (1 << 2) +#define SMM_FEATURE_CONTROL_LOCK (1 << 0) + +static void pmc_lockdown_cfg(int chipset_lockdown) +{ + pmc_or_mmio32(PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); + pmc_or_mmio32(GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK); + + pmc_global_reset_disable_and_lock(); + + assert(chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT); + + pmc_or_mmio32(GEN_PMCON_B, SMI_LOCK); +} + +void soc_lockdown_config(int chipset_lockdown) +{ + pmc_lockdown_cfg(chipset_lockdown); + + pci_or_config32(UBOX_DEV_RACU, SMM_FEATURE_CONTROL, + SMM_CODE_CHK_EN | SMM_FEATURE_CONTROL_LOCK); +} diff --git a/src/soc/intel/snowridge/lpc.c b/src/soc/intel/snowridge/lpc.c new file mode 100644 index 0000000000..128b7487d9 --- /dev/null +++ b/src/soc/intel/snowridge/lpc.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/ioapic.h> +#include <console/console.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <intelblocks/itss.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/pcr.h> +#include <soc/iomap.h> +#include <soc/irq.h> +#include <soc/itss.h> +#include <soc/pcr_ids.h> +#include <static.h> + +static void soc_pch_pirq_init(void) +{ + for (uint32_t reg = PCR_ITSS_PIRQA_ROUT; reg <= PCR_ITSS_PIRQH_ROUT; reg++) + printk(BIOS_SPEW, "PIRQ Routing Control %c at 0x%04x: 0x%02x\n", + reg - PCR_ITSS_PIRQA_ROUT + 'A', reg, pcr_read8(PID_ITSS, reg)); + + for (uint32_t reg = 0; reg < 32; reg++) + printk(BIOS_SPEW, "PCI Interrupt Route %d at 0x%04x: 0x%02x\n", reg, + PCI_ITSS_PIR(reg), pcr_read16(PID_ITSS, PCI_ITSS_PIR(reg))); + + /* The PIRQA-H registers are programmable thus legacy PIC mode is supported. */ + size_t num; + const uint8_t *pch_interrupt_routing = lpc_get_pic_pirq_routing(&num); + itss_irq_init(pch_interrupt_routing); + + for (struct device *dev = all_devices; dev; dev = dev->next) { + if (!is_enabled_pci(dev)) + continue; + + enum pirq pirq = itss_soc_get_dev_pirq(dev); + if (pirq == PIRQ_INVALID) + continue; + + uint8_t pirq_value = pcr_read8(PID_ITSS, PCR_ITSS_PIRQA_ROUT + pirq_idx(pirq)); + if (pirq_value & 0x80) + pci_write_config8(dev, PCI_INTERRUPT_LINE, PCH_IRQ16 + pirq_idx(pirq)); + else + pci_write_config8(dev, PCI_INTERRUPT_LINE, pirq_value & 0x0f); + + printk(BIOS_DEBUG, "%s is using %s, line 0x%2x\n", dev_path(dev), + pin_to_str(pci_read_config8(dev, PCI_INTERRUPT_PIN)), + pci_read_config8(dev, PCI_INTERRUPT_LINE)); + } +} + +void lpc_soc_init(struct device *dev) +{ + lpc_set_serirq_mode(CONFIG(SERIRQ_CONTINUOUS_MODE) ? SERIRQ_CONTINUOUS : SERIRQ_QUIET); + + ioapic_set_max_vectors(IO_APIC_ADDR, PCH_REDIR_ETR); + + setup_ioapic(IO_APIC_ADDR, PCH_IOAPIC_ID); + ioapic_set_boot_config(IO_APIC_ADDR, true); + + soc_pch_pirq_init(); +} + +void pch_lpc_soc_fill_io_resources(struct device *dev) +{ + struct resource *res; + + res = new_resource(dev, PCI_BASE_ADDRESS_4); /**< Use the register offset in PMC. */ + res->base = ACPI_BASE_ADDRESS; + res->size = 0x80; /**< 128 bytes I/O config space */ + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + printk(BIOS_DEBUG, "Adding ACPI IO config space BAR at base 0x%08llx, size 0x%08llx\n", + res->base, res->size); +} diff --git a/src/soc/intel/snowridge/nis.c b/src/soc/intel/snowridge/nis.c new file mode 100644 index 0000000000..d716c3c983 --- /dev/null +++ b/src/soc/intel/snowridge/nis.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +#include "ramstage.h" + +static struct device_operations snr_nis_ops = { + .read_resources = pciexp_pf_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .final = pci_dev_request_bus_master, + .ops_pci = &pci_dev_ops_pci, +}; + +static const unsigned short snr_nis_ids[] = { + PCI_DID_INTEL_SNR_NIS1890, + PCI_DID_INTEL_SNR_NIS1891, + PCI_DID_INTEL_SNR_NIS1892, + PCI_DID_INTEL_SNR_NIS1895, + 0 +}; + +static const struct pci_driver snr_nis_driver __pci_driver = { + .ops = &snr_nis_ops, + .vendor = PCI_VID_INTEL, + .devices = snr_nis_ids +}; diff --git a/src/soc/intel/snowridge/pcie_rp.c b/src/soc/intel/snowridge/pcie_rp.c new file mode 100644 index 0000000000..bf391c5308 --- /dev/null +++ b/src/soc/intel/snowridge/pcie_rp.c @@ -0,0 +1,192 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <commonlib/bsd/compiler.h> +#include <console/console.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <device/pciexp.h> +#include <soc/acpi.h> +#include <soc/pci_devs.h> + +#include "ramstage.h" + +#define INTXSWZCTL 0xf8 + +enum pci_pin pciexp_get_rp_irq_pin(struct device *bridge, enum pci_pin pin) +{ + /* Swizzle according to INTXSWZCTL register. */ + enum pci_pin reg_swizzle_pin = pin; + uint8_t int_swx_ctl = pci_read_config8(bridge, INTXSWZCTL) & 0x07; + switch (int_swx_ctl) { + case 0: + case 1: + case 2: + case 3: + reg_swizzle_pin = (reg_swizzle_pin - 1 + int_swx_ctl) % 4 + 1; + break; + case 4: + reg_swizzle_pin = PCI_INT_A; + break; + default: + reg_swizzle_pin = PCI_INT_NONE; + break; + } + + printk(BIOS_DEBUG, "Root Port %s %s swizzled to %s (INTXSWZCTL).\n", dev_path(bridge), + pin_to_str(pin), pin_to_str(reg_swizzle_pin)); + if (reg_swizzle_pin < PCI_INT_A || reg_swizzle_pin > PCI_INT_D) + return reg_swizzle_pin; + + /* Swizzle between PCIe Root Ports. */ + enum pci_pin hardwired_swizzle_pin = reg_swizzle_pin; + switch (bridge->device) { + case PCI_DID_INTEL_SNR_PCH_PCIE_RP3: + case PCI_DID_INTEL_SNR_PCH_PCIE_RP11: + hardwired_swizzle_pin += 1; + __fallthrough; + case PCI_DID_INTEL_SNR_PCH_PCIE_RP2: + case PCI_DID_INTEL_SNR_PCH_PCIE_RP10: + hardwired_swizzle_pin += 1; + __fallthrough; + case PCI_DID_INTEL_SNR_PCH_PCIE_RP1: + case PCI_DID_INTEL_SNR_PCH_PCIE_RP9: + hardwired_swizzle_pin += 1; + __fallthrough; + case PCI_DID_INTEL_SNR_PCH_PCIE_RP0: + case PCI_DID_INTEL_SNR_PCH_PCIE_RP8: + hardwired_swizzle_pin = (hardwired_swizzle_pin - 1) % 4 + 1; + printk(BIOS_DEBUG, "Root Port %s %s swizzled to %s (Hard-wired).\n", + dev_path(bridge), pin_to_str(reg_swizzle_pin), + pin_to_str(hardwired_swizzle_pin)); + __fallthrough; + default: + return hardwired_swizzle_pin; + } +} + +static bool pcie_rp_is_vrp(struct device *dev) +{ + switch (dev_get_domain_id(dev)) { + case 0: + switch (dev->path.pci.devfn) { + case PCH_DEVFN_QAT_1_7: + return true; + default: + break; + } + break; + case 3: + if (dev->path.pci.devfn == NIS_DEVFN) + return true; + break; + case 4: + if (dev->path.pci.devfn == QAT_1_8_DEVFN) + return true; + break; + default: + break; + } + + return false; +} + +static void pcie_rp_scan_bridge(struct device *dev) +{ + if (pcie_rp_is_vrp(dev)) + return pciexp_scan_bridge(dev); + else if (CONFIG(PCIEXP_HOTPLUG) && pciexp_dev_is_slot_hot_plug_cap(dev)) + return pciexp_hotplug_scan_bridge(dev); + else + return pciexp_scan_bridge(dev); +} + +static const char *pcie_rp_acpi_name(const struct device *dev) +{ + switch (dev_get_domain_id(dev)) { + case 0: + switch (dev->path.pci.devfn) { + case PCH_DEVFN_QAT_1_7: + return "VRP6"; + case PCH_DEVFN_PCIE_RP0: + return "RP00"; + case PCH_DEVFN_PCIE_RP1: + return "RP01"; + case PCH_DEVFN_PCIE_RP2: + return "RP02"; + case PCH_DEVFN_PCIE_RP3: + return "RP03"; + case PCH_DEVFN_PCIE_RP8: + return "RP08"; + case PCH_DEVFN_PCIE_RP9: + return "RP09"; + case PCH_DEVFN_PCIE_RP10: + return "RP10"; + case PCH_DEVFN_PCIE_RP11: + return "RP11"; + default: + break; + } + break; + case 1: + switch (dev->path.pci.devfn) { + case CPU_DEVFN_PCIE_RPA: + return "RPA"; + case CPU_DEVFN_PCIE_RPB: + return "RPB"; + case CPU_DEVFN_PCIE_RPC: + return "RPC"; + case CPU_DEVFN_PCIE_RPD: + return "RPD"; + default: + break; + } + break; + case 3: + if (dev->path.pci.devfn == NIS_DEVFN) + return "VRP4"; + break; + case 4: + if (dev->path.pci.devfn == QAT_1_8_DEVFN) + return "VRP5"; + break; + default: + break; + } + + return NULL; +} + +static struct device_operations snr_pcie_rp_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .scan_bus = pcie_rp_scan_bridge, + .acpi_fill_ssdt = pcie_rp_fill_ssdt, + .acpi_name = pcie_rp_acpi_name, +}; + +static const unsigned short snr_pcie_rp_ids[] = { + PCI_DID_INTEL_SNR_VRP0_QAT_1_7, + PCI_DID_INTEL_SNR_VRP5_QAT_1_8, + PCI_DID_INTEL_SNR_VRP4_NIS, + PCI_DID_INTEL_SNR_PCH_PCIE_RP0, + PCI_DID_INTEL_SNR_PCH_PCIE_RP1, + PCI_DID_INTEL_SNR_PCH_PCIE_RP2, + PCI_DID_INTEL_SNR_PCH_PCIE_RP3, + PCI_DID_INTEL_SNR_PCH_PCIE_RP8, + PCI_DID_INTEL_SNR_PCH_PCIE_RP9, + PCI_DID_INTEL_SNR_PCH_PCIE_RP10, + PCI_DID_INTEL_SNR_PCH_PCIE_RP11, + PCI_DID_INTEL_SNR_CPU_PCIE_RPA, + PCI_DID_INTEL_SNR_CPU_PCIE_RPB, + PCI_DID_INTEL_SNR_CPU_PCIE_RPC, + PCI_DID_INTEL_SNR_CPU_PCIE_RPD, + 0 +}; + +static const struct pci_driver snr_pcie_rp_driver __pci_driver = { + .ops = &snr_pcie_rp_ops, + .vendor = PCI_VID_INTEL, + .devices = snr_pcie_rp_ids +}; diff --git a/src/soc/intel/snowridge/qat.c b/src/soc/intel/snowridge/qat.c new file mode 100644 index 0000000000..5a35c31493 --- /dev/null +++ b/src/soc/intel/snowridge/qat.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> + +#include "ramstage.h" + +static struct device_operations snr_qat_ops = { + .read_resources = pciexp_pf_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .final = pci_dev_request_bus_master, + .ops_pci = &pci_dev_ops_pci, +}; + +static const unsigned short snr_qat_ids[] = { + PCI_DID_INTEL_SNR_QAT_1_7, + PCI_DID_INTEL_SNR_QAT_1_8, + 0 +}; + +static const struct pci_driver snr_qat_driver __pci_driver = { + .ops = &snr_qat_ops, + .vendor = PCI_VID_INTEL, + .devices = snr_qat_ids +}; diff --git a/src/soc/intel/snowridge/ramstage.h b/src/soc/intel/snowridge/ramstage.h new file mode 100644 index 0000000000..bcbc2f834b --- /dev/null +++ b/src/soc/intel/snowridge/ramstage.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_RAMSTAGE_H_ +#define _SOC_SNOWRIDGE_RAMSTAGE_H_ + +#include <device/device.h> +#include <device/pci.h> +#include <southbridge/intel/common/acpi_pirq_gen.h> + +void pciexp_pf_read_resources(struct device *dev); +void pciexp_vf_read_resources(struct device *dev); + +enum pci_pin pciexp_get_rp_irq_pin(struct device *bridge, enum pci_pin pin); + +#endif // _SOC_SNOWRIDGE_RAMSTAGE_H_ diff --git a/src/soc/intel/snowridge/romstage/gpio_snr.c b/src/soc/intel/snowridge/romstage/gpio_snr.c new file mode 100644 index 0000000000..99d994861c --- /dev/null +++ b/src/soc/intel/snowridge/romstage/gpio_snr.c @@ -0,0 +1,200 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <intelblocks/gpio.h> +#include <intelblocks/pcr.h> +#include <soc/gpio_snr.h> +#include <soc/pci_devs.h> + +#define SNR_GPIO_GROUP(GPIO_PAD) (SNR_GPIO_PAD(GPIO_PAD) / GPIO_MAX_NUM_PER_GROUP) +#define SNR_GPIO_WITHIN_GROUP(GPIO_PAD) (SNR_GPIO_PAD(GPIO_PAD) % GPIO_MAX_NUM_PER_GROUP) + +static void gpio_unlock_snr_pad_group(const struct pad_community *comm, + const size_t group_index, const uint32_t bit_mask) +{ + struct pcr_sbi_msg msg = { + .pid = comm->port, + .offset = comm->pad_cfg_lock_offset + group_index * 2 * sizeof(uint32_t), + .opcode = GPIO_LOCK_UNLOCK, + .is_posted = false, + .fast_byte_enable = 0xf, + .bar = 0, + .fid = 0, + }; + uint32_t data; + uint8_t response; + int status; + + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, + "Unlock GPIO community %s, group %zu at offset 0x%04x with mask 0x%08x\n", + comm->name, group_index, msg.offset, bit_mask); + + data = pcr_read32(msg.pid, msg.offset) & (~bit_mask); + status = pcr_execute_sideband_msg(PCH_DEV_P2SB, &msg, &data, &response); + if (status || response) + die("Failed to unlock GPIO PAD, response = %d\n", response); + + msg.offset += sizeof(uint32_t); + data = pcr_read32(msg.pid, msg.offset) & (~bit_mask); + status = pcr_execute_sideband_msg(PCH_DEV_P2SB, &msg, &data, &response); + if (status || response) + die("Failed to unlock GPIO PAD Tx state, response = %d\n", response); +} + +static uint8_t gpio_get_snr_pad_own(gpio_t pad) +{ + size_t num_communities; + const struct pad_community *comm = + soc_gpio_get_community(&num_communities) + SNR_GPIO_COMMUNITY(pad); + uint16_t pad_own_offset = comm->pad_own_reg_0; + uint32_t pad_own; + + /** + * 4 bits for each pad. + */ + pad_own_offset += (pad - comm->first_pad) / 8 * sizeof(uint32_t); + pad_own = pcr_read32(comm->port, pad_own_offset); + + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, + "Pad 0x%08x ownership at 0x%04x value = 0x%08x, mask = 0x%08x\n", pad, + pad_own_offset, pad_own, 0x03 << ((pad - comm->first_pad) % 8 * 4)); + + return (pad_own >> ((pad - comm->first_pad) % 8 * sizeof(uint32_t))) & 0x03; +} + +static uint8_t gpio_get_snr_pad_hostsw_own(gpio_t pad) +{ + size_t num_communities; + const struct pad_community *comm = + soc_gpio_get_community(&num_communities) + SNR_GPIO_COMMUNITY(pad); + uint32_t host_sw_own; + + host_sw_own = pcr_read32(comm->port, comm->host_own_reg_0 + SNR_GPIO_GROUP(pad)); + + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, + "Pad 0x%08x host software ownership at 0x%04x value = 0x%08x, mask = 0x%08x\n", + pad, comm->host_own_reg_0 + SNR_GPIO_GROUP(pad), host_sw_own, + 0x01 << SNR_GPIO_WITHIN_GROUP(pad)); + + return (host_sw_own >> SNR_GPIO_WITHIN_GROUP(pad)) & 0x01; +} + +static void gpio_clear_snr_pad_group_interrupt_status(const struct pad_community *comm, + const size_t group_index, + const uint32_t bit_mask) +{ + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, + "Clear GPIO community %s, group %zu interrupt status with mask 0x%08x\n", + comm->name, group_index, bit_mask); + + const uint16_t offset = group_index * sizeof(uint32_t); + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, "GPI interrupt status at offset 0x%04x\n", + comm->gpi_int_sts_reg_0 + offset); + pcr_write32(comm->port, comm->gpi_int_sts_reg_0 + offset, bit_mask); + + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, "GPI GPE status at offset 0x%04x\n", + comm->gpi_gpe_sts_reg_0 + offset); + pcr_write32(comm->port, comm->gpi_gpe_sts_reg_0 + offset, bit_mask); + + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, "SMI status at offset 0x%04x\n", + comm->gpi_smi_sts_reg_0 + offset); + pcr_write32(comm->port, comm->gpi_smi_sts_reg_0 + offset, bit_mask); + + if (CONFIG(DEBUG_GPIO)) + printk(BIOS_DEBUG, "NMI status at offset 0x%04x\n", + comm->gpi_nmi_sts_reg_0 + offset); + pcr_write32(comm->port, comm->gpi_nmi_sts_reg_0 + offset, bit_mask); +} + +void gpio_configure_snr_pads(struct snr_pad_config *gpio, size_t num) +{ + size_t i, j, num_communities, comm_index, group_index; + const struct pad_community *comm = soc_gpio_get_community(&num_communities); + uint16_t config_offset; + uint32_t bit_mask, pad_conf; + + if (!gpio || num == 0) + return; + + /** + * Unlock pad configuration and pad tx configuration at group level. + */ + for (i = 0; i < num; i++) { + comm_index = SNR_GPIO_COMMUNITY(gpio[i].cfg.pad); + if (comm_index >= num_communities) { + printk(BIOS_WARNING, "Invalid GPIO community index %zu\n", comm_index); + continue; + } + + group_index = SNR_GPIO_GROUP(gpio[i].cfg.pad); + if (group_index >= comm->num_groups) { + printk(BIOS_WARNING, "Invalid GPIO group index %zu\n", group_index); + continue; + } + + bit_mask = 1 << (SNR_GPIO_PAD(gpio[i].cfg.pad) % GPIO_MAX_NUM_PER_GROUP); + + gpio_unlock_snr_pad_group(&comm[comm_index], group_index, bit_mask); + } + + /** + * @note Common block GPIO code doesn't support leaving some bits as default value, thus we + * should read the original value and set concerned bits before calling common code. + */ + for (i = 0; i < num; i++) { + if (gpio_get_snr_pad_own(gpio[i].cfg.pad) != GPIO_PAD_OWN_HOST) { + printk(BIOS_ERR, "GPIO pad 0x%08x is not owned by host\n", + gpio[i].cfg.pad); + continue; + } + + comm_index = SNR_GPIO_COMMUNITY(gpio[i].cfg.pad); + config_offset = comm[comm_index].pad_cfg_base + + (gpio[i].cfg.pad - comm[comm_index].first_pad) * + GPIO_NUM_PAD_CFG_REGS * sizeof(uint32_t); + for (j = 0; j < GPIO_NUM_PAD_CFG_REGS; j++) { + pad_conf = pcr_read32(comm[comm_index].port, + config_offset + j * sizeof(uint32_t)); + pad_conf &= ~gpio[i].pad_config_mask[j]; + gpio[i].cfg.pad_config[j] = + (gpio[i].cfg.pad_config[j] & gpio[i].pad_config_mask[j]) | + pad_conf; + } + + /** + * Set the fourth bit for host software ownership. + */ + switch (gpio[i].hostsw_own) { + case GPIO_HOSTSW_OWN_ACPI: + gpio[i].cfg.pad_config[1] |= PAD_CFG_OWN_GPIO(ACPI); + break; + case GPIO_HOSTSW_OWN_DRIVER: + gpio[i].cfg.pad_config[1] |= PAD_CFG_OWN_GPIO(DRIVER); + break; + default: + gpio[i].cfg.pad_config[1] |= + gpio_get_snr_pad_hostsw_own(gpio[i].cfg.pad) << 4; + break; + } + + gpio_configure_pads(&gpio[i].cfg, 1); + } + + /** + * Clear pad interrupt status at group level. + */ + for (i = 0; i < num; i++) { + comm_index = SNR_GPIO_COMMUNITY(gpio[i].cfg.pad); + group_index = SNR_GPIO_GROUP(gpio[i].cfg.pad); + bit_mask = 1 << (SNR_GPIO_PAD(gpio[i].cfg.pad) % GPIO_MAX_NUM_PER_GROUP); + gpio_clear_snr_pad_group_interrupt_status(&comm[comm_index], group_index, + bit_mask); + } +} diff --git a/src/soc/intel/snowridge/romstage/romstage.c b/src/soc/intel/snowridge/romstage/romstage.c new file mode 100644 index 0000000000..d615da6e92 --- /dev/null +++ b/src/soc/intel/snowridge/romstage/romstage.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/romstage.h> +#include <cbmem.h> +#include <console/console.h> +#include <device/dram/common.h> +#include <device/dram/ddr4.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <fsp/api.h> +#include <fsp/soc_binding.h> +#include <fsp/util.h> +#include <intelblocks/imc.h> +#include <intelblocks/meminit.h> +#include <intelblocks/p2sblib.h> +#include <intelblocks/rtc.h> +#include <lib.h> +#include <romstage.h> +#include <soc/intel/common/smbios.h> +#include <soc/pci_devs.h> +#include <spd.h> +#include <spd_bin.h> +#include <string.h> + +#include "../common/fsp_hob.h" +#include "../common/kti_cache.h" + +#define SPD_DIMM_ADDR(ch, dimm) ((ch) * CONFIG_DIMMS_PER_CHANNEL + (dimm)) + +static void fsp_kti_cache_fill(FSPM_UPD *mupd) +{ + void *data; + size_t kti_size; + + mupd->FspmConfig.PcdKtiBufferPtr = 0; + + data = kti_cache_load(&kti_size); + if (data == NULL) + return; + + mupd->FspmConfig.PcdKtiBufferPtr = (uint32_t)data; + + printk(BIOS_SPEW, "KTI cache found, size %zx bytes\n", kti_size); + hexdump(data, kti_size); +} + +static struct mem_channel_data mem_channel_data; + +static void fsp_mem_spd_fill(FSPM_UPD *mupd) +{ + const struct soc_mem_cfg soc_mem_cfg = { + .num_phys_channels = MRC_CHANNELS, + .phys_to_mrc_map = {0, 1}, + }; + const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus[0] = {.addr_dimm[0] = SPD_DIMM_ADDR(0, 0), + .addr_dimm[1] = SPD_DIMM_ADDR(0, 1)}, + .smbus[1] = {.addr_dimm[0] = SPD_DIMM_ADDR(1, 0), + .addr_dimm[1] = SPD_DIMM_ADDR(1, 1)}, + }; + + imc_spd_smbus_init(IMC_SPD_DEV); + + mem_populate_channel_data(mupd, &soc_mem_cfg, &spd_info, false, &mem_channel_data); + + printk(BIOS_SPEW, "SPD block length: 0x%zx\n", mem_channel_data.spd_len); + + mupd->FspmConfig.PcdMemSpdPtr = (uintptr_t)mem_channel_data.spd[0][0]; + printk(BIOS_SPEW, "PcdMemSpdPtr: 0x%08x\n", mupd->FspmConfig.PcdMemSpdPtr); + + mupd->FspmConfig.PcdDdrFreq = 0; +} + +static void soc_memory_init_params(FSPM_UPD *mupd) +{ + fsp_kti_cache_fill(mupd); + fsp_mem_spd_fill(mupd); + + mupd->FspmConfig.PcdVtdSupport = CONFIG(ENABLE_VTD); + + mupd->FspmConfig.PcdFiaMuxOverride = 1; + mupd->FspmConfig.FiaMuxCfgInvalidate = 0; +} + +void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) +{ + soc_memory_init_params(mupd); + + mainboard_memory_init_params(mupd); +} + +static uint8_t spd_ddr_type_to_smbios_memory_type(uint16_t spd_type) +{ + switch (spd_type) { + case SPD_MEMORY_TYPE_DDR4_SDRAM: + case SPD_MEMORY_TYPE_DDR4E_SDRAM: + return MEMORY_TYPE_DDR4; + case SPD_MEMORY_TYPE_LPDDR4_SDRAM: + return MEMORY_TYPE_LPDDR4; + default: + return MEMORY_TYPE_UNKNOWN; + } +} + +static void smbios_memory_info_save(void) +{ + const FSP_SMBIOS_MEMORY_INFO *fsp_smbios_memory_info = fsp_hob_get_memory_info(); + if (!fsp_smbios_memory_info) { + printk(BIOS_WARNING, "Couldn't find SMBIOS memory info hob!\n"); + return; + } + + struct memory_info *mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info)); + if (!mem_info) { + printk(BIOS_ERR, "Add memory info to cbmem failed!\n"); + return; + } + + memset(mem_info, 0, sizeof(*mem_info)); + + assert(fsp_smbios_memory_info->ChannelCount <= + ARRAY_SIZE(fsp_smbios_memory_info->ChannelInfo)); + + uint8_t dimm_cnt = 0; + for (uint8_t channel = 0; channel < fsp_smbios_memory_info->ChannelCount && + channel < ARRAY_SIZE(fsp_smbios_memory_info->ChannelInfo) && + dimm_cnt < ARRAY_SIZE(mem_info->dimm); + channel++) { + const CHANNEL_INFO *channel_info = + &fsp_smbios_memory_info->ChannelInfo[channel]; + + assert(channel_info->DimmCount <= ARRAY_SIZE(channel_info->DimmInfo)); + + for (uint8_t dimm = 0; dimm < channel_info->DimmCount && + dimm < ARRAY_SIZE(channel_info->DimmInfo) && + dimm_cnt < ARRAY_SIZE(mem_info->dimm); + dimm++) { + const DIMM_INFO *fsp_dimm_info = &channel_info->DimmInfo[dimm]; + struct dimm_info *dimm_info = &mem_info->dimm[dimm_cnt]; + + struct dimm_attr_ddr4_st dimm_attr; + enum spd_status status = spd_decode_ddr4( + &dimm_attr, (uint8_t *)mem_channel_data.spd[channel][dimm]); + + printk(BIOS_INFO, "MemoryType from fsp hob: 0x%02x\n", + fsp_smbios_memory_info->MemoryType); + + /* Populate the DIMM information */ + dimm_info_fill(dimm_info, fsp_dimm_info->SizeInMb, + spd_ddr_type_to_smbios_memory_type( + fsp_smbios_memory_info->MemoryType), + fsp_smbios_memory_info->MemoryFrequencyInMHz, + status == SPD_STATUS_OK ? dimm_attr.ranks : 0, + channel_info->ChannelId, fsp_dimm_info->DimmId, + (const char *)fsp_dimm_info->ModulePartNum, + sizeof(fsp_dimm_info->ModulePartNum), + status == SPD_STATUS_OK ? dimm_attr.serial_number : NULL, + fsp_smbios_memory_info->DataWidth, + status == SPD_STATUS_OK ? dimm_attr.vdd_voltage : 1200, + fsp_smbios_memory_info->ErrorCorrectionType, + fsp_dimm_info->MfgId, + status == SPD_STATUS_OK ? dimm_attr.dimm_type : 0, 0, 0); + + dimm_cnt++; + } + } + + mem_info->dimm_cnt = dimm_cnt; + printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt); +} + +/** + * @brief Intel SoCs place this function in `src/soc`. + */ +void mainboard_romstage_entry(void) +{ + p2sb_dev_enable_bar(PCH_DEV_P2SB, CONFIG_PCR_BASE_ADDRESS); + mainboard_config_gpios(); + + fsp_memory_init(false); + + rtc_init(); + + smbios_memory_info_save(); +} diff --git a/src/soc/intel/snowridge/sata.c b/src/soc/intel/snowridge/sata.c new file mode 100644 index 0000000000..bdd881d996 --- /dev/null +++ b/src/soc/intel/snowridge/sata.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/device.h> +#include <device/mmio.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <soc/sata.h> + +static void sata_init(struct device *dev) +{ + uint32_t reg32, abar; + + printk(BIOS_DEBUG, "Set SATA controller in AHCI mode.\n"); + + uint16_t reg16 = pci_read_config16(dev, SATA_MAP); + reg16 &= ~(3 << 6); + reg16 |= SATA_MAP_AHCI; + pci_write_config16(dev, SATA_MAP, reg16); + + /* Initialize AHCI memory-mapped space */ + abar = pci_read_config32(dev, SATA_ABAR); + + /* Enable AHCI Mode */ + reg32 = read32p(abar + SATA_GHC); + reg32 |= SATA_GHC_AE; + write32p(abar + SATA_GHC, reg32); +} + +static struct device_operations snr_sata_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = sata_init, + .final = pci_dev_request_bus_master, + .ops_pci = &pci_dev_ops_pci, +}; + +static const unsigned short snr_sata_ids[] = { + PCI_DID_INTEL_SNR_SATA0, + PCI_DID_INTEL_SNR_SATA2, + 0, +}; + +static const struct pci_driver snr_sata_driver __pci_driver = { + .ops = &snr_sata_ops, + .vendor = PCI_VID_INTEL, + .devices = snr_sata_ids, +}; diff --git a/src/soc/intel/snowridge/smihandler.c b/src/soc/intel/snowridge/smihandler.c new file mode 100644 index 0000000000..96efa64090 --- /dev/null +++ b/src/soc/intel/snowridge/smihandler.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/fast_spi.h> +#include <intelblocks/smihandler.h> +#include <soc/pm.h> + +void smihandler_soc_at_finalize(void) +{ + fast_spi_enable_wp(); +} + +const smi_handler_t southbridge_smi[SMI_STS_BITS] = { + [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, + [APM_STS_BIT] = smihandler_southbridge_apmc, + [PM1_STS_BIT] = smihandler_southbridge_pm1, + [GPE0_STS_BIT] = smihandler_southbridge_gpe0, + [GPIO_STS_BIT] = smihandler_southbridge_gpi, + [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, + [MCSMI_STS_BIT] = smihandler_southbridge_mc, +#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) + [TCO_STS_BIT] = smihandler_southbridge_tco, +#endif + [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, + [MONITOR_STS_BIT] = smihandler_southbridge_monitor +}; diff --git a/src/soc/intel/snowridge/sriov.c b/src/soc/intel/snowridge/sriov.c new file mode 100644 index 0000000000..61f9c7c8b7 --- /dev/null +++ b/src/soc/intel/snowridge/sriov.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <commonlib/bsd/helpers.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci_def.h> +#include <device/pciexp.h> +#include <device/resource.h> +#include <lib.h> + +#include "ramstage.h" + +void pciexp_vf_read_resources(struct device *dev) +{ + uint32_t sriov_cap_offset, supported_page_size, system_page_size; + uint16_t num_vfs, index; + int align; + struct resource *resource; + + sriov_cap_offset = pciexp_find_extended_cap(dev, PCIE_EXT_CAP_SRIOV_ID, 0); + if (sriov_cap_offset == 0) { + printk(BIOS_DEBUG, "No SRIOV capability for %s!\n", dev_path(dev)); + return; + } + + printk(BIOS_DEBUG, "%s SRIOV capability found at offset 0x%x\n", dev_path(dev), + sriov_cap_offset); + + supported_page_size = pci_read_config32( + dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_SUPPORTED_PAGE_SIZE); + if (supported_page_size == 0) { + printk(BIOS_DEBUG, "No supported page size for %s!\n", dev_path(dev)); + return; + } + + system_page_size = + pci_read_config32(dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_SYSTEM_PAGE_SIZE); + if ((system_page_size & supported_page_size) == 0) { + printk(BIOS_ERR, "Unsupportted system page size 0x%08x for %s!\n", + system_page_size, dev_path(dev)); + return; + } + + if (popcnt(system_page_size) != 1) { + printk(BIOS_ERR, "More than 1 bit is set in system page size for %s!\n", + dev_path(dev)); + return; + } + + num_vfs = pci_read_config16(dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_TOTAL_VFS); + + /** + * If bit `n` is set, the VFs are required to support a page size of 2 ^ (n + 12). + */ + align = __ffs(system_page_size) + 12; + + for (index = PCIE_EXT_CAP_SRIOV_VF_BAR0; index <= PCIE_EXT_CAP_SRIOV_VF_BAR5; + index += 4) { + resource = pci_get_resource(dev, sriov_cap_offset + index); + if (resource->flags == 0) + continue; + + printk(BIOS_DEBUG, "%s SRIOV BAR at offset 0x%x\n", dev_path(dev), + sriov_cap_offset + index); + + /** + * Section 9.3.3.13 of PCIe Base Specification 6.2. + */ + resource->align = MAX(resource->align, align); + resource->gran = MAX(resource->gran, align); + resource->size = 1 << resource->gran; + + resource->size *= num_vfs; + + /** + * Allocate above 4G to avoid exhausting MMIO32 space. + */ + if (resource->size >= 16 * MiB) + resource->flags |= IORESOURCE_ABOVE_4G; + + printk(BIOS_DEBUG, "%s SRIOV BAR size 0x%llx, flags 0x%lx\n", dev_path(dev), + resource->size, resource->flags); + + if (resource->flags & IORESOURCE_PCI64) + index += 4; + } +} + +void pciexp_pf_read_resources(struct device *dev) +{ + uint16_t index; + struct resource *resource; + + printk(BIOS_SPEW, "Reading resource: %s idx %02x\n", dev_path(dev), PCI_BASE_ADDRESS_0); + + for (index = PCI_BASE_ADDRESS_0; index < PCI_BASE_ADDRESS_0 + (6 << 2);) { + resource = pci_get_resource(dev, index); + /** + * Allocate above 4G to avoid exhausting MMIO32 space. + */ + if (resource->size >= 16 * MiB) + resource->flags |= IORESOURCE_ABOVE_4G; + + index += (resource->flags & IORESOURCE_PCI64) ? 8 : 4; + } + + pciexp_vf_read_resources(dev); + + compact_resources(dev); +} diff --git a/src/soc/intel/snowridge/systemagent.c b/src/soc/intel/snowridge/systemagent.c new file mode 100644 index 0000000000..2663dc0168 --- /dev/null +++ b/src/soc/intel/snowridge/systemagent.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/hpet.h> +#include <arch/ioapic.h> +#include <commonlib/bsd/helpers.h> +#include <cpu/x86/lapic_def.h> +#include <device/pci_ops.h> +#include <intelblocks/systemagent_server.h> +#include <soc/iomap.h> +#include <soc/systemagent.h> +#include <security/intel/txt/txt_register.h> + +static bool get_vtd_bar(struct device *dev, uint64_t *base, uint64_t *size) +{ + struct sa_server_mem_map_descriptor vtd_bar_descriptor = { + .reg_offset = VTBAR, + .is_64_bit = true, + .alignment = 4 * KiB, /* Bit(0) is VT-d enable bit. */ + }; + + if (!(pci_read_config32(dev, VTBAR) & VTD_CHIPSET_BASE_ADDRESS_ENABLE)) + return false; + + *base = sa_server_read_map_entry(PCI_BDF(dev), &vtd_bar_descriptor); + *size = 4 * KiB; + return true; +} + +static bool get_pcie_mmcfg_bar(struct device *dev, uint64_t *base, uint64_t *size) +{ + /* The PCIe MMCFG limit in registers is not correct thus using the configuration value here. */ + *base = CONFIG_ECAM_MMCONF_BASE_ADDRESS; + *size = CONFIG_ECAM_MMCONF_LENGTH; + return true; +} + +static bool get_dpr(struct device *dev, uint64_t *base, uint64_t *size) +{ + union dpr_register dpr = { .raw = pci_read_config32(dev, DPR) }; + *size = dpr.size * MiB; + /* DPR base is read as 0s so it is calculated based on the assumption that DPR is below TSEG. */ + *base = sa_server_get_tseg_base() - *size; + return true; +} + +static bool get_tseg(struct device *dev, uint64_t *base, uint64_t *size) +{ + *base = sa_server_get_tseg_base(); + *size = sa_server_get_tseg_size(); + return true; +} + +void sa_server_soc_add_fixed_mmio_resources(struct device *dev, int *resource_cnt) +{ + struct sa_server_mmio_descriptor vtd_descriptor = { + .get_resource = get_vtd_bar, + .description = "VT-d BAR", + }; + + sa_server_add_mmio_resources(dev, resource_cnt, &vtd_descriptor, 1); + + if (!sa_server_is_on_pch_domain(dev)) + return; + + struct sa_server_mmio_descriptor mmio_descriptors[] = { + { + .get_resource = get_pcie_mmcfg_bar, + .description = "PCIe MMCFG BAR", + }, + { + .get_resource = get_dpr, + .description = "DMA Protection Range", + }, + { + .get_resource = get_tseg, + .description = "TSEG", + }, + { + .base = RESERVED_BASE_ADDRESS, + .size = RESERVED_BASE_SIZE, + .description = "PCH Reserved", + }, + { + .base = IO_APIC_ADDR, + .size = 1 * MiB, + .description = "I/O APIC", + }, + { + .base = HPET_BASE_ADDRESS, + .size = 1 * MiB, + .description = "HPET/TXT/TPM", + }, + { + .base = LAPIC_DEFAULT_BASE, + .size = 2 * MiB, + .description = "Local APIC", + }, + }; + + sa_server_add_mmio_resources(dev, resource_cnt, mmio_descriptors, + ARRAY_SIZE(mmio_descriptors)); +} |