yuchi.chen@intel.com has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/83321?usp=email )
Change subject: src/soc/intel/snowridge: add support for Intel Atom Snow Ridge SoC ......................................................................
src/soc/intel/snowridge: add support for Intel Atom Snow Ridge SoC
Change-Id: I32ad836dfaaff0d1816eac41e5a7d19ece11080f Signed-off-by: Yuchi Chen yuchi.chen@intel.com --- A src/soc/intel/snowridge/COPYING-NOTICE A src/soc/intel/snowridge/Kconfig A src/soc/intel/snowridge/Makefile.mk A src/soc/intel/snowridge/acpi.c A src/soc/intel/snowridge/acpi/hostbridges.asl A src/soc/intel/snowridge/acpi/ith.asl A src/soc/intel/snowridge/acpi/lpc.asl A src/soc/intel/snowridge/acpi/pch_irqs.asl A src/soc/intel/snowridge/acpi/pci_irqs.asl A src/soc/intel/snowridge/acpi/pcie.asl A src/soc/intel/snowridge/acpi/pcie_port.asl A src/soc/intel/snowridge/acpi/pmc.asl A src/soc/intel/snowridge/acpi/sata0.asl A src/soc/intel/snowridge/acpi/sata2.asl A src/soc/intel/snowridge/acpi/sleepstates.asl A src/soc/intel/snowridge/acpi/smbus.asl A src/soc/intel/snowridge/acpi/southcluster.asl A src/soc/intel/snowridge/acpi/uncore.asl A src/soc/intel/snowridge/bootblock/bootblock.c A src/soc/intel/snowridge/bootblock/bootblock.h A src/soc/intel/snowridge/bootblock/early_uart_init.c A src/soc/intel/snowridge/chip.c A src/soc/intel/snowridge/chip.h A src/soc/intel/snowridge/common/fsp_hob.c A src/soc/intel/snowridge/common/fsp_hob.h A src/soc/intel/snowridge/common/gpio.c A src/soc/intel/snowridge/common/hob_display.c A src/soc/intel/snowridge/common/kti_cache.c A src/soc/intel/snowridge/common/kti_cache.h A src/soc/intel/snowridge/common/pmclib.c A src/soc/intel/snowridge/common/reset.c A src/soc/intel/snowridge/common/spi.c A src/soc/intel/snowridge/common/uart8250mem.c A src/soc/intel/snowridge/common/uart8250mem.h A src/soc/intel/snowridge/common/upd_display.c A src/soc/intel/snowridge/cpu.c A src/soc/intel/snowridge/finalize.c A src/soc/intel/snowridge/heci.c A src/soc/intel/snowridge/hob_iiouds.h A src/soc/intel/snowridge/hqm.c A src/soc/intel/snowridge/include/soc/acpi.h A src/soc/intel/snowridge/include/soc/cpu.h A src/soc/intel/snowridge/include/soc/gpio.h A src/soc/intel/snowridge/include/soc/gpio_defs.h A src/soc/intel/snowridge/include/soc/gpio_snr.h A src/soc/intel/snowridge/include/soc/gpmr.h A src/soc/intel/snowridge/include/soc/iomap.h A src/soc/intel/snowridge/include/soc/irq.h A src/soc/intel/snowridge/include/soc/itss.h A src/soc/intel/snowridge/include/soc/lpc.h A src/soc/intel/snowridge/include/soc/msr.h A src/soc/intel/snowridge/include/soc/nvs.h A src/soc/intel/snowridge/include/soc/p2sb.h A src/soc/intel/snowridge/include/soc/pci_devs.h A src/soc/intel/snowridge/include/soc/pci_ids.h A src/soc/intel/snowridge/include/soc/pcr_ids.h A src/soc/intel/snowridge/include/soc/pm.h A src/soc/intel/snowridge/include/soc/pmc.h A src/soc/intel/snowridge/include/soc/sata.h A src/soc/intel/snowridge/include/soc/smbus.h A src/soc/intel/snowridge/include/soc/soc_chip.h A src/soc/intel/snowridge/include/soc/systemagent.h A src/soc/intel/snowridge/lockdown.c A src/soc/intel/snowridge/lpc.c A src/soc/intel/snowridge/memmap.c A src/soc/intel/snowridge/nis.c A src/soc/intel/snowridge/qat.c A src/soc/intel/snowridge/ramstage.h A src/soc/intel/snowridge/romstage/gpio_snr.c A src/soc/intel/snowridge/romstage/romstage.c A src/soc/intel/snowridge/sata.c A src/soc/intel/snowridge/smihandler.c A src/soc/intel/snowridge/sriov.c A src/soc/intel/snowridge/systemagent.c 74 files changed, 5,895 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/21/83321/1
diff --git a/src/soc/intel/snowridge/COPYING-NOTICE b/src/soc/intel/snowridge/COPYING-NOTICE new file mode 100644 index 0000000..0e1018c --- /dev/null +++ b/src/soc/intel/snowridge/COPYING-NOTICE @@ -0,0 +1,16 @@ +NOTICE + +This software specifically enables pre-production +hardware provided by Intel Corporation. The terms +describing your rights and responsibilities to use +such hardware are covered by a separate evaluation +agreement. Of specific note in that agreement is +the requirement that you do not release or publish +information on the hardware without the specific +written authorization of Intel Corporation. + +Intel Corporation requests that you do not +release, publish, or distribute this software +until you are specifically authorized. These +terms are deleted upon publication of this +software. diff --git a/src/soc/intel/snowridge/Kconfig b/src/soc/intel/snowridge/Kconfig new file mode 100644 index 0000000..66d5dbf --- /dev/null +++ b/src/soc/intel/snowridge/Kconfig @@ -0,0 +1,282 @@ +## 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 NO_UART_ON_SUPERIO + 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 + + ## Security + select BOOTMEDIA_SMM_BWP + + ## 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 HAVE_SPECIFIC_GPMR + select SOC_INTEL_COMMON_BLOCK_IMC + 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_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_SA + select TOUUD_LIMIT + select TOLUD_LIMIT + select HAVE_TSEG_LIMIT_REGISTER + 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 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 + default 0x40000 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 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 + +config HAVE_PAM0_REGISTER + default n + +config HAVE_CAPID_A_REGISTER + default n + +config TOUUD_ALIGNMENT + default 0x4000000 + +config TOLUD_ALIGNMENT + default 0x4000000 + +config HAVE_BDSM_BGSM_REGISTER + default n + +config HAVE_MULTIPLE_DOMAINS + default y + +## 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 + 0xfe00000. 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 + +config UNDEFINED_REGISTER + int + default 0 + help + To reuse intel common blocks, some undefined registers should be defined. + +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 0000000..588ab8b --- /dev/null +++ b/src/soc/intel/snowridge/Makefile.mk @@ -0,0 +1,58 @@ +## 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_DRIVERS_UART_8250MEM) += 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_PLATFORM_USES_FSP2_0) += common/reset.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_PLATFORM_USES_FSP2_0) += common/reset.c +ramstage-$(CONFIG_PCI) += heci.c +ramstage-$(CONFIG_PCI) += hqm.c +ramstage-$(CONFIG_PCI) += lpc.c +ramstage-$(CONFIG_PCI) += nis.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 memmap.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += cpu.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown.c + +smm-$(CONFIG_ARCH_RAMSTAGE_X86_32) += smihandler.c +smm-$(CONFIG_DRIVERS_UART_8250MEM) += 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_FSP_SNOWRIDGE diff --git a/src/soc/intel/snowridge/acpi.c b/src/soc/intel/snowridge/acpi.c new file mode 100644 index 0000000..84494c0 --- /dev/null +++ b/src/soc/intel/snowridge/acpi.c @@ -0,0 +1,464 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpi.h> +#include <acpi/acpigen.h> +#include <arch/hpet.h> +#include <arch/ioapic.h> +#include <arch/mmio.h> +#include <assert.h> +#include <cbmem.h> +#include <commonlib/bsd/cbmem_id.h> +#include <commonlib/bsd/helpers.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci_ops.h> +#include <device/pci_type.h> +#include <intelblocks/acpi.h> +#include <intelblocks/p2sb.h> +#include <intelblocks/systemagent.h> +#include <soc/acpi.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/pmc.h> +#include <soc/soc_chip.h> +#include <soc/systemagent.h> +#include <stdio.h> +#include <string.h> + +#include "common/fsp_hob.h" +#include "hob_iiouds.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; + else + return MP_IRQ_POLARITY_HIGH; +} + +const char *soc_acpi_name(const struct device *dev) +{ + if (dev->path.type == DEVICE_PATH_DOMAIN) + return "PCI0"; + + if (dev->path.type != DEVICE_PATH_PCI) + return NULL; + + switch (dev->path.pci.devfn) { + case SA_DEVFN_ROOT: + return "MCHC"; + case PCH_DEVFN_UART(0): + return "UAR0"; + case PCH_DEVFN_UART(1): + return "UAR1"; + case PCH_DEVFN_UART(2): + return "UAR2"; + case PCH_DEVFN_LPC: + return "LPCB"; + case PCH_DEVFN_P2SB: + return "P2SB"; + case PCH_DEVFN_PMC: + return "PMC_"; + case PCH_DEVFN_SPI: + return "FSPI"; + } + + return NULL; +} + +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 uncore_fill_ssdt(void) +{ + int domain; + struct device *dev; + config_t *cfg = config_of_soc(); + char sta_name[16], res_name[16], bbn_name[16]; + uint8_t enabled; + + acpigen_write_scope("\_SB"); /* _SB */ + + for (domain = 0; domain < MAX_DOMAIN; domain++) { + printk(BIOS_SPEW, "%s Processing stack/domain %d\n", __func__, domain); + snprintf(sta_name, sizeof(sta_name), "ST%02X", domain); + snprintf(res_name, sizeof(res_name), "RT%02X", domain); + snprintf(bbn_name, sizeof(bbn_name), "BB%02X", domain); + + /** + * Write return value for domain _STA Method. + */ + dev = cfg->domain[domain].dev; + if (!dev || !dev->enabled || !cfg->domain[domain].enabled) + enabled = ACPI_STATUS_DEVICE_ALL_OFF; + else + enabled = ACPI_STATUS_DEVICE_ALL_ON; + + acpigen_write_name_byte(sta_name, enabled); + + /** + * Return value for domain _CRS Method. + */ + acpigen_write_name(res_name); + acpigen_write_resourcetemplate_header(); + + if (enabled == ACPI_STATUS_DEVICE_ALL_ON) { + if (cfg->domain[domain].bus_base <= cfg->domain[domain].bus_limit) + acpigen_resource_producer_bus_number( + cfg->domain[domain].bus_base, + cfg->domain[domain].bus_limit); + + if (cfg->domain[domain].io_base <= cfg->domain[domain].io_limit) + acpigen_resource_producer_io(cfg->domain[domain].io_base, + cfg->domain[domain].io_limit); + + if (cfg->domain[domain].mem32_base <= cfg->domain[domain].mem32_limit) + acpigen_resource_producer_mmio(cfg->domain[domain].mem32_base, + cfg->domain[domain].mem32_limit, + MEM_RSRC_FLAG_MEM_READ_WRITE); + + if (cfg->domain[domain].mem64_base <= cfg->domain[domain].mem64_limit) + acpigen_resource_producer_mmio(cfg->domain[domain].mem64_base, + cfg->domain[domain].mem64_limit, + MEM_RSRC_FLAG_MEM_READ_WRITE); + + if (domain == 0) /**< Additional resources on domain 0. */ + acpigen_resource_dword(0, 0xc, 1, 0, SPI_BASE_ADDRESS, + (SPI_BASE_ADDRESS + SPI_BASE_SIZE - 1), + 0x0, SPI_BASE_SIZE); + } + + acpigen_write_resourcetemplate_footer(); + + acpigen_write_name_byte( + bbn_name, + cfg->domain[domain] + .bus_base); /**< Return value for domain _BBN Method. */ + } + + acpigen_write_scope_end(); +} + +void southcluster_fill_ssdt(const struct device *dev) +{ + if (dev->path.type != DEVICE_PATH_DOMAIN || + dev->path.domain.domain) /**< Fill only for PCI domain 0. */ + return; + + printk(BIOS_DEBUG, "southcluster_fill_ssdt\n"); + + uncore_fill_ssdt(); +} + +unsigned long acpi_create_srat_lapics(unsigned long current) +{ + struct device *cpu; + int index; + + for (index = 0, cpu = all_devices; cpu; cpu = cpu->next, index++) { + if (!is_enabled_cpu(cpu)) { + continue; + } + + printk(BIOS_DEBUG, + "SRAT: CPU index = %d, APIC ID = 0x%02x, package ID = 0x%02x, node ID = 0x%02x, core ID = 0x%02x, thread ID = 0x%02x\n", + index, 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); + index++; + } + + return current; +} + +static unsigned long acpi_fill_srat(unsigned long current) +{ + const uint32_t low_mem_end = sa_get_tolud_base(); + const uint64_t hi_mem_end = sa_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, 1); + + 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, 1); + + return current; +} + +static unsigned long acpi_create_drhd(unsigned long current, int stack) +{ + unsigned long tmp = current; + const BL_IIO_UDS *hob = fsp_hob_get_iio_uds_data(); + const BL_IIO_RESOURCE_INSTANCE *iio_resource = hob->PlatformData.IIO_resource; + const uint32_t pcie_seg = hob->PlatformData.CpuQpiInfo[0].PcieSegment; + uint32_t bus = iio_resource->StackRes[stack].BusBase; + uint32_t reg_base = hob->PlatformData.IIO_resource[0].StackRes[stack].VtdBarAddress; + union p2sb_bdf ioapic_bdf = p2sb_get_ioapic_bdf(); + union p2sb_bdf hpet_bdf = p2sb_get_hpet_bdf(); + + if (iio_resource->StackRes[stack].Personality >= BL_TYPE_RESERVED) + return current; + + if (stack == STACK0) { + 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, reg_base); + current += acpi_create_dmar_drhd_4k(current, DRHD_INCLUDE_PCI_ALL, pcie_seg, + reg_base); + + 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); + + if (read32p(HPET_BASE_ADDRESS + 0x100) & 0x00008000) { + 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, reg_base); + current += acpi_create_dmar_drhd_4k(current, 0, pcie_seg, reg_base); + + if (stack == STACK1) { + /** + * @note `port` starts from 1 because the first device (D3,F0) doesn't exist on stack 1. + */ + for (uint8_t port = 1; port < BL_NUMBER_PORTS_PER_SOCKET; port++) { + const uint32_t dev = + iio_resource->PcieInfo.PortInfo[port].Device; + const uint32_t func = + iio_resource->PcieInfo.PortInfo[port].Function; + const struct device *device = + pcidev_path_on_bus(bus, PCI_DEVFN(dev, func)); + + if (device != NULL && + pci_read_config32(device, PCI_VENDOR_ID) != 0xffffffff) { + printk(BIOS_DEBUG, + "[PCI Sub-hierarchy] PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", + bus, dev, func); + current += acpi_create_dmar_ds_pci_br(current, bus, dev, + func); + } + } + } else if (stack == STACK2) { + bus = (iio_resource->StackRes[stack].BusBase + + iio_resource->StackRes[stack].BusLimit) / + 2; + bus += 1; + printk(BIOS_DEBUG, "Update bus to match BIOS implementations: 0x%x\n", + bus); + current += acpi_create_dmar_ds_pci(current, bus, PCI_SLOT(DLB_DEVFN), + PCI_FUNC(DLB_DEVFN)); + } else if (stack == STACK3) { + printk(BIOS_DEBUG, + "[PCI Sub-hierarchy] PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", bus, + PCI_SLOT(NIS_DEVFN), PCI_FUNC(NIS_DEVFN)); + current += acpi_create_dmar_ds_pci_br(current, bus, PCI_SLOT(NIS_DEVFN), + PCI_FUNC(NIS_DEVFN)); + } else if (stack == STACK4) { + printk(BIOS_DEBUG, + "[PCI Sub-hierarchy] PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", bus, + PCI_SLOT(QAT_1_8_DEVFN), PCI_FUNC(QAT_1_8_DEVFN)); + current += acpi_create_dmar_ds_pci_br( + current, bus, PCI_SLOT(QAT_1_8_DEVFN), PCI_FUNC(QAT_1_8_DEVFN)); + } + + if (hob->PlatformData.VMDStackEnable[0][stack]) { + printk(BIOS_DEBUG, + "[PCI Endpoint Device] Enumeration ID: 0x%x, PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", + 0, bus, PCI_SLOT(SA_DEVFN_VMD), PCI_FUNC(SA_DEVFN_VMD)); + current += acpi_create_dmar_ds_pci(current, bus, PCI_SLOT(SA_DEVFN_VMD), + PCI_FUNC(SA_DEVFN_VMD)); + } + } + + 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; + pci_devfn_t xhci_bdf = PCI_BDF(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", 0, + ptr, ptr + size - 1); + current += + acpi_create_dmar_rmrr(current, 0, (uintptr_t)ptr, (uintptr_t)(ptr + size - 1)); + + printk(BIOS_DEBUG, "[PCI Endpoint Device] PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", + PCI_DEV2BUS(xhci_bdf), PCI_SLOT(PCI_DEV2DEVFN(xhci_bdf)), + PCI_FUNC(PCI_DEV2DEVFN(xhci_bdf))); + current += acpi_create_dmar_ds_pci(current, PCI_DEV2BUS(xhci_bdf), + PCI_SLOT(PCI_DEV2DEVFN(xhci_bdf)), + PCI_FUNC(PCI_DEV2DEVFN(xhci_bdf))); + + if (current != tmp) + acpi_dmar_rmrr_fixup(tmp, current); + + return current; +} + +/** + * From secton 8.6 and section 20.5 of document 575160, only CPU PCIe root ports + * on stack 1 support address translation services (ATS). + */ +static unsigned long acpi_create_atsr(unsigned long current) +{ + const BL_IIO_UDS *hob = fsp_hob_get_iio_uds_data(); + const BL_IIO_RESOURCE_INSTANCE *iio_resource = hob->PlatformData.IIO_resource; + const uint32_t pcie_seg = hob->PlatformData.CpuQpiInfo[0].PcieSegment; + unsigned long tmp = current; + bool first = true; + uint32_t vtd_base, bus; + uint64_t vtd_mmio_cap; + + vtd_base = iio_resource->StackRes[STACK1].VtdBarAddress; + if (vtd_base == 0) + return current; + + vtd_mmio_cap = read64((void *)(vtd_base + VTD_ECAP)); + if ((vtd_mmio_cap & BIT(2)) == 0) + return current; + + printk(BIOS_DEBUG, "STACK1 vtd_base: 0x%x, vtd_mmio_cap: 0x%llx\n", vtd_base, + vtd_mmio_cap); + + bus = iio_resource->StackRes[STACK1].BusBase; + + /** + * @note `port` starts from 1. + */ + for (uint8_t port = 1; port < BL_NUMBER_PORTS_PER_SOCKET; port++) { + const uint32_t dev = iio_resource->PcieInfo.PortInfo[port].Device; + const uint32_t func = iio_resource->PcieInfo.PortInfo[port].Function; + + if (pci_s_read_config32(PCI_DEV(bus, dev, func), PCI_VENDOR_ID) == 0xffffffff) + continue; + + if (first) { + 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] PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n", + bus, dev, func); + current += acpi_create_dmar_ds_pci_br(current, bus, dev, func); + } + + if (tmp != current) + acpi_dmar_atsr_fixup(tmp, current); + + return current; +} + +static unsigned long acpi_fill_dmar(unsigned long current) +{ + for (int stack = STACK1; stack <= STACK4; ++stack) + current = acpi_create_drhd(current, stack); + current = acpi_create_drhd(current, STACK0); + + current = acpi_create_rmrr(current); + current = acpi_create_atsr(current); + + 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; + + if (dev->upstream->secondary) /**< Write only for system agent in the first domain 0. */ + 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; + + /* Create DMAR table only if virtualization is enabled */ + if ((pci_read_config32(dev, VTBAR) & VTD_CHIPSET_BASE_ADDRESS_ENABLE)) { + 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/hostbridges.asl b/src/soc/intel/snowridge/acpi/hostbridges.asl new file mode 100644 index 0000000..346f189 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/hostbridges.asl @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define PCI_HOST_BRIDGE_OSC_UUID "33db4d5b-1ff7-401c-9657-7441c03dd766" + +#define MAKE_PCI_HOST_BRIDGE_DEV(id) \ + External (ST##id, IntObj) \ + External (BB##id, IntObj) \ + External (RT##id, PkgObj) \ + Device (PC##id) \ + { \ + Name (_HID, EisaId ("PNP0A08")) /**< PCI Express Bus */ \ + Name (_CID, EisaId ("PNP0A03")) /**< PCI Bus */ \ + Name (_UID, 0x##id) \ + Method (_STA) \ + { \ + Return (^^ST##id) \ + } \ + Method (_BBN) \ + { \ + Return (^^BB##id) \ + } \ + Method (_PXM) \ + { \ + Return (0) \ + } \ + Method (_SEG) \ + { \ + Return (0) \ + } \ + Method (_CRS) \ + { \ + Return (^^RT##id) \ + } \ + Method (_PRT, 0, NotSerialized) \ + { \ + If (PICM) \ + { \ + Return (^^AR##id) \ + } \ + Else \ + { \ + Return (^^PR##id) \ + } \ + } \ + Method (_OSC, 4) \ + { \ + If (Arg0 != ToUUID (PCI_HOST_BRIDGE_OSC_UUID)) \ + { \ + CreateDWordField (Arg3, 0, DW1) \ + DW1 |= 4 /* Unrecognized UUID */ \ + } \ + Return (Arg3) \ + } \ + } + +MAKE_PCI_HOST_BRIDGE_DEV(00) /**< Base Root Bus. */ +MAKE_PCI_HOST_BRIDGE_DEV(01) /**< Stack 1 RB. */ +MAKE_PCI_HOST_BRIDGE_DEV(02) /**< Stack 2 RB. */ +MAKE_PCI_HOST_BRIDGE_DEV(03) /**< Stack 3 RB. */ +MAKE_PCI_HOST_BRIDGE_DEV(04) /**< Stack 4 RB. */ +MAKE_PCI_HOST_BRIDGE_DEV(07) /**< Uncore 0 RB. */ +MAKE_PCI_HOST_BRIDGE_DEV(08) /**< Uncore 1 RB. */ +MAKE_PCI_HOST_BRIDGE_DEV(09) /**< Additional RB for Stack 2. */ diff --git a/src/soc/intel/snowridge/acpi/ith.asl b/src/soc/intel/snowridge/acpi/ith.asl new file mode 100644 index 0000000..0954935 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/ith.asl @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (ITH0) +{ + Name (_ADR, 0x001f0007) + + Method (_STA, 0, NotSerialized) + { + Return (0x0B) + } +} diff --git a/src/soc/intel/snowridge/acpi/lpc.asl b/src/soc/intel/snowridge/acpi/lpc.asl new file mode 100644 index 0000000..2a3a4233 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/lpc.asl @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/hpet.h> + +Device (LPCB) +{ + Name (_ADR, 0x001f0000) + + OperationRegion (LPC0, PCI_Config, 0x00, 0x100) + Field (LPC0, AnyAcc, NoLock, Preserve) + { + Offset (0x80), // IO Decode Ranges + IOD0, 8, + IOD1, 8, + } + + Device (DMAC) + { + Name (_HID, EisaId ("PNP0200")) /**< PC-class DMA Controller. */ + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x0000, 0x0000, 0x00, 0x10) + IO (Decode16, 0x0081, 0x0081, 0x00, 0x03) + IO (Decode16, 0x0087, 0x0087, 0x00, 0x01) + IO (Decode16, 0x0089, 0x0089, 0x00, 0x03) + IO (Decode16, 0x008F, 0x008F, 0x00, 0x01) + IO (Decode16, 0x00C0, 0x00C0, 0x00, 0x20) + DMA (Compatibility, NotBusMaster, Transfer8) + { + 4 + } + }) + } + + Device (APIC) // IO APIC + { + Name (_HID, EISAID ("PNP0003")) + Name (_CRS, ResourceTemplate() + { + Memory32Fixed (ReadOnly, 0xFEC00000, 0x00100000) + }) + } + + Device (HPET) + { + Name (_HID, EISAID ("PNP0103")) + Name (_CID, 0x010CD041) + + Method (_STA, 0) + { + Return (0xF) + } + + Name (_CRS, ResourceTemplate() + { + Memory32Fixed(ReadOnly, HPET_BASE_ADDRESS, 0x400) + }) + } + + Device (PIC) // 8259 Interrupt Controller + { + Name (_HID,EISAID ("PNP0000")) + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x20, 0x20, 0x01, 0x02) + IO (Decode16, 0x24, 0x24, 0x01, 0x02) + IO (Decode16, 0x28, 0x28, 0x01, 0x02) + IO (Decode16, 0x2c, 0x2c, 0x01, 0x02) + IO (Decode16, 0x30, 0x30, 0x01, 0x02) + IO (Decode16, 0x34, 0x34, 0x01, 0x02) + IO (Decode16, 0x38, 0x38, 0x01, 0x02) + IO (Decode16, 0x3c, 0x3c, 0x01, 0x02) + IO (Decode16, 0xa0, 0xa0, 0x01, 0x02) + IO (Decode16, 0xa4, 0xa4, 0x01, 0x02) + IO (Decode16, 0xa8, 0xa8, 0x01, 0x02) + IO (Decode16, 0xac, 0xac, 0x01, 0x02) + IO (Decode16, 0xb0, 0xb0, 0x01, 0x02) + IO (Decode16, 0xb4, 0xb4, 0x01, 0x02) + IO (Decode16, 0xb8, 0xb8, 0x01, 0x02) + IO (Decode16, 0xbc, 0xbc, 0x01, 0x02) + IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02) + IRQNoFlags () { 2 } + }) + } + + Device (LDRC) // LPC Device Resource consumption + { + Name (_HID, EisaId ("PNP0C02")) /**< PNP Motherboard Resources. */ + Name (_CRS, ResourceTemplate () + { + // TPM/TXT area + Memory32Fixed (ReadWrite, 0xFED12000, 0x00000010) + Memory32Fixed (ReadWrite, 0xFED12010, 0x00000010) + Memory32Fixed (ReadOnly, 0xFED1B000, 0x00001000) + Memory32Fixed (ReadOnly, 0xFED1C000, 0x00024000) + Memory32Fixed (ReadOnly, 0xFED45000, 0x00047000) + // BIOS flash + Memory32Fixed (ReadOnly, 0xFF000000, 0x01000000) + // Local APIC + Memory32Fixed (ReadOnly, 0xFEE00000, 0x00100000) + }) + } + + Device (RTC) // Real Time Clock + { + Name (_HID, EISAID ("PNP0B00")) + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x70, 0x70, 1, 8) + }) + } + + Device (TIMR) // Intel 8254 timer + { + Name(_HID, EISAID ("PNP0100")) + Name(_CRS, ResourceTemplate() + { + IO (Decode16, 0x40, 0x40, 0x01, 0x04) + IO (Decode16, 0x50, 0x50, 0x10, 0x04) + IRQNoFlags() + { + 0 + } + }) + } + + Device (IUR1) // Internal UART 1 + { + Name(_HID, EISAID ("PNP0501")) + + Name(_UID, 1) + + Method (_STA, 0, Serialized) + { + Return (0x000F) + } + + Method (_CRS, 0, Serialized) + { + Name (BUF0,ResourceTemplate() + { + IO (Decode16, 0x03F8, 0x03F8, 0x01, 0x08) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared) + { + 16 + } + }) + + Return (BUF0) + } + } + + Device (IUR2) // Internal UART 2 + { + Name (_HID, EISAID ("PNP0501")) + Name (_UID, 2) + + Method (_STA, 0, Serialized) + { + Return (0x000F) + } + + Method (_CRS, 0, Serialized) + { + Name (BUF0, ResourceTemplate() + { + IO (Decode16,0x02F8,0x02F8,0x01,0x08) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared) + { + 17 + } + }) + Return (BUF0) + } + } + + Device (IUR3) // Internal UART 3 + { + Name (_HID, EISAID ("PNP0501")) + Name (_UID,3) + + Method (_STA,0,Serialized) + { + Return (0x000F) + } + + Method (_CRS,0,Serialized) + { + Name (BUF0, ResourceTemplate() + { + IO (Decode16, 0x03E8, 0x03E8, 0x01, 0x08) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared) + { + 18 + } + }) + Return (BUF0) + } + } + +#ifdef ENABLE_TPM + Device (TPM) // Trusted Platform Module + { + Name (_HID, EISAID ("IFX0102")) + Name (_CID, 0x310cd041) + Name (_UID, 1) + + Method (_STA, 0) + { + If (TPMP) + { + Return (0xf) + } + Else + { + Return (0x0) + } + } + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x2e, 0x2e, 0x01, 0x02) + IO (Decode16, 0x6f0, 0x6f0, 0x01, 0x10) + Memory32Fixed (ReadWrite, 0xfed40000, 0x5000) + IRQ (Edge, Activehigh, Exclusive) + { + 6 + } + }) + } +#endif +} diff --git a/src/soc/intel/snowridge/acpi/pch_irqs.asl b/src/soc/intel/snowridge/acpi/pch_irqs.asl new file mode 100644 index 0000000..391c866 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/pch_irqs.asl @@ -0,0 +1,236 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * PCH devices PCI interrupt routing packages. + * + * See ACPI spec 6.2.13 _PRT (PCI routing table) for details. + * The mapping fields ae Address, Pin, Source, Source Index. + */ + +// External empty package object +External (EMPT, PkgObj) + +Name (PR00, Package () +{ + Package () { 0x0000FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0000FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0000FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0000FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x0001FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0001FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0001FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0001FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x0002FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0002FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0002FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0002FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x0006FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0007FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0009FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0009FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0009FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0009FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x000AFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x000AFFFF, 0x01, LNKB, 0x00 }, + Package () { 0x000AFFFF, 0x02, LNKC, 0x00 }, + Package () { 0x000AFFFF, 0x03, LNKD, 0x00 }, + Package () { 0x000BFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x000BFFFF, 0x01, LNKB, 0x00 }, + Package () { 0x000BFFFF, 0x02, LNKC, 0x00 }, + Package () { 0x000BFFFF, 0x03, LNKD, 0x00 }, + Package () { 0x000CFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x000CFFFF, 0x01, LNKB, 0x00 }, + Package () { 0x000CFFFF, 0x02, LNKC, 0x00 }, + Package () { 0x000CFFFF, 0x03, LNKD, 0x00 }, + Package () { 0x000EFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x000FFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0014FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0014FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0014FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0014FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x0015FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0015FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0015FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0015FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x0016FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0016FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0016FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0016FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x0017FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0017FFFF, 0x01, LNKB, 0x00 }, + Package () { 0x0017FFFF, 0x02, LNKC, 0x00 }, + Package () { 0x0017FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x0018FFFF, 0x00, LNKA, 0x00 }, + Package () { 0x0018FFFF, 0x03, LNKD, 0x00 }, + Package () { 0x001AFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x001AFFFF, 0x01, LNKB, 0x00 }, + Package () { 0x001AFFFF, 0x02, LNKC, 0x00 }, + Package () { 0x001BFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x001BFFFF, 0x01, LNKB, 0x00 }, + Package () { 0x001BFFFF, 0x02, LNKC, 0x00 }, + Package () { 0x001BFFFF, 0x03, LNKD, 0x00 }, + Package () { 0x001CFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x001EFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x001FFFFF, 0x00, LNKA, 0x00 }, + Package () { 0x001FFFFF, 0x01, LNKB, 0x00 }, + Package () { 0x001FFFFF, 0x02, LNKC, 0x00 }, + Package () { 0x001FFFFF, 0x03, LNKD, 0x00 } +}) + +Alias (EMPT, PR01) +Alias (EMPT, PR02) +Alias (EMPT, PR03) +Alias (EMPT, PR04) +Alias (EMPT, PR07) +Alias (EMPT, PR08) +Alias (EMPT, PR09) + +Name (AR00, Package () +{ + Package () { 0x0000FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0000FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0000FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0000FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x0001FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0001FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0001FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0001FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x0002FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0002FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0002FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0002FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x0006FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0007FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0009FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0009FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0009FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0009FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x000AFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000AFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x000AFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x000AFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x000BFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000BFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x000BFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x000BFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x000CFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000CFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x000CFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x000CFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x000EFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000FFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0014FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0014FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0014FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0014FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x0015FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0015FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0015FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0015FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x0016FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0016FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0016FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0016FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x0017FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0017FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0017FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0017FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x0018FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0018FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x001AFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001AFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x001AFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x001BFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001BFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x001BFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x001BFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x001CFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001EFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001FFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001FFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x001FFFFF, 0x02, 0x00, 0x16 }, + Package () { 0x001FFFFF, 0x03, 0x00, 0x17 } +}) + +Name (AR01, Package() +{ + Package() { 0x0004FFFF, 0x00, 0x00, 0x10 }, + Package() { 0x0004FFFF, 0x01, 0x00, 0x11 }, + Package() { 0x0004FFFF, 0x02, 0x00, 0x12 }, + Package() { 0x0004FFFF, 0x03, 0x00, 0x13 }, + Package() { 0x0005FFFF, 0x00, 0x00, 0x10 }, + Package() { 0x0005FFFF, 0x01, 0x00, 0x11 }, + Package() { 0x0005FFFF, 0x02, 0x00, 0x12 }, + Package() { 0x0005FFFF, 0x03, 0x00, 0x13 }, + Package() { 0x0006FFFF, 0x00, 0x00, 0x10 }, + Package() { 0x0006FFFF, 0x01, 0x00, 0x11 }, + Package() { 0x0006FFFF, 0x02, 0x00, 0x12 }, + Package() { 0x0006FFFF, 0x03, 0x00, 0x13 }, + Package() { 0x0007FFFF, 0x00, 0x00, 0x10 }, + Package() { 0x0007FFFF, 0x01, 0x00, 0x11 }, + Package() { 0x0007FFFF, 0x02, 0x00, 0x12 }, + Package() { 0x0007FFFF, 0x03, 0x00, 0x13 } +}) + +Alias (EMPT, AR02) + +Name (AR03, Package() +{ + Package () { 0x0004FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0004FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0004FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0004FFFF, 0x03, 0x00, 0x13 } +}) + +Name (AR04, Package() +{ + Package () { 0x0005FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0005FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0005FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0005FFFF, 0x03, 0x00, 0x13 } +}) + +Name (AR07, Package() +{ + Package () { 0x0000FFFF, 0x00, 0x00, 0x10 }, + Package () { 0x0000FFFF, 0x01, 0x00, 0x11 }, + Package () { 0x0000FFFF, 0x02, 0x00, 0x12 }, + Package () { 0x0000FFFF, 0x03, 0x00, 0x13 }, + Package () { 0x000BFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000BFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x000BFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x000BFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x000CFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000CFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x000CFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x000CFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x000DFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000DFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x000DFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x000DFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x001AFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001AFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x001AFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x001AFFFF, 0x03, 0x00, 0x13 } +}) + +Name (AR08, Package() +{ + Package () { 0x000AFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x000AFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x000AFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x000AFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x001DFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001DFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x001DFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x001DFFFF, 0x03, 0x00, 0x13 }, + Package () { 0x001EFFFF, 0x00, 0x00, 0x10 }, + Package () { 0x001EFFFF, 0x01, 0x00, 0x11 }, + Package () { 0x001EFFFF, 0x02, 0x00, 0x12 }, + Package () { 0x001EFFFF, 0x03, 0x00, 0x13 } +}) + +Name (AR09, Package() +{ + Package () { 0x0000FFFF, 0x00, 0x00, 0x10 } +}) diff --git a/src/soc/intel/snowridge/acpi/pci_irqs.asl b/src/soc/intel/snowridge/acpi/pci_irqs.asl new file mode 100644 index 0000000..d35b1aa --- /dev/null +++ b/src/soc/intel/snowridge/acpi/pci_irqs.asl @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define MAKE_LINK_DEV(id, uid) \ + Device (LNK##id) \ + { \ + Name (_HID, EISAID ("PNP0C0F")) \ + Name (_UID, ##uid) \ + Method (_PRS, 0, NotSerialized) \ + { \ + Return (PRS##id) \ + } \ + Method (_CRS, 0, Serialized) \ + { \ + Name (RTL##id, ResourceTemplate () \ + { \ + IRQ (Level, ActiveLow, Shared) {} \ + }) \ + CreateWordField (RTL##id, 1, IRQ0) \ + ShiftLeft (1, And(^^PRC##id, ^^IREM), IRQ0) \ + Return (RTL##id) \ + } \ + Method (_SRS, 1, Serialized) \ + { \ + CreateWordField (Arg0, 1, IRQ0) \ + FindSetRightBit (IRQ0, Local0) \ + Decrement (Local0) \ + Store (Local0, ^^PRC##id) \ + } \ + Method (_STA, 0, Serialized) \ + { \ + If (And (^^PRC##id, ^^IREN)) \ + { \ + Return (0x9) \ + } \ + Else \ + { \ + Return (0xb) \ + } \ + } \ + Method (_DIS, 0, Serialized) \ + { \ + Or(^^IREN, PRC##id, PRC##id) \ + } \ + } + +OperationRegion (ITSS, SystemMemory, + CONFIG_PCR_BASE_ADDRESS + (PID_ITSS << PCR_PORTID_SHIFT) + PCR_ITSS_PIRQA_ROUT, 8) +Field (ITSS, ByteAcc, NoLock, Preserve) +{ + /** + * According to P2SB document, PIRQA Routing Control should be abbreviated + * to PARC, however, PERC is already defined for PCI ECAM Resource Consumption + * in dsdt_top.asl. + */ + PRCA, 8, + PRCB, 8, + PRCC, 8, + PRCD, 8, + PRCE, 8, + PRCF, 8, + PRCG, 8, + PRCH, 8 +} + +Name (IREN, 0x80) /**< Interrupt Routing Enable. */ +Name (IREM, 0x0f) /**< Interrupt Routing Mask. */ + +Name (PRSA, ResourceTemplate () /**< Possible resource settings for A. */ +{ + IRQ (Level, ActiveLow, Shared) + { + 3, + 4, + 5, + 6, + 7, + 10, + 11, + 12, + 14, + 15 + } +}) + +Alias (PRSA, PRSB) +Alias (PRSA, PRSC) +Alias (PRSA, PRSD) +Alias (PRSA, PRSE) +Alias (PRSA, PRSF) +Alias (PRSA, PRSG) +Alias (PRSA, PRSH) + +MAKE_LINK_DEV(A, 1) +MAKE_LINK_DEV(B, 2) +MAKE_LINK_DEV(C, 3) +MAKE_LINK_DEV(D, 4) +MAKE_LINK_DEV(E, 5) +MAKE_LINK_DEV(F, 6) +MAKE_LINK_DEV(G, 7) +MAKE_LINK_DEV(H, 8) diff --git a/src/soc/intel/snowridge/acpi/pcie.asl b/src/soc/intel/snowridge/acpi/pcie.asl new file mode 100644 index 0000000..5c00d00 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/pcie.asl @@ -0,0 +1,278 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Method (IRQM, 1, Serialized) +{ + /* Interrupt Map INTA->INTA, INTB->INTB, INTC->INTC, INTD->INTD */ + Name (IQAA, Package() { + Package() { 0x0000ffff, 0, 0, 16 }, + Package() { 0x0000ffff, 1, 0, 17 }, + Package() { 0x0000ffff, 2, 0, 18 }, + Package() { 0x0000ffff, 3, 0, 19 } }) + Name (IQAP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKA, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKB, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKC, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKD, 0 } }) + + /* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */ + Name (IQBA, Package() { + Package() { 0x0000ffff, 0, 0, 17 }, + Package() { 0x0000ffff, 1, 0, 18 }, + Package() { 0x0000ffff, 2, 0, 19 }, + Package() { 0x0000ffff, 3, 0, 16 } }) + Name (IQBP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKB, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKC, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKD, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKA, 0 } }) + + /* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */ + Name (IQCA, Package() { + Package() { 0x0000ffff, 0, 0, 18 }, + Package() { 0x0000ffff, 1, 0, 19 }, + Package() { 0x0000ffff, 2, 0, 16 }, + Package() { 0x0000ffff, 3, 0, 17 } }) + Name (IQCP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKC, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKD, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKA, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKB, 0 } }) + + /* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */ + Name (IQDA, Package() { + Package() { 0x0000ffff, 0, 0, 19 }, + Package() { 0x0000ffff, 1, 0, 16 }, + Package() { 0x0000ffff, 2, 0, 17 }, + Package() { 0x0000ffff, 3, 0, 18 } }) + Name (IQDP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKD, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKA, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKB, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKC, 0 } }) + + /* Interrupt Map INTA->INTE, INTB->INTF, INTC->INTG, INTD->INTH */ + Name (IQEA, Package() { + Package() { 0x0000ffff, 0, 0, 20 }, + Package() { 0x0000ffff, 1, 0, 21 }, + Package() { 0x0000ffff, 2, 0, 22 }, + Package() { 0x0000ffff, 3, 0, 23 } }) + Name (IQEP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKE, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKF, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKG, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKH, 0 } }) + + /* Interrupt Map INTA->INTF, INTB->INTG, INTC->INTH, INTD->INTE */ + Name (IQFA, Package() { + Package() { 0x0000ffff, 0, 0, 21 }, + Package() { 0x0000ffff, 1, 0, 22 }, + Package() { 0x0000ffff, 2, 0, 23 }, + Package() { 0x0000ffff, 3, 0, 20 } }) + Name (IQFP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKF, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKG, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKH, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKE, 0 } }) + + /* Interrupt Map INTA->INTG, INTB->INTH, INTC->INTE, INTD->INTF */ + Name (IQGA, Package() { + Package() { 0x0000ffff, 0, 0, 22 }, + Package() { 0x0000ffff, 1, 0, 23 }, + Package() { 0x0000ffff, 2, 0, 20 }, + Package() { 0x0000ffff, 3, 0, 21 } }) + Name (IQGP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKG, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKH, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKE, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKF, 0 } }) + + /* Interrupt Map INTA->INTH, INTB->INTE, INTC->INTF, INTD->INTG */ + Name (IQHA, Package() { + Package() { 0x0000ffff, 0, 0, 23 }, + Package() { 0x0000ffff, 1, 0, 20 }, + Package() { 0x0000ffff, 2, 0, 21 }, + Package() { 0x0000ffff, 3, 0, 22 } }) + Name (IQHP, Package() { + Package() { 0x0000ffff, 0, _SB.LNKH, 0 }, + Package() { 0x0000ffff, 1, _SB.LNKE, 0 }, + Package() { 0x0000ffff, 2, _SB.LNKF, 0 }, + Package() { 0x0000ffff, 3, _SB.LNKG, 0 } }) + + Switch (ToInteger (Arg0)) { + /* PCIe Root Port 1 */ + Case (Package() { 1 }) { + If (PICM) { + Return (IQAA) + } Else { + Return (IQAP) + } + } + + /* PCIe Root Port 2 */ + Case (Package() { 2 }) { + If (PICM) { + Return (IQBA) + } Else { + Return (IQBP) + } + } + + /* PCIe Root Port 3 */ + Case (Package() { 3 }) { + If (PICM) { + Return (IQCA) + } Else { + Return (IQCP) + } + } + + /* PCIe Root Port 4 */ + Case (Package() { 4 }) { + If (PICM) { + Return (IQDA) + } Else { + Return (IQDP) + } + } + + /* PCIe Root Port 5 */ + Case (Package() { 5 }) { + If (PICM) { + Return (IQEA) + } Else { + Return (IQEP) + } + } + + /* PCIe Root Port 6 */ + Case (Package() { 6 }) { + If (PICM) { + Return (IQFA) + } Else { + Return (IQFP) + } + } + + /* PCIe Root Port 7 */ + Case (Package() { 7 }) { + If (PICM) { + Return (IQGA) + } Else { + Return (IQGP) + } + } + + /* PCIe Root Port 8 */ + Case (Package() { 8 }) { + If (PICM) { + Return (IQHA) + } Else { + Return (IQHP) + } + } + + Default { + If (PICM) { + Return (IQDA) + } Else { + Return (IQDP) + } + } + } +} + +Device (RP00) +{ + Name (_ADR, 0x00090000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP01) +{ + Name (_ADR, 0x000A0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP02) +{ + Name (_ADR, 0x000B0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP03) +{ + Name (_ADR, 0x000C0000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP08) +{ + Name (_ADR, 0x00140000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP09) +{ + Name (_ADR, 0x00150000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP10) +{ + Name (_ADR, 0x00160000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP11) +{ + Name (_ADR, 0x00170000) + + #include "pcie_port.asl" + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} diff --git a/src/soc/intel/snowridge/acpi/pcie_port.asl b/src/soc/intel/snowridge/acpi/pcie_port.asl new file mode 100644 index 0000000..abc2e1e --- /dev/null +++ b/src/soc/intel/snowridge/acpi/pcie_port.asl @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/** + * This file is included in each PCIe Root Port device. + */ + +OperationRegion (RPCS, PCI_Config, 0x00, 0xFF) +Field (RPCS, AnyAcc, NoLock, Preserve) +{ + Offset (0x4c), // Link Capabilities + , 24, + RPPN, 8, // Root Port Number +} diff --git a/src/soc/intel/snowridge/acpi/pmc.asl b/src/soc/intel/snowridge/acpi/pmc.asl new file mode 100644 index 0000000..adf1b80 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/pmc.asl @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <soc/iomap.h> + +Device (PMC0) +{ + Name (_ADR, 0x001F0002) + + Device (PDRC) // PMC Device Resource Consumption + { + Name (_HID, EISAID ("PNP0C02")) + Name (_UID, 0x10) + + Name (PMCR, ResourceTemplate() + { + IO (Decode16, ACPI_BASE_ADDRESS, ACPI_BASE_ADDRESS, 0x1, 0x80) + Memory32Fixed (ReadOnly, PCH_PWRM_BASE_ADDRESS, 0x10000) + }) + + Method (_CRS, 0) + { + Return (PMCR) + } + } +} diff --git a/src/soc/intel/snowridge/acpi/sata0.asl b/src/soc/intel/snowridge/acpi/sata0.asl new file mode 100644 index 0000000..b064555 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/sata0.asl @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +// Intel SATA Controller 0:07.0 + +Device (SAT0) +{ + Name (_ADR, 0x00070000) +} diff --git a/src/soc/intel/snowridge/acpi/sata2.asl b/src/soc/intel/snowridge/acpi/sata2.asl new file mode 100644 index 0000000..76177cf --- /dev/null +++ b/src/soc/intel/snowridge/acpi/sata2.asl @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (SAT2) +{ + Name (_ADR, 0x000e0000) +} diff --git a/src/soc/intel/snowridge/acpi/sleepstates.asl b/src/soc/intel/snowridge/acpi/sleepstates.asl new file mode 100644 index 0000000..c29d43f --- /dev/null +++ b/src/soc/intel/snowridge/acpi/sleepstates.asl @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Name(_S0, Package(){0x0,0x0,0x0,0x0}) +//Name(_S1, Package(){0x1,0x1,0x0,0x0}) +Name(_S3, Package(){0x5,0x5,0x0,0x0}) +Name(_S4, Package(){0x6,0x6,0x0,0x0}) +Name(_S5, Package(){0x7,0x7,0x0,0x0}) diff --git a/src/soc/intel/snowridge/acpi/smbus.asl b/src/soc/intel/snowridge/acpi/smbus.asl new file mode 100644 index 0000000..615f9a8 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/smbus.asl @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (SMB) +{ + Name (_ADR, 0x001f0004) + +#ifdef ENABLE_SMBUS_METHODS + OperationRegion (SMBP, PCI_Config, 0x00, 0x100) + Field(SMBP, DWordAcc, NoLock, Preserve) + { + Offset(0x40), + , 2, + I2CE, 1 + } + + OperationRegion (SMBI, SystemMemory, SMBUS_IO_BASE, 0x20) + Field (SMBI, ByteAcc, NoLock, Preserve) + { + HSTS, 8, // Host Status + , 8, + HCNT, 8, // Host Control + HCMD, 8, // Host Command + TXSA, 8, // Transmit Slave Address + DAT0, 8, // Host Data 0 + DAT1, 8, // Host Data 1 + HBDB, 8, // Host Block Data Byte + PECK, 8, // Packet Error Check + RXSA, 8, // Receive Slave Address + RXDA, 16, // Receive Slave Data + AUXS, 8, // Auxiliary Status + AUXC, 8, // Auxiliary Control + SLPC, 8, // SMLink Pin Control + SBPC, 8, // SMBus Pin Control + SSTS, 8, // Slave Status + SCMD, 8, // Slave Command + NADR, 8, // Notify Device Address + NDLB, 8, // Notify Data Low Byte + NDLH, 8, // Notify Data High Byte + } + + // Kill all SMBus communication + Method (KILL, 0, Serialized) + { + Or (HCNT, 0x02, HCNT) + Or (HSTS, 0xff, HSTS) + } + + // Check if last operation completed + Method (CMPL, 0, Serialized) + { + Store (4000, Local0) + While (Local0) + { + If (And (HSTS, 0x01)) + { + Stall (50) // us + Decrement (Local0) + If (LEqual (Local0, 0)) + { + KILL() + } + } + Else + { + Return (1) + } + } + + Return (0) + } + + // Wait for SMBus to become ready + Method (SRDY, 0, Serialized) + { + Store (200, Local0) // Timeout 200ms + While (Local0) + { + If (And (HSTS, 0x40)) + { + Sleep (1) // ms + Decrement (Local0) + If (LEqual (Local0, 0)) + { + Return (0) + } + } + Else + { + Return (1) + } + } + } + + // SMBus Send Byte + // Arg0: Address + // Arg1: Data + // Return: 1 = Success, 0 = Failure + Method (SSXB, 2, Serialized) + { + If (LNot (SRDY())) + { + Return (0) + } + + Store (0, I2CE) + Store (0xbf, HSTS) + Store (Arg0, TXSA) + Store (Arg1, HCMD) + Store (0x44, HCNT) + + If (CMPL()) + { + Or (HSTS, 0xff, HSTS) + Return (1) + } + Else + { + Return (0) + } + } + + // SMBus Receive Byte + // Arg0: Address + // Return: 0xffff = Failure, Data (8bit) = Success + Method (SRXB, 1, Serialized) + { + If (LNot (SRDY())) + { + Return (0xffff) + } + + Store (0, I2CE) + Store (0xbf, HSTS) + Store (Or (Arg0, 1), TXSA) + Store (0x48, HCNT) + + If (CMPL()) + { + Or (HSTS, 0xff, HSTS) + Return (DAT0) + } + Else + { + Return (0xffff) + } + } + + // SMBus Write Byte + // Arg0: Address + // Arg1: Command + // Arg2: Data + // Return: 1 = Success, 0 = Failure + Method (SWRB, 3, Serialized) + { + If (LNot (SRDY())) + { + Return (0) + } + + Store (0, I2CE) + Store (0xbf, HSTS) + Store (Arg0, TXSA) + Store (Arg1, HCMD) + Store (Arg2, DAT0) + Store (0x48, HCNT) + + If (CMPL()) + { + Or (HSTS, 0xff, HSTS) + Return (1) + } + Else + { + Return (0) + } + } + + // SMBus Read Byte + // Arg0: Address + // Arg1: Command + // Return: 0xffff = Failure, Data (8bit) = Success + Method (SRDB, 2, Serialized) + { + If (LNot (SRDY())) + { + Return (0xffff) + } + + Store (0, I2CE) + Store (0xbf, HSTS) + Store (Or (Arg0, 1), TXSA) + Store (Arg1, HCMD) + Store (0x48, HCNT) + + If (CMPL()) + { + Or (HSTS, 0xff, HSTS) + Return (DAT0) + } + Else + { + Return (0xffff) + } + } +#endif +} diff --git a/src/soc/intel/snowridge/acpi/southcluster.asl b/src/soc/intel/snowridge/acpi/southcluster.asl new file mode 100644 index 0000000..bf8df86 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/southcluster.asl @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "pcie.asl" + +#include "sata0.asl" + +#include "sata2.asl" + +// ME HECI 1 +Device (HEC1) +{ + Name (_ADR, 0x00180000) +} + +// ME HECI 2 +Device (HEC2) +{ + Name (_ADR, 0x00180001) +} + +// UART 0 +Device (UAR0) +{ + Name (_ADR, 0x001A0000) + Name (_DDN, "HSUART 0 Controller") +} + +// UART 1 +Device (UAR1) +{ + Name (_ADR, 0x001A0001) + Name (_DDN, "HSUART 1 Controller") +} + +// UART 2 +Device (UAR2) +{ + Name (_ADR, 0x001A0002) + Name (_DDN, "HSUART 2 Controller") +} + +// eMMC +Device (EMMC) +{ + Name (_ADR, 0x001C0000) + Name (_DDN, "eMMC Controller") +} + +#include "lpc.asl" + +// P2SB +Device (P2SB) +{ + Name (_ADR, 0x001F0001) +} + +#include "pmc.asl" + +#include "smbus.asl" + +// SPI +Device (SPI) +{ + Name (_ADR, 0x001F0005) + Name (_DDN, "SPI Controller") +} + +#include "ith.asl" diff --git a/src/soc/intel/snowridge/acpi/uncore.asl b/src/soc/intel/snowridge/acpi/uncore.asl new file mode 100644 index 0000000..1db3fe0 --- /dev/null +++ b/src/soc/intel/snowridge/acpi/uncore.asl @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/itss.h> +#include <intelblocks/pcr.h> +#include "soc/pcr_ids.h" + +Scope (_SB) +{ + #include "pci_irqs.asl" + #include "pch_irqs.asl" + #include "hostbridges.asl" +} + +Scope (_SB.PC00) { + #include "southcluster.asl" +} diff --git a/src/soc/intel/snowridge/bootblock/bootblock.c b/src/soc/intel/snowridge/bootblock/bootblock.c new file mode 100644 index 0000000..d830464 --- /dev/null +++ b/src/soc/intel/snowridge/bootblock/bootblock.c @@ -0,0 +1,57 @@ +/* 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 0000000..2cc7320 --- /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 0000000..945f271 --- /dev/null +++ b/src/soc/intel/snowridge/bootblock/early_uart_init.c @@ -0,0 +1,59 @@ +/* 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_probe(uint8_t bus, uint8_t dev, uint8_t func, + uint16_t io_base) +{ + register uint16_t reg16; + register uint32_t reg32; + + reg32 = pci_read_config32(PCH_DEV_UART(func), UART_IOBA); + reg32 |= io_base; + pci_write_config32(PCH_DEV_UART(func), UART_IOBA, reg32); + + /** + * Enable memory/io space and allow to initiate a transaction as a master. + */ + reg16 = pci_read_config16(PCH_DEV_UART(func), PCI_COMMAND); + reg16 |= 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); + reg16 |= PCI_COMMAND_MEMORY; +#endif + + pci_write_config16(PCH_DEV_UART(func), PCI_COMMAND, reg16); + +#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(reg32 + UCMR_OFFSET, read32p(reg32 + 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_probe(0, CONFIG_HSUART_DEV, 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 0000000..ccb4d81 --- /dev/null +++ b/src/soc/intel/snowridge/chip.c @@ -0,0 +1,447 @@ +/* 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 <ramstage.h> +#include <soc/acpi.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(void *chip_info) +{ + int i; + config_t *cfg = chip_info; + + memset(&cfg->domain, 0, sizeof(cfg->domain)); + for (i = 0; i < MAX_DOMAIN; i++) { + cfg->domain[i].personality = BL_TYPE_NONE; + cfg->domain[i].bus_base = -1; + cfg->domain[i].io_base = -1; + cfg->domain[i].mem32_base = -1; + cfg->domain[i].mem64_base = -1; + } +} + +static void chip_domain_resource_table_load(void *chip_info) +{ + const BL_IIO_UDS *hob; + const BL_STACK_RES *sr; + int i; + config_t *cfg = chip_info; + + /** + * Only one socket is present on SNR. Check `BL_MAX_SOCKET` and `BL_MAX_LOGIC_IIO_STACK` + * defined in FspmUpd.h. + */ + assert(BL_MAX_SOCKET == 1); + assert(BL_MAX_LOGIC_IIO_STACK); + + hob = fsp_hob_get_iio_uds_data(); + if (!hob) + die("Universal data hob not found!!!\n"); + + sr = &hob->PlatformData.IIO_resource[0].StackRes[0]; + for (i = 0; i < BL_MAX_LOGIC_IIO_STACK; i++) { + cfg->domain[i].personality = sr[i].Personality; + + if (sr[i].Personality >= BL_TYPE_DISABLED) + continue; + + if (sr[i].BusBase > sr[i].BusLimit) + die("Incorrect bus base 0x%02x and limit 0x%02x for domain %d", + sr[i].BusBase, sr[i].BusLimit, i); + + cfg->domain[i].bus_base = sr[i].BusBase; + cfg->domain[i].bus_limit = sr[i].BusLimit; + + if (sr[i].Personality == BL_TYPE_RESERVED) + continue; + + cfg->domain[i].enabled = 1; + + if (sr[i].PciResourceIoBase) { + if (sr[i].PciResourceIoBase > sr[i].PciResourceIoLimit) + die("Incorrect IO base 0x%04x and limit 0x%04x for domain %d", + sr[i].PciResourceIoBase, sr[i].PciResourceIoLimit, i); + + cfg->domain[i].io_base = sr[i].PciResourceIoBase; + cfg->domain[i].io_limit = sr[i].PciResourceIoLimit; + } + + if (sr[i].PciResourceMem32Base) { + if (sr[i].PciResourceMem32Base > sr[i].PciResourceMem32Limit) + die("Incorrect Mem32 base 0x%08x and limit 0x%08x for domain %d", + sr[i].PciResourceMem32Base, sr[i].PciResourceMem32Limit, i); + + cfg->domain[i].mem32_base = sr[i].PciResourceMem32Base; + cfg->domain[i].mem32_limit = sr[i].PciResourceMem32Limit; + } + + if (sr[i].PciResourceMem64Base) { + if (sr[i].PciResourceMem64Base > sr[i].PciResourceMem64Limit) + die("Incorrect Mem64 base 0x%16llx and limit 0x%16llx for domain %d", + sr[i].PciResourceMem64Base, sr[i].PciResourceMem64Limit, i); + + cfg->domain[i].mem64_base = sr[i].PciResourceMem64Base; + cfg->domain[i].mem64_limit = sr[i].PciResourceMem64Limit; + } + } +} + +static void chip_cfg_domain_resource_table_split(config_t *cfg, int base_domain, + int addtional_domain) +{ + memcpy(&cfg->domain[addtional_domain], &cfg->domain[base_domain], + sizeof(cfg->domain[addtional_domain])); + + /** + * Base + (Limit - Base) / 2 to avoid overflow. + */ + if (cfg->domain[base_domain].bus_base < cfg->domain[base_domain].bus_limit) { + cfg->domain[base_domain].bus_limit = cfg->domain[base_domain].bus_base + + (cfg->domain[base_domain].bus_limit - + cfg->domain[base_domain].bus_base) / + 2; + cfg->domain[addtional_domain].bus_base = cfg->domain[base_domain].bus_limit + 1; + } + + if (cfg->domain[base_domain].io_base < cfg->domain[base_domain].io_limit) { + cfg->domain[base_domain].io_limit = + cfg->domain[base_domain].io_base + + (cfg->domain[base_domain].io_limit - cfg->domain[base_domain].io_base) / + 2; + cfg->domain[addtional_domain].io_base = cfg->domain[base_domain].io_limit + 1; + } + + if (cfg->domain[base_domain].mem32_base < cfg->domain[base_domain].mem32_limit) { + cfg->domain[base_domain].mem32_limit = cfg->domain[base_domain].mem32_base + + (cfg->domain[base_domain].mem32_limit - + cfg->domain[base_domain].mem32_base) / + 2; + cfg->domain[addtional_domain].mem32_base = + cfg->domain[base_domain].mem32_limit + 1; + } + + if (cfg->domain[base_domain].mem64_base < cfg->domain[base_domain].mem64_limit) { + cfg->domain[base_domain].mem64_limit = cfg->domain[base_domain].mem64_base + + (cfg->domain[base_domain].mem64_limit - + cfg->domain[base_domain].mem64_base) / + 2; + cfg->domain[addtional_domain].mem64_base = + cfg->domain[base_domain].mem64_limit + 1; + } +} + +static void chip_domain_resource_table_handle_multi_root(void *chip_info) +{ + /** + * Split domains that have more than 1 root bus. + */ + config_t *cfg = chip_info; + int addtional_domain = BL_MAX_LOGIC_IIO_STACK; + chip_cfg_domain_resource_table_split(cfg, 7, + addtional_domain++); /**< Domain 8 (Ubox1). */ + + if (cfg->domain[2].personality < BL_TYPE_DISABLED) + chip_cfg_domain_resource_table_split( + cfg, 2, addtional_domain++); /**< Domain 2 (S2) has 2 root bus.*/ +} + +static void chip_domain_resource_table_dump(void *chip_info) +{ + int i; + config_t *cfg = chip_info; + + printk(BIOS_DEBUG, + "---------------------------------------------------------------------------------------------------------------------\n" + "| Domain | Enabled | Bus Base/Limit | IO Base/Limit | Mem32 Base/Limit | Mem64 Base/Limit |\n" + "---------------------------------------------------------------------------------------------------------------------\n"); + for (i = 0; i < MAX_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, cfg->domain[i].enabled ? 'Y' : 'N', cfg->domain[i].personality, + cfg->domain[i].bus_base, cfg->domain[i].bus_limit, + cfg->domain[i].io_base, cfg->domain[i].io_limit, + cfg->domain[i].mem32_base, cfg->domain[i].mem32_limit, + cfg->domain[i].mem64_base, cfg->domain[i].mem64_limit); + } + printk(BIOS_DEBUG, + "---------------------------------------------------------------------------------------------------------------------\n"); +} + +static void chip_domain_resource_table_fill(void *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(void *chip_info) +{ + struct device *dev, *last_domain = NULL; + struct device_path new_domain = {.type = DEVICE_PATH_DOMAIN}; + int domain; + config_t *cfg = chip_info; + + /** + * Fill domain device. + */ + for (dev = all_devices; dev; dev = dev->next) { + if (dev->path.type != DEVICE_PATH_DOMAIN) + continue; + + domain = dev->path.domain.domain; + if (domain >= MAX_DOMAIN) + die("Incorrect domain[%d] in devicetree\n", domain); + + cfg->domain[domain].dev = dev; + last_domain = dev; + + printk(BIOS_SPEW, "%s -> domain[%d] defined in devicetree\n", dev_path(dev), + domain); + } + + if (!last_domain) + die("Please add at least one domain to devicetree\n"); + + if (!cfg->domain[0].dev) + die("Please add domain 0 in devicetree.cb\n"); + + for (domain = 0; domain < MAX_DOMAIN; domain++) { + if (!cfg->domain[domain].enabled) { + if (cfg->domain[domain].dev && cfg->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(cfg->domain[domain].dev, 0); + } + continue; + } + + /** + * Check if domain is defined in device tree, add it if not. + */ + if (!cfg->domain[domain].dev) { + printk(BIOS_WARNING, + "Domain[%d] is active but not defined in device tree!\n", + domain); + printk(BIOS_SPEW, "Dynamicaly adding domain[%d]\n", domain); + + new_domain.domain.domain = domain; + dev = alloc_dev( + cfg->domain[0].dev->upstream, + &new_domain); /**< Use same parent device as domain 0. */ + if (!dev) { + die("Allocate new domain device failed!\n"); + } + + last_domain->sibling = dev; + last_domain = dev; +#if !DEVTREE_EARLY + dev->chip_ops = cfg->domain[0].dev->chip_ops; +#endif + dev->chip_info = cfg->domain[0].dev->chip_info; + + cfg->domain[domain].dev = dev; + dev_set_enabled(cfg->domain[domain].dev, 1); + } + + dev = cfg->domain[domain].dev; + if (dev->enabled) { + if (!dev->downstream) + dev->downstream = alloc_bus(dev); + + printk(BIOS_SPEW, + "Domain[%d] is active - updating PCI root bus to 0x%02x\n", + domain, cfg->domain[domain].bus_base); + + dev->downstream->secondary = cfg->domain[domain].bus_base; + dev->downstream->subordinate = + cfg->domain[domain] + .bus_base; /**< Use the same bus number before PCI enumeration. */ + dev->downstream->max_subordinate = cfg->domain[domain].bus_limit; + } else { + printk(BIOS_DEBUG, + "Domain device %d is disabled in device tree, disabling it in chip.\n", + domain); + cfg->domain[domain].enabled = 0; + } + } +} + +static void soc_init_pre_device(void *chip_info) +{ + fsp_silicon_init(); + + chip_domain_resource_table_fill(chip_info); + + devicetree_domain_definition_update(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; + const config_t *cfg = dev->chip_info; + + printk(BIOS_DEBUG, "Reading resources for %s\n", dev_path(dev)); + + /** + * Allocate IO resource. + */ + if (cfg->domain[domain].io_limit >= cfg->domain[domain].io_base) { + res = new_resource(dev, IOINDEX_SUBTRACTIVE(index++, 0)); + if (!res) + die("Allocate resource for %s failed!\n", dev_path(dev)); + + res->base = cfg->domain[domain].io_base; + res->limit = cfg->domain[domain].io_limit; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + printk(BIOS_SPEW, "IO Base/Limit: 0x%04llx/0x%04llx\n", res->base, res->limit); + } + + /** + * Allocate Mem32 resource. + */ + if (cfg->domain[domain].mem32_limit >= cfg->domain[domain].mem32_base) { + res = new_resource(dev, IOINDEX_SUBTRACTIVE(index++, 0)); + if (!res) + die("Allocate resource for %s failed!\n", dev_path(dev)); + + res->base = cfg->domain[domain].mem32_base; + res->limit = cfg->domain[domain].mem32_limit; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED; + printk(BIOS_SPEW, "Mem32 Base/Limit: 0x%08llx/0x%08llx\n", res->base, + res->limit); + } + + /** + * Allocate Mem64 resource. + */ + if (cfg->domain[domain].mem64_limit >= cfg->domain[domain].mem64_base) { + res = new_resource(dev, IOINDEX_SUBTRACTIVE(index++, 0)); + if (!res) + die("Allocate resource for %s failed!\n", dev_path(dev)); + + res->base = cfg->domain[domain].mem64_base; + res->limit = cfg->domain[domain].mem64_limit; + res->size = res->limit - res->base + 1; + res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | 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)); + + if (dev->enabled) { + 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)); + + if (dev->enabled) + pci_host_bridge_scan_bus(dev); + + printk(BIOS_DEBUG, "Scanning %s done\n", dev_path(dev)); +} + +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 = southcluster_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) +{ + uint32_t reg32; + + if (!dev->enabled) { + printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev)); + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + pci_write_config32(dev, PCI_COMMAND, reg32); + } else { + reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 |= PCI_COMMAND_SERR; + pci_write_config32(dev, PCI_COMMAND, reg32); + } +} + +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) { + /* Handle south cluster enablement. */ + /** + * @todo Change the magic number. + */ + if (dev->upstream->secondary == 0 && PCI_SLOT(dev->path.pci.devfn) > 0x5 && + (dev->ops == NULL || dev->ops->enable == NULL)) { + printk(BIOS_SPEW, "Set operation for south cluster device %s\n", + dev_path(dev)); + 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 0000000..3a1744a --- /dev/null +++ b/src/soc/intel/snowridge/chip.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_CHIP_H_ +#define _SOC_SNOWRIDGE_CHIP_H_ + +#include <intelblocks/cfg.h> +#include <fsp/soc_binding.h> +#include <stdint.h> + +/** + * @brief Total number of domains. SNR needs two additional domains to handle + * additional root bus in stack 2 and 7 (UBox1). + */ +#define MAX_DOMAIN (BL_MAX_SOCKET * BL_MAX_LOGIC_IIO_STACK + 2) + +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 { + 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; + } domain[MAX_DOMAIN]; +}; + +typedef struct soc_intel_snowridge_config config_t; + +#endif // _SOC_SNOWRIDGE_CHIP_H_ 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 0000000..db7747d --- /dev/null +++ b/src/soc/intel/snowridge/common/fsp_hob.c @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <fsp/util.h> + +#include "fsp_hob.h" + +const uint8_t fsp_hob_fia_override_status_guid[16] = {0xc1, 0x94, 0x8d, 0x61, 0xde, 0x0e, + 0xe3, 0x4e, 0x98, 0x4F, 0xB2, 0x07, + 0x6B, 0x05, 0x50, 0xFB}; + +const uint8_t fsp_hob_iio_uds_data_guid[16] = {0xbd, 0x74, 0x6b, 0x83, 0xf3, 0xc2, 0x28, 0x4d, + 0xa3, 0xb8, 0x91, 0x33, 0x10, 0x52, 0x52, 0x9b}; + +const uint8_t fsp_hob_kti_cache_guid[16] = {0xd6, 0xd3, 0x45, 0xac, 0x6e, 0xa3, 0xa6, 0x43, + 0xad, 0x17, 0x0a, 0x45, 0xbb, 0x47, 0xbe, 0xd6}; + +const uint8_t fsp_hob_smbios_memory_info_guid[16] = {0x8c, 0x10, 0xa1, 0x01, 0xee, 0x9d, + 0x84, 0x49, 0x88, 0xc3, 0xee, 0xe8, + 0xc4, 0x9e, 0xfb, 0x89}; + +static const void *fsp_hob_get(const uint8_t *guid, size_t *hob_size) +{ + return fsp_find_extension_hob_by_guid(guid, 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 0000000..3ce3b28 --- /dev/null +++ b/src/soc/intel/snowridge/common/fsp_hob.h @@ -0,0 +1,19 @@ +/* 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> + +extern const uint8_t fsp_hob_fia_override_status_guid[16]; +extern const uint8_t fsp_hob_iio_uds_data_guid[16]; +extern const uint8_t fsp_hob_kti_cache_guid[16]; +extern const uint8_t fsp_hob_smbios_memory_info_guid[16]; + +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 0000000..056495b --- /dev/null +++ b/src/soc/intel/snowridge/common/gpio.c @@ -0,0 +1,309 @@ +/* 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 0000000..0362ad8 --- /dev/null +++ b/src/soc/intel/snowridge/common/hob_display.c @@ -0,0 +1,307 @@ +/* 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 "fsp_hob.h" + +struct guid_name_map { + const void *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)) + 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); + 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)) + 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)) + 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)) + 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 0000000..b5583f1 --- /dev/null +++ b/src/soc/intel/snowridge/common/kti_cache.c @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boot_device.h> +#include <bootstate.h> +#include <commonlib/bsd/cb_err.h> +#include <commonlib/bsd/ipchksum.h> +#include <commonlib/bsd/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); + return; +} + +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, "Erase stale 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 0000000..26191e8 --- /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 0000000..ae995ca --- /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 0000000..4715dd4 --- /dev/null +++ b/src/soc/intel/snowridge/common/reset.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cf9_reset.h> +#include <console/console.h> +#include <fsp/util.h> +#include <soc/intel/common/reset.h> +#include <FspEas/FspApi.h> + +void chipset_handle_reset(uint32_t status) +{ + switch (status) { + case FSP_STATUS_RESET_REQUIRED_4: + case FSP_STATUS_RESET_REQUIRED_5: /**< Global Reset */ + printk(BIOS_DEBUG, "Global Reset requested!!! (type %x)\n", status); + global_reset(); + break; + default: + printk(BIOS_ERR, "unhandled reset type %x\n", status); + die("unknown reset type"); + break; + } +} + +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 0000000..7fbb911 --- /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/uart8250mem.c b/src/soc/intel/snowridge/common/uart8250mem.c new file mode 100644 index 0000000..51d0604 --- /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 0000000..2c5b6fb --- /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 0000000..3c7f44b --- /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 0000000..d1a92fa --- /dev/null +++ b/src/soc/intel/snowridge/cpu.c @@ -0,0 +1,93 @@ +/* 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/soc_chip.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(); +} diff --git a/src/soc/intel/snowridge/finalize.c b/src/soc/intel/snowridge/finalize.c new file mode 100644 index 0000000..476b2c1 --- /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 0000000..65523f4 --- /dev/null +++ b/src/soc/intel/snowridge/heci.c @@ -0,0 +1,41 @@ +/* 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> +#include <soc/pci_ids.h> + +static void heci_read_resources(struct device *dev) +{ + struct resource *res; + + printk(BIOS_SPEW, "%s: Setting MEM_LIMIT_32 resource: %s idx %02x\n", __func__, + dev_path(dev), PCI_BASE_ADDRESS_0); + res = pci_get_resource(dev, PCI_BASE_ADDRESS_0); + res->limit = 0xffffffff; + + /** + * Clear `IORESOURCE_PCI64` since we want this device to remain under 4G as it is used + * by FSP Notify. + */ + res->flags &= ~IORESOURCE_PCI64; + res->flags |= IORESOURCE_MEM; + + compact_resources(dev); +} + +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 = ME_HECI1_DEVID, +}; diff --git a/src/soc/intel/snowridge/hob_iiouds.h b/src/soc/intel/snowridge/hob_iiouds.h new file mode 100644 index 0000000..b666951 --- /dev/null +++ b/src/soc/intel/snowridge/hob_iiouds.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_HOB_IIOUDS_H_ +#define _SOC_SNOWRIDGE_HOB_IIOUDS_H_ + +/** + * IIO Stacks + */ +enum IIO_STACKS { STACK0 = 0, STACK1, STACK2, STACK3, STACK4, STACK5, MAX_STACKS }; + +#endif // _SOC_SNOWRIDGE_HOB_IIOUDS_H_ diff --git a/src/soc/intel/snowridge/hqm.c b/src/soc/intel/snowridge/hqm.c new file mode 100644 index 0000000..3015ab4 --- /dev/null +++ b/src/soc/intel/snowridge/hqm.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <soc/pci_ids.h> + +#include "ramstage.h" + +static void hqm_init(struct device *dev) +{ + printk(BIOS_NOTICE, "%s\n", __func__); + + pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER); +} + +static struct device_operations snr_hqm_ops = { + .read_resources = pciexp_pf_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = hqm_init, + .ops_pci = &pci_dev_ops_pci, +}; + +static const struct pci_driver snr_hqm_driver __pci_driver = { + .ops = &snr_hqm_ops, + .vendor = PCI_VID_INTEL, + .device = HQM_DEVID +}; 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 0000000..848554e --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/acpi.h @@ -0,0 +1,11 @@ +/* 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 southcluster_fill_ssdt(const struct device *device); + +#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 0000000..eaf0a01 --- /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 0000000..ca2ea9f --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/gpio.h @@ -0,0 +1,69 @@ +/* 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) + +/** + * @brief Per `intelblock/gpio.h`, the following are needed, values are from section 20.4 and + * 20.9 of 575161. + */ +#define GPIO_MISCCFG 0x10 /**< Miscellaneous Configuration. */ +#define GPIO_NUM_PAD_CFG_REGS 4 /**< DW0, DW1 and DW2 but 16-bytes aligned. */ + +/** + * @sa section 29.4 and 29.5 of document 575161. + */ +#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 alreay included this file, but to support those file that + * include this file directly, we need include `intelblocks/gpio.h` circularly. + */ +#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 0000000..eb103c6 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/gpio_defs.h @@ -0,0 +1,174 @@ +/* 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 = 0b00, + GPIO_PAD_OWN_ME = 0b11 +}; + +#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 0000000..9ef2e03 --- /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 | (1 << 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/gpmr.h b/src/soc/intel/snowridge/include/soc/gpmr.h new file mode 100644 index 0000000..770c362 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/gpmr.h @@ -0,0 +1,29 @@ +/* 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 (1 << 31) + +#define GPMR_LPCGMR 0xe40 +#define GPMR_GCS 0xe4c +#define GPMR_GCS_BILD (1 << 0) + +#define GPMR_LPCIOD 0xe70 +#define GPMR_LPCIOE 0xe74 +#define GPMR_TCOBASE 0xe78 +#define GPMR_TCOEN (1 << 1) + +#define MAX_GPMR_REGS CONFIG_UNDEFINED_REGISTER + +#define GPMR_OFFSET(x) CONFIG_UNDEFINED_REGISTER +#define GPMR_LIMIT_MASK CONFIG_UNDEFINED_REGISTER +#define GPMR_BASE_SHIFT CONFIG_UNDEFINED_REGISTER +#define GPMR_BASE_MASK CONFIG_UNDEFINED_REGISTER + +#define GPMR_DID_OFFSET(x) CONFIG_UNDEFINED_REGISTER +#define GPMR_EN CONFIG_UNDEFINED_REGISTER + +#endif // _SOC_SNOWRIDGE_GPMR_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 0000000..f6ae195 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/iomap.h @@ -0,0 +1,35 @@ +/* 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 + +/** + * @sa Section 3.2.1 of 575160. + */ +#define RESERVED_BASE_ADDRESS 0xfc000000 +#define RESERVED_BASE_SIZE 0x02c00000 +#define BIOS_BASE_ADDRESS 0xff000000 +#define BIOS_BASE_SIZE 0x01000000 + +/** + * @sa Section 18.9.1.1 of Snow Ridge BIOS Writer Guide. + */ +#define PCH_PRESERVED_BASE_ADDRESS 0xfc800000 +#define PCH_PRESERVED_BASE_SIZE 0x02000000 +#define DEFAULT_TH_BASE 0xfc800000 +#define PCH_PWRM_BASE_ADDRESS 0xfe000000 +#define SPI_BASE_ADDRESS 0xfe010000 +#define SPI_BASE_SIZE 0x00001000 + +#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 0000000..06d1dd7 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/irq.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _SOC_SNOWRIDGE_IRQ_H_ +#define _SOC_SNOWRIDGE_IRQ_H_ + +#define PCH_IRQ0 0 + +/** + * SNR doesn't support route PIRQ to legacy interrupts thus defining IRQ10 and IRQ11 to a + * reserved value. + */ +#define PCH_IRQ10 PCH_IRQ0 +#define PCH_IRQ11 PCH_IRQ0 + +#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 0000000..4103261 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/itss.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_ITSS_H_ +#define _SOC_SNOWRIDGE_ITSS_H_ + +#define ITSS_MAX_IRQ 119 +#define IRQS_PER_IPC 32 +#define NUM_IPC_REGS ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1) / IRQS_PER_IPC) + +#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 0000000..bea9a03 --- /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 0000000..15d7b9f --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/msr.h @@ -0,0 +1,16 @@ +/* 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 + +#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 0000000..7b09503 --- /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 0000000..d876ef5 --- /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 (1 << 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 0000000..76a502d --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pci_devs.h @@ -0,0 +1,109 @@ +/* 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(0, slot, func) +#define _PCH_DEV(slot, func) PCI_DEV(0, 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 + +/** + * @brief Stack S0. + */ +#define SA_DEVFN_ROOT PCI_DEVFN(0x00, 0) +#define SA_DEV_ROOT _SA_DEV(0x00, 0) + +#define SA_DEVFN_M2PCIE PCI_DEVFN(0x00, 1) +#define SA_DEV_M2PCIE _SA_DEV(0x00, 1) + +#define SA_DEVFN_RAS PCI_DEVFN(0x00, 2) +#define SA_DEV_RAS _SA_DEV(0x00, 2) + +#define SA_DEVFN_DFX PCI_DEVFN(0x00, 3) +#define SA_DEV_DFX _SA_DEV(0x00, 3) + +#define SA_DEVFN_IEH PCI_DEVFN(0x00, 4) +#define SA_DEV_IEH _SA_DEV(0x00, 4) + +#define SA_DEVFN_VMD PCI_DEVFN(0x00, 5) +#define SA_DEV_VMD _SA_DEV(0x00, 5) + +#define SA_DEVFN_DMA PCI_DEVFN(0x1, 0) +#define SA_DEV_DMA _SA_DEV(0x1, 0) + +#define SA_DEVFN_MSM PCI_DEVFN(0x2, 0) +#define SA_DEV_MSM _SA_DEV(0x2, 0) + +#define SA_DEVFN_MSM_PMU PCI_DEVFN(0x2, 1) +#define SA_DEV_MSM_PMU _SA_DEV(0x2, 1) + +#define PCH_DEVFN_UART(func) PCI_DEVFN(0x1a, func) +#define PCH_DEV_UART(func) _PCH_DEV(0x1a, func) + +/** + * @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(0, 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_DEV_PMC _PCH_DEV(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) + +/** + * @brief Stack S2. + */ +#define DLB_DEVFN PCI_DEVFN(0x00, 0) + +/** + * @brief Stack S3. + */ +#define NIS_DEVFN PCI_DEVFN(0x04, 0) + +/** + * @brief Stack S4. + */ +#define QAT_1_8_DEVFN PCI_DEVFN(0x05, 0) + +/** + * @brief Stack U0. + */ +#define UBOX_DEVFN_RACU PCI_DEVFN(0x00, 1) +#define UBOX_DEV_RACU _UBOX0_DEV(0x00, 1) + +/** + * @brief Stack U1. + */ +#define CHAALL_DEVFN(func) PCI_DEVFN(0x1d, func) +#define CHAALL_DEV(func) _UBOX1_DEV(0x1d, func) +#define PCU_DEVFN(func) PCI_DEVFN(0x1e, func) +#define PCU_DEV(func) _UBOX1_DEV(0x1e, func) + +/** + * @note Before calling FspMemoryInit(), the MMCFG size is 32M, thus the bus + * number for UBox 0 is 0x1E. This value should be consistent with section + * 9.3.37 of document 575161. + */ +#define IMC_SPD_DEV PCI_DEV(0x1e, 0x0b, 0) + +#endif // _SOC_SNOWRIDGE_PCI_DEVS_H_ diff --git a/src/soc/intel/snowridge/include/soc/pci_ids.h b/src/soc/intel/snowridge/include/soc/pci_ids.h new file mode 100644 index 0000000..8d23850 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pci_ids.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_PCR_IDS_H_ +#define _SOC_SNOWRIDGE_PCR_IDS_H_ + +#define AHCI0_DEVID 0x18b3 /**< SATA Controller 0. */ +#define AHCI2_DEVID 0x18f3 /**< SATA Controller 2. */ +#define ME_HECI1_DEVID 0x18d3 /**< Intel ME - HECI 1. */ +#define XHCI_DEVID 0x18d0 /**< USB Controller. */ +#define VRP0_QAT_1_7_DEVID 0x18ee /**< Intel QAT v1.7. */ +#define VRP4_QAT_1_8_DEVID 0x18a0 /**< Intel QAT v1.8. */ +#define NIS1890_DEVID 0x1890 /**< Intel Ethernet Connection E822-C for backplane. */ +#define NIS1891_DEVID 0x1891 /**< Intel Ethernet Connection E822-C for QSFP. */ +#define NIS1892_DEVID 0x1892 /**< Intel Ethernet Connection E822-C for SFP. */ +#define HQM_DEVID 0x270b /**< Intel DLB. */ + +#endif // _SOC_SNOWRIDGE_PCR_IDS_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 0000000..3a41746 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pcr_ids.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_PCR_IDS_H_ +#define _SOC_SNOWRIDGE_PCR_IDS_H_ + +/** + * @sa Section 43.5.2 of document 575160. + */ +#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 + +/** + * @sa Section 15.2 of document 574281. + */ +#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 0000000..a8b924d --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pm.h @@ -0,0 +1,131 @@ +/* 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> + +/** + * @brief Power Management controller IO space registers, @sa section 20.3 of document 575161. + */ +#define PM1_STS 0x00 +#define WAK_STS (1 << 15) +#define PWRBTN_STS (1 << 8) +#define PM1_EN 0x02 +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define PM1_CNT 0x04 +#define SCI_EN (1 << 0) +#define PM1_TMR 0x08 +#define SMI_EN 0x30 +#define XHCI_SMI_EN (1 << 31) +#define ME_SMI_EN (1 << 30) +#define ESPI_SMI_EN (1 << 28) +#define GPIO_UNLOCK_SMI_EN (1 << 27) +#define SDX_SMI_EN (1 << 25) +#define THERM_SMI_EN (1 << 18) +#define LEGACY_USB2_EN (1 << 17) +#define PERIODIC_EN (1 << 14) +#define TCO_SMI_EN (1 << 13) +#define MCSMI_EN (1 << 11) +#define BIOS_RLS (1 << 7) +#define SWSMI_TMR_EN (1 << 6) +#define APMC_EN (1 << 5) +#define SLP_SMI_EN (1 << 4) +#define LEGACY_USB_EN (1 << 3) +#define BIOS_EN (1 << 2) +#define EOS (1 << 1) +#define GBL_SMI_EN (1 << 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 (1 << 18) +#define USB_CON_DSX_EN (1 << 17) +#define LANWAKE_EN (1 << 16) +#define GPIO_T2_EN (1 << 15) +#define ESPI_EN (1 << 14) +#define PME_B0_EN (1 << 13) +#define ME_SCI_EN (1 << 12) +#define PME_EN (1 << 11) +#define BATLOW_EN (1 << 10) +#define PCI_EXP_EN (1 << 9) +#define TCOSCI_EN (1 << 6) +#define THERM_EN (1 << 4) +#define SWGPE_EN (1 << 2) +#define HOT_PLUG_EN (1 << 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 0000000..c6f1ae74 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/pmc.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_PMC_H_ +#define _SOC_SNOWRIDGE_PMC_H_ + +/** + * @sa Section 20.2 of document 575161. + */ +#define GEN_PMCON_A 0x1020 +#define GBL_RST_STS (1 << 24) +#define MS4V (1 << 18) +#define SUS_PWR_FLR (1 << 16) +#define PWR_FLR (1 << 14) +#define PER_SMI_SEL_MASK (3 << 1) +#define SMI_RATE_64S (0 << 1) +#define SMI_RATE_32S (1 << 1) +#define SMI_RATE_16S (2 << 1) +#define SMI_RATE_8S (3 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) +#define GEN_PMCON_B 0x1024 +#define SLP_STR_POL_LOCK (1 << 18) +#define ACPI_BASE_LOCK (1 << 17) +#define SMI_LOCK (1 << 4) +#define ETR 0x1048 +#define CF9_LOCK (1 << 31) +#define CF9_GLB_RST (1 << 20) +#define PRSTS 0x1810 +#define PMSYNC_TPR_CFG 0x18C4 +#define PCH2CPU_TPR_CFG_LOCK (1 << 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 0000000..0137405 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/sata.h @@ -0,0 +1,17 @@ +/* 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) + +/** + * @sa Section 15.3 of document 575161. + */ +#define SATA_GHC 0x04 +#define SATA_GHC_AE (1 << 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 0000000..2dd5018 --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/smbus.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_SMBUS_H_ +#define _SOC_SNOWRIDGE_SMBUS_H_ + +#include <intelpch/smbus.h> + +#define TCOBASE 0x50 +#define TCOBA_MASK (0x7FF << 5) +#define TCOCTL 0x54 +#define TCO_BASE_EN (1 << 8) +#define TCO_BASE_LOCK (1 << 0) + +#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 0000000..713291c --- /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 0000000..29da26d --- /dev/null +++ b/src/soc/intel/snowridge/include/soc/systemagent.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_SNOWRIDGE_SYSTEMAGENT_H_ +#define _SOC_SNOWRIDGE_SYSTEMAGENT_H_ + +/** + * @brief SoC specific systemagent are included after the one in intelblocks thus the following + * registers should be redefined. + */ +#ifdef PCIEXBAR +#undef PCIEXBAR +#endif +#define PCIEXBAR 0x90 /**< PCI Express Configuration Space Base Address Register. */ + +#ifdef TOUUD +#undef TOUUD +#endif +#define TOUUD 0xC8 + +#ifdef TOLUD +#undef TOLUD +#endif +#define TOLUD 0xD0 + +#ifdef TSEG +#undef TSEG +#endif +#define TSEG 0xA8 + +#define VTBAR 0x180 +#define VTD_CHIPSET_BASE_ADDRESS_ENABLE (1 << 0) + +#ifdef DPR +#undef DPR +#endif +#define DPR 0x290 + +#define VTD_ECAP 0x10 + +uint64_t sa_get_touud(void); + +/** + * @warning SNR system agent doesn't have the following registers definitions, this is just + * defined for using common block systemagent. Make sure functions referring them are not called + * anywhere and are removed in the generated binary. + */ +#define MCH_BASE_ADDRESS CONFIG_UNDEFINED_REGISTER +#define BIOS_RESET_CPL CONFIG_UNDEFINED_REGISTER +#define CAPID0_A CONFIG_UNDEFINED_REGISTER + +#endif // _SOC_SNOWRIDGE_SYSTEMAGENT_H_ diff --git a/src/soc/intel/snowridge/lockdown.c b/src/soc/intel/snowridge/lockdown.c new file mode 100644 index 0000000..5a1e86c --- /dev/null +++ b/src/soc/intel/snowridge/lockdown.c @@ -0,0 +1,32 @@ +/* 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(); + + if (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 0000000..7c00f40 --- /dev/null +++ b/src/soc/intel/snowridge/lpc.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/ioapic.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <intelblocks/lpc_lib.h> +#include <soc/iomap.h> +#include <soc/irq.h> + +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); +} + +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/memmap.c b/src/soc/intel/snowridge/memmap.c new file mode 100644 index 0000000..74124e2 --- /dev/null +++ b/src/soc/intel/snowridge/memmap.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <commonlib/bsd/helpers.h> +#include <device/pci_ops.h> +#include <soc/pci_devs.h> +#include <soc/systemagent.h> + +uint64_t sa_get_touud(void) +{ + return ALIGN_DOWN(((uint64_t)(pci_read_config32(SA_DEV_ROOT, TOUUD + 4)) << 32) + + (uint64_t)(pci_read_config32(SA_DEV_ROOT, TOUUD)) + + CONFIG_TOUUD_ALIGNMENT, + CONFIG_TOUUD_ALIGNMENT); +} diff --git a/src/soc/intel/snowridge/nis.c b/src/soc/intel/snowridge/nis.c new file mode 100644 index 0000000..c7d1cd4 --- /dev/null +++ b/src/soc/intel/snowridge/nis.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <soc/pci_ids.h> + +#include "ramstage.h" + +static void nis_init(struct device *dev) +{ + printk(BIOS_NOTICE, "%s\n", __func__); + + pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER); +} + +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, + .init = nis_init, + .ops_pci = &pci_dev_ops_pci, +}; + +static const unsigned short snr_nis_ids[] = { + NIS1890_DEVID, + NIS1891_DEVID, + NIS1892_DEVID, + 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/qat.c b/src/soc/intel/snowridge/qat.c new file mode 100644 index 0000000..5b09592 --- /dev/null +++ b/src/soc/intel/snowridge/qat.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <soc/pci_ids.h> + +#include "ramstage.h" + +static void qat_init(struct device *dev) +{ + printk(BIOS_NOTICE, "%s\n", __func__); + + pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER); +} + +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, + .init = qat_init, + .ops_pci = &pci_dev_ops_pci, +}; + +static const unsigned short snr_qat_ids[] = { + VRP0_QAT_1_7_DEVID, + VRP4_QAT_1_8_DEVID, + 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 0000000..524eec7 --- /dev/null +++ b/src/soc/intel/snowridge/ramstage.h @@ -0,0 +1,12 @@ +/* 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> + +void pciexp_pf_read_resources(struct device* dev); +void pciexp_vf_read_resources(struct device *dev); + +#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 0000000..e46175f --- /dev/null +++ b/src/soc/intel/snowridge/romstage/gpio_snr.c @@ -0,0 +1,216 @@ +/* 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, 0b11 << ((pad - comm->first_pad) % 8 * 4)); + + return (pad_own >> ((pad - comm->first_pad) % 8 * sizeof(uint32_t))) & 0b11; +} + +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, + 0b1 << SNR_GPIO_WITHIN_GROUP(pad)); + + return (host_sw_own >> SNR_GPIO_WITHIN_GROUP(pad)) & 0b1; +} + +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;) { + 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); + i++; + 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); + i++; + continue; + } + + bit_mask = 1 << (SNR_GPIO_PAD(gpio[i].cfg.pad) % GPIO_MAX_NUM_PER_GROUP); + for (j = i + 1; j < num; j++) { + if (comm_index != SNR_GPIO_COMMUNITY(gpio[j].cfg.pad) || + group_index != SNR_GPIO_GROUP(gpio[j].cfg.pad)) + break; + bit_mask |= 1 + << (SNR_GPIO_PAD(gpio[j].cfg.pad) % GPIO_MAX_NUM_PER_GROUP); + } + + gpio_unlock_snr_pad_group(&comm[comm_index], group_index, bit_mask); + i = j; + } + + /** + * @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;) { + comm_index = SNR_GPIO_COMMUNITY(gpio[i].cfg.pad); + group_index = SNR_GPIO_GROUP(gpio[i].cfg.pad); + for (j = i + 1; j < num; j++) + if (comm_index != SNR_GPIO_COMMUNITY(gpio[j].cfg.pad) || + group_index != SNR_GPIO_GROUP(gpio[j].cfg.pad)) { + break; + } + + gpio_clear_snr_pad_group_interrupt_status(&comm[comm_index], group_index, + 0xffffffff); + i = j; + } +} diff --git a/src/soc/intel/snowridge/romstage/romstage.c b/src/soc/intel/snowridge/romstage/romstage.c new file mode 100644 index 0000000..e7134de --- /dev/null +++ b/src/soc/intel/snowridge/romstage/romstage.c @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/romstage.h> +#include <cbmem.h> +#include <commonlib/bsd/cbmem_id.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_smbus_spd_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; + struct memory_info *mem_info; + uint8_t channel, dimm, index; + const CHANNEL_INFO *channel_info; + const DIMM_INFO *fsp_dimm_info; + struct dimm_info *dimm_info; + struct dimm_attr_ddr4_st dimm_attr; + enum spd_status status; + + 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; + } + + 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)); + + for (channel = 0, index = 0; + channel < fsp_smbios_memory_info->ChannelCount && + channel < ARRAY_SIZE(fsp_smbios_memory_info->ChannelInfo) && + index < ARRAY_SIZE(mem_info->dimm); + channel++) { + channel_info = &fsp_smbios_memory_info->ChannelInfo[channel]; + + for (dimm = 0; dimm < channel_info->DimmCount && + dimm < ARRAY_SIZE(channel_info->DimmInfo) && + index < ARRAY_SIZE(mem_info->dimm); + dimm++) { + fsp_dimm_info = &channel_info->DimmInfo[dimm]; + dimm_info = &mem_info->dimm[index]; + + 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); + + index++; + } + } + + mem_info->dimm_cnt = index; + 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) +{ + if (!CONFIG(BOOTBLOCK_CONSOLE)) { + console_init(); + printk(BIOS_DEBUG, "FSP TempRamInit successful...\n"); + } + + 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 0000000..1cc4cbf --- /dev/null +++ b/src/soc/intel/snowridge/sata.c @@ -0,0 +1,53 @@ +/* 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/pci_ids.h> +#include <soc/sata.h> + +static void sata_init(struct device *dev) +{ + uint32_t reg32, abar; + + pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER); + + 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, + .ops_pci = &pci_dev_ops_pci, +}; + +static const unsigned short snr_sata_ids[] = { + AHCI0_DEVID, + AHCI2_DEVID, + 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 0000000..96efa64 --- /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 0000000..a293390 --- /dev/null +++ b/src/soc/intel/snowridge/sriov.c @@ -0,0 +1,104 @@ +/* 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); + + /** + * @sa 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; + + 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); + 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 0000000..f077a78 --- /dev/null +++ b/src/soc/intel/snowridge/systemagent.c @@ -0,0 +1,79 @@ +/* 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.h> +#include <soc/iomap.h> +#include <soc/systemagent.h> + +static void get_pcie_bar(struct device *dev, uint16_t index, uint64_t *base, uint64_t *size) +{ + *base = ALIGN_DOWN(((uint64_t)(pci_read_config32(dev, index + 4)) << 32) | + pci_read_config32(dev, index), + 64 * MiB); + *size = CONFIG_ECAM_MMCONF_LENGTH; +} + +static void get_dpr(struct device *dev, uint16_t index, uint64_t *base, uint64_t *size) +{ + *size = sa_get_dpr_size(); + *base = sa_get_tseg_base() - *size; +} + +static void get_tseg(struct device *dev, uint16_t index, uint64_t *base, uint64_t *size) +{ + *base = sa_get_tseg_base(); + *size = sa_get_tseg_size(); +} + +void soc_add_fixed_mmio_resources(struct device *dev, int *resource_cnt) +{ + struct sa_mmio_descriptor snr_fixed_resources[] = { + {0, RESERVED_BASE_ADDRESS, RESERVED_BASE_SIZE, "PCH Reserved"}, + {0, IO_APIC_ADDR, 1 * MiB, "I/O APIC" }, + {0, HPET_BASE_ADDRESS, 1 * MiB, "HPET/TXT/TPM"}, + {0, LAPIC_DEFAULT_BASE, 2 * MiB, "Local APIC" }, + {0, BIOS_BASE_ADDRESS, BIOS_BASE_SIZE, "BIOS" }, + }; + + sa_add_fixed_mmio_resources(dev, resource_cnt, snr_fixed_resources, + ARRAY_SIZE(snr_fixed_resources)); +} + +struct sa_configurable_mmio_descriptor { + struct sa_mmio_descriptor resources; + void (*get_resource)(struct device *dev, uint16_t index, uint64_t *base, + uint64_t *size); +}; + +void soc_add_configurable_mmio_resources(struct device *dev, int *resource_cnt) +{ + struct sa_configurable_mmio_descriptor snr_configurable_resources[] = { + { + .resources = {.index = PCIEXBAR, .description = "PCI Express BAR"}, + .get_resource = get_pcie_bar, + }, + { + .resources = {.index = DPR, .description = "DMA Protection Range"}, + .get_resource = get_dpr, + }, + { + .resources = {.index = TSEG, .description = "TSEG"}, + .get_resource = get_tseg, + }, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(snr_configurable_resources); i++) { + snr_configurable_resources[i].get_resource( + dev, snr_configurable_resources[i].resources.index, + &snr_configurable_resources[i].resources.base, + &snr_configurable_resources[i].resources.size); + + sa_add_fixed_mmio_resources(dev, resource_cnt, + &snr_configurable_resources[i].resources, 1); + } +}