Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 34 files changed, 3,337 insertions(+), 6 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/1
diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 553131b..c99ad5c 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -9,25 +9,45 @@ def_bool y select ACPI_INTEL_HARDWARE_SLEEP_VALUES select ARCH_BOOTBLOCK_X86_32 + select ARCH_RAMSTAGE_X86_32 select ARCH_ROMSTAGE_X86_32 select ARCH_VERSTAGE_X86_32 select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if BOOT_DEVICE_SPI_FLASH select BOOT_DEVICE_SUPPORTS_WRITES select CACHE_MRC_SETTINGS select CPU_INTEL_COMMON + select CPU_INTEL_COMMON_HYPERTHREADING + select CPU_INTEL_FIRMWARE_INTERFACE_TABLE + select FSP_COMPRESS_FSP_S_LZ4 select FSP_M_XIP + select GENERIC_GPIO_LIB + select HAVE_FSP_GOP select INTEL_DESCRIPTOR_MODE_CAPABLE + select HAVE_SMI_HANDLER select IDT_IN_EVERY_STAGE select INTEL_CAR_NEM #TODO - Enable INTEL_CAR_NEM_ENHANCED + select INTEL_GMA_ACPI + select INTEL_GMA_ADD_VBT if RUN_FSP_GOP + select IOAPIC select MRC_SETTINGS_PROTECT + select PARALLEL_MP + select PARALLEL_MP_AP_WORK select MICROCODE_BLOB_UNDISCLOSED select PLATFORM_USES_FSP2_2 + select FSP_PEIM_TO_PEIM_INTERFACE + select REG_SCRIPT + select PMC_GLOBAL_RESET_ENABLE_LOCK select SOC_INTEL_COMMON select SOC_INTEL_COMMON_BLOCK 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_GPIO_DUAL_ROUTE_SUPPORT select SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2 + select SOC_INTEL_COMMON_BLOCK_HDA select SOC_INTEL_COMMON_BLOCK_SA + select SOC_INTEL_COMMON_BLOCK_SMM + select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_PCH_BASE select SOC_INTEL_COMMON_RESET select SOC_INTEL_COMMON_BLOCK_CAR @@ -36,6 +56,12 @@ select TSC_MONOTONIC_TIMER select UDELAY_TSC select UDK_202005_BINDING + select DISPLAY_FSP_VERSION_INFO + select HECI_DISABLE_USING_SMM + +config MAX_CPUS + int + default 24
config DCACHE_RAM_BASE default 0xfef00000 @@ -75,6 +101,22 @@ hex default 0x10000
+config MAX_ROOT_PORTS + int + default 12 + +config MAX_PCIE_CLOCKS + int + default 12 + +config SMM_TSEG_SIZE + hex + default 0x800000 + +config SMM_RESERVED_SIZE + hex + default 0x200000 + config PCR_BASE_ADDRESS hex default 0xfd000000 @@ -146,6 +188,7 @@ config PRERAM_CBMEM_CONSOLE_SIZE hex default 0x1400 + config FSP_HEADER_PATH string "Location of FSP headers" default "src/vendorcode/intel/fsp/fsp2_0/alderlake/" diff --git a/src/soc/intel/alderlake/Makefile.inc b/src/soc/intel/alderlake/Makefile.inc index 7ea9301..687058a 100644 --- a/src/soc/intel/alderlake/Makefile.inc +++ b/src/soc/intel/alderlake/Makefile.inc @@ -7,6 +7,13 @@ subdirs-y += ../../../cpu/x86/smm subdirs-y += ../../../cpu/x86/tsc
+# all (bootblock, verstage, romstage, postcar, ramstage) +all-y += gspi.c +all-y += i2c.c +all-y += pmutil.c +all-y += spi.c +all-y += uart.c + bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/cpu.c bootblock-y += bootblock/pch.c @@ -20,9 +27,28 @@ romstage-y += meminit.c romstage-y += reset.c
+ramstage-y += acpi.c +ramstage-y += chip.c +ramstage-y += cpu.c +ramstage-y += elog.c +ramstage-y += espi.c +ramstage-y += finalize.c +ramstage-y += fsp_params.c ramstage-y += gpio.c +ramstage-y += lockdown.c +ramstage-y += p2sb.c +ramstage-y += pmc.c +ramstage-y += reset.c +ramstage-y += smmrelocate.c +ramstage-y += soundwire.c +ramstage-y += systemagent.c +ramstage-y += me.c
smm-y += gpio.c +smm-y += p2sb.c +smm-y += pmutil.c +smm-y += smihandler.c +smm-y += uart.c
CPPFLAGS_common += -I$(src)/soc/intel/alderlake CPPFLAGS_common += -I$(src)/soc/intel/alderlake/include diff --git a/src/soc/intel/alderlake/acpi.c b/src/soc/intel/alderlake/acpi.c new file mode 100644 index 0000000..c7c5446 --- /dev/null +++ b/src/soc/intel/alderlake/acpi.c @@ -0,0 +1,370 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> +#include <acpi/acpigen.h> +#include <device/mmio.h> +#include <arch/smp/mpspec.h> +#include <cbmem.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci_ops.h> +#include <ec/google/chromeec/ec.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/acpi.h> +#include <soc/cpu.h> +#include <soc/iomap.h> +#include <soc/nvs.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_chip.h> +#include <soc/systemagent.h> +#include <string.h> +#include <wrdd.h> + +/* + * List of supported C-states in this processor. + */ +enum { + C_STATE_C0, /* 0 */ + C_STATE_C1, /* 1 */ + C_STATE_C1E, /* 2 */ + C_STATE_C6_SHORT_LAT, /* 3 */ + C_STATE_C6_LONG_LAT, /* 4 */ + C_STATE_C7_SHORT_LAT, /* 5 */ + C_STATE_C7_LONG_LAT, /* 6 */ + C_STATE_C7S_SHORT_LAT, /* 7 */ + C_STATE_C7S_LONG_LAT, /* 8 */ + C_STATE_C8, /* 9 */ + C_STATE_C9, /* 10 */ + C_STATE_C10, /* 11 */ + NUM_C_STATES +}; + +#define MWAIT_RES(state, sub_state) \ + { \ + .addrl = (((state) << 4) | (sub_state)), \ + .space_id = ACPI_ADDRESS_SPACE_FIXED, \ + .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \ + .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \ + .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \ + } + +static const acpi_cstate_t cstate_map[NUM_C_STATES] = { + [C_STATE_C0] = {}, + [C_STATE_C1] = { + .latency = C1_LATENCY, + .power = C1_POWER, + .resource = MWAIT_RES(0, 0), + }, + [C_STATE_C1E] = { + .latency = C1_LATENCY, + .power = C1_POWER, + .resource = MWAIT_RES(0, 1), + }, + [C_STATE_C6_SHORT_LAT] = { + .latency = C6_LATENCY, + .power = C6_POWER, + .resource = MWAIT_RES(2, 0), + }, + [C_STATE_C6_LONG_LAT] = { + .latency = C6_LATENCY, + .power = C6_POWER, + .resource = MWAIT_RES(2, 1), + }, + [C_STATE_C7_SHORT_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 0), + }, + [C_STATE_C7_LONG_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 1), + }, + [C_STATE_C7S_SHORT_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 2), + }, + [C_STATE_C7S_LONG_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 3), + }, + [C_STATE_C8] = { + .latency = C8_LATENCY, + .power = C8_POWER, + .resource = MWAIT_RES(4, 0), + }, + [C_STATE_C9] = { + .latency = C9_LATENCY, + .power = C9_POWER, + .resource = MWAIT_RES(5, 0), + }, + [C_STATE_C10] = { + .latency = C10_LATENCY, + .power = C10_POWER, + .resource = MWAIT_RES(6, 0), + }, +}; + +static int cstate_set_non_s0ix[] = { + C_STATE_C1, + C_STATE_C6_LONG_LAT, + C_STATE_C7S_LONG_LAT +}; + +static int cstate_set_s0ix[] = { + C_STATE_C1, + C_STATE_C7S_LONG_LAT, + C_STATE_C10 +}; + +acpi_cstate_t *soc_get_cstate_map(size_t *entries) +{ + static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix), + ARRAY_SIZE(cstate_set_non_s0ix))]; + int *set; + int i; + + config_t *config = config_of_soc(); + + int is_s0ix_enable = config->s0ix_enable; + + if (is_s0ix_enable) { + *entries = ARRAY_SIZE(cstate_set_s0ix); + set = cstate_set_s0ix; + } else { + *entries = ARRAY_SIZE(cstate_set_non_s0ix); + set = cstate_set_non_s0ix; + } + + for (i = 0; i < *entries; i++) { + memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t)); + map[i].ctype = i + 1; + } + return map; +} + +void soc_power_states_generation(int core_id, int cores_per_package) +{ + config_t *config = config_of_soc(); + + if (config->eist_enable) + /* Generate P-state tables */ + generate_p_state_entries(core_id, cores_per_package); +} + +void soc_fill_fadt(acpi_fadt_t *fadt) +{ + const uint16_t pmbase = ACPI_BASE_ADDRESS; + + config_t *config = config_of_soc(); + + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->pm_tmr_len = 4; + fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; + fadt->x_pm_tmr_blk.addrh = 0x0; + + if (config->s0ix_enable) + fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0; +} + +uint32_t soc_read_sci_irq_select(void) +{ + uintptr_t pmc_bar = soc_read_pmc_base(); + return read32((void *)pmc_bar + IRQ_REG); +} + +static unsigned long soc_fill_dmar(unsigned long current) +{ + const struct device *const igfx_dev = pcidev_path_on_root(SA_DEVFN_IGD); + uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK; + bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED; + + if (is_dev_enabled(igfx_dev) && gfxvtbar && gfxvten) { + unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar); + current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + + acpi_dmar_drhd_fixup(tmp, current); + } + + const struct device *const ipu_dev = pcidev_path_on_root(SA_DEVFN_IPU); + uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK; + bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED; + + if (is_dev_enabled(ipu_dev) && ipuvtbar && ipuvten) { + unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar); + current += acpi_create_dmar_ds_pci(current, 0, 5, 0); + + acpi_dmar_drhd_fixup(tmp, current); + } + + uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK; + bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED; + + if (vtvc0bar && vtvc0en) { + const unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, + DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); + current += acpi_create_dmar_ds_ioapic(current, + 2, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV, + V_P2SB_CFG_IBDF_FUNC); + current += acpi_create_dmar_ds_msi_hpet(current, + 0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV, + V_P2SB_CFG_HBDF_FUNC); + + acpi_dmar_drhd_fixup(tmp, current); + } + + /* TCSS Thunderbolt root ports */ + for (unsigned int i = 0; i < MAX_TBT_PCIE_PORT; i++) { + uint64_t tbtbar = MCHBAR64(TBT0BAR + i * 8) & VTBAR_MASK; + bool tbten = MCHBAR32(TBT0BAR + i * 8) & VTBAR_ENABLED; + if (tbtbar && tbten) { + unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, tbtbar); + current += acpi_create_dmar_ds_pci_br(current, 0, 7, i); + + acpi_dmar_drhd_fixup(tmp, current); + } + } + + /* Add RMRR entry */ + const unsigned long tmp = current; + current += acpi_create_dmar_rmrr(current, 0, + sa_get_gsm_base(), sa_get_tolud_base() - 1); + current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + acpi_dmar_rmrr_fixup(tmp, current); + + return current; +} + +unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current, + struct acpi_rsdp *rsdp) +{ + acpi_dmar_t *const dmar = (acpi_dmar_t *)current; + + /* + * Create DMAR table only if we have VT-d capability and FSP does not override its + * feature. + */ + if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) || + !(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED)) + return current; + + printk(BIOS_DEBUG, "ACPI: * DMAR\n"); + acpi_create_dmar(dmar, DMAR_INTR_REMAP | DMA_CTRL_PLATFORM_OPT_IN_FLAG, soc_fill_dmar); + current += dmar->header.length; + current = acpi_align_current(current); + acpi_add_table(rsdp, dmar); + + return current; +} + +void acpi_create_gnvs(struct global_nvs *gnvs) +{ + config_t *config = config_of_soc(); + + /* Set unknown wake source */ + gnvs->pm1i = -1; + + /* CPU core count */ + gnvs->pcnt = dev_count_cpu(); + + if (CONFIG(CONSOLE_CBMEM)) + /* Update the mem console pointer. */ + gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE); + + if (CONFIG(CHROMEOS)) { + /* Initialize Verified Boot data */ + chromeos_init_chromeos_acpi(&(gnvs->chromeos)); + if (CONFIG(EC_GOOGLE_CHROMEEC)) { + gnvs->chromeos.vbt2 = google_ec_running_ro() ? + ACTIVE_ECFW_RO : ACTIVE_ECFW_RW; + } else + gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO; + } + + /* Enable DPTF based on mainboard configuration */ + gnvs->dpte = config->dptf_enable; + + /* Fill in the Wifi Region id */ + gnvs->cid1 = wifi_regulatory_domain(); + + /* Set USB2/USB3 wake enable bitmaps. */ + gnvs->u2we = config->usb2_wake_enable_bitmap; + gnvs->u3we = config->usb3_wake_enable_bitmap; + + /* Fill in Above 4GB MMIO resource */ + sa_fill_gnvs(gnvs); +} + +uint32_t acpi_fill_soc_wake(uint32_t generic_pm1_en, + const struct chipset_power_state *ps) +{ + /* + * WAK_STS bit is set when the system is in one of the sleep states + * (via the SLP_EN bit) and an enabled wake event occurs. Upon setting + * this bit, the PMC will transition the system to the ON state and + * can only be set by hardware and can only be cleared by writing a one + * to this bit position. + */ + + generic_pm1_en |= WAK_STS | RTC_EN | PWRBTN_EN; + return generic_pm1_en; +} + +int soc_madt_sci_irq_polarity(int sci) +{ + return MP_IRQ_POLARITY_HIGH; +} + +static int acpigen_soc_gpio_op(const char *op, unsigned int gpio_num) +{ + /* op (gpio_num) */ + acpigen_emit_namestring(op); + acpigen_write_integer(gpio_num); + return 0; +} + +static int acpigen_soc_get_gpio_state(const char *op, unsigned int gpio_num) +{ + /* Store (op (gpio_num), Local0) */ + acpigen_write_store(); + acpigen_soc_gpio_op(op, gpio_num); + acpigen_emit_byte(LOCAL0_OP); + return 0; +} + +int acpigen_soc_read_rx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_get_gpio_state("\_SB.PCI0.GRXS", gpio_num); +} + +int acpigen_soc_get_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_get_gpio_state("\_SB.PCI0.GTXS", gpio_num); +} + +int acpigen_soc_set_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_gpio_op("\_SB.PCI0.STXS", gpio_num); +} + +int acpigen_soc_clear_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_gpio_op("\_SB.PCI0.CTXS", gpio_num); +} diff --git a/src/soc/intel/alderlake/chip.c b/src/soc/intel/alderlake/chip.c new file mode 100644 index 0000000..61b3c20 --- /dev/null +++ b/src/soc/intel/alderlake/chip.c @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <fsp/api.h> +#include <fsp/util.h> +#include <intelblocks/acpi.h> +#include <intelblocks/cfg.h> +#include <intelblocks/itss.h> +#include <intelblocks/pcie_rp.h> +#include <intelblocks/xdci.h> +#include <romstage_handoff.h> +#include <soc/intel/common/vbt.h> +#include <soc/itss.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/soc_chip.h> + +static const struct pcie_rp_group pch_lp_rp_groups[] = { + { .slot = PCH_DEV_SLOT_PCIE, .count = 8 }, + { .slot = PCH_DEV_SLOT_PCIE_1, .count = 4 }, + { 0 } +}; + +#if CONFIG(HAVE_ACPI_TABLES) +const char *soc_acpi_name(const struct device *dev) +{ + if (dev->path.type == DEVICE_PATH_DOMAIN) + return "PCI0"; + + if (dev->path.type == DEVICE_PATH_USB) { + switch (dev->path.usb.port_type) { + case 0: + /* Root Hub */ + return "RHUB"; + case 2: + /* USB2 ports */ + switch (dev->path.usb.port_id) { + case 0: return "HS01"; + case 1: return "HS02"; + case 2: return "HS03"; + case 3: return "HS04"; + case 4: return "HS05"; + case 5: return "HS06"; + case 6: return "HS07"; + case 7: return "HS08"; + case 8: return "HS09"; + case 9: return "HS10"; + } + break; + case 3: + /* USB3 ports */ + switch (dev->path.usb.port_id) { + case 0: return "SS01"; + case 1: return "SS02"; + case 2: return "SS03"; + case 3: return "SS04"; + } + break; + } + return NULL; + } + if (dev->path.type != DEVICE_PATH_PCI) + return NULL; + + switch (dev->path.pci.devfn) { + case SA_DEVFN_ROOT: return "MCHC"; + case SA_DEVFN_TCSS_XHCI: return "TXHC"; + case SA_DEVFN_TCSS_XDCI: return "TXDC"; + case SA_DEVFN_TCSS_DMA0: return "TDM0"; + case SA_DEVFN_TCSS_DMA1: return "TDM1"; + case SA_DEVFN_TBT0: return "TRP0"; + case SA_DEVFN_TBT1: return "TRP1"; + case SA_DEVFN_TBT2: return "TRP2"; + case SA_DEVFN_TBT3: return "TRP3"; + case SA_DEVFN_IPU: return "IPU0"; + case PCH_DEVFN_ISH: return "ISHB"; + case PCH_DEVFN_XHCI: return "XHCI"; + case PCH_DEVFN_I2C0: return "I2C0"; + case PCH_DEVFN_I2C1: return "I2C1"; + case PCH_DEVFN_I2C2: return "I2C2"; + case PCH_DEVFN_I2C3: return "I2C3"; + case PCH_DEVFN_I2C4: return "I2C4"; + case PCH_DEVFN_I2C5: return "I2C5"; + case PCH_DEVFN_SATA: return "SATA"; + case PCH_DEVFN_PCIE1: return "RP01"; + case PCH_DEVFN_PCIE2: return "RP02"; + case PCH_DEVFN_PCIE3: return "RP03"; + case PCH_DEVFN_PCIE4: return "RP04"; + case PCH_DEVFN_PCIE5: return "RP05"; + case PCH_DEVFN_PCIE6: return "RP06"; + case PCH_DEVFN_PCIE7: return "RP07"; + case PCH_DEVFN_PCIE8: return "RP08"; + case PCH_DEVFN_PCIE9: return "RP09"; + case PCH_DEVFN_PCIE10: return "RP10"; + case PCH_DEVFN_PCIE11: return "RP11"; + case PCH_DEVFN_PCIE12: return "RP12"; + case PCH_DEVFN_PMC: return "PMC"; + case PCH_DEVFN_UART0: return "UAR0"; + case PCH_DEVFN_UART1: return "UAR1"; + case PCH_DEVFN_UART2: return "UAR2"; + case PCH_DEVFN_GSPI0: return "SPI0"; + case PCH_DEVFN_GSPI1: return "SPI1"; + case PCH_DEVFN_GSPI2: return "SPI2"; + case PCH_DEVFN_GSPI3: return "SPI3"; + /* Keeping ACPI device name coherent with ec.asl */ + case PCH_DEVFN_ESPI: return "LPCB"; + case PCH_DEVFN_HDA: return "HDAS"; + case PCH_DEVFN_SMBUS: return "SBUS"; + case PCH_DEVFN_GBE: return "GLAN"; + } + + return NULL; +} +#endif + +/* SoC rotine to fill GPIO PM mask and value for GPIO_MISCCFG register */ +static void soc_fill_gpio_pm_configuration(void) +{ + uint8_t value[TOTAL_GPIO_COMM]; + const config_t *config = config_of_soc(); + + if (config->gpio_override_pm) + memcpy(value, config->gpio_pm, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + else + memset(value, MISCCFG_ENABLE_GPIO_PM_CONFIG, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + + gpio_pm_configure(value, TOTAL_GPIO_COMM); +} + +void soc_init_pre_device(void *chip_info) +{ + /* Snapshot the current GPIO IRQ polarities. FSP is setting a + * default policy that doesn't honor boards' requirements. */ + itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); + + /* Perform silicon specific init. */ + fsp_silicon_init(romstage_handoff_is_resume()); + + /* Display FIRMWARE_VERSION_INFO_HOB */ + fsp_display_fvi_version_hob(); + + /* Restore GPIO IRQ polarities back to previous settings. */ + itss_restore_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); + + soc_fill_gpio_pm_configuration(); + + /* Swap enabled PCI ports in device tree if needed. */ + pcie_rp_update_devicetree(pch_lp_rp_groups); +} + +static struct device_operations pci_domain_ops = { + .read_resources = &pci_domain_read_resources, + .set_resources = &pci_domain_set_resources, + .scan_bus = &pci_domain_scan_bus, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = &soc_acpi_name, +#endif +}; + +static struct device_operations cpu_bus_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = generate_cpu_entries, +#endif +}; + +static void soc_enable(struct device *dev) +{ + /* + * Set the operations if it is a special bus type or a hidden PCI + * device. + */ + if (dev->path.type == DEVICE_PATH_DOMAIN) + dev->ops = &pci_domain_ops; + else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) + dev->ops = &cpu_bus_ops; + else if (dev->path.type == DEVICE_PATH_PCI && + dev->path.pci.devfn == PCH_DEVFN_PMC) + dev->ops = &pmc_ops; +} + +struct chip_operations soc_intel_alderlake_ops = { + CHIP_NAME("Intel Alderlake") + .enable_dev = &soc_enable, + .init = &soc_init_pre_device, +}; diff --git a/src/soc/intel/alderlake/chip.h b/src/soc/intel/alderlake/chip.h index 2721da6..5675b54 100644 --- a/src/soc/intel/alderlake/chip.h +++ b/src/soc/intel/alderlake/chip.h @@ -11,6 +11,8 @@ #include <soc/pch.h> #include <soc/pci_devs.h> #include <soc/pmc.h> +#include <soc/serialio.h> +#include <soc/usb.h> #include <stdint.h>
#define MAX_HD_AUDIO_DMIC_LINKS 2 @@ -239,10 +241,6 @@ /* Enable Pch iSCLK */ uint8_t pch_isclk;
- /* CNVi */ - uint8_t CnviMode; - uint8_t CnviBtCore; - /* CNVi BT Audio Offload: Enable/Disable BT Audio Offload. */ enum { FORCE_DISABLE, @@ -250,6 +248,19 @@ } CnviBtAudioOffload;
/* + * IOM Port Config + * If a port orientation needs to be controlled by the SOC this setting must be + * updated to reflect the correct GPIOs being used for the SOC port flipping. + * There are 4 ports each with a pair of GPIOs for Pull Up and Pull Down + * 0,1 are pull up and pull down for port 0 + * 2,3 are pull up and pull down for port 1 + * 4,5 are pull up and pull down for port 2 + * 6,7 are pull up and pull down for port 3 + * values to be programmed correspond to the GPIO family and offsets + */ + uint32_t IomTypeCPortPadCfg[8]; + + /* * SOC Aux orientation override: * This is a bitfield that corresponds to up to 4 TCSS ports on ADL. * Even numbered bits (0, 2, 4, 6) control the retimer being handled by SOC. diff --git a/src/soc/intel/alderlake/cpu.c b/src/soc/intel/alderlake/cpu.c new file mode 100644 index 0000000..ee8051d --- /dev/null +++ b/src/soc/intel/alderlake/cpu.c @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor CPU Datasheet + * Document number: 619501 + * Chapter number: 14 + */ + +#include <arch/cpu.h> +#include <console/console.h> +#include <device/pci.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/intel/smm_reloc.h> +#include <cpu/intel/turbo.h> +#include <fsp/api.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/mp_init.h> +#include <intelblocks/msr.h> +#include <romstage_handoff.h> +#include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_chip.h> + +static void soc_fsp_load(void) +{ + fsps_load(romstage_handoff_is_resume()); +} + +static void configure_isst(void) +{ + config_t *conf = config_of_soc(); + msr_t msr; + + if (conf->speed_shift_enable) { + /* + * Kernel driver checks CPUID.06h:EAX[Bit 7] to determine if HWP + * is supported or not. coreboot needs to configure MSR 0x1AA + * which is then reflected in the CPUID register. + */ + msr = rdmsr(MSR_MISC_PWR_MGMT); + msr.lo |= MISC_PWR_MGMT_ISST_EN; /* Enable Speed Shift */ + msr.lo |= MISC_PWR_MGMT_ISST_EN_INT; /* Enable Interrupt */ + msr.lo |= MISC_PWR_MGMT_ISST_EN_EPP; /* Enable EPP */ + wrmsr(MSR_MISC_PWR_MGMT, msr); + } else { + msr = rdmsr(MSR_MISC_PWR_MGMT); + msr.lo &= ~MISC_PWR_MGMT_ISST_EN; /* Disable Speed Shift */ + msr.lo &= ~MISC_PWR_MGMT_ISST_EN_INT; /* Disable Interrupt */ + msr.lo &= ~MISC_PWR_MGMT_ISST_EN_EPP; /* Disable EPP */ + wrmsr(MSR_MISC_PWR_MGMT, msr); + } +} + +static void configure_misc(void) +{ + msr_t msr; + + config_t *conf = config_of_soc(); + + msr = rdmsr(IA32_MISC_ENABLE); + msr.lo |= (1 << 0); /* Fast String enable */ + msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ + wrmsr(IA32_MISC_ENABLE, msr); + + /* Set EIST status */ + cpu_set_eist(conf->eist_enable); + + /* Disable Thermal interrupts */ + msr.lo = 0; + msr.hi = 0; + wrmsr(IA32_THERM_INTERRUPT, msr); + + /* Enable package critical interrupt only */ + msr.lo = 1 << 4; + msr.hi = 0; + wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr); + + /* Enable PROCHOT */ + 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); +} + +static void enable_lapic_tpr(void) +{ + msr_t msr; + + msr = rdmsr(MSR_PIC_MSG_CONTROL); + msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */ + wrmsr(MSR_PIC_MSG_CONTROL, msr); +} + +static void configure_dca_cap(void) +{ + uint32_t feature_flag; + msr_t msr; + + /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */ + feature_flag = cpu_get_feature_flags_ecx(); + if (feature_flag & CPUID_DCA) { + msr = rdmsr(IA32_PLATFORM_DCA_CAP); + msr.lo |= 1; + wrmsr(IA32_PLATFORM_DCA_CAP, msr); + } +} + +static void enable_pm_timer_emulation(void) +{ + /* ACPI PM timer emulation */ + msr_t msr; + /* + * The derived frequency is calculated as follows: + * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. + * Back solve the multiplier so the 3.579545MHz ACPI timer + * frequency is used. + */ + msr.hi = (3579545ULL << 32) / CTC_FREQ; + /* Set PM1 timer IO port and enable */ + msr.lo = (EMULATE_DELAY_VALUE << EMULATE_DELAY_OFFSET_VALUE) | + EMULATE_PM_TMR_EN | (ACPI_BASE_ADDRESS + PM1_TMR); + wrmsr(MSR_EMULATE_PM_TIMER, msr); +} + +static void set_energy_perf_bias(u8 policy) +{ + msr_t msr; + int ecx; + + /* Determine if energy efficient policy is supported. */ + ecx = cpuid_ecx(0x6); + if (!(ecx & (1 << 3))) + return; + + /* Energy Policy is bits 3:0 */ + msr = rdmsr(IA32_ENERGY_PERF_BIAS); + msr.lo &= ~0xf; + msr.lo |= policy & 0xf; + wrmsr(IA32_ENERGY_PERF_BIAS, msr); +} + +/* All CPUs including BSP will run the following function. */ +void soc_core_init(struct device *cpu) +{ + /* Clear out pending MCEs */ + /* TODO(adurbin): This should only be done on a cold boot. Also, some + * of these banks are core vs package scope. For now every CPU clears + * every bank. */ + mca_configure(); + + /* Enable the local CPU apics */ + enable_lapic_tpr(); + setup_lapic(); + + /* Configure Enhanced SpeedStep and Thermal Sensors */ + configure_misc(); + + /* Configure Intel Speed Shift */ + configure_isst(); + + /* Enable PM timer emulation */ + enable_pm_timer_emulation(); + + /* Enable Direct Cache Access */ + configure_dca_cap(); + + /* Set energy policy */ + set_energy_perf_bias(ENERGY_POLICY_NORMAL); + + /* Enable Turbo */ + enable_turbo(); +} + +static void per_cpu_smm_trigger(void) +{ + /* Relocate the SMM handler. */ + smm_relocate(); +} + +static void post_mp_init(void) +{ + /* Set Max Ratio */ + cpu_set_max_ratio(); + + /* + * Now that all APs have been relocated as well as the BSP let SMIs + * 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. + */ + .pre_mp_init = soc_fsp_load, + .get_cpu_count = get_cpu_count, + .get_smm_info = smm_info, + .get_microcode_info = get_microcode_info, + .pre_mp_smm_init = smm_initialize, + .per_cpu_smm_trigger = per_cpu_smm_trigger, + .relocation_handler = smm_relocation_handler, + .post_mp_init = post_mp_init, +}; + +void soc_init_cpus(struct bus *cpu_bus) +{ + if (mp_init_with_smm(cpu_bus, &mp_ops)) + printk(BIOS_ERR, "MP initialization failure.\n"); + + /* Thermal throttle activation offset */ + configure_tcc_thermal_target(); +} diff --git a/src/soc/intel/alderlake/elog.c b/src/soc/intel/alderlake/elog.c new file mode 100644 index 0000000..84f0a7e --- /dev/null +++ b/src/soc/intel/alderlake/elog.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootstate.h> +#include <console/console.h> +#include <stdint.h> +#include <elog.h> +#include <intelblocks/pmclib.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> + +static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start) +{ + int i; + + gpe0_sts &= gpe0_en; + + for (i = 0; i <= 31; i++) { + if (gpe0_sts & (1 << i)) + elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start); + } +} + +static void pch_log_wake_source(struct chipset_power_state *ps) +{ + /* Power Button */ + if (ps->pm1_sts & PWRBTN_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0); + + /* RTC */ + if (ps->pm1_sts & RTC_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0); + + /* PCI Express (TODO: determine wake device) */ + if (ps->pm1_sts & PCIEXPWAK_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0); + + /* PME (TODO: determine wake device) */ + if (ps->gpe0_sts[GPE_STD] & PME_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0); + + /* Internal PME (TODO: determine wake device) */ + if (ps->gpe0_sts[GPE_STD] & PME_B0_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0); + + /* SMBUS Wake */ + if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0); + + /* Log GPIO events in set 1-3 */ + pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64); + /* Treat the STD as an extension of GPIO to obtain visibility. */ + pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96); +} + +static void pch_log_power_and_resets(struct chipset_power_state *ps) +{ + /* Thermal Trip */ + if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP) + elog_add_event(ELOG_TYPE_THERM_TRIP); + + /* CSME-Initiated Host Reset with power down */ + if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPD) + elog_add_event(ELOG_TYPE_MI_HRPD); + + /* CSME-Initiated Host Reset with power cycle */ + if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPC) + elog_add_event(ELOG_TYPE_MI_HRPC); + + /* CSME-Initiated Host Reset without power cycle */ + if (ps->hpr_cause0 & HPR_CAUSE0_MI_HR) + elog_add_event(ELOG_TYPE_MI_HR); + + /* PWR_FLR Power Failure */ + if (ps->gen_pmcon_a & PWR_FLR) + elog_add_event(ELOG_TYPE_POWER_FAIL); + + /* SUS Well Power Failure */ + if (ps->gen_pmcon_a & SUS_PWR_FLR) + elog_add_event(ELOG_TYPE_SUS_POWER_FAIL); + + /* TCO Timeout */ + if (ps->prev_sleep_state != ACPI_S3 && + ps->tco2_sts & TCO_STS_SECOND_TO) + elog_add_event(ELOG_TYPE_TCO_RESET); + + /* Power Button Override */ + if (ps->pm1_sts & PRBTNOR_STS) + elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE); + + /* RTC reset */ + if (ps->gen_pmcon_b & RTC_BATTERY_DEAD) + elog_add_event(ELOG_TYPE_RTC_RESET); + + /* Host Reset Status */ + if (ps->gen_pmcon_a & HOST_RST_STS) + elog_add_event(ELOG_TYPE_SYSTEM_RESET); + + /* ACPI Wake Event */ + if (ps->prev_sleep_state != ACPI_S0) + elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state); +} + +static void pch_log_state(void *unused) +{ + struct chipset_power_state *ps = pmc_get_power_state(); + + if (!ps) { + printk(BIOS_ERR, "chipset_power_state not found!\n"); + return; + } + + /* Power and Reset */ + pch_log_power_and_resets(ps); + + /* Wake Sources */ + if (ps->prev_sleep_state > ACPI_S0) + pch_log_wake_source(ps); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pch_log_state, NULL); + +void elog_gsmi_cb_platform_log_wake_source(void) +{ + struct chipset_power_state ps; + pmc_fill_pm_reg_info(&ps); + pch_log_wake_source(&ps); +} diff --git a/src/soc/intel/alderlake/espi.c b/src/soc/intel/alderlake/espi.c index bad4ab9..9fe9505 100644 --- a/src/soc/intel/alderlake/espi.c +++ b/src/soc/intel/alderlake/espi.c @@ -9,10 +9,14 @@ #include <device/pci.h> #include <pc80/isa-dma.h> #include <pc80/i8259.h> +#include <arch/ioapic.h> +#include <intelblocks/itss.h> #include <intelblocks/lpc_lib.h> #include <intelblocks/pcr.h> #include <soc/espi.h> #include <soc/iomap.h> +#include <soc/irq.h> +#include <soc/pci_devs.h> #include <soc/pcr_ids.h> #include <soc/soc_chip.h>
@@ -49,3 +53,144 @@ pcr_write32(PID_DMI, PCR_DMI_LPCLGIR3, gen_io_dec[2]); pcr_write32(PID_DMI, PCR_DMI_LPCLGIR4, gen_io_dec[3]); } + +#if ENV_RAMSTAGE +static void soc_mirror_dmi_pcr_io_dec(void) +{ + struct device *dev = pcidev_on_root(PCH_DEV_SLOT_ESPI, 0); + uint32_t io_dec_arr[] = { + pci_read_config32(dev, ESPI_GEN1_DEC), + pci_read_config32(dev, ESPI_GEN2_DEC), + pci_read_config32(dev, ESPI_GEN3_DEC), + pci_read_config32(dev, ESPI_GEN4_DEC), + }; + /* Mirror these same settings in DMI PCR */ + soc_setup_dmi_pcr_io_dec(&io_dec_arr[0]); +} + +static void pch_enable_ioapic(const struct device *dev) +{ + u32 reg32; + /* PCH-LP has 120 redirection entries */ + const int redir_entries = 120; + + set_ioapic_id((void *)IO_APIC_ADDR, 0x02); + + /* affirm full set of redirection table entries ("write once") */ + reg32 = io_apic_read((void *)IO_APIC_ADDR, 0x01); + + reg32 &= ~0x00ff0000; + reg32 |= (redir_entries - 1) << 16; + + io_apic_write((void *)IO_APIC_ADDR, 0x01, reg32); + + /* + * Select Boot Configuration register (0x03) and + * use Processor System Bus (0x01) to deliver interrupts. + */ + io_apic_write((void *)IO_APIC_ADDR, 0x03, 0x01); +} +/* + * PIRQ[n]_ROUT[3:0] - PIRQ Routing Control + * 0x00 - 0000 = Reserved + * 0x01 - 0001 = Reserved + * 0x02 - 0010 = Reserved + * 0x03 - 0011 = IRQ3 + * 0x04 - 0100 = IRQ4 + * 0x05 - 0101 = IRQ5 + * 0x06 - 0110 = IRQ6 + * 0x07 - 0111 = IRQ7 + * 0x08 - 1000 = Reserved + * 0x09 - 1001 = IRQ9 + * 0x0A - 1010 = IRQ10 + * 0x0B - 1011 = IRQ11 + * 0x0C - 1100 = IRQ12 + * 0x0D - 1101 = Reserved + * 0x0E - 1110 = IRQ14 + * 0x0F - 1111 = IRQ15 + * PIRQ[n]_ROUT[7] - PIRQ Routing Control + * 0x80 - The PIRQ is not routed. + */ + +void soc_pch_pirq_init(const struct device *dev) +{ + struct device *irq_dev; + uint8_t pch_interrupt_routing[MAX_PXRC_CONFIG]; + + pch_interrupt_routing[0] = PCH_IRQ11; + pch_interrupt_routing[1] = PCH_IRQ10; + pch_interrupt_routing[2] = PCH_IRQ11; + pch_interrupt_routing[3] = PCH_IRQ11; + pch_interrupt_routing[4] = PCH_IRQ11; + pch_interrupt_routing[5] = PCH_IRQ11; + pch_interrupt_routing[6] = PCH_IRQ11; + pch_interrupt_routing[7] = PCH_IRQ11; + + itss_irq_init(pch_interrupt_routing); + + for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) { + u8 int_pin = 0, int_line = 0; + + if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI) + continue; + + int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN); + + switch (int_pin) { + case 1: /* INTA# */ + int_line = PCH_IRQ11; + break; + case 2: /* INTB# */ + int_line = PCH_IRQ10; + break; + case 3: /* INTC# */ + int_line = PCH_IRQ11; + break; + case 4: /* INTD# */ + int_line = PCH_IRQ11; + break; + } + + if (!int_line) + continue; + + pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line); + } +} + +static void pch_misc_init(void) +{ + uint8_t reg8; + + /* Setup NMI on errors, disable SERR */ + reg8 = (inb(0x61)) & 0xf0; + outb((reg8 | (1 << 2)), 0x61); + + /* Disable NMI sources */ + outb((1 << 7), 0x70); +}; + +void lpc_soc_init(struct device *dev) +{ + /* Legacy initialization */ + isa_dma_init(); + pch_misc_init(); + + /* Enable CLKRUN_EN for power gating ESPI */ + lpc_enable_pci_clk_cntl(); + + /* Set ESPI Serial IRQ mode */ + if (CONFIG(SERIRQ_CONTINUOUS_MODE)) + lpc_set_serirq_mode(SERIRQ_CONTINUOUS); + else + lpc_set_serirq_mode(SERIRQ_QUIET); + + /* Interrupt configuration */ + pch_enable_ioapic(dev); + soc_pch_pirq_init(dev); + setup_i8259(); + i8259_configure_irq_trigger(9, 1); + soc_mirror_dmi_pcr_io_dec(); +} + +#endif diff --git a/src/soc/intel/alderlake/finalize.c b/src/soc/intel/alderlake/finalize.c new file mode 100644 index 0000000..f3576ef --- /dev/null +++ b/src/soc/intel/alderlake/finalize.c @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4, 29 + */ + +#include <arch/io.h> +#include <device/mmio.h> +#include <bootstate.h> +#include <console/console.h> +#include <console/post_codes.h> +#include <cpu/x86/smm.h> +#include <device/pci.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/pcr.h> +#include <intelblocks/tco.h> +#include <intelblocks/thermal.h> +#include <spi-generic.h> +#include <soc/p2sb.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> +#include <soc/pm.h> +#include <soc/smbus.h> +#include <soc/soc_chip.h> +#include <soc/systemagent.h> + +#define CAMERA1_CLK 0x8000 /* Camera 1 Clock */ +#define CAMERA2_CLK 0x8080 /* Camera 2 Clock */ +#define CAM_CLK_EN (1 << 1) +#define MIPI_CLK (1 << 0) +#define HDPLL_CLK (0 << 0) + +static void pch_enable_isclk(void) +{ + pcr_or32(PID_ISCLK, CAMERA1_CLK, CAM_CLK_EN | MIPI_CLK); + pcr_or32(PID_ISCLK, CAMERA2_CLK, CAM_CLK_EN | MIPI_CLK); +} + +static void pch_handle_sideband(config_t *config) +{ + if (config->pch_isclk) + pch_enable_isclk(); +} + +static void pch_finalize(void) +{ + uint32_t reg32; + uint8_t *pmcbase; + config_t *config; + uint8_t reg8; + + /* TCO Lock down */ + tco_lockdown(); + + /* TODO: Add Thermal Configuration */ + + /* + * Disable ACPI PM timer based on dt policy + * + * Disabling ACPI PM timer is necessary for XTAL OSC shutdown. + * Disabling ACPI PM timer also switches off TCO + * + * SA_DEV_ROOT device is used here instead of PCH_DEV_PMC since it is + * just required to get to chip config. PCH_DEV_PMC is hidden by this + * point and hence removed from the root bus. pcidev_path_on_root thus + * returns NULL for PCH_DEV_PMC device. + */ + config = config_of_soc(); + pmcbase = pmc_mmio_regs(); + if (config->PmTimerDisabled) { + reg8 = read8(pmcbase + PCH_PWRM_ACPI_TMR_CTL); + reg8 |= (1 << 1); + write8(pmcbase + PCH_PWRM_ACPI_TMR_CTL, reg8); + } + + /* Disable XTAL shutdown qualification for low power idle. */ + if (config->s0ix_enable) { + reg32 = read32(pmcbase + CPPMVRIC); + reg32 |= XTALSDQDIS; + write32(pmcbase + CPPMVRIC, reg32); + } + + pch_handle_sideband(config); + + pmc_clear_pmcon_sts(); +} + +static void tbt_finalize(void) +{ + int i; + const struct device *dev; + + /* Disable Thunderbolt PCIe root ports bus master */ + for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { + dev = pcidev_path_on_root(SA_DEVFN_TBT(i)); + if (dev) + pci_dev_disable_bus_master(dev); + } +} + +static void soc_finalize(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); + + /* Indicate finalize step with post code */ + post_code(POST_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/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c new file mode 100644 index 0000000..572fc79 --- /dev/null +++ b/src/soc/intel/alderlake/fsp_params.c @@ -0,0 +1,323 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <assert.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <fsp/api.h> +#include <fsp/ppi/mp_service_ppi.h> +#include <fsp/util.h> +#include <intelblocks/lpss.h> +#include <intelblocks/xdci.h> +#include <intelpch/lockdown.h> +#include <intelblocks/mp_init.h> +#include <soc/gpio_soc_defs.h> +#include <soc/intel/common/vbt.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/soc_chip.h> +#include <string.h> + +/* THC assignment definition */ +#define THC_NONE 0 +#define THC_0 1 +#define THC_1 2 + +/* SATA DEVSLP idle timeout default values */ +#define DEF_DMVAL 15 +#define DEF_DITOVAL 625 + +/* + * Chip config parameter PcieRpL1Substates uses (UPD value + 1) + * because UPD value of 0 for PcieRpL1Substates means disabled for FSP. + * In order to ensure that mainboard setting does not disable L1 substates + * incorrectly, chip config parameter values are offset by 1 with 0 meaning + * use FSP UPD default. get_l1_substate_control() ensures that the right UPD + * value is set in fsp_params. + * 0: Use FSP UPD default + * 1: Disable L1 substates + * 2: Use L1.1 + * 3: Use L1.2 (FSP UPD default) + */ +static int get_l1_substate_control(enum L1_substates_control ctl) +{ + if ((ctl > L1_SS_L1_2) || (ctl == L1_SS_FSP_DEFAULT)) + ctl = L1_SS_L1_2; + return ctl - 1; +} + +static void parse_devicetree(FSP_S_CONFIG *params) +{ + const struct soc_intel_alderlake_config *config; + config = config_of_soc(); + + for (int i = 0; i < CONFIG_SOC_INTEL_I2C_DEV_MAX; i++) + params->SerialIoI2cMode[i] = config->SerialIoI2cMode[i]; + + for (int i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++) { + params->SerialIoSpiMode[i] = config->SerialIoGSpiMode[i]; + params->SerialIoSpiCsMode[i] = config->SerialIoGSpiCsMode[i]; + params->SerialIoSpiCsState[i] = config->SerialIoGSpiCsState[i]; + } + + for (int i = 0; i < CONFIG_SOC_INTEL_UART_DEV_MAX; i++) + params->SerialIoUartMode[i] = config->SerialIoUartMode[i]; +} + +static const pci_devfn_t serial_io_dev[] = { + PCH_DEVFN_I2C0, + PCH_DEVFN_I2C1, + PCH_DEVFN_I2C2, + PCH_DEVFN_I2C3, + PCH_DEVFN_I2C4, + PCH_DEVFN_I2C5, + PCH_DEVFN_GSPI0, + PCH_DEVFN_GSPI1, + PCH_DEVFN_GSPI2, + PCH_DEVFN_GSPI3, + PCH_DEVFN_UART0, + PCH_DEVFN_UART1, + PCH_DEVFN_UART2 +}; + +__weak void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config) +{ + /* Override settings per board. */ +} + +/* UPD parameters to be initialized before SiliconInit */ +void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) +{ + int i; + FSP_S_CONFIG *params = &supd->FspsConfig; + + struct device *dev; + struct soc_intel_alderlake_config *config; + config = config_of_soc(); + mainboard_update_soc_chip_config(config); + + /* Parse device tree and enable/disable Serial I/O devices */ + parse_devicetree(params); + + /* Load VBT before devicetree-specific config. */ + params->GraphicsConfigPtr = (uintptr_t)vbt_get(); + + /* Check if IGD is present and fill Graphics init param accordingly */ + dev = pcidev_path_on_root(SA_DEVFN_IGD); + params->PeiGraphicsPeimInit = CONFIG(RUN_FSP_GOP) && is_dev_enabled(dev); + + /* Use coreboot MP PPI services if Kconfig is enabled */ + if (CONFIG(USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI)) + params->CpuMpPpi = (uintptr_t) mp_fill_ppi_services_data(); + + /* D3Hot and D3Cold for TCSS */ + params->D3HotEnable = !config->TcssD3HotDisable; + params->D3ColdEnable = !config->TcssD3ColdDisable; + + params->TcssAuxOri = config->TcssAuxOri; + for (i = 0; i < 8; i++) + params->IomTypeCPortPadCfg[i] = config->IomTypeCPortPadCfg[i]; + + /* + * Set FSPS UPD ITbtConnectTopologyTimeoutInMs with value 0. FSP will + * evaluate this UPD value and skip sending command. There will be no + * delay for command completion. + */ + params->ITbtConnectTopologyTimeoutInMs = 0; + + /* Chipset Lockdown */ + if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) { + params->PchLockDownGlobalSmi = 0; + params->PchLockDownBiosInterface = 0; + params->PchUnlockGpioPads = 1; + params->RtcMemoryLock = 0; + } else { + params->PchLockDownGlobalSmi = 1; + params->PchLockDownBiosInterface = 1; + params->PchUnlockGpioPads = 0; + params->RtcMemoryLock = 1; + } + + /* USB */ + for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) { + params->PortUsb20Enable[i] = config->usb2_ports[i].enable; + params->Usb2PhyPetxiset[i] = config->usb2_ports[i].pre_emp_bias; + params->Usb2PhyTxiset[i] = config->usb2_ports[i].tx_bias; + params->Usb2PhyPredeemp[i] = config->usb2_ports[i].tx_emp_enable; + params->Usb2PhyPehalfbit[i] = config->usb2_ports[i].pre_emp_bit; + + if (config->usb2_ports[i].enable) + params->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin; + else + params->Usb2OverCurrentPin[i] = 0xff; + } + + for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) { + params->PortUsb30Enable[i] = config->usb3_ports[i].enable; + if (config->usb3_ports[i].enable) { + params->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin; + } else { + params->Usb3OverCurrentPin[i] = 0xff; + } + if (config->usb3_ports[i].tx_de_emp) { + params->Usb3HsioTxDeEmphEnable[i] = 1; + params->Usb3HsioTxDeEmph[i] = config->usb3_ports[i].tx_de_emp; + } + if (config->usb3_ports[i].tx_downscale_amp) { + params->Usb3HsioTxDownscaleAmpEnable[i] = 1; + params->Usb3HsioTxDownscaleAmp[i] = + config->usb3_ports[i].tx_downscale_amp; + } + } + + /* Enable xDCI controller if enabled in devicetree and allowed */ + dev = pcidev_path_on_root(PCH_DEVFN_USBOTG); + if (dev) { + if (!xdci_can_enable()) + dev->enabled = 0; + params->XdciEnable = dev->enabled; + } else { + params->XdciEnable = 0; + } + + /* PCH UART selection for FSP Debug */ + params->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE; + ASSERT(ARRAY_SIZE(params->SerialIoUartAutoFlow) > CONFIG_UART_FOR_CONSOLE); + params->SerialIoUartAutoFlow[CONFIG_UART_FOR_CONSOLE] = 0; + + /* SATA */ + dev = pcidev_path_on_root(PCH_DEVFN_SATA); + params->SataEnable = is_dev_enabled(dev); + if (params->SataEnable) { + params->SataMode = config->SataMode; + params->SataSalpSupport = config->SataSalpSupport; + memcpy(params->SataPortsEnable, config->SataPortsEnable, + sizeof(params->SataPortsEnable)); + memcpy(params->SataPortsDevSlp, config->SataPortsDevSlp, + sizeof(params->SataPortsDevSlp)); + } + + /* + * Power Optimizer for DMI and SATA. + * DmiPwrOptimizeDisable and SataPwrOptimizeDisable is default to 0. + * Boards not needing the optimizers explicitly disables them by setting + * these disable variables to 1 in devicetree overrides. + */ + params->PchPwrOptEnable = !(config->DmiPwrOptimizeDisable); + params->SataPwrOptEnable = !(config->SataPwrOptimizeDisable); + + /* + * Enable DEVSLP Idle Timeout settings DmVal and DitoVal. + * SataPortsDmVal is the DITO multiplier. Default is 15. + * SataPortsDitoVal is the DEVSLP Idle Timeout (DITO), Default is 625ms. + * The default values can be changed from devicetree. + */ + for (i = 0; i < ARRAY_SIZE(config->SataPortsEnableDitoConfig); i++) { + if (config->SataPortsEnableDitoConfig[i]) { + if (config->SataPortsDmVal[i]) + params->SataPortsDmVal[i] = config->SataPortsDmVal[i]; + else + params->SataPortsDmVal[i] = DEF_DMVAL; + + if (config->SataPortsDitoVal[i]) + params->SataPortsDitoVal[i] = config->SataPortsDitoVal[i]; + else + params->SataPortsDitoVal[i] = DEF_DITOVAL; + } + } + + /* Enable TCPU for processor thermal control */ + params->Device4Enable = config->Device4Enable; + + /* Set TccActivationOffset */ + params->TccActivationOffset = config->tcc_offset; + + /* LAN */ + dev = pcidev_path_on_root(PCH_DEVFN_GBE); + params->PchLanEnable = is_dev_enabled(dev); + + /* CNVi */ + dev = pcidev_path_on_root(PCH_DEVFN_CNVI_WIFI); + params->CnviMode = is_dev_enabled(dev); + + /* CNVi BT Core */ + dev = pcidev_path_on_root(PCH_DEVFN_CNVI_BT); + params->CnviBtCore = is_dev_enabled(dev); + + /* CNVi BT Audio Offload */ + params->CnviBtAudioOffload = config->CnviBtAudioOffload; + + /* VMD */ + dev = pcidev_path_on_root(SA_DEVFN_VMD); + params->VmdEnable = is_dev_enabled(dev); + + /* THC */ + dev = pcidev_path_on_root(PCH_DEVFN_THC0); + params->ThcPort0Assignment = is_dev_enabled(dev) ? THC_0 : THC_NONE; + + dev = pcidev_path_on_root(PCH_DEVFN_THC1); + params->ThcPort1Assignment = is_dev_enabled(dev) ? THC_1 : THC_NONE; + + /* Legacy 8254 timer support */ + params->Enable8254ClockGating = !CONFIG(USE_LEGACY_8254_TIMER); + params->Enable8254ClockGatingOnS3 = !CONFIG(USE_LEGACY_8254_TIMER); + + /* Enable Hybrid storage auto detection */ + params->HybridStorageMode = config->HybridStorageMode; + + for (i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) { + params->PcieRpL1Substates[i] = + get_l1_substate_control(config->PcieRpL1Substates[i]); + params->PcieRpLtrEnable[i] = config->PcieRpLtrEnable[i]; + params->PcieRpAdvancedErrorReporting[i] = + config->PcieRpAdvancedErrorReporting[i]; + params->PcieRpHotPlug[i] = config->PcieRpHotPlug[i]; + } + + /* Enable ClkReqDetect for enabled port */ + memcpy(params->PcieRpClkReqDetect, config->PcieRpClkReqDetect, + sizeof(config->PcieRpClkReqDetect)); + + params->PmSupport = 1; + params->Hwp = 1; + params->Cx = 1; + params->PsOnEnable = 1; + + mainboard_silicon_init_params(params); +} + +int soc_fsp_multi_phase_init_is_enable(void) +{ + return 0; +} + +/* + * Callbacks for SoC/Mainboard specific overrides for FspMultiPhaseSiInit + * This platform supports below MultiPhaseSIInit Phase(s): + * Phase | FSP return point | Purpose + * ------- + ------------------------------------------------ + ------------------------------- + * 1 | After TCSS initialization completed | for TCSS specific init + */ +void platform_fsp_multi_phase_init_cb(uint32_t phase_index) +{ + switch (phase_index) { + case 1: + /* TCSS specific initialization here */ + break; + default: + break; + } +} + +/* Mainboard GPIO Configuration */ +__weak void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__); +} + +/* Return list of SOC LPSS controllers */ +const pci_devfn_t *soc_lpss_controllers_list(size_t *size) +{ + *size = ARRAY_SIZE(serial_io_dev); + return serial_io_dev; +} diff --git a/src/soc/intel/alderlake/gspi.c b/src/soc/intel/alderlake/gspi.c new file mode 100644 index 0000000..dd07b07 --- /dev/null +++ b/src/soc/intel/alderlake/gspi.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 11 + */ + +#include <intelblocks/gspi.h> +#include <soc/pci_devs.h> + +int gspi_soc_bus_to_devfn(unsigned int gspi_bus) +{ + switch (gspi_bus) { + case 0: + return PCH_DEVFN_GSPI0; + case 1: + return PCH_DEVFN_GSPI1; + case 2: + return PCH_DEVFN_GSPI2; + case 3: + return PCH_DEVFN_GSPI3; + } + return -1; +} diff --git a/src/soc/intel/alderlake/i2c.c b/src/soc/intel/alderlake/i2c.c new file mode 100644 index 0000000..ef34e2e --- /dev/null +++ b/src/soc/intel/alderlake/i2c.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 13 + */ + +#include <device/device.h> +#include <drivers/i2c/designware/dw_i2c.h> +#include <soc/pci_devs.h> + +int dw_i2c_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { + case PCH_DEVFN_I2C0: + return 0; + case PCH_DEVFN_I2C1: + return 1; + case PCH_DEVFN_I2C2: + return 2; + case PCH_DEVFN_I2C3: + return 3; + case PCH_DEVFN_I2C4: + return 4; + case PCH_DEVFN_I2C5: + return 5; + } + return -1; +} + +int dw_i2c_soc_bus_to_devfn(unsigned int bus) +{ + switch (bus) { + case 0: + return PCH_DEVFN_I2C0; + case 1: + return PCH_DEVFN_I2C1; + case 2: + return PCH_DEVFN_I2C2; + case 3: + return PCH_DEVFN_I2C3; + case 4: + return PCH_DEVFN_I2C4; + case 5: + return PCH_DEVFN_I2C5; + } + return -1; +} diff --git a/src/soc/intel/alderlake/include/soc/cpu.h b/src/soc/intel/alderlake/include/soc/cpu.h new file mode 100644 index 0000000..7fdf7d1 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/cpu.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_ALDERLAKE_CPU_H_ +#define _SOC_ALDERLAKE_CPU_H_ + +#include <intelblocks/msr.h> + +/* Latency times in us */ +#define C1_LATENCY 1 +#define C6_LATENCY 127 +#define C7_LATENCY 253 +#define C8_LATENCY 260 +#define C9_LATENCY 487 +#define C10_LATENCY 1048 + +/* Power in units of mW */ +#define C1_POWER 0x3e8 +#define C6_POWER 0x15e +#define C7_POWER 0xc8 +#define C8_POWER 0xc8 +#define C9_POWER 0xc8 +#define C10_POWER 0xc8 + +/* Common Timer Copy (CTC) frequency - 38.4MHz. */ +#define CTC_FREQ 38400000 + +#endif diff --git a/src/soc/intel/alderlake/include/soc/irq.h b/src/soc/intel/alderlake/include/soc/irq.h new file mode 100644 index 0000000..98e3f42 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/irq.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_IRQ_H_ +#define _SOC_IRQ_H_ + +#define GPIO_IRQ14 14 +#define GPIO_IRQ15 15 + +#define PCH_IRQ10 10 +#define PCH_IRQ11 11 + +#define LPSS_I2C0_IRQ 27 +#define LPSS_I2C1_IRQ 40 +#define LPSS_I2C2_IRQ 29 +#define LPSS_I2C3_IRQ 30 +#define LPSS_I2C4_IRQ 31 +#define LPSS_I2C5_IRQ 32 +#define LPSS_SPI0_IRQ 36 +#define LPSS_SPI1_IRQ 37 +#define LPSS_SPI2_IRQ 34 +#define LPSS_SPI3_IRQ 43 + +#define LPSS_UART0_IRQ 16 +#define LPSS_UART1_IRQ 17 +#define LPSS_UART2_IRQ 33 + +#define HDA_IRQ 16 +#define SMBUS_IRQ 16 +#define TRACEHUB_IRQ 16 + +#define PCIE_1_IRQ 16 +#define PCIE_2_IRQ 17 +#define PCIE_3_IRQ 18 +#define PCIE_4_IRQ 19 +#define PCIE_5_IRQ 16 +#define PCIE_6_IRQ 17 +#define PCIE_7_IRQ 18 +#define PCIE_8_IRQ 19 +#define PCIE_9_IRQ 16 +#define PCIE_10_IRQ 17 +#define PCIE_11_IRQ 18 +#define PCIE_12_IRQ 19 + +#define SATA_IRQ 16 + +#define xHCI_IRQ 16 +#define xDCI_IRQ 17 +#define CNVI_WIFI_IRQ 16 + +#define CNVI_BT_IRQ 18 + +#define THC0_IRQ 23 +#define THC1_IRQ 24 + +#define ISH_IRQ 16 + +#define TBT_PCIe0_IRQ 16 +#define TBT_PCIe1_IRQ 17 +#define TBT_PCIe2_IRQ 18 +#define TBT_PCIe3_IRQ 19 + +#define HECI_1_IRQ 16 +#define HECI_2_IRQ 17 +#define HECI_3_IRQ 16 +#define HECI_4_IRQ 19 + +#define PEG_IRQ 16 +#define IGFX_IRQ 16 +#define THERMAL_IRQ 16 +#define IPU_IRQ 16 +#define GNA_IRQ 16 +#endif diff --git a/src/soc/intel/alderlake/include/soc/itss.h b/src/soc/intel/alderlake/include/soc/itss.h new file mode 100644 index 0000000..ff26c9f --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/itss.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_INTEL_ADL_ITSS_H +#define SOC_INTEL_ADL_ITSS_H + +#define GPIO_IRQ_START 50 +#define GPIO_IRQ_END ITSS_MAX_IRQ + +#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_INTEL_ADL_ITSS_H */ diff --git a/src/soc/intel/alderlake/include/soc/me.h b/src/soc/intel/alderlake/include/soc/me.h new file mode 100644 index 0000000..a4aea89 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/me.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ALDERLAKE_ME_H_ +#define _ALDERLAKE_ME_H_ + +/* ME Host Firmware Status register 1 */ +union me_hfsts1 { + u32 data; + struct { + u32 working_state: 4; + u32 spi_protection_mode: 1; + u32 fpt_bad: 1; + u32 operation_state: 3; + u32 fw_init_complete: 1; + u32 ft_bup_ld_flr: 1; + u32 update_in_progress: 1; + u32 error_code: 4; + u32 operation_mode: 4; + u32 reset_count: 4; + u32 boot_options_present: 1; + u32 invoke_enhance_dbg_mode: 1; + u32 bist_test_state: 1; + u32 bist_reset_request: 1; + u32 current_power_source: 2; + u32 reserved: 1; + u32 d0i3_support_valid: 1; + } __packed fields; +}; + +/* ME Host Firmware Status Register 3 */ +union me_hfsts3 { + u32 data; + struct { + u32 reserved_0: 4; + u32 fw_sku: 3; + u32 reserved_7: 2; + u32 reserved_9: 2; + u32 resered_11: 3; + u32 resered_14: 16; + u32 reserved_30: 2; + } __packed fields; +}; +#endif /* _ALDERLAKE_ME_H_ */ diff --git a/src/soc/intel/alderlake/include/soc/meminit.h b/src/soc/intel/alderlake/include/soc/meminit.h new file mode 100644 index 0000000..9733f2e --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/meminit.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_ALDERLAKE_MEMINIT_H_ +#define _SOC_ALDERLAKE_MEMINIT_H_ + +#include <stddef.h> +#include <stdint.h> +#include <fsp/soc_binding.h> + +#define BYTES_PER_CHANNEL 2 +#define BITS_PER_BYTE 8 +#define DQS_PER_CHANNEL 2 + +/* 64-bit Channel identification */ +enum { + DDR_CH0, + DDR_CH1, + DDR_CH2, + DDR_CH3, + DDR_CH4, + DDR_CH5, + DDR_CH6, + DDR_CH7, + DDR_NUM_CHANNELS +}; +/* Number of memory DIMM slots available on Alderlake board */ +#define NUM_DIMM_SLOT 16 + +struct spd_by_pointer { + size_t spd_data_len; + uintptr_t spd_data_ptr; +}; + +enum mem_info_read_type { + NOT_EXISTING, /* No memory in this slot */ + READ_SMBUS, /* Read on-module spd by SMBUS. */ + READ_SPD_CBFS, /* Find SPD file in CBFS. */ + READ_SPD_MEMPTR /* Find SPD data from pointer. */ +}; + +struct spd_info { + enum mem_info_read_type read_type; + union spd_data_by { + /* To read on-module SPD when read_type is READ_SMBUS. */ + uint8_t spd_smbus_address[NUM_DIMM_SLOT]; + + /* To identify SPD file when read_type is READ_SPD_CBFS. */ + int spd_index; + + /* To find SPD data when read_type is READ_SPD_MEMPTR. */ + struct spd_by_pointer spd_data_ptr_info; + } spd_spec; +}; + +/* Board-specific memory configuration information */ +struct mb_cfg { + /* DQ mapping */ + uint8_t dq_map[DDR_NUM_CHANNELS][BYTES_PER_CHANNEL * BITS_PER_BYTE]; + + /* + * DQS CPU<>DRAM map. Each array entry represents a + * mapping of a dq bit on the CPU to the bit it's connected to on + * the memory part. The array index represents the dqs bit number + * on the memory part, and the values in the array represent which + * pin on the CPU that DRAM pin connects to. + */ + uint8_t dqs_map[DDR_NUM_CHANNELS][DQS_PER_CHANNEL]; + + /* + * Rcomp resistor values. These values represent the resistance in + * ohms of the three rcomp resistors attached to the DDR_COMP_0, + * DDR_COMP_1, and DDR_COMP_2 pins on the DRAM. + */ + uint16_t rcomp_resistor[3]; + + /* Rcomp target values. */ + uint16_t rcomp_targets[5]; + + /* + * Early Command Training Enable/Disable Control + * 1 = enable, 0 = disable + */ + uint8_t ect; + + /* Board type */ + uint8_t UserBd; +}; + +/* + * Initialize default memory configurations for Alder Lake. + */ + +void memcfg_init(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *board_cfg, + const struct spd_info *spd_info, bool half_populated); + +#endif /* _SOC_ALDERLAKE_MEMINIT_H_ */ diff --git a/src/soc/intel/alderlake/include/soc/nvs.h b/src/soc/intel/alderlake/include/soc/nvs.h new file mode 100644 index 0000000..5129458 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/nvs.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_NVS_H_ +#define _SOC_NVS_H_ + +#include <intelblocks/nvs.h> + +#endif diff --git a/src/soc/intel/alderlake/include/soc/pci_devs.h b/src/soc/intel/alderlake/include/soc/pci_devs.h index eedcc27..d86e81d 100644 --- a/src/soc/intel/alderlake/include/soc/pci_devs.h +++ b/src/soc/intel/alderlake/include/soc/pci_devs.h @@ -30,6 +30,10 @@ #define SA_DEVFN_DPTF PCI_DEVFN(SA_DEV_SLOT_DPTF, 0) #define SA_DEV_DPTF PCI_DEV(0, SA_DEV_SLOT_DPTF, 0)
+#define SA_DEV_SLOT_IPU 0x05 +#define SA_DEVFN_IPU PCI_DEVFN(SA_DEV_SLOT_IPU, 0) +#define SA_DEV_IPU PCI_DEV(0, SA_DEV_SLOT_IPU, 0) + #define SA_DEV_SLOT_CPU_PCIE 0x06 #define SA_DEVFN_CPU_PCIE PCI_DEVFN(SA_DEV_SLOT_CPU_PCIE, 0)
@@ -63,8 +67,10 @@ #define PCH_DEV_SLOT_SIO0 0x10 #define PCH_DEVFN_THC0 _PCH_DEVFN(SIO0, 0) #define PCH_DEVFN_THC1 _PCH_DEVFN(SIO0, 1) +#define PCH_DEVFN_CNVI_BT _PCH_DEVFN(SIO0, 2) #define PCH_DEV_THC0 _PCH_DEV(SIO0, 0) #define PCH_DEV_THC1 _PCH_DEV(SIO0, 1) +#define PCH_DEV_CNVI_BT _PCH_DEV(SIO0, 2)
#define PCH_DEV_SLOT_ISH 0x12 #define PCH_DEVFN_ISH _PCH_DEVFN(ISH, 0) @@ -72,6 +78,10 @@ #define PCH_DEV_ISH _PCH_DEV(ISH, 0) #define PCH_DEV_GSPI2 _PCH_DEV(ISH, 6)
+#define PCH_DEV_SLOT_SIO2 0x13 +#define PCH_DEVFN_GSPI3 _PCH_DEVFN(SIO2, 0) +#define PCH_DEV_GSPI3 _PCH_DEV(SIO2, 0) + #define PCH_DEV_SLOT_XHCI 0x14 #define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0) #define PCH_DEVFN_USBOTG _PCH_DEVFN(XHCI, 1) diff --git a/src/soc/intel/alderlake/include/soc/pmc.h b/src/soc/intel/alderlake/include/soc/pmc.h index 03fe02f..e4e3dfb 100644 --- a/src/soc/intel/alderlake/include/soc/pmc.h +++ b/src/soc/intel/alderlake/include/soc/pmc.h @@ -2,6 +2,9 @@
#ifndef _SOC_ALDERLAKE_PMC_H_ #define _SOC_ALDERLAKE_PMC_H_ +#include <device/device.h> + +extern struct device_operations pmc_ops;
/* PCI Configuration Space (D31:F2): PMC */ #define PWRMBASE 0x10 diff --git a/src/soc/intel/alderlake/include/soc/ramstage.h b/src/soc/intel/alderlake/include/soc/ramstage.h new file mode 100644 index 0000000..19f55ee --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/ramstage.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_RAMSTAGE_H_ +#define _SOC_RAMSTAGE_H_ + +#include <device/device.h> +#include <fsp/api.h> +#include <fsp/util.h> +#include <soc/soc_chip.h> + +void mainboard_silicon_init_params(FSP_S_CONFIG *params); +void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config); +void soc_init_pre_device(void *chip_info); + +#endif diff --git a/src/soc/intel/alderlake/include/soc/serialio.h b/src/soc/intel/alderlake/include/soc/serialio.h new file mode 100644 index 0000000..e42af5f --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/serialio.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SERIALIO_H_ +#define _SERIALIO_H_ + +enum { + PchSerialIoDisabled, + PchSerialIoPci, + PchSerialIoHidden, + PchSerialIoLegacyUart, + PchSerialIoSkipInit +}; + +enum { + PchSerialIoIndexI2C0, + PchSerialIoIndexI2C1, + PchSerialIoIndexI2C2, + PchSerialIoIndexI2C3, + PchSerialIoIndexI2C4, + PchSerialIoIndexI2C5, +}; + +enum { + PchSerialIoIndexGSPI0, + PchSerialIoIndexGSPI1, + PchSerialIoIndexGSPI2, + PchSerialIoIndexGSPI3, +}; + +enum { + PchSerialIoIndexUART0, + PchSerialIoIndexUART1, + PchSerialIoIndexUART2, +}; + +#endif diff --git a/src/soc/intel/alderlake/include/soc/usb.h b/src/soc/intel/alderlake/include/soc/usb.h new file mode 100644 index 0000000..846849a --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/usb.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_USB_H_ +#define _SOC_USB_H_ + +#include <stdint.h> + +/* Per Port HS Transmitter Emphasis */ +#define USB2_EMP_OFF 0 +#define USB2_DE_EMP_ON 1 +#define USB2_PRE_EMP_ON 2 +#define USB2_DE_EMP_ON_PRE_EMP_ON 3 + +/* Per Port Half Bit Pre-emphasis */ +#define USB2_FULL_BIT_PRE_EMP 0 +#define USB2_HALF_BIT_PRE_EMP 1 + +/* Per Port HS Preemphasis Bias */ +#define USB2_BIAS_0MV 0 +#define USB2_BIAS_11P25MV 1 +#define USB2_BIAS_16P9MV 2 +#define USB2_BIAS_28P15MV 3 +#define USB2_BIAS_39P35MV 5 +#define USB2_BIAS_45MV 6 +#define USB2_BIAS_56P3MV 7 + +struct usb2_port_config { + uint8_t enable; + uint8_t ocpin; + uint8_t tx_bias; + uint8_t tx_emp_enable; + uint8_t pre_emp_bias; + uint8_t pre_emp_bit; +}; + +/* USB Overcurrent pins definition */ +enum { + OC0 = 0, + OC1, + OC2, + OC3, + OC4, + OC5, + OC6, + OC7, + OCMAX, + OC_SKIP = 0xff, /* Skip OC programming */ +}; + +/* Standard USB Port based on length: + * - External + * - Back Panel + * - OTG + * - M.2 + * - Internal device down */ + +#define USB2_PORT_EMPTY { \ + .enable = 0, \ + .ocpin = OC_SKIP, \ + .tx_bias = USB2_BIAS_0MV, \ + .tx_emp_enable = USB2_EMP_OFF, \ + .pre_emp_bias = USB2_BIAS_0MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +/* Length = 11.5"-12" */ +#define USB2_PORT_LONG(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_39P35MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_56P3MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +/* Length = 6"-11.49" */ +#define USB2_PORT_MID(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_0MV, \ + .tx_emp_enable = USB2_DE_EMP_ON_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_45MV, \ + .pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \ +} + +/* Length = 3"-5.99" */ +#define USB2_PORT_SHORT(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_39P35MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_39P35MV, \ + .pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \ +} + +/* Max TX and Pre-emp settings */ +#define USB2_PORT_MAX(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_56P3MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_56P3MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +/* Type-C Port, no BC1.2 charge detect module / MUX + * Length = 3.0" - 9.00" */ +#define USB2_PORT_TYPE_C(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_0MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_56P3MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +struct usb3_port_config { + uint8_t enable; + uint8_t ocpin; + uint8_t tx_de_emp; + uint8_t tx_downscale_amp; +}; + +#define USB3_PORT_EMPTY { \ + .enable = 0, \ + .ocpin = OC_SKIP, \ + .tx_de_emp = 0x00, \ + .tx_downscale_amp = 0x00, \ +} + +#define USB3_PORT_DEFAULT(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_de_emp = 0x0, \ + .tx_downscale_amp = 0x00, \ +} + +#endif diff --git a/src/soc/intel/alderlake/lockdown.c b/src/soc/intel/alderlake/lockdown.c new file mode 100644 index 0000000..e7bce27 --- /dev/null +++ b/src/soc/intel/alderlake/lockdown.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4 + */ + +#include <device/mmio.h> +#include <intelblocks/cfg.h> +#include <intelpch/lockdown.h> +#include <soc/pm.h> + +static void pmc_lock_pmsync(void) +{ + uint8_t *pmcbase; + uint32_t pmsyncreg; + + pmcbase = pmc_mmio_regs(); + + pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG); + pmsyncreg |= PCH2CPU_TPR_CFG_LOCK; + write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg); +} + +static void pmc_lock_abase(void) +{ + uint8_t *pmcbase; + uint32_t reg32; + + pmcbase = pmc_mmio_regs(); + + reg32 = read32(pmcbase + GEN_PMCON_B); + reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK); + write32(pmcbase + GEN_PMCON_B, reg32); +} + +static void pmc_lock_smi(void) +{ + uint8_t *pmcbase; + uint8_t reg8; + + pmcbase = pmc_mmio_regs(); + + reg8 = read8(pmcbase + GEN_PMCON_B); + reg8 |= SMI_LOCK; + write8(pmcbase + GEN_PMCON_B, reg8); +} + +static void pmc_lockdown_cfg(int chipset_lockdown) +{ + /* PMSYNC */ + pmc_lock_pmsync(); + /* Lock down ABASE and sleep stretching policy */ + pmc_lock_abase(); + + if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) + pmc_lock_smi(); +} + +void soc_lockdown_config(int chipset_lockdown) +{ + /* PMC lock down configuration */ + pmc_lockdown_cfg(chipset_lockdown); +} diff --git a/src/soc/intel/alderlake/me.c b/src/soc/intel/alderlake/me.c new file mode 100644 index 0000000..da1a299 --- /dev/null +++ b/src/soc/intel/alderlake/me.c @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootstate.h> +#include <intelblocks/cse.h> +#include <console/console.h> +#include <soc/me.h> +#include <stdint.h> + +/* Host Firmware Status Register 2 */ +union me_hfsts2 { + uint32_t data; + struct { + uint32_t nftp_load_failure : 1; + uint32_t icc_prog_status : 2; + uint32_t invoke_mebx : 1; + uint32_t cpu_replaced : 1; + uint32_t rsvd0 : 1; + uint32_t mfs_failure : 1; + uint32_t warm_reset_rqst : 1; + uint32_t cpu_replaced_valid : 1; + uint32_t low_power_state : 1; + uint32_t me_power_gate : 1; + uint32_t ipu_needed : 1; + uint32_t forced_safe_boot : 1; + uint32_t rsvd1 : 2; + uint32_t listener_change : 1; + uint32_t status_data : 8; + uint32_t current_pmevent : 4; + uint32_t phase : 4; + } __packed fields; +}; + +/* Host Firmware Status Register 4 */ +union me_hfsts4 { + uint32_t data; + struct { + uint32_t rsvd0 : 9; + uint32_t enforcement_flow : 1; + uint32_t sx_resume_type : 1; + uint32_t rsvd1 : 1; + uint32_t tpms_disconnected : 1; + uint32_t rvsd2 : 1; + uint32_t fwsts_valid : 1; + uint32_t boot_guard_self_test : 1; + uint32_t rsvd3 : 16; + } __packed fields; +}; + +/* Host Firmware Status Register 5 */ +union me_hfsts5 { + uint32_t data; + struct { + uint32_t acm_active : 1; + uint32_t valid : 1; + uint32_t result_code_source : 1; + uint32_t error_status_code : 5; + uint32_t acm_done_sts : 1; + uint32_t timeout_count : 7; + uint32_t scrtm_indicator : 1; + uint32_t inc_boot_guard_acm : 4; + uint32_t inc_key_manifest : 4; + uint32_t inc_boot_policy : 4; + uint32_t rsvd0 : 2; + uint32_t start_enforcement : 1; + } __packed fields; +}; + +/* Host Firmware Status Register 6 */ +union me_hfsts6 { + uint32_t data; + struct { + uint32_t force_boot_guard_acm : 1; + uint32_t cpu_debug_disable : 1; + uint32_t bsp_init_disable : 1; + uint32_t protect_bios_env : 1; + uint32_t rsvd0 : 2; + uint32_t error_enforce_policy : 2; + uint32_t measured_boot : 1; + uint32_t verified_boot : 1; + uint32_t boot_guard_acmsvn : 4; + uint32_t kmsvn : 4; + uint32_t bpmsvn : 4; + uint32_t key_manifest_id : 4; + uint32_t boot_policy_status : 1; + uint32_t error : 1; + uint32_t boot_guard_disable : 1; + uint32_t fpf_disable : 1; + uint32_t fpf_soc_lock : 1; + uint32_t txt_support : 1; + } __packed fields; +}; + +static void dump_me_status(void *unused) +{ + union me_hfsts1 hfsts1; + union me_hfsts2 hfsts2; + union me_hfsts3 hfsts3; + union me_hfsts4 hfsts4; + union me_hfsts5 hfsts5; + union me_hfsts6 hfsts6; + + if (!is_cse_enabled()) + return; + + hfsts1.data = me_read_config32(PCI_ME_HFSTS1); + hfsts2.data = me_read_config32(PCI_ME_HFSTS2); + hfsts3.data = me_read_config32(PCI_ME_HFSTS3); + hfsts4.data = me_read_config32(PCI_ME_HFSTS4); + hfsts5.data = me_read_config32(PCI_ME_HFSTS5); + hfsts6.data = me_read_config32(PCI_ME_HFSTS6); + + printk(BIOS_DEBUG, "ME: HFSTS1 : 0x%08X\n", hfsts1.data); + printk(BIOS_DEBUG, "ME: HFSTS2 : 0x%08X\n", hfsts2.data); + printk(BIOS_DEBUG, "ME: HFSTS3 : 0x%08X\n", hfsts3.data); + printk(BIOS_DEBUG, "ME: HFSTS4 : 0x%08X\n", hfsts4.data); + printk(BIOS_DEBUG, "ME: HFSTS5 : 0x%08X\n", hfsts5.data); + printk(BIOS_DEBUG, "ME: HFSTS6 : 0x%08X\n", hfsts6.data); + + /* + * Lock Descriptor, and Fuses must be programmed on a + * production system to indicate ME Manufacturing mode is disabled. + */ + printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n", + ((hfsts1.fields.spi_protection_mode == 0) && + (hfsts6.fields.fpf_soc_lock == 1)) ? "NO" : "YES"); + /* + * The SPI Protection Mode bit reflects SPI descriptor + * locked(0) or unlocked(1). + */ + printk(BIOS_DEBUG, "ME: SPI Protection Mode Enabled : %s\n", + hfsts1.fields.spi_protection_mode ? "NO" : "YES"); + printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n", + hfsts1.fields.fpt_bad ? "BAD" : "OK"); + printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n", + hfsts1.fields.ft_bup_ld_flr ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n", + hfsts1.fields.fw_init_complete ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n", + hfsts1.fields.boot_options_present ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Update In Progress : %s\n", + hfsts1.fields.update_in_progress ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n", + hfsts1.fields.d0i3_support_valid ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n", + hfsts2.fields.low_power_state ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n", + hfsts2.fields.cpu_replaced ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n", + hfsts2.fields.cpu_replaced_valid ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Current Working State : %u\n", + hfsts1.fields.working_state); + printk(BIOS_DEBUG, "ME: Current Operation State : %u\n", + hfsts1.fields.operation_state); + printk(BIOS_DEBUG, "ME: Current Operation Mode : %u\n", + hfsts1.fields.operation_mode); + printk(BIOS_DEBUG, "ME: Error Code : %u\n", + hfsts1.fields.error_code); + printk(BIOS_DEBUG, "ME: Enhanced Debug Mode : %s\n", + hfsts1.fields.invoke_enhance_dbg_mode ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Debug Disabled : %s\n", + hfsts6.fields.cpu_debug_disable ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: TXT Support : %s\n", + hfsts6.fields.txt_support ? "YES" : "NO"); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_EXIT, print_me_fw_version, NULL); +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME_CHECK, BS_ON_EXIT, dump_me_status, NULL); diff --git a/src/soc/intel/alderlake/pmc.c b/src/soc/intel/alderlake/pmc.c new file mode 100644 index 0000000..12f3080 --- /dev/null +++ b/src/soc/intel/alderlake/pmc.c @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4 + */ + +#include <acpi/acpigen.h> +#include <console/console.h> +#include <device/mmio.h> +#include <device/device.h> +#include <drivers/intel/pmc_mux/chip.h> +#include <intelblocks/pmc.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/rtc.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_chip.h> + +#define PMC_HID "INTC1026" + +enum pch_pmc_xtal pmc_get_xtal_freq(void) +{ + uint8_t *const pmcbase = pmc_mmio_regs(); + + return PCH_EPOC_XTAL_FREQ(read32(pmcbase + PCH_PMC_EPOC)); +} + +static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable) +{ + uint32_t reg; + uint8_t *pmcbase = pmc_mmio_regs(); + + printk(BIOS_DEBUG, "%sabling Deep S%c\n", + enable ? "En" : "Dis", sx + '0'); + reg = read32(pmcbase + offset); + if (enable) + reg |= mask; + else + reg &= ~mask; + write32(pmcbase + offset, reg); +} + +static void config_deep_s5(int on_ac, int on_dc) +{ + /* Treat S4 the same as S5. */ + config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac); + config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc); + config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac); + config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc); +} + +static void config_deep_s3(int on_ac, int on_dc) +{ + config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac); + config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc); +} + +static void config_deep_sx(uint32_t deepsx_config) +{ + uint32_t reg; + uint8_t *pmcbase = pmc_mmio_regs(); + + reg = read32(pmcbase + DSX_CFG); + reg &= ~DSX_CFG_MASK; + reg |= deepsx_config; + write32(pmcbase + DSX_CFG, reg); +} + +static void pmc_init(struct device *dev) +{ + const config_t *config = config_of_soc(); + + rtc_init(); + + pmc_set_power_failure_state(true); + pmc_gpe_init(); + + config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc); + config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc); + config_deep_sx(config->deep_sx_config); +} + +static void soc_pmc_read_resources(struct device *dev) +{ + struct resource *res; + + /* Add the fixed MMIO resource */ + mmio_resource(dev, 0, PCH_PWRM_BASE_ADDRESS / KiB, PCH_PWRM_BASE_SIZE / KiB); + + /* Add the fixed I/O resource */ + res = new_resource(dev, 1); + res->base = (resource_t)ACPI_BASE_ADDRESS; + res->size = (resource_t)ACPI_BASE_SIZE; + res->limit = res->base + res->size - 1; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void soc_pmc_fill_ssdt(const struct device *dev) +{ + const char *scope = acpi_device_scope(dev); + const char *name = acpi_device_name(dev); + if (!scope || !name) + return; + + acpigen_write_scope(scope); + acpigen_write_device(name); + + acpigen_write_name_string("_HID", PMC_HID); + acpigen_write_name_string("_DDN", "Intel(R) Alder Lake IPC Controller"); + + /* + * Part of the PCH's reserved 32 MB MMIO range (0xFC800000 - 0xFE7FFFFF). + * The PMC gets 0xFE000000 - 0xFE00FFFF. + */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpigen_write_mem32fixed(1, PCH_PWRM_BASE_ADDRESS, PCH_PWRM_BASE_SIZE); + acpigen_write_resourcetemplate_footer(); + + acpigen_pop_len(); /* PMC Device */ + acpigen_pop_len(); /* Scope */ + + printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name, + dev_path(dev)); +} + +/* FIXME: Rewrite loop below without this. */ +extern struct chip_operations drivers_intel_pmc_mux_ops; + +/* By default, TGL uses the PMC MUX for all ports, so port_number is unused */ +const struct device *soc_get_pmc_mux_device(int port_number) +{ + const struct device *pmc; + struct device *child; + + child = NULL; + pmc = pcidev_path_on_root(PCH_DEVFN_PMC); + if (!pmc || !pmc->link_list) + return NULL; + + while ((child = dev_bus_each_child(pmc->link_list, child)) != NULL) + if (child->chip_ops == &drivers_intel_pmc_mux_ops) + break; + + /* child will either be the correct device or NULL if not found */ + return child; +} + +static void soc_acpi_mode_init(struct device *dev) +{ + /* + * pmc_set_acpi_mode() should be delayed until BS_DEV_INIT in order + * to ensure the ordering does not break the assumptions that other + * drivers make about ACPI mode (e.g. Chrome EC). Since it disables + * ACPI mode, other drivers may take different actions based on this + * (e.g. Chrome EC will flush any pending hostevent bits). Because + * TGL has its PMC device available for device_operations, it can be + * done from the "ops->init" callback. + */ + pmc_set_acpi_mode(); +} + +struct device_operations pmc_ops = { + .read_resources = soc_pmc_read_resources, + .set_resources = noop_set_resources, + .init = soc_acpi_mode_init, + .enable = pmc_init, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = soc_pmc_fill_ssdt, +#endif + .scan_bus = scan_static_bus, +}; diff --git a/src/soc/intel/alderlake/pmutil.c b/src/soc/intel/alderlake/pmutil.c new file mode 100644 index 0000000..b6a1f3a --- /dev/null +++ b/src/soc/intel/alderlake/pmutil.c @@ -0,0 +1,292 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Helper functions for dealing with power management registers + * and the differences between PCH variants. + */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4 + */ + +#define __SIMPLE_DEVICE__ + +#include <device/mmio.h> +#include <cbmem.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <console/console.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/rtc.h> +#include <intelblocks/tco.h> +#include <soc/espi.h> +#include <soc/gpe.h> +#include <soc/gpio.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/smbus.h> +#include <soc/soc_chip.h> +#include <security/vboot/vbnv.h> + +/* + * SMI + */ + +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; +} + +/* + * TCO + */ + +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; +} + +/* + * GPE0 + */ + +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_set_disb(void) +{ + /* Set the DISB after DRAM init */ + uint8_t disb_val; + /* Only care about bits [23:16] of register GEN_PMCON_A */ + uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); + + disb_val = read8(addr); + disb_val |= (DISB >> 16); + + /* Don't clear bits that are write-1-to-clear */ + disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); + write8(addr, disb_val); +} + +void pmc_clear_pmcon_sts(void) +{ + uint32_t reg_val; + uint8_t *addr; + addr = pmc_mmio_regs(); + + reg_val = read32(addr + GEN_PMCON_A); + /* Clear SUS_PWR_FLR, GBL_RST_STS, HOST_RST_STS, PWR_FLR bits + * while retaining MS4V write-1-to-clear bit */ + reg_val &= ~(MS4V); + + write32((addr + GEN_PMCON_A), reg_val); +} + +/* + * PMC controller gets hidden from PCI bus + * during FSP-Silicon init call. Hence PWRMBASE + * can't be accessible using PCI configuration space + * read/write. + */ +uint8_t *pmc_mmio_regs(void) +{ + return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; +} + +uintptr_t soc_read_pmc_base(void) +{ + return (uintptr_t)pmc_mmio_regs(); +} + +uint32_t *soc_pmc_etr_addr(void) +{ + return (uint32_t *)(soc_read_pmc_base() + ETR); +} + +void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) +{ + DEVTREE_CONST struct soc_intel_alderlake_config *config; + + config = config_of_soc(); + + /* Assign to out variable */ + *dw0 = config->pmc_gpe0_dw0; + *dw1 = config->pmc_gpe0_dw1; + *dw2 = config->pmc_gpe0_dw2; +} + +static int rtc_failed(uint32_t gen_pmcon_b) +{ + return !!(gen_pmcon_b & RTC_BATTERY_DEAD); +} + +int soc_get_rtc_failed(void) +{ + const struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); + + if (!ps) { + printk(BIOS_ERR, "Could not find power state in cbmem, RTC init aborted\n"); + return 1; + } + + return rtc_failed(ps->gen_pmcon_b); +} + +int vbnv_cmos_failed(void) +{ + return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); +} + +static inline int deep_s3_enabled(void) +{ + uint32_t deep_s3_pol; + + deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); + return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); +} + +/* Return 0, 3, or 5 to indicate the previous sleep state. */ +int soc_prev_sleep_state(const struct chipset_power_state *ps, + int prev_sleep_state) +{ + + /* + * Check for any power failure to determine if this a wake from + * S5 because the PCH does not set the WAK_STS bit when waking + * from a true G3 state. + */ + if (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR)) + prev_sleep_state = ACPI_S5; + + /* + * If waking from S3 determine if deep S3 is enabled. If not, + * need to check both deep sleep well and normal suspend well. + * Otherwise just check deep sleep well. + */ + if (prev_sleep_state == ACPI_S3) { + /* PWR_FLR represents deep sleep power well loss. */ + uint32_t mask = PWR_FLR; + + /* If deep s3 isn't enabled check the suspend well too. */ + if (!deep_s3_enabled()) + mask |= SUS_PWR_FLR; + + if (ps->gen_pmcon_a & mask) + prev_sleep_state = ACPI_S5; + } + + return prev_sleep_state; +} + +void soc_fill_power_state(struct chipset_power_state *ps) +{ + uint8_t *pmc; + + ps->tco1_sts = tco_read_reg(TCO1_STS); + ps->tco2_sts = tco_read_reg(TCO2_STS); + + printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", + ps->tco1_sts, ps->tco2_sts); + + pmc = pmc_mmio_regs(); + ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); + ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); + ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); + ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); + ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); + + printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", + ps->gen_pmcon_a, ps->gen_pmcon_b); + + printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", + ps->gblrst_cause[0], ps->gblrst_cause[1]); + + printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); +} + +/* STM Support */ +uint16_t get_pmbase(void) +{ + return (uint16_t) ACPI_BASE_ADDRESS; +} + +/* + * Set which power state system will be after reapplying + * the power (from G3 State) + */ +void pmc_soc_set_afterg3_en(const bool on) +{ + uint8_t reg8; + uint8_t *const pmcbase = pmc_mmio_regs(); + + reg8 = read8(pmcbase + GEN_PMCON_A); + if (on) + reg8 &= ~SLEEP_AFTER_POWER_FAIL; + else + reg8 |= SLEEP_AFTER_POWER_FAIL; + write8(pmcbase + GEN_PMCON_A, reg8); +} diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 83c84ac..80420f0 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -16,7 +16,7 @@ #include <string.h>
static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, - const struct soc_intel_alderlake_dev_config *config) + const struct soc_intel_alderlake_config *config) { unsigned int i; uint32_t mask = 0; @@ -159,7 +159,7 @@
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) { - const struct soc_intel_alderlake_dev_config *config; + const struct soc_intel_alderlake_config *config; FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
config = config_of_soc(); diff --git a/src/soc/intel/alderlake/smihandler.c b/src/soc/intel/alderlake/smihandler.c new file mode 100644 index 0000000..edbf5bd --- /dev/null +++ b/src/soc/intel/alderlake/smihandler.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/pci_def.h> +#include <intelblocks/cse.h> +#include <intelblocks/smihandler.h> +#include <soc/soc_chip.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> + +/* + * Specific SOC SMI handler during ramstage finalize phase + * + * BIOS can't make CSME function disable as is due to POSTBOOT_SAI + * restriction in place from ADP chipset. Hence create SMI Handler to + * perform CSME function disabling logic during SMM mode. + */ +void smihandler_soc_at_finalize(void) +{ + const struct soc_intel_alderlake_config *config; + + config = config_of_soc(); + + if (!config->HeciEnabled && CONFIG(HECI_DISABLE_USING_SMM)) + heci_disable(); +} + +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/alderlake/smmrelocate.c b/src/soc/intel/alderlake/smmrelocate.c new file mode 100644 index 0000000..e75e884 --- /dev/null +++ b/src/soc/intel/alderlake/smmrelocate.c @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <types.h> +#include <string.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ops.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/smm.h> +#include <cpu/intel/common/common.h> +#include <cpu/intel/em64t101_save_state.h> +#include <cpu/intel/smm_reloc.h> +#include <console/console.h> +#include <smp/node.h> +#include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/soc_chip.h> + +static void update_save_state(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase, + struct smm_relocation_params *relo_params) +{ + u32 smbase; + u32 iedbase; + + /* + * The relocated handler runs with all CPUs concurrently. Therefore + * stagger the entry points adjusting SMBASE downwards by save state + * size * CPU num. + */ + smbase = staggered_smbase; + iedbase = relo_params->ied_base; + + printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n", + smbase, iedbase); + + /* + * All threads need to set IEDBASE and SMBASE to the relocated + * handler region. However, the save state location depends on the + * smm_save_state_in_msrs field in the relocation parameters. If + * smm_save_state_in_msrs is non-zero then the CPUs are relocating + * the SMM handler in parallel, and each CPUs save state area is + * located in their respective MSR space. If smm_save_state_in_msrs + * is zero then the SMM relocation is happening serially so the + * save state is at the same default location for all CPUs. + */ + if (relo_params->smm_save_state_in_msrs) { + msr_t smbase_msr; + msr_t iedbase_msr; + + smbase_msr.lo = smbase; + smbase_msr.hi = 0; + + /* + * According the BWG the IEDBASE MSR is in bits 63:32. It's + * not clear why it differs from the SMBASE MSR. + */ + iedbase_msr.lo = 0; + iedbase_msr.hi = iedbase; + + wrmsr(SMBASE_MSR, smbase_msr); + wrmsr(IEDBASE_MSR, iedbase_msr); + } else { + em64t101_smm_state_save_area_t *save_state; + + save_state = (void *)(curr_smbase + SMM_DEFAULT_SIZE - + sizeof(*save_state)); + + save_state->smbase = smbase; + save_state->iedbase = iedbase; + } +} + +/* Returns 1 if SMM MSR save state was set. */ +static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params) +{ + msr_t smm_mca_cap; + + smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR); + if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) { + msr_t smm_feature_control; + + smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR); + smm_feature_control.hi = 0; + smm_feature_control.lo |= SMM_CPU_SAVE_EN; + wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control); + relo_params->smm_save_state_in_msrs = 1; + } + return relo_params->smm_save_state_in_msrs; +} + +/* + * The relocation work is actually performed in SMM context, but the code + * resides in the ramstage module. This occurs by trampolining from the default + * SMRAM entry point to here. + */ +void smm_relocation_handler(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase) +{ + msr_t mtrr_cap; + struct smm_relocation_params *relo_params = &smm_reloc_params; + + printk(BIOS_DEBUG, "In relocation handler: CPU %d\n", cpu); + + /* + * Determine if the processor supports saving state in MSRs. If so, + * enable it before the non-BSPs run so that SMM relocation can occur + * in parallel in the non-BSP CPUs. + */ + if (cpu == 0) { + /* + * If smm_save_state_in_msrs is 1 then that means this is the + * 2nd time through the relocation handler for the BSP. + * Parallel SMM handler relocation is taking place. However, + * it is desired to access other CPUs save state in the real + * SMM handler. Therefore, disable the SMM save state in MSRs + * feature. + */ + if (relo_params->smm_save_state_in_msrs) { + msr_t smm_feature_control; + + smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR); + smm_feature_control.lo &= ~SMM_CPU_SAVE_EN; + wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control); + } else if (bsp_setup_msr_save_state(relo_params)) + /* + * Just return from relocation handler if MSR save + * state is enabled. In that case the BSP will come + * back into the relocation handler to setup the new + * SMBASE as well disabling SMM save state in MSRs. + */ + return; + } + + /* Make appropriate changes to the save state map. */ + update_save_state(cpu, curr_smbase, staggered_smbase, relo_params); + + /* + * The SMRR MSRs are core-level registers, so if two threads that share + * a core try to both set the lock bit (in the same physical register), + * a #GP will be raised on the second write to that register (which is + * exactly what the lock is supposed to do), therefore secondary threads + * should exit here. + */ + if (intel_ht_sibling()) + return; + + /* Write SMRR MSRs based on indicated support. */ + mtrr_cap = rdmsr(MTRR_CAP_MSR); + + /* Set Lock bit if supported */ + if (mtrr_cap.lo & SMRR_LOCK_SUPPORTED) + relo_params->smrr_mask.lo |= SMRR_PHYS_MASK_LOCK; + + /* Write SMRRs if supported */ + if (mtrr_cap.lo & SMRR_SUPPORTED) + write_smrr(relo_params); +} + +static void fill_in_relocation_params(struct smm_relocation_params *params) +{ + uintptr_t tseg_base; + size_t tseg_size; + /* All range registers are aligned to 4KiB */ + const u32 rmask = ~(4 * KiB - 1); + + smm_region(&tseg_base, &tseg_size); + + if (!IS_ALIGNED(tseg_base, tseg_size)) { + printk(BIOS_WARNING, + "TSEG base not aligned with TSEG SIZE! Not setting SMRR\n"); + return; + } + + smm_subregion(SMM_SUBREGION_CHIPSET, ¶ms->ied_base, ¶ms->ied_size); + + /* SMRR has 32-bits of valid address aligned to 4KiB. */ + params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK; + params->smrr_base.hi = 0; + params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID; + params->smrr_mask.hi = 0; +} + +static void setup_ied_area(struct smm_relocation_params *params) +{ + char *ied_base; + + struct ied_header ied = { + .signature = "INTEL RSVD", + .size = params->ied_size, + .reserved = {0}, + }; + + ied_base = (void *)params->ied_base; + + printk(BIOS_DEBUG, "IED base = 0x%08x\n", (u32)params->ied_base); + printk(BIOS_DEBUG, "IED size = 0x%08x\n", (u32)params->ied_size); + + /* Place IED header at IEDBASE. */ + memcpy(ied_base, &ied, sizeof(ied)); + + /* Zero out 32KiB at IEDBASE + 1MiB */ + memset(ied_base + 1 * MiB, 0, 32 * KiB); +} + +void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, + size_t *smm_save_state_size) +{ + printk(BIOS_DEBUG, "Setting up SMI for CPU\n"); + + fill_in_relocation_params(&smm_reloc_params); + + smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize); + + if (smm_reloc_params.ied_size) + setup_ied_area(&smm_reloc_params); + + *smm_save_state_size = sizeof(em64t101_smm_state_save_area_t); +} + +void smm_initialize(void) +{ + /* Clear the SMM state in the southbridge. */ + smm_southbridge_clear_state(); + + /* + * Run the relocation handler for on the BSP to check and set up + * parallel SMM relocation. + */ + smm_initiate_relocation(); + + if (smm_reloc_params.smm_save_state_in_msrs) + printk(BIOS_DEBUG, "Doing parallel SMM relocation.\n"); +} + +void smm_relocate(void) +{ + /* + * If smm_save_state_in_msrs is non-zero then parallel SMM relocation + * shall take place. Run the relocation handler a second time on the + * BSP to do * the final move. For APs, a relocation handler always + * needs to be run. + */ + if (smm_reloc_params.smm_save_state_in_msrs) + smm_initiate_relocation_parallel(); + else if (!boot_cpu()) + smm_initiate_relocation(); +} diff --git a/src/soc/intel/alderlake/soundwire.c b/src/soc/intel/alderlake/soundwire.c new file mode 100644 index 0000000..326da2a --- /dev/null +++ b/src/soc/intel/alderlake/soundwire.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpi_soundwire.h> +#include <console/console.h> +#include <device/mmio.h> +#include <device/soundwire.h> +#include <drivers/intel/soundwire/soundwire.h> +#include <intelblocks/pmclib.h> +#include <soc/pmc.h> +#include <string.h> + +static const struct soundwire_link link_xtal_38_4 = { + .clock_stop_mode0_supported = 1, + .clock_stop_mode1_supported = 1, + .clock_frequencies_supported_count = 1, + .clock_frequencies_supported = { 4800 * KHz }, + .default_frame_rate = 48 * KHz, + .default_frame_row_size = 50, + .default_frame_col_size = 4, + .dynamic_frame_shape = 1, + .command_error_threshold = 16, +}; + +static const struct soundwire_link link_xtal_24 = { + .clock_stop_mode0_supported = 1, + .clock_stop_mode1_supported = 1, + .clock_frequencies_supported_count = 1, + .clock_frequencies_supported = { 6 * MHz }, + .default_frame_rate = 48 * KHz, + .default_frame_row_size = 125, + .default_frame_col_size = 2, + .dynamic_frame_shape = 1, + .command_error_threshold = 16, +}; + +static struct intel_soundwire_controller intel_controller = { + .acpi_address = 0x40000000, + .sdw = { + /* TODO: Verified Audio in nocodec mode, add codec suppport */ + .master_list_count = 0 + } +}; + +int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) +{ + const struct soundwire_link *link; + enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); + size_t i; + + /* Select link config based on XTAL frequency and set IP clock. */ + switch (xtal) { + case XTAL_24_MHZ: + link = &link_xtal_24; + intel_controller.ip_clock = 24 * MHz; + break; + case XTAL_38_4_MHZ: + link = &link_xtal_38_4; + intel_controller.ip_clock = 38400 * KHz; + break; + case XTAL_19_2_MHZ: + default: + printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); + return -1; + } + + /* Fill link config in controller map based on selected XTAL. */ + for (i = 0; i < intel_controller.sdw.master_list_count; i++) + memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); + + *controller = &intel_controller; + return 0; +} diff --git a/src/soc/intel/alderlake/spi.c b/src/soc/intel/alderlake/spi.c new file mode 100644 index 0000000..2940de1 --- /dev/null +++ b/src/soc/intel/alderlake/spi.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 7 + */ + +#include <intelblocks/spi.h> +#include <soc/pci_devs.h> + +int spi_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { + case PCH_DEVFN_SPI: + return 0; + case PCH_DEVFN_GSPI0: + return 1; + case PCH_DEVFN_GSPI1: + return 2; + case PCH_DEVFN_GSPI2: + return 3; + case PCH_DEVFN_GSPI3: + return 4; + } + return -1; +} diff --git a/src/soc/intel/alderlake/systemagent.c b/src/soc/intel/alderlake/systemagent.c new file mode 100644 index 0000000..3e7a404 --- /dev/null +++ b/src/soc/intel/alderlake/systemagent.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor SA Datasheet + * Document number: 619503 + * Chapter number: 3 + */ + +#include <device/device.h> +#include <device/pci.h> +#include <intelblocks/systemagent.h> +#include <soc/iomap.h> +#include <soc/systemagent.h> + +/* + * SoC implementation + * + * Add all known fixed memory ranges for Host Controller/Memory + * controller. + */ +void soc_add_fixed_mmio_resources(struct device *dev, int *index) +{ + static const struct sa_mmio_descriptor soc_fixed_resources[] = { + { PCIEXBAR, CONFIG_MMCONF_BASE_ADDRESS, CONFIG_SA_PCIEX_LENGTH, + "PCIEXBAR" }, + { MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" }, + { DMIBAR, DMI_BASE_ADDRESS, DMI_BASE_SIZE, "DMIBAR" }, + { EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" }, + { REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" }, + { EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" }, + }; + + sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources, + ARRAY_SIZE(soc_fixed_resources)); + + /* Add Vt-d resources if VT-d is enabled */ + if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE)) + return; + + sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources, + ARRAY_SIZE(soc_vtd_resources)); +} + +/* + * SoC implementation + * + * Perform System Agent Initialization during Ramstage phase. + */ +void soc_systemagent_init(struct device *dev) +{ + /* Enable Power Aware Interrupt Routing */ + enable_power_aware_intr(); + + /* Enable BIOS Reset CPL */ + enable_bios_reset_cpl(); + /* TODO: Add set_power_limits() */ +} + +uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz) +{ + switch (capid0_a_ddrsz) { + case 1: + return 8192; + case 2: + return 4096; + case 3: + return 2048; + default: + return 65536; + } +} diff --git a/src/soc/intel/alderlake/uart.c b/src/soc/intel/alderlake/uart.c new file mode 100644 index 0000000..cdbf8ec --- /dev/null +++ b/src/soc/intel/alderlake/uart.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 9 + */ + +#include <console/console.h> +#include <device/pci_def.h> +#include <intelblocks/gpio.h> +#include <intelblocks/lpss.h> +#include <intelblocks/pcr.h> +#include <intelblocks/uart.h> +#include <soc/iomap.h> +#include <soc/pch.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> + +const struct uart_gpio_pad_config uart_gpio_pads[] = { + { + .console_index = 0, + .gpios = { + PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0 RX */ + PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0 TX */ + }, + }, + { + .console_index = 1, + .gpios = { + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* UART1 RX */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1), /* UART1 TX */ + }, + }, + { + .console_index = 2, + .gpios = { + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* UART2 RX */ + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* UART2 TX */ + }, + } +}; + +const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); + +DEVTREE_CONST struct device *soc_uart_console_to_device(int uart_console) +{ + /* + * if index is valid, this function will return corresponding structure + * for uart console else will return NULL. + */ + switch (uart_console) { + case 0: + return pcidev_path_on_root(PCH_DEVFN_UART0); + case 1: + return pcidev_path_on_root(PCH_DEVFN_UART1); + case 2: + return pcidev_path_on_root(PCH_DEVFN_UART2); + default: + printk(BIOS_ERR, "Invalid UART console index\n"); + return NULL; + } +}
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 1:
(2 comments)
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/fsp... PS1, Line 157: if (config->usb3_ports[i].enable) { braces {} are not necessary for any arm of this statement
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/sou... File src/soc/intel/alderlake/soundwire.c:
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/sou... PS1, Line 39: /* TODO: Verified Audio in nocodec mode, add codec suppport */ 'suppport' may be misspelled - perhaps 'support'?
Hello build bot (Jenkins), Patrick Georgi, Martin Roth, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/45759
to look at the new patch set (#2).
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 34 files changed, 3,337 insertions(+), 6 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/2
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 2:
(2 comments)
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/fsp... PS1, Line 157: if (config->usb3_ports[i].enable) {
braces {} are not necessary for any arm of this statement
Done
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/sou... File src/soc/intel/alderlake/soundwire.c:
https://review.coreboot.org/c/coreboot/+/45759/1/src/soc/intel/alderlake/sou... PS1, Line 39: /* TODO: Verified Audio in nocodec mode, add codec suppport */
'suppport' may be misspelled - perhaps 'support'?
Done
Hello build bot (Jenkins), Furquan Shaikh, Patrick Georgi, Martin Roth, Tim Wawrzynczak, Angel Pons, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/45759
to look at the new patch set (#3).
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 34 files changed, 3,338 insertions(+), 9 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/3
HAOUAS Elyes has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 3:
(11 comments)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... File src/soc/intel/alderlake/acpi.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 23: #include <string.h> <string.h> not used.
missing <stdint.h> and <stddef.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... File src/soc/intel/alderlake/chip.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 3: #include <console/console.h> not used?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/cpu.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 6: #include <intelblocks/msr.h> not used.
or is current file is supposed to indirectly include <intelblocks/msr.h> ?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/me.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 10: u32 <stdint.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/ramstage.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 6: #include <device/device.h> not used?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/loc... File src/soc/intel/alderlake/lockdown.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/loc... PS3, Line 16: uint8_t <stdint.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... PS3, Line 25: uint8_t <stdint.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... File src/soc/intel/alderlake/pmutil.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 39: size_t <stddef.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 123: uint8_t <stdint.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smi... File src/soc/intel/alderlake/smihandler.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smi... PS3, Line 3: console/console.h> not used?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/sou... File src/soc/intel/alderlake/soundwire.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/sou... PS3, Line 48: size_t <stddef.h>
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 3:
(10 comments)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/Mak... File src/soc/intel/alderlake/Makefile.inc:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/Mak... PS3, Line 45: r Please keep entries sorted in alphabetical order
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... File src/soc/intel/alderlake/acpi.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 23: #include <string.h>
<string.h> not used. […]
Untrue. `memcpy` appears in this file.
Also, `bool` is used, so just include <types.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 181: uintptr_t pmc_bar = soc_read_pmc_base(); no need for a temporary variable
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 188: uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK; Many things here can be const
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 233: TBT0BAR You could redefine these registers as follows:
#define TBTxBAR(x) (0x7888 + (x) * 8)
This way, the macros can be easily used in loops 😊
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 245: /* Add RMRR entry */ : const unsigned long tmp = current; : current += acpi_create_dmar_rmrr(current, 0, : sa_get_gsm_base(), sa_get_tolud_base() - 1); : current += acpi_create_dmar_ds_pci(current, 0, 2, 0); : acpi_dmar_rmrr_fixup(tmp, current); Shouldn't this be skipped if the IGD is disabled?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... File src/soc/intel/alderlake/chip.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 118: rotine ro*u*tine
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 136: /* Snapshot the current GPIO IRQ polarities. FSP is setting a : * default policy that doesn't honor boards' requirements. */ : itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); Does this still apply to ADL?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... File src/soc/intel/alderlake/pmutil.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 281: bool <types.h>
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smm... PS3, Line 3: #include <types.h> I prefer to keep #includes sorted alphabetically.
Hello build bot (Jenkins), Furquan Shaikh, Patrick Georgi, Martin Roth, Tim Wawrzynczak, Angel Pons, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/45759
to look at the new patch set (#4).
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h M src/soc/intel/alderlake/include/soc/systemagent.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 35 files changed, 3,346 insertions(+), 17 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/4
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 3:
(20 comments)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/Mak... File src/soc/intel/alderlake/Makefile.inc:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/Mak... PS3, Line 45: r
Please keep entries sorted in alphabetical order
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... File src/soc/intel/alderlake/acpi.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 23: #include <string.h>
Untrue. `memcpy` appears in this file. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 181: uintptr_t pmc_bar = soc_read_pmc_base();
no need for a temporary variable
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 188: uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
Many things here can be const
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 233: TBT0BAR
You could redefine these registers as follows: […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 245: /* Add RMRR entry */ : const unsigned long tmp = current; : current += acpi_create_dmar_rmrr(current, 0, : sa_get_gsm_base(), sa_get_tolud_base() - 1); : current += acpi_create_dmar_ds_pci(current, 0, 2, 0); : acpi_dmar_rmrr_fixup(tmp, current);
Shouldn't this be skipped if the IGD is disabled?
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... File src/soc/intel/alderlake/chip.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 3: #include <console/console.h>
not used?
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 118: rotine
ro*u*tine
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 136: /* Snapshot the current GPIO IRQ polarities. FSP is setting a : * default policy that doesn't honor boards' requirements. */ : itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
Does this still apply to ADL?
so far yes, we have bug filled and mostly its early FSP hence scope for improvement is here
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/cpu.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 6: #include <intelblocks/msr.h>
not used. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/me.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 10: u32
<stdint. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/ramstage.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 6: #include <device/device.h>
not used?
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/loc... File src/soc/intel/alderlake/lockdown.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/loc... PS3, Line 16: uint8_t
<stdint. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... PS3, Line 25: uint8_t
<stdint. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... File src/soc/intel/alderlake/pmutil.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 39: size_t
<stddef. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 123: uint8_t
<stdint. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 281: bool
<types. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smi... File src/soc/intel/alderlake/smihandler.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smi... PS3, Line 3: console/console.h>
not used?
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smm... PS3, Line 3: #include <types.h>
I prefer to keep #includes sorted alphabetically.
Done. thanks
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/sou... File src/soc/intel/alderlake/soundwire.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/sou... PS3, Line 48: size_t
<stddef. […]
Ack
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 5: Code-Review+1
(20 comments)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... File src/soc/intel/alderlake/chip.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 136: /* Snapshot the current GPIO IRQ polarities. FSP is setting a : * default policy that doesn't honor boards' requirements. */ : itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
so far yes, we have bug filled and mostly its early FSP hence scope for improvement is here
Thank you! In the meantime, please mention that a bug has been filed (one `l`), and that this W/A should be removed once fixed in FSP. For example:
TODO: a bug has been filed, remove this workaround once FSP is updated.
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... File src/soc/intel/alderlake/espi.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 27: */ This comment has been here since Cannonlake. Does it need an update?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 68: soc_setup_dmi_pcr_io_dec(&io_dec_arr[0]); I see this function being called from lpc_lib.c already. Do we need to write these twice?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 71: static void pch_enable_ioapic(const struct device *dev) This function is the same for all Intel SoCs except Broadwell
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 121: PCH_IRQ10 Is this one using IRQ10 for any particular reason? I see many other platforms do this too, but I don't know why.
Plus, this looks pretty much the same for other SoCs. If PIRQ routing is still necessary for some reason (which I would like to know about), this should be moved to common code. If not required, we might as well remove it as PIRQ shouldn't be necessary on modern systems.
If in doubt, we can move this to common code now, and maybe remove it later.
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 192: i8259_configure_irq_trigger(9, 1); Why these two numbers?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... File src/soc/intel/alderlake/finalize.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... PS5, Line 49: uint32_t reg32; : uint8_t *pmcbase; : config_t *config; : uint8_t reg8; Scope of `reg32` and `reg8` can be reduced
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... PS5, Line 65: SA_DEV_ROOT I can't see it anywhere (got replaced by `config_of_soc`)
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... PS5, Line 78: /* Disable XTAL shutdown qualification for low power idle. */ : if (config->s0ix_enable) { : reg32 = read32(pmcbase + CPPMVRIC); : reg32 |= XTALSDQDIS; : write32(pmcbase + CPPMVRIC, reg32); : } This seems to come from other SoCs, and its purpose is unclear. What does this do?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 152: 0xff OC_SKIP
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 160: 0xff OC_SKIP
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 219: else else... bug?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 230: params->Device4Enable = config->Device4Enable; Use `is_dev_enabled` with `SA_DEVFN_DPTF` instead?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/meminit.h:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/inc... PS5, Line 83: uint8_t bool ?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... PS5, Line 130: /* FIXME: Rewrite loop below without this. */ Are `dev->vendor` and `dev->device` initialized when `soc_get_pmc_mux_device` gets called?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... PS5, Line 133: /* By default, TGL uses the PMC MUX for all ports, so port_number is unused */ Hmmmmm... But this is not TGL
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmu... File src/soc/intel/alderlake/pmutil.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmu... PS5, Line 220: * S5 because the PCH does not set the WAK_STS bit when waking : * from a true G3 state. : */ nit: comment is misaligned
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/smm... PS3, Line 3: #include <types.h>
Done. […]
Thank you 😊
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
PS5: How much of this is ADL-specific?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... PS5, Line 58: * According the BWG the IEDBASE MSR is in bits 63:32. It's This comment has been there since Haswell. Is it accurate?
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 5:
(18 comments)
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... File src/soc/intel/alderlake/espi.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 27: */
This comment has been here since Cannonlake. […]
Its same Angel. its 32MB in size
#define PCH_PRESERVED_BASE_ADDRESS 0xFC800000 ///< Pch preserved MMIO base address #define PCH_PRESERVED_MMIO_SIZE 0x02000000 ///< 32MB
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 68: soc_setup_dmi_pcr_io_dec(&io_dec_arr[0]);
I see this function being called from lpc_lib.c already. […]
Thank u, very valid point
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 71: static void pch_enable_ioapic(const struct device *dev)
This function is the same for all Intel SoCs except Broadwell
Good candidate for common code migration
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 121: PCH_IRQ10
Is this one using IRQ10 for any particular reason? I see many other platforms do this too, but I don't know why.
i could always see INTB is IRQ10 and rest of IRQ11
Plus, this looks pretty much the same for other SoCs. If PIRQ routing is still necessary for some reason (which I would like to know about), this should be moved to common code. If not required, we might as well remove it as PIRQ shouldn't be necessary on modern systems.
If in doubt, we can move this to common code now, and maybe remove it later.
yes good candidate for common code migration
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 192: i8259_configure_irq_trigger(9, 1);
Why these two numbers?
9 refer as interrupt number and 1 refer as level trigger for 8259
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... File src/soc/intel/alderlake/finalize.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... PS5, Line 49: uint32_t reg32; : uint8_t *pmcbase; : config_t *config; : uint8_t reg8;
Scope of `reg32` and `reg8` can be reduced
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... PS5, Line 65: SA_DEV_ROOT
I can't see it anywhere (got replaced by `config_of_soc`)
Done
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fin... PS5, Line 78: /* Disable XTAL shutdown qualification for low power idle. */ : if (config->s0ix_enable) { : reg32 = read32(pmcbase + CPPMVRIC); : reg32 |= XTALSDQDIS; : write32(pmcbase + CPPMVRIC, reg32); : }
This seems to come from other SoCs, and its purpose is unclear. […]
this is to disqualify XTAL power while measuring low power KPI as per PnP team requirement.
Good candidate for common code.
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 152: 0xff
OC_SKIP
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 160: 0xff
OC_SKIP
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 219: else
else... […]
Didn't get this Angel
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 230: params->Device4Enable = config->Device4Enable;
Use `is_dev_enabled` with `SA_DEVFN_DPTF` instead?
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/meminit.h:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/inc... PS5, Line 83: uint8_t
bool ?
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... PS5, Line 130: /* FIXME: Rewrite loop below without this. */
Are `dev->vendor` and `dev->device` initialized when `soc_get_pmc_mux_device` gets called?
Answer should be yes as this is getting called from ec_lpc.c as part of acpi_fill_ssdt.
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... PS5, Line 133: /* By default, TGL uses the PMC MUX for all ports, so port_number is unused */
Hmmmmm... […]
my bad, TGL and ADL should use the same PMC MUX programming for Type-C
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmu... File src/soc/intel/alderlake/pmutil.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmu... PS5, Line 220: * S5 because the PCH does not set the WAK_STS bit when waking : * from a true G3 state. : */
nit: comment is misaligned
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
PS5:
How much of this is ADL-specific?
Honestly this file a good candidate for common code, many function can be moved into common, i believe i had a CL in past from common code (2017/18) time didn't merge for some reason, i can again revive the same post ADL upstream. Thoughts ?
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... PS5, Line 58: * According the BWG the IEDBASE MSR is in bits 63:32. It's
This comment has been there since Haswell. […]
Yes.
SMBASE is between 0:31 and IEDBASE is 32:64
Hello build bot (Jenkins), Furquan Shaikh, Patrick Georgi, Martin Roth, Tim Wawrzynczak, Angel Pons, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/45759
to look at the new patch set (#6).
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h M src/soc/intel/alderlake/include/soc/systemagent.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 35 files changed, 3,216 insertions(+), 18 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/6
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 6:
(13 comments)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... File src/soc/intel/alderlake/acpi.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 235: if (tbtbar && tbten) { Should there also be a check here depending on whether or not each device (00:07.0 - 7.3) is enabled ?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... File src/soc/intel/alderlake/chip.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 242: /* CNVi */ : uint8_t CnviMode; : uint8_t CnviBtCore; Why did these get removed?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/cpu... File src/soc/intel/alderlake/cpu.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/cpu... PS3, Line 150: /* TODO(adurbin): This should only be done on a cold boot. Also, some : * of these banks are core vs package scope. For now every CPU clears : * every bank. */ fun fact, AFAICT this TODO has been in the codebase for 7 years
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/esp... File src/soc/intel/alderlake/espi.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/esp... PS3, Line 132: u8 stdint.h
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fin... File src/soc/intel/alderlake/finalize.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fin... PS3, Line 57: /* TODO: Add Thermal Configuration */ Is there still a reason that `pch_thermal_configuration()` isn't called here? (should we be calling it in tigerlake too?)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fsp... PS3, Line 152: 0xff OC_SKIP
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fsp... PS3, Line 160: 0xff OC_SKIP
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/meminit.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 27: 16 16 DIMM slots?
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 38: nit:tab
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/me.... File src/soc/intel/alderlake/me.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/me.... PS3, Line 9: /* Host Firmware Status Register 2 */ : union me_hfsts2 { : uint32_t data; : struct { : uint32_t nftp_load_failure : 1; : uint32_t icc_prog_status : 2; : uint32_t invoke_mebx : 1; : uint32_t cpu_replaced : 1; : uint32_t rsvd0 : 1; : uint32_t mfs_failure : 1; : uint32_t warm_reset_rqst : 1; : uint32_t cpu_replaced_valid : 1; : uint32_t low_power_state : 1; : uint32_t me_power_gate : 1; : uint32_t ipu_needed : 1; : uint32_t forced_safe_boot : 1; : uint32_t rsvd1 : 2; : uint32_t listener_change : 1; : uint32_t status_data : 8; : uint32_t current_pmevent : 4; : uint32_t phase : 4; : } __packed fields; : }; : : /* Host Firmware Status Register 4 */ : union me_hfsts4 { : uint32_t data; : struct { : uint32_t rsvd0 : 9; : uint32_t enforcement_flow : 1; : uint32_t sx_resume_type : 1; : uint32_t rsvd1 : 1; : uint32_t tpms_disconnected : 1; : uint32_t rvsd2 : 1; : uint32_t fwsts_valid : 1; : uint32_t boot_guard_self_test : 1; : uint32_t rsvd3 : 16; : } __packed fields; : }; : : /* Host Firmware Status Register 5 */ : union me_hfsts5 { : uint32_t data; : struct { : uint32_t acm_active : 1; : uint32_t valid : 1; : uint32_t result_code_source : 1; : uint32_t error_status_code : 5; : uint32_t acm_done_sts : 1; : uint32_t timeout_count : 7; : uint32_t scrtm_indicator : 1; : uint32_t inc_boot_guard_acm : 4; : uint32_t inc_key_manifest : 4; : uint32_t inc_boot_policy : 4; : uint32_t rsvd0 : 2; : uint32_t start_enforcement : 1; : } __packed fields; : }; : : /* Host Firmware Status Register 6 */ : union me_hfsts6 { : uint32_t data; : struct { : uint32_t force_boot_guard_acm : 1; : uint32_t cpu_debug_disable : 1; : uint32_t bsp_init_disable : 1; : uint32_t protect_bios_env : 1; : uint32_t rsvd0 : 2; : uint32_t error_enforce_policy : 2; : uint32_t measured_boot : 1; : uint32_t verified_boot : 1; : uint32_t boot_guard_acmsvn : 4; : uint32_t kmsvn : 4; : uint32_t bpmsvn : 4; : uint32_t key_manifest_id : 4; : uint32_t boot_policy_status : 1; : uint32_t error : 1; : uint32_t boot_guard_disable : 1; : uint32_t fpf_disable : 1; : uint32_t fpf_soc_lock : 1; : uint32_t txt_support : 1; : } __packed fields; : }; : note to self: convert to masks & shifts, bitfields are not OK
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... PS3, Line 128: : /* FIXME: Rewrite loop below without this. */ : extern struct chip_operations drivers_intel_pmc_mux_ops; : : /* By default, TGL uses the PMC MUX for all ports, so port_number is unused */ : const struct device *soc_get_pmc_mux_device(int port_number) : { : const struct device *pmc; : struct device *child; : : child = NULL; : pmc = pcidev_path_on_root(PCH_DEVFN_PMC); : if (!pmc || !pmc->link_list) : return NULL; : : while ((child = dev_bus_each_child(pmc->link_list, child)) != NULL) : if (child->chip_ops == &drivers_intel_pmc_mux_ops) : break; : : /* child will either be the correct device or NULL if not found */ : return child; : } Good news, this is being removed! CB:45747, feel free to rebase there or not and I'll clean up my mess later 😄
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... File src/soc/intel/alderlake/pmutil.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 217: /* : * Check for any power failure to determine if this a wake from : * S5 because the PCH does not set the WAK_STS bit when waking : * from a true G3 state. : */ alignment of `*`
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 253: ps->tco1_sts, ps->tco2_sts); can fit on previous line
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 6: Code-Review+1
(8 comments)
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... File src/soc/intel/alderlake/espi.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 27: */
Its same Angel. its 32MB in size […]
Ack, thanks for confirming
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/esp... PS5, Line 192: i8259_configure_irq_trigger(9, 1);
9 refer as interrupt number and 1 refer as level trigger for 8259
I see.
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 219: else
Didn't get this Angel
If devicetree has enabled DITO config for this SATA port (config->SataPortsEnableDitoConfig[i]), it should provide valid values for DITO multiplier and DITO. If it doesn't, it's a bug in the devicetree.
Yesterday, I thought about printing a message here stating that the devicetree value is invalid, but I doubt anyone will notice. Instead, we may drop the non-zero check and always write the devicetree value:
if (config->SataPortsEnableDitoConfig[i]) { params->SataPortsDmVal[i] = config->SataPortsDmVal[i]; params->SataPortsDitoVal[i] = config->SataPortsDitoVal[i]; }
Note that the FSP UPDs are left untouched when `config->SataPortsEnableDitoConfig[i]` is false.
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/me.... File src/soc/intel/alderlake/me.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/me.... PS3, Line 9: /* Host Firmware Status Register 2 */ : union me_hfsts2 { : uint32_t data; : struct { : uint32_t nftp_load_failure : 1; : uint32_t icc_prog_status : 2; : uint32_t invoke_mebx : 1; : uint32_t cpu_replaced : 1; : uint32_t rsvd0 : 1; : uint32_t mfs_failure : 1; : uint32_t warm_reset_rqst : 1; : uint32_t cpu_replaced_valid : 1; : uint32_t low_power_state : 1; : uint32_t me_power_gate : 1; : uint32_t ipu_needed : 1; : uint32_t forced_safe_boot : 1; : uint32_t rsvd1 : 2; : uint32_t listener_change : 1; : uint32_t status_data : 8; : uint32_t current_pmevent : 4; : uint32_t phase : 4; : } __packed fields; : }; : : /* Host Firmware Status Register 4 */ : union me_hfsts4 { : uint32_t data; : struct { : uint32_t rsvd0 : 9; : uint32_t enforcement_flow : 1; : uint32_t sx_resume_type : 1; : uint32_t rsvd1 : 1; : uint32_t tpms_disconnected : 1; : uint32_t rvsd2 : 1; : uint32_t fwsts_valid : 1; : uint32_t boot_guard_self_test : 1; : uint32_t rsvd3 : 16; : } __packed fields; : }; : : /* Host Firmware Status Register 5 */ : union me_hfsts5 { : uint32_t data; : struct { : uint32_t acm_active : 1; : uint32_t valid : 1; : uint32_t result_code_source : 1; : uint32_t error_status_code : 5; : uint32_t acm_done_sts : 1; : uint32_t timeout_count : 7; : uint32_t scrtm_indicator : 1; : uint32_t inc_boot_guard_acm : 4; : uint32_t inc_key_manifest : 4; : uint32_t inc_boot_policy : 4; : uint32_t rsvd0 : 2; : uint32_t start_enforcement : 1; : } __packed fields; : }; : : /* Host Firmware Status Register 6 */ : union me_hfsts6 { : uint32_t data; : struct { : uint32_t force_boot_guard_acm : 1; : uint32_t cpu_debug_disable : 1; : uint32_t bsp_init_disable : 1; : uint32_t protect_bios_env : 1; : uint32_t rsvd0 : 2; : uint32_t error_enforce_policy : 2; : uint32_t measured_boot : 1; : uint32_t verified_boot : 1; : uint32_t boot_guard_acmsvn : 4; : uint32_t kmsvn : 4; : uint32_t bpmsvn : 4; : uint32_t key_manifest_id : 4; : uint32_t boot_policy_status : 1; : uint32_t error : 1; : uint32_t boot_guard_disable : 1; : uint32_t fpf_disable : 1; : uint32_t fpf_soc_lock : 1; : uint32_t txt_support : 1; : } __packed fields; : }; :
note to self: convert to masks & shifts, bitfields are not OK
Why are bitfields not OK? IMHO, bitfields provide type safety and overflow checking.
CB:40981 patched some values that would result in a build failure when the temporary `IOSAV_SUBSEQUENCE` macro is redefined to use structs instead of masks and shifts.
Don't forget about CB:45713 either! 😄
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... PS5, Line 130: /* FIXME: Rewrite loop below without this. */
Answer should be yes as this is getting called from ec_lpc.c as part of acpi_fill_ssdt.
You can try adding printk's when this code runs to see if they are initialized, then check those fields instead of comparing the ops. This would need to be done for TGL too.
Or we can go with CB:45747 instead.
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... PS5, Line 133: /* By default, TGL uses the PMC MUX for all ports, so port_number is unused */
my bad, TGL and ADL should use the same PMC MUX programming for Type-C
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
PS5:
Honestly this file a good candidate for common code, many function can be moved into common, i belie […]
Sounds good. I'll be happy to review. Some exceptions to account for:
- Bay Trail, Braswell and Apollo Lake need special handling as they are using a different SMM save state. - I plan on refactoring Haswell and Broadwell at some point, and will move Broadwell out of soc/intel.
SKL, CFL and newer should be good to unify.
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... PS5, Line 58: * According the BWG the IEDBASE MSR is in bits 63:32. It's
Yes. […]
Ack
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 6:
(1 comment)
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
PS5:
Sounds good. I'll be happy to review. Some exceptions to account for: […]
Also, Arthur Heymans has done some cleanup already: https://review.coreboot.org/q/topic:%22common_smm_save_state"
Hello build bot (Jenkins), Furquan Shaikh, Patrick Georgi, Martin Roth, Tim Wawrzynczak, Angel Pons, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/45759
to look at the new patch set (#7).
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h M src/soc/intel/alderlake/include/soc/systemagent.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 35 files changed, 3,188 insertions(+), 18 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/7
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 6:
(15 comments)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... File src/soc/intel/alderlake/chip.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 242: /* CNVi */ : uint8_t CnviMode; : uint8_t CnviBtCore;
Why did these get removed?
using is_dev_enable directly
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... File src/soc/intel/alderlake/chip.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/chi... PS3, Line 136: /* Snapshot the current GPIO IRQ polarities. FSP is setting a : * default policy that doesn't honor boards' requirements. */ : itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
Thank you! In the meantime, please mention that a bug has been filed (one `l`), and that this W/A sh […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/cpu... File src/soc/intel/alderlake/cpu.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/cpu... PS3, Line 150: /* TODO(adurbin): This should only be done on a cold boot. Also, some : * of these banks are core vs package scope. For now every CPU clears : * every bank. */
fun fact, AFAICT this TODO has been in the codebase for 7 years
yes indeed. 😊
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/esp... File src/soc/intel/alderlake/espi.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/esp... PS3, Line 132: u8
stdint. […]
please check patchset 6
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fin... File src/soc/intel/alderlake/finalize.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fin... PS3, Line 57: /* TODO: Add Thermal Configuration */
Is there still a reason that `pch_thermal_configuration()` isn't called here? (should we be calling […]
Eventually we will add those thermal configuration code, but right now we don't have any FF device hence add thermal configuration has put under TODO. hope that is okay.
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fsp... PS3, Line 152: 0xff
OC_SKIP
Please check latets patch set. its done already 😊
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/fsp... PS3, Line 160: 0xff
OC_SKIP
Please check latets patch set. its done already 😊
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/fsp... PS5, Line 219: else
If devicetree has enabled DITO config for this SATA port (config->SataPortsEnableDitoConfig[i]), it […]
Thanks Angel
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... File src/soc/intel/alderlake/include/soc/meminit.h:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 27: 16
16 DIMM slots?
2 memory controller, each has 8 channel
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/inc... PS3, Line 38:
nit:tab
Ack
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmc... PS3, Line 128: : /* FIXME: Rewrite loop below without this. */ : extern struct chip_operations drivers_intel_pmc_mux_ops; : : /* By default, TGL uses the PMC MUX for all ports, so port_number is unused */ : const struct device *soc_get_pmc_mux_device(int port_number) : { : const struct device *pmc; : struct device *child; : : child = NULL; : pmc = pcidev_path_on_root(PCH_DEVFN_PMC); : if (!pmc || !pmc->link_list) : return NULL; : : while ((child = dev_bus_each_child(pmc->link_list, child)) != NULL) : if (child->chip_ops == &drivers_intel_pmc_mux_ops) : break; : : /* child will either be the correct device or NULL if not found */ : return child; : }
Good news, this is being removed! CB:45747, feel free to rebase there or not and I'll clean up my me […]
delete it
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... File src/soc/intel/alderlake/pmc.c:
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/pmc... PS5, Line 130: /* FIXME: Rewrite loop below without this. */
You can try adding printk's when this code runs to see if they are initialized, then check those fie […]
Removed now as part of CB:45747 and will add into devicetree.cb
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... File src/soc/intel/alderlake/pmutil.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 217: /* : * Check for any power failure to determine if this a wake from : * S5 because the PCH does not set the WAK_STS bit when waking : * from a true G3 state. : */
alignment of `*`
done as part of latest patchset
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/pmu... PS3, Line 253: ps->tco1_sts, ps->tco2_sts);
can fit on previous line
Ack
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
PS5:
Also, Arthur Heymans has done some cleanup already: https://review.coreboot. […]
yes, saw that, after ADL also merge, Arthur could fine tune this files as part of CB:45477
build bot (Jenkins) has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 7:
(1 comment)
https://review.coreboot.org/c/coreboot/+/45759/7/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/7/src/soc/intel/alderlake/fsp... PS7, Line 216: if (config->SataPortsEnableDitoConfig[i]) { suspect code indent for conditional statements (16, 32)
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 7:
(2 comments)
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... File src/soc/intel/alderlake/acpi.c:
https://review.coreboot.org/c/coreboot/+/45759/3/src/soc/intel/alderlake/acp... PS3, Line 235: if (tbtbar && tbten) {
Should there also be a check here depending on whether or not each device (00:07.0 - 7. […]
Ack
https://review.coreboot.org/c/coreboot/+/45759/7/src/soc/intel/alderlake/fsp... File src/soc/intel/alderlake/fsp_params.c:
https://review.coreboot.org/c/coreboot/+/45759/7/src/soc/intel/alderlake/fsp... PS7, Line 216: if (config->SataPortsEnableDitoConfig[i]) {
suspect code indent for conditional statements (16, 32)
done
Hello build bot (Jenkins), Furquan Shaikh, Patrick Georgi, Martin Roth, Tim Wawrzynczak, Angel Pons, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/45759
to look at the new patch set (#8).
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h M src/soc/intel/alderlake/include/soc/systemagent.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 35 files changed, 3,191 insertions(+), 18 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/8
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 8:
(1 comment)
https://review.coreboot.org/c/coreboot/+/45759/5/src/soc/intel/alderlake/smm... File src/soc/intel/alderlake/smmrelocate.c:
PS5:
yes, saw that, after ADL also merge, Arthur could fine tune this files as part of CB:45477
Done
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 8: Code-Review+1
LGTM
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 9: Code-Review+1
Tim Wawrzynczak has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 10: Code-Review+2
If it's good enough for Angel, it's good enough for me 😉
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 10:
Patch Set 10: Code-Review+2
If it's good enough for Angel, it's good enough for me 😉
Thanks Tim and Angel. Still 2 base patch need to go first https://review.coreboot.org/c/coreboot/+/45796/6 and https://review.coreboot.org/c/coreboot/+/45794/5. can you please help to review those as well?
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 10: Code-Review+2
Hello build bot (Jenkins), Furquan Shaikh, Patrick Georgi, Martin Roth, Tim Wawrzynczak, Angel Pons, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/45759
to look at the new patch set (#11).
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h M src/soc/intel/alderlake/include/soc/systemagent.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 35 files changed, 3,191 insertions(+), 18 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/45759/11
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 11:
Patch Set 10: Code-Review+2
If it's good enough for Angel, it's good enough for me 😉
Angel, Tim, if you could give your vote again (sorry for several time review request), lost again due to rebasing of CB:45740 😞
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 11: Code-Review+2
Angel Pons has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 11:
Patch Set 11:
Patch Set 10: Code-Review+2
If it's good enough for Angel, it's good enough for me 😉
Angel, Tim, if you could give your vote again (sorry for several time review request), lost again due to rebasing of CB:45740 😞
No worries. I just checked the differences between PS10 and PS11 😄
Subrata Banik has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
Patch Set 11:
Patch Set 11:
Patch Set 11:
Patch Set 10: Code-Review+2
If it's good enough for Angel, it's good enough for me 😉
Angel, Tim, if you could give your vote again (sorry for several time review request), lost again due to rebasing of CB:45740 😞
No worries. I just checked the differences between PS10 and PS11 😄
yes, Angel. 😊 thanks. submitting it now to avoid further confusion.
Subrata Banik has submitted this change. ( https://review.coreboot.org/c/coreboot/+/45759 )
Change subject: soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage ......................................................................
soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API
Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik subrata.banik@intel.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/45759 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Angel Pons th3fanbus@gmail.com --- M src/soc/intel/alderlake/Kconfig M src/soc/intel/alderlake/Makefile.inc A src/soc/intel/alderlake/acpi.c A src/soc/intel/alderlake/chip.c M src/soc/intel/alderlake/chip.h A src/soc/intel/alderlake/cpu.c A src/soc/intel/alderlake/elog.c M src/soc/intel/alderlake/espi.c A src/soc/intel/alderlake/finalize.c A src/soc/intel/alderlake/fsp_params.c A src/soc/intel/alderlake/gspi.c A src/soc/intel/alderlake/i2c.c A src/soc/intel/alderlake/include/soc/cpu.h A src/soc/intel/alderlake/include/soc/irq.h A src/soc/intel/alderlake/include/soc/itss.h A src/soc/intel/alderlake/include/soc/me.h A src/soc/intel/alderlake/include/soc/meminit.h A src/soc/intel/alderlake/include/soc/nvs.h M src/soc/intel/alderlake/include/soc/pci_devs.h M src/soc/intel/alderlake/include/soc/pmc.h A src/soc/intel/alderlake/include/soc/ramstage.h A src/soc/intel/alderlake/include/soc/serialio.h M src/soc/intel/alderlake/include/soc/systemagent.h A src/soc/intel/alderlake/include/soc/usb.h A src/soc/intel/alderlake/lockdown.c A src/soc/intel/alderlake/me.c A src/soc/intel/alderlake/pmc.c A src/soc/intel/alderlake/pmutil.c M src/soc/intel/alderlake/romstage/fsp_params.c A src/soc/intel/alderlake/smihandler.c A src/soc/intel/alderlake/smmrelocate.c A src/soc/intel/alderlake/soundwire.c A src/soc/intel/alderlake/spi.c A src/soc/intel/alderlake/systemagent.c A src/soc/intel/alderlake/uart.c 35 files changed, 3,191 insertions(+), 18 deletions(-)
Approvals: build bot (Jenkins): Verified Angel Pons: Looks good to me, approved
diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 8f12350..1e05897 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -8,25 +8,44 @@ config CPU_SPECIFIC_OPTIONS def_bool y select ACPI_INTEL_HARDWARE_SLEEP_VALUES - select ARCH_BOOTBLOCK_X86_32 - select ARCH_ROMSTAGE_X86_32 - select ARCH_VERSTAGE_X86_32 + select ARCH_ALL_STAGES_X86_32 select BOOT_DEVICE_SUPPORTS_WRITES select CACHE_MRC_SETTINGS select CPU_INTEL_COMMON + select CPU_INTEL_COMMON_HYPERTHREADING + select CPU_INTEL_FIRMWARE_INTERFACE_TABLE + select FSP_COMPRESS_FSP_S_LZ4 select FSP_M_XIP + select GENERIC_GPIO_LIB + select HAVE_FSP_GOP select INTEL_DESCRIPTOR_MODE_CAPABLE + select HAVE_SMI_HANDLER select IDT_IN_EVERY_STAGE select INTEL_CAR_NEM #TODO - Enable INTEL_CAR_NEM_ENHANCED + select INTEL_GMA_ACPI + select INTEL_GMA_ADD_VBT if RUN_FSP_GOP + select IOAPIC select MRC_SETTINGS_PROTECT + select PARALLEL_MP + select PARALLEL_MP_AP_WORK select MICROCODE_BLOB_UNDISCLOSED select PLATFORM_USES_FSP2_2 + select FSP_PEIM_TO_PEIM_INTERFACE + select REG_SCRIPT + select PMC_GLOBAL_RESET_ENABLE_LOCK + select PMC_LOW_POWER_MODE_PROGRAM select SOC_INTEL_COMMON select SOC_INTEL_COMMON_BLOCK 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_DTT + select SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT select SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2 + select SOC_INTEL_COMMON_BLOCK_HDA select SOC_INTEL_COMMON_BLOCK_SA + select SOC_INTEL_COMMON_BLOCK_SMM + select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_PCH_BASE select SOC_INTEL_COMMON_RESET select SOC_INTEL_COMMON_BLOCK_CAR @@ -35,6 +54,12 @@ select TSC_MONOTONIC_TIMER select UDELAY_TSC select UDK_202005_BINDING + select DISPLAY_FSP_VERSION_INFO + select HECI_DISABLE_USING_SMM + +config MAX_CPUS + int + default 24
config DCACHE_RAM_BASE default 0xfef00000 @@ -74,6 +99,22 @@ hex default 0x10000
+config MAX_ROOT_PORTS + int + default 12 + +config MAX_PCIE_CLOCKS + int + default 12 + +config SMM_TSEG_SIZE + hex + default 0x800000 + +config SMM_RESERVED_SIZE + hex + default 0x200000 + config PCR_BASE_ADDRESS hex default 0xfd000000 @@ -145,6 +186,7 @@ config PRERAM_CBMEM_CONSOLE_SIZE hex default 0x1400 + config FSP_HEADER_PATH string "Location of FSP headers" default "src/vendorcode/intel/fsp/fsp2_0/alderlake/" diff --git a/src/soc/intel/alderlake/Makefile.inc b/src/soc/intel/alderlake/Makefile.inc index 7ea9301..d962b75 100644 --- a/src/soc/intel/alderlake/Makefile.inc +++ b/src/soc/intel/alderlake/Makefile.inc @@ -7,6 +7,13 @@ subdirs-y += ../../../cpu/x86/smm subdirs-y += ../../../cpu/x86/tsc
+# all (bootblock, verstage, romstage, postcar, ramstage) +all-y += gspi.c +all-y += i2c.c +all-y += pmutil.c +all-y += spi.c +all-y += uart.c + bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/cpu.c bootblock-y += bootblock/pch.c @@ -20,9 +27,28 @@ romstage-y += meminit.c romstage-y += reset.c
+ramstage-y += acpi.c +ramstage-y += chip.c +ramstage-y += cpu.c +ramstage-y += elog.c +ramstage-y += espi.c +ramstage-y += finalize.c +ramstage-y += fsp_params.c ramstage-y += gpio.c +ramstage-y += lockdown.c +ramstage-y += me.c +ramstage-y += p2sb.c +ramstage-y += pmc.c +ramstage-y += reset.c +ramstage-y += smmrelocate.c +ramstage-y += soundwire.c +ramstage-y += systemagent.c
smm-y += gpio.c +smm-y += p2sb.c +smm-y += pmutil.c +smm-y += smihandler.c +smm-y += uart.c
CPPFLAGS_common += -I$(src)/soc/intel/alderlake CPPFLAGS_common += -I$(src)/soc/intel/alderlake/include diff --git a/src/soc/intel/alderlake/acpi.c b/src/soc/intel/alderlake/acpi.c new file mode 100644 index 0000000..ca5d726 --- /dev/null +++ b/src/soc/intel/alderlake/acpi.c @@ -0,0 +1,375 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpi.h> +#include <acpi/acpi_gnvs.h> +#include <acpi/acpigen.h> +#include <device/mmio.h> +#include <arch/smp/mpspec.h> +#include <cbmem.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci_ops.h> +#include <ec/google/chromeec/ec.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/acpi.h> +#include <soc/cpu.h> +#include <soc/iomap.h> +#include <soc/nvs.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_chip.h> +#include <soc/systemagent.h> +#include <string.h> +#include <types.h> +#include <wrdd.h> + +/* + * List of supported C-states in this processor. + */ +enum { + C_STATE_C0, /* 0 */ + C_STATE_C1, /* 1 */ + C_STATE_C1E, /* 2 */ + C_STATE_C6_SHORT_LAT, /* 3 */ + C_STATE_C6_LONG_LAT, /* 4 */ + C_STATE_C7_SHORT_LAT, /* 5 */ + C_STATE_C7_LONG_LAT, /* 6 */ + C_STATE_C7S_SHORT_LAT, /* 7 */ + C_STATE_C7S_LONG_LAT, /* 8 */ + C_STATE_C8, /* 9 */ + C_STATE_C9, /* 10 */ + C_STATE_C10, /* 11 */ + NUM_C_STATES +}; + +#define MWAIT_RES(state, sub_state) \ + { \ + .addrl = (((state) << 4) | (sub_state)), \ + .space_id = ACPI_ADDRESS_SPACE_FIXED, \ + .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \ + .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \ + .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \ + } + +static const acpi_cstate_t cstate_map[NUM_C_STATES] = { + [C_STATE_C0] = {}, + [C_STATE_C1] = { + .latency = C1_LATENCY, + .power = C1_POWER, + .resource = MWAIT_RES(0, 0), + }, + [C_STATE_C1E] = { + .latency = C1_LATENCY, + .power = C1_POWER, + .resource = MWAIT_RES(0, 1), + }, + [C_STATE_C6_SHORT_LAT] = { + .latency = C6_LATENCY, + .power = C6_POWER, + .resource = MWAIT_RES(2, 0), + }, + [C_STATE_C6_LONG_LAT] = { + .latency = C6_LATENCY, + .power = C6_POWER, + .resource = MWAIT_RES(2, 1), + }, + [C_STATE_C7_SHORT_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 0), + }, + [C_STATE_C7_LONG_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 1), + }, + [C_STATE_C7S_SHORT_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 2), + }, + [C_STATE_C7S_LONG_LAT] = { + .latency = C7_LATENCY, + .power = C7_POWER, + .resource = MWAIT_RES(3, 3), + }, + [C_STATE_C8] = { + .latency = C8_LATENCY, + .power = C8_POWER, + .resource = MWAIT_RES(4, 0), + }, + [C_STATE_C9] = { + .latency = C9_LATENCY, + .power = C9_POWER, + .resource = MWAIT_RES(5, 0), + }, + [C_STATE_C10] = { + .latency = C10_LATENCY, + .power = C10_POWER, + .resource = MWAIT_RES(6, 0), + }, +}; + +static int cstate_set_non_s0ix[] = { + C_STATE_C1, + C_STATE_C6_LONG_LAT, + C_STATE_C7S_LONG_LAT +}; + +static int cstate_set_s0ix[] = { + C_STATE_C1, + C_STATE_C7S_LONG_LAT, + C_STATE_C10 +}; + +acpi_cstate_t *soc_get_cstate_map(size_t *entries) +{ + static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix), + ARRAY_SIZE(cstate_set_non_s0ix))]; + int *set; + int i; + + config_t *config = config_of_soc(); + + int is_s0ix_enable = config->s0ix_enable; + + if (is_s0ix_enable) { + *entries = ARRAY_SIZE(cstate_set_s0ix); + set = cstate_set_s0ix; + } else { + *entries = ARRAY_SIZE(cstate_set_non_s0ix); + set = cstate_set_non_s0ix; + } + + for (i = 0; i < *entries; i++) { + memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t)); + map[i].ctype = i + 1; + } + return map; +} + +void soc_power_states_generation(int core_id, int cores_per_package) +{ + config_t *config = config_of_soc(); + + if (config->eist_enable) + /* Generate P-state tables */ + generate_p_state_entries(core_id, cores_per_package); +} + +void soc_fill_fadt(acpi_fadt_t *fadt) +{ + const uint16_t pmbase = ACPI_BASE_ADDRESS; + + config_t *config = config_of_soc(); + + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->pm_tmr_len = 4; + fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO; + fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; + fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; + fadt->x_pm_tmr_blk.addrh = 0x0; + + if (config->s0ix_enable) + fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0; +} + +uint32_t soc_read_sci_irq_select(void) +{ + return read32((void *)soc_read_pmc_base() + IRQ_REG); +} + +static unsigned long soc_fill_dmar(unsigned long current) +{ + const struct device *const igfx_dev = pcidev_path_on_root(SA_DEVFN_IGD); + const uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK; + const bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED; + + if (is_dev_enabled(igfx_dev) && gfxvtbar && gfxvten) { + const unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar); + current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + + acpi_dmar_drhd_fixup(tmp, current); + } + + const struct device *const ipu_dev = pcidev_path_on_root(SA_DEVFN_IPU); + const uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK; + const bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED; + + if (is_dev_enabled(ipu_dev) && ipuvtbar && ipuvten) { + const unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar); + current += acpi_create_dmar_ds_pci(current, 0, 5, 0); + + acpi_dmar_drhd_fixup(tmp, current); + } + + const uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK; + const bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED; + + if (vtvc0bar && vtvc0en) { + const unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, + DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); + current += acpi_create_dmar_ds_ioapic(current, + 2, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV, + V_P2SB_CFG_IBDF_FUNC); + current += acpi_create_dmar_ds_msi_hpet(current, + 0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV, + V_P2SB_CFG_HBDF_FUNC); + + acpi_dmar_drhd_fixup(tmp, current); + } + + /* TCSS Thunderbolt root ports */ + for (unsigned int i = 0; i < MAX_TBT_PCIE_PORT; i++) { + const struct device *const tbt_dev = pcidev_path_on_root(SA_DEVFN_TBT(i)); + if (is_dev_enabled(tbt_dev)) { + const uint64_t tbtbar = MCHBAR64(TBTxBAR(i)) & VTBAR_MASK; + const bool tbten = MCHBAR32(TBTxBAR(i)) & VTBAR_ENABLED; + if (tbtbar && tbten) { + const unsigned long tmp = current; + + current += acpi_create_dmar_drhd(current, 0, 0, tbtbar); + current += acpi_create_dmar_ds_pci_br(current, 0, 7, i); + + acpi_dmar_drhd_fixup(tmp, current); + } + } + } + + /* Add RMRR entry */ + if (is_dev_enabled(igfx_dev)) { + const unsigned long tmp = current; + current += acpi_create_dmar_rmrr(current, 0, + sa_get_gsm_base(), sa_get_tolud_base() - 1); + current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + acpi_dmar_rmrr_fixup(tmp, current); + } + + return current; +} + +unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current, + struct acpi_rsdp *rsdp) +{ + acpi_dmar_t *const dmar = (acpi_dmar_t *)current; + + /* + * Create DMAR table only if we have VT-d capability and FSP does not override its + * feature. + */ + if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) || + !(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED)) + return current; + + printk(BIOS_DEBUG, "ACPI: * DMAR\n"); + acpi_create_dmar(dmar, DMAR_INTR_REMAP | DMA_CTRL_PLATFORM_OPT_IN_FLAG, soc_fill_dmar); + current += dmar->header.length; + current = acpi_align_current(current); + acpi_add_table(rsdp, dmar); + + return current; +} + +void acpi_create_gnvs(struct global_nvs *gnvs) +{ + config_t *config = config_of_soc(); + + /* Set unknown wake source */ + gnvs->pm1i = -1; + + /* CPU core count */ + gnvs->pcnt = dev_count_cpu(); + + if (CONFIG(CONSOLE_CBMEM)) + /* Update the mem console pointer. */ + gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE); + + if (CONFIG(CHROMEOS)) { + /* Initialize Verified Boot data */ + chromeos_init_chromeos_acpi(&(gnvs->chromeos)); + if (CONFIG(EC_GOOGLE_CHROMEEC)) { + gnvs->chromeos.vbt2 = google_ec_running_ro() ? + ACTIVE_ECFW_RO : ACTIVE_ECFW_RW; + } else + gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO; + } + + /* Enable DPTF based on mainboard configuration */ + gnvs->dpte = config->dptf_enable; + + /* Fill in the Wifi Region id */ + gnvs->cid1 = wifi_regulatory_domain(); + + /* Set USB2/USB3 wake enable bitmaps. */ + gnvs->u2we = config->usb2_wake_enable_bitmap; + gnvs->u3we = config->usb3_wake_enable_bitmap; + + /* Fill in Above 4GB MMIO resource */ + sa_fill_gnvs(gnvs); +} + +uint32_t acpi_fill_soc_wake(uint32_t generic_pm1_en, + const struct chipset_power_state *ps) +{ + /* + * WAK_STS bit is set when the system is in one of the sleep states + * (via the SLP_EN bit) and an enabled wake event occurs. Upon setting + * this bit, the PMC will transition the system to the ON state and + * can only be set by hardware and can only be cleared by writing a one + * to this bit position. + */ + + generic_pm1_en |= WAK_STS | RTC_EN | PWRBTN_EN; + return generic_pm1_en; +} + +int soc_madt_sci_irq_polarity(int sci) +{ + return MP_IRQ_POLARITY_HIGH; +} + +static int acpigen_soc_gpio_op(const char *op, unsigned int gpio_num) +{ + /* op (gpio_num) */ + acpigen_emit_namestring(op); + acpigen_write_integer(gpio_num); + return 0; +} + +static int acpigen_soc_get_gpio_state(const char *op, unsigned int gpio_num) +{ + /* Store (op (gpio_num), Local0) */ + acpigen_write_store(); + acpigen_soc_gpio_op(op, gpio_num); + acpigen_emit_byte(LOCAL0_OP); + return 0; +} + +int acpigen_soc_read_rx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_get_gpio_state("\_SB.PCI0.GRXS", gpio_num); +} + +int acpigen_soc_get_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_get_gpio_state("\_SB.PCI0.GTXS", gpio_num); +} + +int acpigen_soc_set_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_gpio_op("\_SB.PCI0.STXS", gpio_num); +} + +int acpigen_soc_clear_tx_gpio(unsigned int gpio_num) +{ + return acpigen_soc_gpio_op("\_SB.PCI0.CTXS", gpio_num); +} diff --git a/src/soc/intel/alderlake/chip.c b/src/soc/intel/alderlake/chip.c new file mode 100644 index 0000000..794c3ba --- /dev/null +++ b/src/soc/intel/alderlake/chip.c @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/device.h> +#include <device/pci.h> +#include <fsp/api.h> +#include <fsp/util.h> +#include <intelblocks/acpi.h> +#include <intelblocks/cfg.h> +#include <intelblocks/itss.h> +#include <intelblocks/pcie_rp.h> +#include <intelblocks/xdci.h> +#include <romstage_handoff.h> +#include <soc/intel/common/vbt.h> +#include <soc/itss.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/soc_chip.h> + +static const struct pcie_rp_group pch_lp_rp_groups[] = { + { .slot = PCH_DEV_SLOT_PCIE, .count = 8 }, + { .slot = PCH_DEV_SLOT_PCIE_1, .count = 4 }, + { 0 } +}; + +#if CONFIG(HAVE_ACPI_TABLES) +const char *soc_acpi_name(const struct device *dev) +{ + if (dev->path.type == DEVICE_PATH_DOMAIN) + return "PCI0"; + + if (dev->path.type == DEVICE_PATH_USB) { + switch (dev->path.usb.port_type) { + case 0: + /* Root Hub */ + return "RHUB"; + case 2: + /* USB2 ports */ + switch (dev->path.usb.port_id) { + case 0: return "HS01"; + case 1: return "HS02"; + case 2: return "HS03"; + case 3: return "HS04"; + case 4: return "HS05"; + case 5: return "HS06"; + case 6: return "HS07"; + case 7: return "HS08"; + case 8: return "HS09"; + case 9: return "HS10"; + } + break; + case 3: + /* USB3 ports */ + switch (dev->path.usb.port_id) { + case 0: return "SS01"; + case 1: return "SS02"; + case 2: return "SS03"; + case 3: return "SS04"; + } + break; + } + return NULL; + } + if (dev->path.type != DEVICE_PATH_PCI) + return NULL; + + switch (dev->path.pci.devfn) { + case SA_DEVFN_ROOT: return "MCHC"; + case SA_DEVFN_TCSS_XHCI: return "TXHC"; + case SA_DEVFN_TCSS_XDCI: return "TXDC"; + case SA_DEVFN_TCSS_DMA0: return "TDM0"; + case SA_DEVFN_TCSS_DMA1: return "TDM1"; + case SA_DEVFN_TBT0: return "TRP0"; + case SA_DEVFN_TBT1: return "TRP1"; + case SA_DEVFN_TBT2: return "TRP2"; + case SA_DEVFN_TBT3: return "TRP3"; + case SA_DEVFN_IPU: return "IPU0"; + case PCH_DEVFN_ISH: return "ISHB"; + case PCH_DEVFN_XHCI: return "XHCI"; + case PCH_DEVFN_I2C0: return "I2C0"; + case PCH_DEVFN_I2C1: return "I2C1"; + case PCH_DEVFN_I2C2: return "I2C2"; + case PCH_DEVFN_I2C3: return "I2C3"; + case PCH_DEVFN_I2C4: return "I2C4"; + case PCH_DEVFN_I2C5: return "I2C5"; + case PCH_DEVFN_SATA: return "SATA"; + case PCH_DEVFN_PCIE1: return "RP01"; + case PCH_DEVFN_PCIE2: return "RP02"; + case PCH_DEVFN_PCIE3: return "RP03"; + case PCH_DEVFN_PCIE4: return "RP04"; + case PCH_DEVFN_PCIE5: return "RP05"; + case PCH_DEVFN_PCIE6: return "RP06"; + case PCH_DEVFN_PCIE7: return "RP07"; + case PCH_DEVFN_PCIE8: return "RP08"; + case PCH_DEVFN_PCIE9: return "RP09"; + case PCH_DEVFN_PCIE10: return "RP10"; + case PCH_DEVFN_PCIE11: return "RP11"; + case PCH_DEVFN_PCIE12: return "RP12"; + case PCH_DEVFN_PMC: return "PMC"; + case PCH_DEVFN_UART0: return "UAR0"; + case PCH_DEVFN_UART1: return "UAR1"; + case PCH_DEVFN_UART2: return "UAR2"; + case PCH_DEVFN_GSPI0: return "SPI0"; + case PCH_DEVFN_GSPI1: return "SPI1"; + case PCH_DEVFN_GSPI2: return "SPI2"; + case PCH_DEVFN_GSPI3: return "SPI3"; + /* Keeping ACPI device name coherent with ec.asl */ + case PCH_DEVFN_ESPI: return "LPCB"; + case PCH_DEVFN_HDA: return "HDAS"; + case PCH_DEVFN_SMBUS: return "SBUS"; + case PCH_DEVFN_GBE: return "GLAN"; + } + + return NULL; +} +#endif + +/* SoC routine to fill GPIO PM mask and value for GPIO_MISCCFG register */ +static void soc_fill_gpio_pm_configuration(void) +{ + uint8_t value[TOTAL_GPIO_COMM]; + const config_t *config = config_of_soc(); + + if (config->gpio_override_pm) + memcpy(value, config->gpio_pm, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + else + memset(value, MISCCFG_ENABLE_GPIO_PM_CONFIG, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + + gpio_pm_configure(value, TOTAL_GPIO_COMM); +} + +void soc_init_pre_device(void *chip_info) +{ + /* TODO: A bug has been filed, remove this W/A once FSP is updated */ + /* Snapshot the current GPIO IRQ polarities. FSP is setting a + * default policy that doesn't honor boards' requirements. */ + itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); + + /* Perform silicon specific init. */ + fsp_silicon_init(romstage_handoff_is_resume()); + + /* Display FIRMWARE_VERSION_INFO_HOB */ + fsp_display_fvi_version_hob(); + + /* Restore GPIO IRQ polarities back to previous settings. */ + itss_restore_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); + + soc_fill_gpio_pm_configuration(); + + /* Swap enabled PCI ports in device tree if needed. */ + pcie_rp_update_devicetree(pch_lp_rp_groups); +} + +static struct device_operations pci_domain_ops = { + .read_resources = &pci_domain_read_resources, + .set_resources = &pci_domain_set_resources, + .scan_bus = &pci_domain_scan_bus, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = &soc_acpi_name, +#endif +}; + +static struct device_operations cpu_bus_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = generate_cpu_entries, +#endif +}; + +static void soc_enable(struct device *dev) +{ + /* + * Set the operations if it is a special bus type or a hidden PCI + * device. + */ + if (dev->path.type == DEVICE_PATH_DOMAIN) + dev->ops = &pci_domain_ops; + else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) + dev->ops = &cpu_bus_ops; + else if (dev->path.type == DEVICE_PATH_PCI && + dev->path.pci.devfn == PCH_DEVFN_PMC) + dev->ops = &pmc_ops; +} + +struct chip_operations soc_intel_alderlake_ops = { + CHIP_NAME("Intel Alderlake") + .enable_dev = &soc_enable, + .init = &soc_init_pre_device, +}; diff --git a/src/soc/intel/alderlake/chip.h b/src/soc/intel/alderlake/chip.h index 2721da6..aaf03f5 100644 --- a/src/soc/intel/alderlake/chip.h +++ b/src/soc/intel/alderlake/chip.h @@ -11,6 +11,8 @@ #include <soc/pch.h> #include <soc/pci_devs.h> #include <soc/pmc.h> +#include <soc/serialio.h> +#include <soc/usb.h> #include <stdint.h>
#define MAX_HD_AUDIO_DMIC_LINKS 2 @@ -177,7 +179,6 @@ uint8_t SkipExtGfxScan;
uint32_t GraphicsConfigPtr; - uint8_t Device4Enable;
/* HeciEnabled decides the state of Heci1 at end of boot * Setting to 0 (default) disables Heci1 and hides the device from OS */ @@ -239,10 +240,6 @@ /* Enable Pch iSCLK */ uint8_t pch_isclk;
- /* CNVi */ - uint8_t CnviMode; - uint8_t CnviBtCore; - /* CNVi BT Audio Offload: Enable/Disable BT Audio Offload. */ enum { FORCE_DISABLE, @@ -250,6 +247,19 @@ } CnviBtAudioOffload;
/* + * IOM Port Config + * If a port orientation needs to be controlled by the SOC this setting must be + * updated to reflect the correct GPIOs being used for the SOC port flipping. + * There are 4 ports each with a pair of GPIOs for Pull Up and Pull Down + * 0,1 are pull up and pull down for port 0 + * 2,3 are pull up and pull down for port 1 + * 4,5 are pull up and pull down for port 2 + * 6,7 are pull up and pull down for port 3 + * values to be programmed correspond to the GPIO family and offsets + */ + uint32_t IomTypeCPortPadCfg[8]; + + /* * SOC Aux orientation override: * This is a bitfield that corresponds to up to 4 TCSS ports on ADL. * Even numbered bits (0, 2, 4, 6) control the retimer being handled by SOC. diff --git a/src/soc/intel/alderlake/cpu.c b/src/soc/intel/alderlake/cpu.c new file mode 100644 index 0000000..ee8051d --- /dev/null +++ b/src/soc/intel/alderlake/cpu.c @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor CPU Datasheet + * Document number: 619501 + * Chapter number: 14 + */ + +#include <arch/cpu.h> +#include <console/console.h> +#include <device/pci.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/intel/smm_reloc.h> +#include <cpu/intel/turbo.h> +#include <fsp/api.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/mp_init.h> +#include <intelblocks/msr.h> +#include <romstage_handoff.h> +#include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_chip.h> + +static void soc_fsp_load(void) +{ + fsps_load(romstage_handoff_is_resume()); +} + +static void configure_isst(void) +{ + config_t *conf = config_of_soc(); + msr_t msr; + + if (conf->speed_shift_enable) { + /* + * Kernel driver checks CPUID.06h:EAX[Bit 7] to determine if HWP + * is supported or not. coreboot needs to configure MSR 0x1AA + * which is then reflected in the CPUID register. + */ + msr = rdmsr(MSR_MISC_PWR_MGMT); + msr.lo |= MISC_PWR_MGMT_ISST_EN; /* Enable Speed Shift */ + msr.lo |= MISC_PWR_MGMT_ISST_EN_INT; /* Enable Interrupt */ + msr.lo |= MISC_PWR_MGMT_ISST_EN_EPP; /* Enable EPP */ + wrmsr(MSR_MISC_PWR_MGMT, msr); + } else { + msr = rdmsr(MSR_MISC_PWR_MGMT); + msr.lo &= ~MISC_PWR_MGMT_ISST_EN; /* Disable Speed Shift */ + msr.lo &= ~MISC_PWR_MGMT_ISST_EN_INT; /* Disable Interrupt */ + msr.lo &= ~MISC_PWR_MGMT_ISST_EN_EPP; /* Disable EPP */ + wrmsr(MSR_MISC_PWR_MGMT, msr); + } +} + +static void configure_misc(void) +{ + msr_t msr; + + config_t *conf = config_of_soc(); + + msr = rdmsr(IA32_MISC_ENABLE); + msr.lo |= (1 << 0); /* Fast String enable */ + msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ + wrmsr(IA32_MISC_ENABLE, msr); + + /* Set EIST status */ + cpu_set_eist(conf->eist_enable); + + /* Disable Thermal interrupts */ + msr.lo = 0; + msr.hi = 0; + wrmsr(IA32_THERM_INTERRUPT, msr); + + /* Enable package critical interrupt only */ + msr.lo = 1 << 4; + msr.hi = 0; + wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr); + + /* Enable PROCHOT */ + 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); +} + +static void enable_lapic_tpr(void) +{ + msr_t msr; + + msr = rdmsr(MSR_PIC_MSG_CONTROL); + msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */ + wrmsr(MSR_PIC_MSG_CONTROL, msr); +} + +static void configure_dca_cap(void) +{ + uint32_t feature_flag; + msr_t msr; + + /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */ + feature_flag = cpu_get_feature_flags_ecx(); + if (feature_flag & CPUID_DCA) { + msr = rdmsr(IA32_PLATFORM_DCA_CAP); + msr.lo |= 1; + wrmsr(IA32_PLATFORM_DCA_CAP, msr); + } +} + +static void enable_pm_timer_emulation(void) +{ + /* ACPI PM timer emulation */ + msr_t msr; + /* + * The derived frequency is calculated as follows: + * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. + * Back solve the multiplier so the 3.579545MHz ACPI timer + * frequency is used. + */ + msr.hi = (3579545ULL << 32) / CTC_FREQ; + /* Set PM1 timer IO port and enable */ + msr.lo = (EMULATE_DELAY_VALUE << EMULATE_DELAY_OFFSET_VALUE) | + EMULATE_PM_TMR_EN | (ACPI_BASE_ADDRESS + PM1_TMR); + wrmsr(MSR_EMULATE_PM_TIMER, msr); +} + +static void set_energy_perf_bias(u8 policy) +{ + msr_t msr; + int ecx; + + /* Determine if energy efficient policy is supported. */ + ecx = cpuid_ecx(0x6); + if (!(ecx & (1 << 3))) + return; + + /* Energy Policy is bits 3:0 */ + msr = rdmsr(IA32_ENERGY_PERF_BIAS); + msr.lo &= ~0xf; + msr.lo |= policy & 0xf; + wrmsr(IA32_ENERGY_PERF_BIAS, msr); +} + +/* All CPUs including BSP will run the following function. */ +void soc_core_init(struct device *cpu) +{ + /* Clear out pending MCEs */ + /* TODO(adurbin): This should only be done on a cold boot. Also, some + * of these banks are core vs package scope. For now every CPU clears + * every bank. */ + mca_configure(); + + /* Enable the local CPU apics */ + enable_lapic_tpr(); + setup_lapic(); + + /* Configure Enhanced SpeedStep and Thermal Sensors */ + configure_misc(); + + /* Configure Intel Speed Shift */ + configure_isst(); + + /* Enable PM timer emulation */ + enable_pm_timer_emulation(); + + /* Enable Direct Cache Access */ + configure_dca_cap(); + + /* Set energy policy */ + set_energy_perf_bias(ENERGY_POLICY_NORMAL); + + /* Enable Turbo */ + enable_turbo(); +} + +static void per_cpu_smm_trigger(void) +{ + /* Relocate the SMM handler. */ + smm_relocate(); +} + +static void post_mp_init(void) +{ + /* Set Max Ratio */ + cpu_set_max_ratio(); + + /* + * Now that all APs have been relocated as well as the BSP let SMIs + * 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. + */ + .pre_mp_init = soc_fsp_load, + .get_cpu_count = get_cpu_count, + .get_smm_info = smm_info, + .get_microcode_info = get_microcode_info, + .pre_mp_smm_init = smm_initialize, + .per_cpu_smm_trigger = per_cpu_smm_trigger, + .relocation_handler = smm_relocation_handler, + .post_mp_init = post_mp_init, +}; + +void soc_init_cpus(struct bus *cpu_bus) +{ + if (mp_init_with_smm(cpu_bus, &mp_ops)) + printk(BIOS_ERR, "MP initialization failure.\n"); + + /* Thermal throttle activation offset */ + configure_tcc_thermal_target(); +} diff --git a/src/soc/intel/alderlake/elog.c b/src/soc/intel/alderlake/elog.c new file mode 100644 index 0000000..84f0a7e --- /dev/null +++ b/src/soc/intel/alderlake/elog.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootstate.h> +#include <console/console.h> +#include <stdint.h> +#include <elog.h> +#include <intelblocks/pmclib.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> + +static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start) +{ + int i; + + gpe0_sts &= gpe0_en; + + for (i = 0; i <= 31; i++) { + if (gpe0_sts & (1 << i)) + elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start); + } +} + +static void pch_log_wake_source(struct chipset_power_state *ps) +{ + /* Power Button */ + if (ps->pm1_sts & PWRBTN_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0); + + /* RTC */ + if (ps->pm1_sts & RTC_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0); + + /* PCI Express (TODO: determine wake device) */ + if (ps->pm1_sts & PCIEXPWAK_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0); + + /* PME (TODO: determine wake device) */ + if (ps->gpe0_sts[GPE_STD] & PME_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0); + + /* Internal PME (TODO: determine wake device) */ + if (ps->gpe0_sts[GPE_STD] & PME_B0_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0); + + /* SMBUS Wake */ + if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0); + + /* Log GPIO events in set 1-3 */ + pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64); + /* Treat the STD as an extension of GPIO to obtain visibility. */ + pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96); +} + +static void pch_log_power_and_resets(struct chipset_power_state *ps) +{ + /* Thermal Trip */ + if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP) + elog_add_event(ELOG_TYPE_THERM_TRIP); + + /* CSME-Initiated Host Reset with power down */ + if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPD) + elog_add_event(ELOG_TYPE_MI_HRPD); + + /* CSME-Initiated Host Reset with power cycle */ + if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPC) + elog_add_event(ELOG_TYPE_MI_HRPC); + + /* CSME-Initiated Host Reset without power cycle */ + if (ps->hpr_cause0 & HPR_CAUSE0_MI_HR) + elog_add_event(ELOG_TYPE_MI_HR); + + /* PWR_FLR Power Failure */ + if (ps->gen_pmcon_a & PWR_FLR) + elog_add_event(ELOG_TYPE_POWER_FAIL); + + /* SUS Well Power Failure */ + if (ps->gen_pmcon_a & SUS_PWR_FLR) + elog_add_event(ELOG_TYPE_SUS_POWER_FAIL); + + /* TCO Timeout */ + if (ps->prev_sleep_state != ACPI_S3 && + ps->tco2_sts & TCO_STS_SECOND_TO) + elog_add_event(ELOG_TYPE_TCO_RESET); + + /* Power Button Override */ + if (ps->pm1_sts & PRBTNOR_STS) + elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE); + + /* RTC reset */ + if (ps->gen_pmcon_b & RTC_BATTERY_DEAD) + elog_add_event(ELOG_TYPE_RTC_RESET); + + /* Host Reset Status */ + if (ps->gen_pmcon_a & HOST_RST_STS) + elog_add_event(ELOG_TYPE_SYSTEM_RESET); + + /* ACPI Wake Event */ + if (ps->prev_sleep_state != ACPI_S0) + elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state); +} + +static void pch_log_state(void *unused) +{ + struct chipset_power_state *ps = pmc_get_power_state(); + + if (!ps) { + printk(BIOS_ERR, "chipset_power_state not found!\n"); + return; + } + + /* Power and Reset */ + pch_log_power_and_resets(ps); + + /* Wake Sources */ + if (ps->prev_sleep_state > ACPI_S0) + pch_log_wake_source(ps); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pch_log_state, NULL); + +void elog_gsmi_cb_platform_log_wake_source(void) +{ + struct chipset_power_state ps; + pmc_fill_pm_reg_info(&ps); + pch_log_wake_source(&ps); +} diff --git a/src/soc/intel/alderlake/espi.c b/src/soc/intel/alderlake/espi.c index bad4ab9..8a4007c 100644 --- a/src/soc/intel/alderlake/espi.c +++ b/src/soc/intel/alderlake/espi.c @@ -9,10 +9,14 @@ #include <device/pci.h> #include <pc80/isa-dma.h> #include <pc80/i8259.h> +#include <arch/ioapic.h> +#include <intelblocks/itss.h> #include <intelblocks/lpc_lib.h> #include <intelblocks/pcr.h> #include <soc/espi.h> #include <soc/iomap.h> +#include <soc/irq.h> +#include <soc/pci_devs.h> #include <soc/pcr_ids.h> #include <soc/soc_chip.h>
@@ -49,3 +53,27 @@ pcr_write32(PID_DMI, PCR_DMI_LPCLGIR3, gen_io_dec[2]); pcr_write32(PID_DMI, PCR_DMI_LPCLGIR4, gen_io_dec[3]); } + +#if ENV_RAMSTAGE +void lpc_soc_init(struct device *dev) +{ + /* Legacy initialization */ + isa_dma_init(); + lpc_pch_misc_init(); + + /* Enable CLKRUN_EN for power gating ESPI */ + lpc_enable_pci_clk_cntl(); + + /* Set ESPI Serial IRQ mode */ + if (CONFIG(SERIRQ_CONTINUOUS_MODE)) + lpc_set_serirq_mode(SERIRQ_CONTINUOUS); + else + lpc_set_serirq_mode(SERIRQ_QUIET); + + /* Interrupt configuration */ + lpc_pch_enable_ioapic(); + lpc_pch_pirq_init(); + setup_i8259(); + i8259_configure_irq_trigger(9, 1); +} +#endif diff --git a/src/soc/intel/alderlake/finalize.c b/src/soc/intel/alderlake/finalize.c new file mode 100644 index 0000000..24dbbd6 --- /dev/null +++ b/src/soc/intel/alderlake/finalize.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4, 29 + */ + +#include <arch/io.h> +#include <device/mmio.h> +#include <bootstate.h> +#include <console/console.h> +#include <console/post_codes.h> +#include <cpu/x86/smm.h> +#include <device/pci.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/pcr.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/tco.h> +#include <intelblocks/thermal.h> +#include <spi-generic.h> +#include <soc/p2sb.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> +#include <soc/pm.h> +#include <soc/smbus.h> +#include <soc/soc_chip.h> +#include <soc/systemagent.h> + +#define CAMERA1_CLK 0x8000 /* Camera 1 Clock */ +#define CAMERA2_CLK 0x8080 /* Camera 2 Clock */ +#define CAM_CLK_EN (1 << 1) +#define MIPI_CLK (1 << 0) +#define HDPLL_CLK (0 << 0) + +static void pch_enable_isclk(void) +{ + pcr_or32(PID_ISCLK, CAMERA1_CLK, CAM_CLK_EN | MIPI_CLK); + pcr_or32(PID_ISCLK, CAMERA2_CLK, CAM_CLK_EN | MIPI_CLK); +} + +static void pch_handle_sideband(config_t *config) +{ + if (config->pch_isclk) + pch_enable_isclk(); +} + +static void pch_finalize(void) +{ + config_t *config; + + /* TCO Lock down */ + tco_lockdown(); + + /* TODO: Add Thermal Configuration */ + + /* + * Disable ACPI PM timer based on dt policy + * + * Disabling ACPI PM timer is necessary for XTAL OSC shutdown. + * Disabling ACPI PM timer also switches off TCO + */ + config = config_of_soc(); + if (config->PmTimerDisabled) + pmc_disable_acpi_timer(); + + /* Disable XTAL shutdown qualification for low power idle. */ + if (config->s0ix_enable) + pmc_ignore_xtal_shutdown(); + + pch_handle_sideband(config); + + pmc_clear_pmcon_sts(); +} + +static void tbt_finalize(void) +{ + int i; + const struct device *dev; + + /* Disable Thunderbolt PCIe root ports bus master */ + for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { + dev = pcidev_path_on_root(SA_DEVFN_TBT(i)); + if (dev) + pci_dev_disable_bus_master(dev); + } +} + +static void soc_finalize(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); + + /* Indicate finalize step with post code */ + post_code(POST_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/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c new file mode 100644 index 0000000..a21ca4a --- /dev/null +++ b/src/soc/intel/alderlake/fsp_params.c @@ -0,0 +1,317 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <assert.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <fsp/api.h> +#include <fsp/ppi/mp_service_ppi.h> +#include <fsp/util.h> +#include <intelblocks/lpss.h> +#include <intelblocks/xdci.h> +#include <intelpch/lockdown.h> +#include <intelblocks/mp_init.h> +#include <soc/gpio_soc_defs.h> +#include <soc/intel/common/vbt.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/soc_chip.h> +#include <string.h> + +/* THC assignment definition */ +#define THC_NONE 0 +#define THC_0 1 +#define THC_1 2 + +/* SATA DEVSLP idle timeout default values */ +#define DEF_DMVAL 15 +#define DEF_DITOVAL 625 + +/* + * Chip config parameter PcieRpL1Substates uses (UPD value + 1) + * because UPD value of 0 for PcieRpL1Substates means disabled for FSP. + * In order to ensure that mainboard setting does not disable L1 substates + * incorrectly, chip config parameter values are offset by 1 with 0 meaning + * use FSP UPD default. get_l1_substate_control() ensures that the right UPD + * value is set in fsp_params. + * 0: Use FSP UPD default + * 1: Disable L1 substates + * 2: Use L1.1 + * 3: Use L1.2 (FSP UPD default) + */ +static int get_l1_substate_control(enum L1_substates_control ctl) +{ + if ((ctl > L1_SS_L1_2) || (ctl == L1_SS_FSP_DEFAULT)) + ctl = L1_SS_L1_2; + return ctl - 1; +} + +static void parse_devicetree(FSP_S_CONFIG *params) +{ + const struct soc_intel_alderlake_config *config; + config = config_of_soc(); + + for (int i = 0; i < CONFIG_SOC_INTEL_I2C_DEV_MAX; i++) + params->SerialIoI2cMode[i] = config->SerialIoI2cMode[i]; + + for (int i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++) { + params->SerialIoSpiMode[i] = config->SerialIoGSpiMode[i]; + params->SerialIoSpiCsMode[i] = config->SerialIoGSpiCsMode[i]; + params->SerialIoSpiCsState[i] = config->SerialIoGSpiCsState[i]; + } + + for (int i = 0; i < CONFIG_SOC_INTEL_UART_DEV_MAX; i++) + params->SerialIoUartMode[i] = config->SerialIoUartMode[i]; +} + +static const pci_devfn_t serial_io_dev[] = { + PCH_DEVFN_I2C0, + PCH_DEVFN_I2C1, + PCH_DEVFN_I2C2, + PCH_DEVFN_I2C3, + PCH_DEVFN_I2C4, + PCH_DEVFN_I2C5, + PCH_DEVFN_GSPI0, + PCH_DEVFN_GSPI1, + PCH_DEVFN_GSPI2, + PCH_DEVFN_GSPI3, + PCH_DEVFN_UART0, + PCH_DEVFN_UART1, + PCH_DEVFN_UART2 +}; + +__weak void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config) +{ + /* Override settings per board. */ +} + +/* UPD parameters to be initialized before SiliconInit */ +void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) +{ + int i; + FSP_S_CONFIG *params = &supd->FspsConfig; + + struct device *dev; + struct soc_intel_alderlake_config *config; + config = config_of_soc(); + mainboard_update_soc_chip_config(config); + + /* Parse device tree and enable/disable Serial I/O devices */ + parse_devicetree(params); + + /* Load VBT before devicetree-specific config. */ + params->GraphicsConfigPtr = (uintptr_t)vbt_get(); + + /* Check if IGD is present and fill Graphics init param accordingly */ + dev = pcidev_path_on_root(SA_DEVFN_IGD); + params->PeiGraphicsPeimInit = CONFIG(RUN_FSP_GOP) && is_dev_enabled(dev); + + /* Use coreboot MP PPI services if Kconfig is enabled */ + if (CONFIG(USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI)) + params->CpuMpPpi = (uintptr_t) mp_fill_ppi_services_data(); + + /* D3Hot and D3Cold for TCSS */ + params->D3HotEnable = !config->TcssD3HotDisable; + params->D3ColdEnable = !config->TcssD3ColdDisable; + + params->TcssAuxOri = config->TcssAuxOri; + for (i = 0; i < 8; i++) + params->IomTypeCPortPadCfg[i] = config->IomTypeCPortPadCfg[i]; + + /* + * Set FSPS UPD ITbtConnectTopologyTimeoutInMs with value 0. FSP will + * evaluate this UPD value and skip sending command. There will be no + * delay for command completion. + */ + params->ITbtConnectTopologyTimeoutInMs = 0; + + /* Chipset Lockdown */ + if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) { + params->PchLockDownGlobalSmi = 0; + params->PchLockDownBiosInterface = 0; + params->PchUnlockGpioPads = 1; + params->RtcMemoryLock = 0; + } else { + params->PchLockDownGlobalSmi = 1; + params->PchLockDownBiosInterface = 1; + params->PchUnlockGpioPads = 0; + params->RtcMemoryLock = 1; + } + + /* USB */ + for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) { + params->PortUsb20Enable[i] = config->usb2_ports[i].enable; + params->Usb2PhyPetxiset[i] = config->usb2_ports[i].pre_emp_bias; + params->Usb2PhyTxiset[i] = config->usb2_ports[i].tx_bias; + params->Usb2PhyPredeemp[i] = config->usb2_ports[i].tx_emp_enable; + params->Usb2PhyPehalfbit[i] = config->usb2_ports[i].pre_emp_bit; + + if (config->usb2_ports[i].enable) + params->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin; + else + params->Usb2OverCurrentPin[i] = OC_SKIP; + } + + for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) { + params->PortUsb30Enable[i] = config->usb3_ports[i].enable; + if (config->usb3_ports[i].enable) + params->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin; + else + params->Usb3OverCurrentPin[i] = OC_SKIP; + + if (config->usb3_ports[i].tx_de_emp) { + params->Usb3HsioTxDeEmphEnable[i] = 1; + params->Usb3HsioTxDeEmph[i] = config->usb3_ports[i].tx_de_emp; + } + if (config->usb3_ports[i].tx_downscale_amp) { + params->Usb3HsioTxDownscaleAmpEnable[i] = 1; + params->Usb3HsioTxDownscaleAmp[i] = + config->usb3_ports[i].tx_downscale_amp; + } + } + + /* Enable xDCI controller if enabled in devicetree and allowed */ + dev = pcidev_path_on_root(PCH_DEVFN_USBOTG); + if (dev) { + if (!xdci_can_enable()) + dev->enabled = 0; + params->XdciEnable = dev->enabled; + } else { + params->XdciEnable = 0; + } + + /* PCH UART selection for FSP Debug */ + params->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE; + ASSERT(ARRAY_SIZE(params->SerialIoUartAutoFlow) > CONFIG_UART_FOR_CONSOLE); + params->SerialIoUartAutoFlow[CONFIG_UART_FOR_CONSOLE] = 0; + + /* SATA */ + dev = pcidev_path_on_root(PCH_DEVFN_SATA); + params->SataEnable = is_dev_enabled(dev); + if (params->SataEnable) { + params->SataMode = config->SataMode; + params->SataSalpSupport = config->SataSalpSupport; + memcpy(params->SataPortsEnable, config->SataPortsEnable, + sizeof(params->SataPortsEnable)); + memcpy(params->SataPortsDevSlp, config->SataPortsDevSlp, + sizeof(params->SataPortsDevSlp)); + } + + /* + * Power Optimizer for DMI and SATA. + * DmiPwrOptimizeDisable and SataPwrOptimizeDisable is default to 0. + * Boards not needing the optimizers explicitly disables them by setting + * these disable variables to 1 in devicetree overrides. + */ + params->PchPwrOptEnable = !(config->DmiPwrOptimizeDisable); + params->SataPwrOptEnable = !(config->SataPwrOptimizeDisable); + + /* + * Enable DEVSLP Idle Timeout settings DmVal and DitoVal. + * SataPortsDmVal is the DITO multiplier. Default is 15. + * SataPortsDitoVal is the DEVSLP Idle Timeout (DITO), Default is 625ms. + * The default values can be changed from devicetree. + */ + for (i = 0; i < ARRAY_SIZE(config->SataPortsEnableDitoConfig); i++) { + if (config->SataPortsEnableDitoConfig[i]) { + params->SataPortsDmVal[i] = config->SataPortsDmVal[i]; + params->SataPortsDitoVal[i] = config->SataPortsDitoVal[i]; + } + } + + /* Enable TCPU for processor thermal control */ + dev = pcidev_path_on_root(SA_DEVFN_DPTF); + params->Device4Enable = is_dev_enabled(dev); + + /* Set TccActivationOffset */ + params->TccActivationOffset = config->tcc_offset; + + /* LAN */ + dev = pcidev_path_on_root(PCH_DEVFN_GBE); + params->PchLanEnable = is_dev_enabled(dev); + + /* CNVi */ + dev = pcidev_path_on_root(PCH_DEVFN_CNVI_WIFI); + params->CnviMode = is_dev_enabled(dev); + + /* CNVi BT Core */ + dev = pcidev_path_on_root(PCH_DEVFN_CNVI_BT); + params->CnviBtCore = is_dev_enabled(dev); + + /* CNVi BT Audio Offload */ + params->CnviBtAudioOffload = config->CnviBtAudioOffload; + + /* VMD */ + dev = pcidev_path_on_root(SA_DEVFN_VMD); + params->VmdEnable = is_dev_enabled(dev); + + /* THC */ + dev = pcidev_path_on_root(PCH_DEVFN_THC0); + params->ThcPort0Assignment = is_dev_enabled(dev) ? THC_0 : THC_NONE; + + dev = pcidev_path_on_root(PCH_DEVFN_THC1); + params->ThcPort1Assignment = is_dev_enabled(dev) ? THC_1 : THC_NONE; + + /* Legacy 8254 timer support */ + params->Enable8254ClockGating = !CONFIG(USE_LEGACY_8254_TIMER); + params->Enable8254ClockGatingOnS3 = !CONFIG(USE_LEGACY_8254_TIMER); + + /* Enable Hybrid storage auto detection */ + params->HybridStorageMode = config->HybridStorageMode; + + for (i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) { + params->PcieRpL1Substates[i] = + get_l1_substate_control(config->PcieRpL1Substates[i]); + params->PcieRpLtrEnable[i] = config->PcieRpLtrEnable[i]; + params->PcieRpAdvancedErrorReporting[i] = + config->PcieRpAdvancedErrorReporting[i]; + params->PcieRpHotPlug[i] = config->PcieRpHotPlug[i]; + } + + /* Enable ClkReqDetect for enabled port */ + memcpy(params->PcieRpClkReqDetect, config->PcieRpClkReqDetect, + sizeof(config->PcieRpClkReqDetect)); + + params->PmSupport = 1; + params->Hwp = 1; + params->Cx = 1; + params->PsOnEnable = 1; + + mainboard_silicon_init_params(params); +} + +int soc_fsp_multi_phase_init_is_enable(void) +{ + return 0; +} + +/* + * Callbacks for SoC/Mainboard specific overrides for FspMultiPhaseSiInit + * This platform supports below MultiPhaseSIInit Phase(s): + * Phase | FSP return point | Purpose + * ------- + ------------------------------------------------ + ------------------------------- + * 1 | After TCSS initialization completed | for TCSS specific init + */ +void platform_fsp_multi_phase_init_cb(uint32_t phase_index) +{ + switch (phase_index) { + case 1: + /* TCSS specific initialization here */ + break; + default: + break; + } +} + +/* Mainboard GPIO Configuration */ +__weak void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__); +} + +/* Return list of SOC LPSS controllers */ +const pci_devfn_t *soc_lpss_controllers_list(size_t *size) +{ + *size = ARRAY_SIZE(serial_io_dev); + return serial_io_dev; +} diff --git a/src/soc/intel/alderlake/gspi.c b/src/soc/intel/alderlake/gspi.c new file mode 100644 index 0000000..dd07b07 --- /dev/null +++ b/src/soc/intel/alderlake/gspi.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 11 + */ + +#include <intelblocks/gspi.h> +#include <soc/pci_devs.h> + +int gspi_soc_bus_to_devfn(unsigned int gspi_bus) +{ + switch (gspi_bus) { + case 0: + return PCH_DEVFN_GSPI0; + case 1: + return PCH_DEVFN_GSPI1; + case 2: + return PCH_DEVFN_GSPI2; + case 3: + return PCH_DEVFN_GSPI3; + } + return -1; +} diff --git a/src/soc/intel/alderlake/i2c.c b/src/soc/intel/alderlake/i2c.c new file mode 100644 index 0000000..ef34e2e --- /dev/null +++ b/src/soc/intel/alderlake/i2c.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 13 + */ + +#include <device/device.h> +#include <drivers/i2c/designware/dw_i2c.h> +#include <soc/pci_devs.h> + +int dw_i2c_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { + case PCH_DEVFN_I2C0: + return 0; + case PCH_DEVFN_I2C1: + return 1; + case PCH_DEVFN_I2C2: + return 2; + case PCH_DEVFN_I2C3: + return 3; + case PCH_DEVFN_I2C4: + return 4; + case PCH_DEVFN_I2C5: + return 5; + } + return -1; +} + +int dw_i2c_soc_bus_to_devfn(unsigned int bus) +{ + switch (bus) { + case 0: + return PCH_DEVFN_I2C0; + case 1: + return PCH_DEVFN_I2C1; + case 2: + return PCH_DEVFN_I2C2; + case 3: + return PCH_DEVFN_I2C3; + case 4: + return PCH_DEVFN_I2C4; + case 5: + return PCH_DEVFN_I2C5; + } + return -1; +} diff --git a/src/soc/intel/alderlake/include/soc/cpu.h b/src/soc/intel/alderlake/include/soc/cpu.h new file mode 100644 index 0000000..3c11183 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/cpu.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_ALDERLAKE_CPU_H_ +#define _SOC_ALDERLAKE_CPU_H_ + +/* Latency times in us */ +#define C1_LATENCY 1 +#define C6_LATENCY 127 +#define C7_LATENCY 253 +#define C8_LATENCY 260 +#define C9_LATENCY 487 +#define C10_LATENCY 1048 + +/* Power in units of mW */ +#define C1_POWER 0x3e8 +#define C6_POWER 0x15e +#define C7_POWER 0xc8 +#define C8_POWER 0xc8 +#define C9_POWER 0xc8 +#define C10_POWER 0xc8 + +/* Common Timer Copy (CTC) frequency - 38.4MHz. */ +#define CTC_FREQ 38400000 + +#endif diff --git a/src/soc/intel/alderlake/include/soc/irq.h b/src/soc/intel/alderlake/include/soc/irq.h new file mode 100644 index 0000000..98e3f42 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/irq.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_IRQ_H_ +#define _SOC_IRQ_H_ + +#define GPIO_IRQ14 14 +#define GPIO_IRQ15 15 + +#define PCH_IRQ10 10 +#define PCH_IRQ11 11 + +#define LPSS_I2C0_IRQ 27 +#define LPSS_I2C1_IRQ 40 +#define LPSS_I2C2_IRQ 29 +#define LPSS_I2C3_IRQ 30 +#define LPSS_I2C4_IRQ 31 +#define LPSS_I2C5_IRQ 32 +#define LPSS_SPI0_IRQ 36 +#define LPSS_SPI1_IRQ 37 +#define LPSS_SPI2_IRQ 34 +#define LPSS_SPI3_IRQ 43 + +#define LPSS_UART0_IRQ 16 +#define LPSS_UART1_IRQ 17 +#define LPSS_UART2_IRQ 33 + +#define HDA_IRQ 16 +#define SMBUS_IRQ 16 +#define TRACEHUB_IRQ 16 + +#define PCIE_1_IRQ 16 +#define PCIE_2_IRQ 17 +#define PCIE_3_IRQ 18 +#define PCIE_4_IRQ 19 +#define PCIE_5_IRQ 16 +#define PCIE_6_IRQ 17 +#define PCIE_7_IRQ 18 +#define PCIE_8_IRQ 19 +#define PCIE_9_IRQ 16 +#define PCIE_10_IRQ 17 +#define PCIE_11_IRQ 18 +#define PCIE_12_IRQ 19 + +#define SATA_IRQ 16 + +#define xHCI_IRQ 16 +#define xDCI_IRQ 17 +#define CNVI_WIFI_IRQ 16 + +#define CNVI_BT_IRQ 18 + +#define THC0_IRQ 23 +#define THC1_IRQ 24 + +#define ISH_IRQ 16 + +#define TBT_PCIe0_IRQ 16 +#define TBT_PCIe1_IRQ 17 +#define TBT_PCIe2_IRQ 18 +#define TBT_PCIe3_IRQ 19 + +#define HECI_1_IRQ 16 +#define HECI_2_IRQ 17 +#define HECI_3_IRQ 16 +#define HECI_4_IRQ 19 + +#define PEG_IRQ 16 +#define IGFX_IRQ 16 +#define THERMAL_IRQ 16 +#define IPU_IRQ 16 +#define GNA_IRQ 16 +#endif diff --git a/src/soc/intel/alderlake/include/soc/itss.h b/src/soc/intel/alderlake/include/soc/itss.h new file mode 100644 index 0000000..ff26c9f --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/itss.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_INTEL_ADL_ITSS_H +#define SOC_INTEL_ADL_ITSS_H + +#define GPIO_IRQ_START 50 +#define GPIO_IRQ_END ITSS_MAX_IRQ + +#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_INTEL_ADL_ITSS_H */ diff --git a/src/soc/intel/alderlake/include/soc/me.h b/src/soc/intel/alderlake/include/soc/me.h new file mode 100644 index 0000000..993a3bc --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/me.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ALDERLAKE_ME_H_ +#define _ALDERLAKE_ME_H_ + +#include <stdint.h> + +/* ME Host Firmware Status register 1 */ +union me_hfsts1 { + u32 data; + struct { + u32 working_state: 4; + u32 spi_protection_mode: 1; + u32 fpt_bad: 1; + u32 operation_state: 3; + u32 fw_init_complete: 1; + u32 ft_bup_ld_flr: 1; + u32 update_in_progress: 1; + u32 error_code: 4; + u32 operation_mode: 4; + u32 reset_count: 4; + u32 boot_options_present: 1; + u32 invoke_enhance_dbg_mode: 1; + u32 bist_test_state: 1; + u32 bist_reset_request: 1; + u32 current_power_source: 2; + u32 reserved: 1; + u32 d0i3_support_valid: 1; + } __packed fields; +}; + +/* ME Host Firmware Status Register 3 */ +union me_hfsts3 { + u32 data; + struct { + u32 reserved_0: 4; + u32 fw_sku: 3; + u32 reserved_7: 2; + u32 reserved_9: 2; + u32 resered_11: 3; + u32 resered_14: 16; + u32 reserved_30: 2; + } __packed fields; +}; +#endif /* _ALDERLAKE_ME_H_ */ diff --git a/src/soc/intel/alderlake/include/soc/meminit.h b/src/soc/intel/alderlake/include/soc/meminit.h new file mode 100644 index 0000000..76930be --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/meminit.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_ALDERLAKE_MEMINIT_H_ +#define _SOC_ALDERLAKE_MEMINIT_H_ + +#include <stddef.h> +#include <stdint.h> +#include <fsp/soc_binding.h> + +#define BYTES_PER_CHANNEL 2 +#define BITS_PER_BYTE 8 +#define DQS_PER_CHANNEL 2 + +/* 64-bit Channel identification */ +enum { + DDR_CH0, + DDR_CH1, + DDR_CH2, + DDR_CH3, + DDR_CH4, + DDR_CH5, + DDR_CH6, + DDR_CH7, + DDR_NUM_CHANNELS +}; +/* Number of memory DIMM slots available on Alderlake board */ +#define NUM_DIMM_SLOT 16 + +struct spd_by_pointer { + size_t spd_data_len; + uintptr_t spd_data_ptr; +}; + +enum mem_info_read_type { + NOT_EXISTING, /* No memory in this slot */ + READ_SMBUS, /* Read on-module spd by SMBUS. */ + READ_SPD_CBFS, /* Find SPD file in CBFS. */ + READ_SPD_MEMPTR /* Find SPD data from pointer. */ +}; + +struct spd_info { + enum mem_info_read_type read_type; + union spd_data_by { + /* To read on-module SPD when read_type is READ_SMBUS. */ + uint8_t spd_smbus_address[NUM_DIMM_SLOT]; + + /* To identify SPD file when read_type is READ_SPD_CBFS. */ + int spd_index; + + /* To find SPD data when read_type is READ_SPD_MEMPTR. */ + struct spd_by_pointer spd_data_ptr_info; + } spd_spec; +}; + +/* Board-specific memory configuration information */ +struct mb_cfg { + /* DQ mapping */ + uint8_t dq_map[DDR_NUM_CHANNELS][BYTES_PER_CHANNEL * BITS_PER_BYTE]; + + /* + * DQS CPU<>DRAM map. Each array entry represents a + * mapping of a dq bit on the CPU to the bit it's connected to on + * the memory part. The array index represents the dqs bit number + * on the memory part, and the values in the array represent which + * pin on the CPU that DRAM pin connects to. + */ + uint8_t dqs_map[DDR_NUM_CHANNELS][DQS_PER_CHANNEL]; + + /* + * Rcomp resistor values. These values represent the resistance in + * ohms of the three rcomp resistors attached to the DDR_COMP_0, + * DDR_COMP_1, and DDR_COMP_2 pins on the DRAM. + */ + uint16_t rcomp_resistor[3]; + + /* Rcomp target values. */ + uint16_t rcomp_targets[5]; + + /* + * Early Command Training Enable/Disable Control + * TRUE = enable, FALSE = disable + */ + bool ect; + + /* Board type */ + uint8_t UserBd; +}; + +/* + * Initialize default memory configurations for Alder Lake. + */ + +void memcfg_init(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *board_cfg, + const struct spd_info *spd_info, bool half_populated); + +#endif /* _SOC_ALDERLAKE_MEMINIT_H_ */ diff --git a/src/soc/intel/alderlake/include/soc/nvs.h b/src/soc/intel/alderlake/include/soc/nvs.h new file mode 100644 index 0000000..5129458 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/nvs.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_NVS_H_ +#define _SOC_NVS_H_ + +#include <intelblocks/nvs.h> + +#endif diff --git a/src/soc/intel/alderlake/include/soc/pci_devs.h b/src/soc/intel/alderlake/include/soc/pci_devs.h index eedcc27..d86e81d 100644 --- a/src/soc/intel/alderlake/include/soc/pci_devs.h +++ b/src/soc/intel/alderlake/include/soc/pci_devs.h @@ -30,6 +30,10 @@ #define SA_DEVFN_DPTF PCI_DEVFN(SA_DEV_SLOT_DPTF, 0) #define SA_DEV_DPTF PCI_DEV(0, SA_DEV_SLOT_DPTF, 0)
+#define SA_DEV_SLOT_IPU 0x05 +#define SA_DEVFN_IPU PCI_DEVFN(SA_DEV_SLOT_IPU, 0) +#define SA_DEV_IPU PCI_DEV(0, SA_DEV_SLOT_IPU, 0) + #define SA_DEV_SLOT_CPU_PCIE 0x06 #define SA_DEVFN_CPU_PCIE PCI_DEVFN(SA_DEV_SLOT_CPU_PCIE, 0)
@@ -63,8 +67,10 @@ #define PCH_DEV_SLOT_SIO0 0x10 #define PCH_DEVFN_THC0 _PCH_DEVFN(SIO0, 0) #define PCH_DEVFN_THC1 _PCH_DEVFN(SIO0, 1) +#define PCH_DEVFN_CNVI_BT _PCH_DEVFN(SIO0, 2) #define PCH_DEV_THC0 _PCH_DEV(SIO0, 0) #define PCH_DEV_THC1 _PCH_DEV(SIO0, 1) +#define PCH_DEV_CNVI_BT _PCH_DEV(SIO0, 2)
#define PCH_DEV_SLOT_ISH 0x12 #define PCH_DEVFN_ISH _PCH_DEVFN(ISH, 0) @@ -72,6 +78,10 @@ #define PCH_DEV_ISH _PCH_DEV(ISH, 0) #define PCH_DEV_GSPI2 _PCH_DEV(ISH, 6)
+#define PCH_DEV_SLOT_SIO2 0x13 +#define PCH_DEVFN_GSPI3 _PCH_DEVFN(SIO2, 0) +#define PCH_DEV_GSPI3 _PCH_DEV(SIO2, 0) + #define PCH_DEV_SLOT_XHCI 0x14 #define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0) #define PCH_DEVFN_USBOTG _PCH_DEVFN(XHCI, 1) diff --git a/src/soc/intel/alderlake/include/soc/pmc.h b/src/soc/intel/alderlake/include/soc/pmc.h index 03fe02f..e4e3dfb 100644 --- a/src/soc/intel/alderlake/include/soc/pmc.h +++ b/src/soc/intel/alderlake/include/soc/pmc.h @@ -2,6 +2,9 @@
#ifndef _SOC_ALDERLAKE_PMC_H_ #define _SOC_ALDERLAKE_PMC_H_ +#include <device/device.h> + +extern struct device_operations pmc_ops;
/* PCI Configuration Space (D31:F2): PMC */ #define PWRMBASE 0x10 diff --git a/src/soc/intel/alderlake/include/soc/ramstage.h b/src/soc/intel/alderlake/include/soc/ramstage.h new file mode 100644 index 0000000..e655198 --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/ramstage.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_RAMSTAGE_H_ +#define _SOC_RAMSTAGE_H_ + +#include <fsp/api.h> +#include <fsp/util.h> +#include <soc/soc_chip.h> + +void mainboard_silicon_init_params(FSP_S_CONFIG *params); +void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config); +void soc_init_pre_device(void *chip_info); + +#endif diff --git a/src/soc/intel/alderlake/include/soc/serialio.h b/src/soc/intel/alderlake/include/soc/serialio.h new file mode 100644 index 0000000..e42af5f --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/serialio.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SERIALIO_H_ +#define _SERIALIO_H_ + +enum { + PchSerialIoDisabled, + PchSerialIoPci, + PchSerialIoHidden, + PchSerialIoLegacyUart, + PchSerialIoSkipInit +}; + +enum { + PchSerialIoIndexI2C0, + PchSerialIoIndexI2C1, + PchSerialIoIndexI2C2, + PchSerialIoIndexI2C3, + PchSerialIoIndexI2C4, + PchSerialIoIndexI2C5, +}; + +enum { + PchSerialIoIndexGSPI0, + PchSerialIoIndexGSPI1, + PchSerialIoIndexGSPI2, + PchSerialIoIndexGSPI3, +}; + +enum { + PchSerialIoIndexUART0, + PchSerialIoIndexUART1, + PchSerialIoIndexUART2, +}; + +#endif diff --git a/src/soc/intel/alderlake/include/soc/systemagent.h b/src/soc/intel/alderlake/include/soc/systemagent.h index b564e7d..ebb3d71 100644 --- a/src/soc/intel/alderlake/include/soc/systemagent.h +++ b/src/soc/intel/alderlake/include/soc/systemagent.h @@ -31,10 +31,7 @@ #define IMRBASE 0x6a40 #define IMRLIMIT 0x6a48 #define IPUVTBAR 0x7880 -#define TBT0BAR 0x7888 -#define TBT1BAR 0x7890 -#define TBT2BAR 0x7898 -#define TBT3BAR 0x78a0 +#define TBTxBAR(x) (0x7888 + (x) * 8)
#define MAX_TBT_PCIE_PORT 4
@@ -44,10 +41,10 @@ static const struct sa_mmio_descriptor soc_vtd_resources[] = { { GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" }, { IPUVTBAR, IPUVT_BASE_ADDRESS, IPUVT_BASE_SIZE, "IPUVTBAR" }, - { TBT0BAR, TBT0_BASE_ADDRESS, TBT0_BASE_SIZE, "TBT0BAR" }, - { TBT1BAR, TBT1_BASE_ADDRESS, TBT1_BASE_SIZE, "TBT1BAR" }, - { TBT2BAR, TBT2_BASE_ADDRESS, TBT2_BASE_SIZE, "TBT2BAR" }, - { TBT3BAR, TBT3_BASE_ADDRESS, TBT3_BASE_SIZE, "TBT3BAR" }, + { TBTxBAR(0), TBT0_BASE_ADDRESS, TBT0_BASE_SIZE, "TBT0BAR" }, + { TBTxBAR(1), TBT1_BASE_ADDRESS, TBT1_BASE_SIZE, "TBT1BAR" }, + { TBTxBAR(2), TBT2_BASE_ADDRESS, TBT2_BASE_SIZE, "TBT2BAR" }, + { TBTxBAR(3), TBT3_BASE_ADDRESS, TBT3_BASE_SIZE, "TBT3BAR" }, { VTVC0BAR, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE, "VTVC0BAR" }, };
diff --git a/src/soc/intel/alderlake/include/soc/usb.h b/src/soc/intel/alderlake/include/soc/usb.h new file mode 100644 index 0000000..846849a --- /dev/null +++ b/src/soc/intel/alderlake/include/soc/usb.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_USB_H_ +#define _SOC_USB_H_ + +#include <stdint.h> + +/* Per Port HS Transmitter Emphasis */ +#define USB2_EMP_OFF 0 +#define USB2_DE_EMP_ON 1 +#define USB2_PRE_EMP_ON 2 +#define USB2_DE_EMP_ON_PRE_EMP_ON 3 + +/* Per Port Half Bit Pre-emphasis */ +#define USB2_FULL_BIT_PRE_EMP 0 +#define USB2_HALF_BIT_PRE_EMP 1 + +/* Per Port HS Preemphasis Bias */ +#define USB2_BIAS_0MV 0 +#define USB2_BIAS_11P25MV 1 +#define USB2_BIAS_16P9MV 2 +#define USB2_BIAS_28P15MV 3 +#define USB2_BIAS_39P35MV 5 +#define USB2_BIAS_45MV 6 +#define USB2_BIAS_56P3MV 7 + +struct usb2_port_config { + uint8_t enable; + uint8_t ocpin; + uint8_t tx_bias; + uint8_t tx_emp_enable; + uint8_t pre_emp_bias; + uint8_t pre_emp_bit; +}; + +/* USB Overcurrent pins definition */ +enum { + OC0 = 0, + OC1, + OC2, + OC3, + OC4, + OC5, + OC6, + OC7, + OCMAX, + OC_SKIP = 0xff, /* Skip OC programming */ +}; + +/* Standard USB Port based on length: + * - External + * - Back Panel + * - OTG + * - M.2 + * - Internal device down */ + +#define USB2_PORT_EMPTY { \ + .enable = 0, \ + .ocpin = OC_SKIP, \ + .tx_bias = USB2_BIAS_0MV, \ + .tx_emp_enable = USB2_EMP_OFF, \ + .pre_emp_bias = USB2_BIAS_0MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +/* Length = 11.5"-12" */ +#define USB2_PORT_LONG(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_39P35MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_56P3MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +/* Length = 6"-11.49" */ +#define USB2_PORT_MID(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_0MV, \ + .tx_emp_enable = USB2_DE_EMP_ON_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_45MV, \ + .pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \ +} + +/* Length = 3"-5.99" */ +#define USB2_PORT_SHORT(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_39P35MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_39P35MV, \ + .pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \ +} + +/* Max TX and Pre-emp settings */ +#define USB2_PORT_MAX(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_56P3MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_56P3MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +/* Type-C Port, no BC1.2 charge detect module / MUX + * Length = 3.0" - 9.00" */ +#define USB2_PORT_TYPE_C(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_bias = USB2_BIAS_0MV, \ + .tx_emp_enable = USB2_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_56P3MV, \ + .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \ +} + +struct usb3_port_config { + uint8_t enable; + uint8_t ocpin; + uint8_t tx_de_emp; + uint8_t tx_downscale_amp; +}; + +#define USB3_PORT_EMPTY { \ + .enable = 0, \ + .ocpin = OC_SKIP, \ + .tx_de_emp = 0x00, \ + .tx_downscale_amp = 0x00, \ +} + +#define USB3_PORT_DEFAULT(pin) { \ + .enable = 1, \ + .ocpin = (pin), \ + .tx_de_emp = 0x0, \ + .tx_downscale_amp = 0x00, \ +} + +#endif diff --git a/src/soc/intel/alderlake/lockdown.c b/src/soc/intel/alderlake/lockdown.c new file mode 100644 index 0000000..e9e4b59 --- /dev/null +++ b/src/soc/intel/alderlake/lockdown.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4 + */ + +#include <device/mmio.h> +#include <intelblocks/cfg.h> +#include <intelpch/lockdown.h> +#include <soc/pm.h> +#include <stdint.h> + +static void pmc_lock_pmsync(void) +{ + uint8_t *pmcbase; + uint32_t pmsyncreg; + + pmcbase = pmc_mmio_regs(); + + pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG); + pmsyncreg |= PCH2CPU_TPR_CFG_LOCK; + write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg); +} + +static void pmc_lock_abase(void) +{ + uint8_t *pmcbase; + uint32_t reg32; + + pmcbase = pmc_mmio_regs(); + + reg32 = read32(pmcbase + GEN_PMCON_B); + reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK); + write32(pmcbase + GEN_PMCON_B, reg32); +} + +static void pmc_lock_smi(void) +{ + uint8_t *pmcbase; + uint8_t reg8; + + pmcbase = pmc_mmio_regs(); + + reg8 = read8(pmcbase + GEN_PMCON_B); + reg8 |= SMI_LOCK; + write8(pmcbase + GEN_PMCON_B, reg8); +} + +static void pmc_lockdown_cfg(int chipset_lockdown) +{ + /* PMSYNC */ + pmc_lock_pmsync(); + /* Lock down ABASE and sleep stretching policy */ + pmc_lock_abase(); + + if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) + pmc_lock_smi(); +} + +void soc_lockdown_config(int chipset_lockdown) +{ + /* PMC lock down configuration */ + pmc_lockdown_cfg(chipset_lockdown); +} diff --git a/src/soc/intel/alderlake/me.c b/src/soc/intel/alderlake/me.c new file mode 100644 index 0000000..da1a299 --- /dev/null +++ b/src/soc/intel/alderlake/me.c @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootstate.h> +#include <intelblocks/cse.h> +#include <console/console.h> +#include <soc/me.h> +#include <stdint.h> + +/* Host Firmware Status Register 2 */ +union me_hfsts2 { + uint32_t data; + struct { + uint32_t nftp_load_failure : 1; + uint32_t icc_prog_status : 2; + uint32_t invoke_mebx : 1; + uint32_t cpu_replaced : 1; + uint32_t rsvd0 : 1; + uint32_t mfs_failure : 1; + uint32_t warm_reset_rqst : 1; + uint32_t cpu_replaced_valid : 1; + uint32_t low_power_state : 1; + uint32_t me_power_gate : 1; + uint32_t ipu_needed : 1; + uint32_t forced_safe_boot : 1; + uint32_t rsvd1 : 2; + uint32_t listener_change : 1; + uint32_t status_data : 8; + uint32_t current_pmevent : 4; + uint32_t phase : 4; + } __packed fields; +}; + +/* Host Firmware Status Register 4 */ +union me_hfsts4 { + uint32_t data; + struct { + uint32_t rsvd0 : 9; + uint32_t enforcement_flow : 1; + uint32_t sx_resume_type : 1; + uint32_t rsvd1 : 1; + uint32_t tpms_disconnected : 1; + uint32_t rvsd2 : 1; + uint32_t fwsts_valid : 1; + uint32_t boot_guard_self_test : 1; + uint32_t rsvd3 : 16; + } __packed fields; +}; + +/* Host Firmware Status Register 5 */ +union me_hfsts5 { + uint32_t data; + struct { + uint32_t acm_active : 1; + uint32_t valid : 1; + uint32_t result_code_source : 1; + uint32_t error_status_code : 5; + uint32_t acm_done_sts : 1; + uint32_t timeout_count : 7; + uint32_t scrtm_indicator : 1; + uint32_t inc_boot_guard_acm : 4; + uint32_t inc_key_manifest : 4; + uint32_t inc_boot_policy : 4; + uint32_t rsvd0 : 2; + uint32_t start_enforcement : 1; + } __packed fields; +}; + +/* Host Firmware Status Register 6 */ +union me_hfsts6 { + uint32_t data; + struct { + uint32_t force_boot_guard_acm : 1; + uint32_t cpu_debug_disable : 1; + uint32_t bsp_init_disable : 1; + uint32_t protect_bios_env : 1; + uint32_t rsvd0 : 2; + uint32_t error_enforce_policy : 2; + uint32_t measured_boot : 1; + uint32_t verified_boot : 1; + uint32_t boot_guard_acmsvn : 4; + uint32_t kmsvn : 4; + uint32_t bpmsvn : 4; + uint32_t key_manifest_id : 4; + uint32_t boot_policy_status : 1; + uint32_t error : 1; + uint32_t boot_guard_disable : 1; + uint32_t fpf_disable : 1; + uint32_t fpf_soc_lock : 1; + uint32_t txt_support : 1; + } __packed fields; +}; + +static void dump_me_status(void *unused) +{ + union me_hfsts1 hfsts1; + union me_hfsts2 hfsts2; + union me_hfsts3 hfsts3; + union me_hfsts4 hfsts4; + union me_hfsts5 hfsts5; + union me_hfsts6 hfsts6; + + if (!is_cse_enabled()) + return; + + hfsts1.data = me_read_config32(PCI_ME_HFSTS1); + hfsts2.data = me_read_config32(PCI_ME_HFSTS2); + hfsts3.data = me_read_config32(PCI_ME_HFSTS3); + hfsts4.data = me_read_config32(PCI_ME_HFSTS4); + hfsts5.data = me_read_config32(PCI_ME_HFSTS5); + hfsts6.data = me_read_config32(PCI_ME_HFSTS6); + + printk(BIOS_DEBUG, "ME: HFSTS1 : 0x%08X\n", hfsts1.data); + printk(BIOS_DEBUG, "ME: HFSTS2 : 0x%08X\n", hfsts2.data); + printk(BIOS_DEBUG, "ME: HFSTS3 : 0x%08X\n", hfsts3.data); + printk(BIOS_DEBUG, "ME: HFSTS4 : 0x%08X\n", hfsts4.data); + printk(BIOS_DEBUG, "ME: HFSTS5 : 0x%08X\n", hfsts5.data); + printk(BIOS_DEBUG, "ME: HFSTS6 : 0x%08X\n", hfsts6.data); + + /* + * Lock Descriptor, and Fuses must be programmed on a + * production system to indicate ME Manufacturing mode is disabled. + */ + printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n", + ((hfsts1.fields.spi_protection_mode == 0) && + (hfsts6.fields.fpf_soc_lock == 1)) ? "NO" : "YES"); + /* + * The SPI Protection Mode bit reflects SPI descriptor + * locked(0) or unlocked(1). + */ + printk(BIOS_DEBUG, "ME: SPI Protection Mode Enabled : %s\n", + hfsts1.fields.spi_protection_mode ? "NO" : "YES"); + printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n", + hfsts1.fields.fpt_bad ? "BAD" : "OK"); + printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n", + hfsts1.fields.ft_bup_ld_flr ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n", + hfsts1.fields.fw_init_complete ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n", + hfsts1.fields.boot_options_present ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Update In Progress : %s\n", + hfsts1.fields.update_in_progress ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n", + hfsts1.fields.d0i3_support_valid ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n", + hfsts2.fields.low_power_state ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n", + hfsts2.fields.cpu_replaced ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n", + hfsts2.fields.cpu_replaced_valid ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Current Working State : %u\n", + hfsts1.fields.working_state); + printk(BIOS_DEBUG, "ME: Current Operation State : %u\n", + hfsts1.fields.operation_state); + printk(BIOS_DEBUG, "ME: Current Operation Mode : %u\n", + hfsts1.fields.operation_mode); + printk(BIOS_DEBUG, "ME: Error Code : %u\n", + hfsts1.fields.error_code); + printk(BIOS_DEBUG, "ME: Enhanced Debug Mode : %s\n", + hfsts1.fields.invoke_enhance_dbg_mode ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Debug Disabled : %s\n", + hfsts6.fields.cpu_debug_disable ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: TXT Support : %s\n", + hfsts6.fields.txt_support ? "YES" : "NO"); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_EXIT, print_me_fw_version, NULL); +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME_CHECK, BS_ON_EXIT, dump_me_status, NULL); diff --git a/src/soc/intel/alderlake/pmc.c b/src/soc/intel/alderlake/pmc.c new file mode 100644 index 0000000..e4c1009 --- /dev/null +++ b/src/soc/intel/alderlake/pmc.c @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4 + */ + +#include <acpi/acpigen.h> +#include <console/console.h> +#include <device/mmio.h> +#include <device/device.h> +#include <drivers/intel/pmc_mux/chip.h> +#include <intelblocks/pmc.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/rtc.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/soc_chip.h> +#include <stdint.h> + +#define PMC_HID "INTC1026" + +enum pch_pmc_xtal pmc_get_xtal_freq(void) +{ + uint8_t *const pmcbase = pmc_mmio_regs(); + + return PCH_EPOC_XTAL_FREQ(read32(pmcbase + PCH_PMC_EPOC)); +} + +static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable) +{ + uint32_t reg; + uint8_t *pmcbase = pmc_mmio_regs(); + + printk(BIOS_DEBUG, "%sabling Deep S%c\n", + enable ? "En" : "Dis", sx + '0'); + reg = read32(pmcbase + offset); + if (enable) + reg |= mask; + else + reg &= ~mask; + write32(pmcbase + offset, reg); +} + +static void config_deep_s5(int on_ac, int on_dc) +{ + /* Treat S4 the same as S5. */ + config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac); + config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc); + config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac); + config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc); +} + +static void config_deep_s3(int on_ac, int on_dc) +{ + config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac); + config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc); +} + +static void config_deep_sx(uint32_t deepsx_config) +{ + uint32_t reg; + uint8_t *pmcbase = pmc_mmio_regs(); + + reg = read32(pmcbase + DSX_CFG); + reg &= ~DSX_CFG_MASK; + reg |= deepsx_config; + write32(pmcbase + DSX_CFG, reg); +} + +static void pmc_init(struct device *dev) +{ + const config_t *config = config_of_soc(); + + rtc_init(); + + pmc_set_power_failure_state(true); + pmc_gpe_init(); + + config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc); + config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc); + config_deep_sx(config->deep_sx_config); +} + +static void soc_pmc_read_resources(struct device *dev) +{ + struct resource *res; + + /* Add the fixed MMIO resource */ + mmio_resource(dev, 0, PCH_PWRM_BASE_ADDRESS / KiB, PCH_PWRM_BASE_SIZE / KiB); + + /* Add the fixed I/O resource */ + res = new_resource(dev, 1); + res->base = (resource_t)ACPI_BASE_ADDRESS; + res->size = (resource_t)ACPI_BASE_SIZE; + res->limit = res->base + res->size - 1; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void soc_pmc_fill_ssdt(const struct device *dev) +{ + const char *scope = acpi_device_scope(dev); + const char *name = acpi_device_name(dev); + if (!scope || !name) + return; + + acpigen_write_scope(scope); + acpigen_write_device(name); + + acpigen_write_name_string("_HID", PMC_HID); + acpigen_write_name_string("_DDN", "Intel(R) Alder Lake IPC Controller"); + + /* + * Part of the PCH's reserved 32 MB MMIO range (0xFC800000 - 0xFE7FFFFF). + * The PMC gets 0xFE000000 - 0xFE00FFFF. + */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpigen_write_mem32fixed(1, PCH_PWRM_BASE_ADDRESS, PCH_PWRM_BASE_SIZE); + acpigen_write_resourcetemplate_footer(); + + acpigen_pop_len(); /* PMC Device */ + acpigen_pop_len(); /* Scope */ + + printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name, + dev_path(dev)); +} + +static void soc_acpi_mode_init(struct device *dev) +{ + /* + * pmc_set_acpi_mode() should be delayed until BS_DEV_INIT in order + * to ensure the ordering does not break the assumptions that other + * drivers make about ACPI mode (e.g. Chrome EC). Since it disables + * ACPI mode, other drivers may take different actions based on this + * (e.g. Chrome EC will flush any pending hostevent bits). Because + * TGL has its PMC device available for device_operations, it can be + * done from the "ops->init" callback. + */ + pmc_set_acpi_mode(); +} + +struct device_operations pmc_ops = { + .read_resources = soc_pmc_read_resources, + .set_resources = noop_set_resources, + .init = soc_acpi_mode_init, + .enable = pmc_init, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = soc_pmc_fill_ssdt, +#endif + .scan_bus = scan_static_bus, +}; diff --git a/src/soc/intel/alderlake/pmutil.c b/src/soc/intel/alderlake/pmutil.c new file mode 100644 index 0000000..79088dd --- /dev/null +++ b/src/soc/intel/alderlake/pmutil.c @@ -0,0 +1,292 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Helper functions for dealing with power management registers + * and the differences between PCH variants. + */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 4 + */ + +#define __SIMPLE_DEVICE__ + +#include <device/mmio.h> +#include <cbmem.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <console/console.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/rtc.h> +#include <intelblocks/tco.h> +#include <security/vboot/vbnv.h> +#include <soc/espi.h> +#include <soc/gpe.h> +#include <soc/gpio.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/smbus.h> +#include <soc/soc_chip.h> +#include <types.h> + +/* + * SMI + */ + +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; +} + +/* + * TCO + */ + +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; +} + +/* + * GPE0 + */ + +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_set_disb(void) +{ + /* Set the DISB after DRAM init */ + uint8_t disb_val; + /* Only care about bits [23:16] of register GEN_PMCON_A */ + uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); + + disb_val = read8(addr); + disb_val |= (DISB >> 16); + + /* Don't clear bits that are write-1-to-clear */ + disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); + write8(addr, disb_val); +} + +void pmc_clear_pmcon_sts(void) +{ + uint32_t reg_val; + uint8_t *addr; + addr = pmc_mmio_regs(); + + reg_val = read32(addr + GEN_PMCON_A); + /* Clear SUS_PWR_FLR, GBL_RST_STS, HOST_RST_STS, PWR_FLR bits + * while retaining MS4V write-1-to-clear bit */ + reg_val &= ~(MS4V); + + write32((addr + GEN_PMCON_A), reg_val); +} + +/* + * PMC controller gets hidden from PCI bus + * during FSP-Silicon init call. Hence PWRMBASE + * can't be accessible using PCI configuration space + * read/write. + */ +uint8_t *pmc_mmio_regs(void) +{ + return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; +} + +uintptr_t soc_read_pmc_base(void) +{ + return (uintptr_t)pmc_mmio_regs(); +} + +uint32_t *soc_pmc_etr_addr(void) +{ + return (uint32_t *)(soc_read_pmc_base() + ETR); +} + +void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) +{ + DEVTREE_CONST struct soc_intel_alderlake_config *config; + + config = config_of_soc(); + + /* Assign to out variable */ + *dw0 = config->pmc_gpe0_dw0; + *dw1 = config->pmc_gpe0_dw1; + *dw2 = config->pmc_gpe0_dw2; +} + +static int rtc_failed(uint32_t gen_pmcon_b) +{ + return !!(gen_pmcon_b & RTC_BATTERY_DEAD); +} + +int soc_get_rtc_failed(void) +{ + const struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); + + if (!ps) { + printk(BIOS_ERR, "Could not find power state in cbmem, RTC init aborted\n"); + return 1; + } + + return rtc_failed(ps->gen_pmcon_b); +} + +int vbnv_cmos_failed(void) +{ + return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); +} + +static inline int deep_s3_enabled(void) +{ + uint32_t deep_s3_pol; + + deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); + return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); +} + +/* Return 0, 3, or 5 to indicate the previous sleep state. */ +int soc_prev_sleep_state(const struct chipset_power_state *ps, + int prev_sleep_state) +{ + + /* + * Check for any power failure to determine if this a wake from + * S5 because the PCH does not set the WAK_STS bit when waking + * from a true G3 state. + */ + if (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR)) + prev_sleep_state = ACPI_S5; + + /* + * If waking from S3 determine if deep S3 is enabled. If not, + * need to check both deep sleep well and normal suspend well. + * Otherwise just check deep sleep well. + */ + if (prev_sleep_state == ACPI_S3) { + /* PWR_FLR represents deep sleep power well loss. */ + uint32_t mask = PWR_FLR; + + /* If deep s3 isn't enabled check the suspend well too. */ + if (!deep_s3_enabled()) + mask |= SUS_PWR_FLR; + + if (ps->gen_pmcon_a & mask) + prev_sleep_state = ACPI_S5; + } + + return prev_sleep_state; +} + +void soc_fill_power_state(struct chipset_power_state *ps) +{ + uint8_t *pmc; + + ps->tco1_sts = tco_read_reg(TCO1_STS); + ps->tco2_sts = tco_read_reg(TCO2_STS); + + printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); + + pmc = pmc_mmio_regs(); + ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); + ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); + ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); + ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); + ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); + + printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", + ps->gen_pmcon_a, ps->gen_pmcon_b); + + printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", + ps->gblrst_cause[0], ps->gblrst_cause[1]); + + printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); +} + +/* STM Support */ +uint16_t get_pmbase(void) +{ + return (uint16_t) ACPI_BASE_ADDRESS; +} + +/* + * Set which power state system will be after reapplying + * the power (from G3 State) + */ +void pmc_soc_set_afterg3_en(const bool on) +{ + uint8_t reg8; + uint8_t *const pmcbase = pmc_mmio_regs(); + + reg8 = read8(pmcbase + GEN_PMCON_A); + if (on) + reg8 &= ~SLEEP_AFTER_POWER_FAIL; + else + reg8 |= SLEEP_AFTER_POWER_FAIL; + write8(pmcbase + GEN_PMCON_A, reg8); +} diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 83c84ac..80420f0 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -16,7 +16,7 @@ #include <string.h>
static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, - const struct soc_intel_alderlake_dev_config *config) + const struct soc_intel_alderlake_config *config) { unsigned int i; uint32_t mask = 0; @@ -159,7 +159,7 @@
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) { - const struct soc_intel_alderlake_dev_config *config; + const struct soc_intel_alderlake_config *config; FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
config = config_of_soc(); diff --git a/src/soc/intel/alderlake/smihandler.c b/src/soc/intel/alderlake/smihandler.c new file mode 100644 index 0000000..a072138 --- /dev/null +++ b/src/soc/intel/alderlake/smihandler.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/pci_def.h> +#include <intelblocks/cse.h> +#include <intelblocks/smihandler.h> +#include <soc/soc_chip.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> + +/* + * Specific SOC SMI handler during ramstage finalize phase + * + * BIOS can't make CSME function disable as is due to POSTBOOT_SAI + * restriction in place from ADP chipset. Hence create SMI Handler to + * perform CSME function disabling logic during SMM mode. + */ +void smihandler_soc_at_finalize(void) +{ + const struct soc_intel_alderlake_config *config; + + config = config_of_soc(); + + if (!config->HeciEnabled && CONFIG(HECI_DISABLE_USING_SMM)) + heci_disable(); +} + +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/alderlake/smmrelocate.c b/src/soc/intel/alderlake/smmrelocate.c new file mode 100644 index 0000000..17b4f2d --- /dev/null +++ b/src/soc/intel/alderlake/smmrelocate.c @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <cpu/intel/common/common.h> +#include <cpu/intel/em64t101_save_state.h> +#include <cpu/intel/smm_reloc.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/smm.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ops.h> +#include <smp/node.h> +#include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/soc_chip.h> +#include <string.h> +#include <types.h> + +static void update_save_state(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase, + struct smm_relocation_params *relo_params) +{ + u32 smbase; + u32 iedbase; + + /* + * The relocated handler runs with all CPUs concurrently. Therefore + * stagger the entry points adjusting SMBASE downwards by save state + * size * CPU num. + */ + smbase = staggered_smbase; + iedbase = relo_params->ied_base; + + printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n", + smbase, iedbase); + + /* + * All threads need to set IEDBASE and SMBASE to the relocated + * handler region. However, the save state location depends on the + * smm_save_state_in_msrs field in the relocation parameters. If + * smm_save_state_in_msrs is non-zero then the CPUs are relocating + * the SMM handler in parallel, and each CPUs save state area is + * located in their respective MSR space. If smm_save_state_in_msrs + * is zero then the SMM relocation is happening serially so the + * save state is at the same default location for all CPUs. + */ + if (relo_params->smm_save_state_in_msrs) { + msr_t smbase_msr; + msr_t iedbase_msr; + + smbase_msr.lo = smbase; + smbase_msr.hi = 0; + + /* + * According the BWG the IEDBASE MSR is in bits 63:32. It's + * not clear why it differs from the SMBASE MSR. + */ + iedbase_msr.lo = 0; + iedbase_msr.hi = iedbase; + + wrmsr(SMBASE_MSR, smbase_msr); + wrmsr(IEDBASE_MSR, iedbase_msr); + } else { + em64t101_smm_state_save_area_t *save_state; + + save_state = (void *)(curr_smbase + SMM_DEFAULT_SIZE - + sizeof(*save_state)); + + save_state->smbase = smbase; + save_state->iedbase = iedbase; + } +} + +/* Returns 1 if SMM MSR save state was set. */ +static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params) +{ + msr_t smm_mca_cap; + + smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR); + if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) { + msr_t smm_feature_control; + + smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR); + smm_feature_control.hi = 0; + smm_feature_control.lo |= SMM_CPU_SAVE_EN; + wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control); + relo_params->smm_save_state_in_msrs = 1; + } + return relo_params->smm_save_state_in_msrs; +} + +/* + * The relocation work is actually performed in SMM context, but the code + * resides in the ramstage module. This occurs by trampolining from the default + * SMRAM entry point to here. + */ +void smm_relocation_handler(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase) +{ + msr_t mtrr_cap; + struct smm_relocation_params *relo_params = &smm_reloc_params; + + printk(BIOS_DEBUG, "In relocation handler: CPU %d\n", cpu); + + /* + * Determine if the processor supports saving state in MSRs. If so, + * enable it before the non-BSPs run so that SMM relocation can occur + * in parallel in the non-BSP CPUs. + */ + if (cpu == 0) { + /* + * If smm_save_state_in_msrs is 1 then that means this is the + * 2nd time through the relocation handler for the BSP. + * Parallel SMM handler relocation is taking place. However, + * it is desired to access other CPUs save state in the real + * SMM handler. Therefore, disable the SMM save state in MSRs + * feature. + */ + if (relo_params->smm_save_state_in_msrs) { + msr_t smm_feature_control; + + smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR); + smm_feature_control.lo &= ~SMM_CPU_SAVE_EN; + wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control); + } else if (bsp_setup_msr_save_state(relo_params)) + /* + * Just return from relocation handler if MSR save + * state is enabled. In that case the BSP will come + * back into the relocation handler to setup the new + * SMBASE as well disabling SMM save state in MSRs. + */ + return; + } + + /* Make appropriate changes to the save state map. */ + update_save_state(cpu, curr_smbase, staggered_smbase, relo_params); + + /* + * The SMRR MSRs are core-level registers, so if two threads that share + * a core try to both set the lock bit (in the same physical register), + * a #GP will be raised on the second write to that register (which is + * exactly what the lock is supposed to do), therefore secondary threads + * should exit here. + */ + if (intel_ht_sibling()) + return; + + /* Write SMRR MSRs based on indicated support. */ + mtrr_cap = rdmsr(MTRR_CAP_MSR); + + /* Set Lock bit if supported */ + if (mtrr_cap.lo & SMRR_LOCK_SUPPORTED) + relo_params->smrr_mask.lo |= SMRR_PHYS_MASK_LOCK; + + /* Write SMRRs if supported */ + if (mtrr_cap.lo & SMRR_SUPPORTED) + write_smrr(relo_params); +} + +static void fill_in_relocation_params(struct smm_relocation_params *params) +{ + uintptr_t tseg_base; + size_t tseg_size; + /* All range registers are aligned to 4KiB */ + const u32 rmask = ~(4 * KiB - 1); + + smm_region(&tseg_base, &tseg_size); + + if (!IS_ALIGNED(tseg_base, tseg_size)) { + printk(BIOS_WARNING, + "TSEG base not aligned with TSEG SIZE! Not setting SMRR\n"); + return; + } + + smm_subregion(SMM_SUBREGION_CHIPSET, ¶ms->ied_base, ¶ms->ied_size); + + /* SMRR has 32-bits of valid address aligned to 4KiB. */ + params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK; + params->smrr_base.hi = 0; + params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID; + params->smrr_mask.hi = 0; +} + +static void setup_ied_area(struct smm_relocation_params *params) +{ + char *ied_base; + + struct ied_header ied = { + .signature = "INTEL RSVD", + .size = params->ied_size, + .reserved = {0}, + }; + + ied_base = (void *)params->ied_base; + + printk(BIOS_DEBUG, "IED base = 0x%08x\n", (u32)params->ied_base); + printk(BIOS_DEBUG, "IED size = 0x%08x\n", (u32)params->ied_size); + + /* Place IED header at IEDBASE. */ + memcpy(ied_base, &ied, sizeof(ied)); + + /* Zero out 32KiB at IEDBASE + 1MiB */ + memset(ied_base + 1 * MiB, 0, 32 * KiB); +} + +void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, + size_t *smm_save_state_size) +{ + printk(BIOS_DEBUG, "Setting up SMI for CPU\n"); + + fill_in_relocation_params(&smm_reloc_params); + + smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize); + + if (smm_reloc_params.ied_size) + setup_ied_area(&smm_reloc_params); + + *smm_save_state_size = sizeof(em64t101_smm_state_save_area_t); +} + +void smm_initialize(void) +{ + /* Clear the SMM state in the southbridge. */ + smm_southbridge_clear_state(); + + /* + * Run the relocation handler for on the BSP to check and set up + * parallel SMM relocation. + */ + smm_initiate_relocation(); + + if (smm_reloc_params.smm_save_state_in_msrs) + printk(BIOS_DEBUG, "Doing parallel SMM relocation.\n"); +} + +void smm_relocate(void) +{ + /* + * If smm_save_state_in_msrs is non-zero then parallel SMM relocation + * shall take place. Run the relocation handler a second time on the + * BSP to do * the final move. For APs, a relocation handler always + * needs to be run. + */ + if (smm_reloc_params.smm_save_state_in_msrs) + smm_initiate_relocation_parallel(); + else if (!boot_cpu()) + smm_initiate_relocation(); +} diff --git a/src/soc/intel/alderlake/soundwire.c b/src/soc/intel/alderlake/soundwire.c new file mode 100644 index 0000000..38a2c37 --- /dev/null +++ b/src/soc/intel/alderlake/soundwire.c @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <acpi/acpi_soundwire.h> +#include <console/console.h> +#include <device/mmio.h> +#include <device/soundwire.h> +#include <drivers/intel/soundwire/soundwire.h> +#include <intelblocks/pmclib.h> +#include <soc/pmc.h> +#include <stddef.h> +#include <string.h> + +static const struct soundwire_link link_xtal_38_4 = { + .clock_stop_mode0_supported = 1, + .clock_stop_mode1_supported = 1, + .clock_frequencies_supported_count = 1, + .clock_frequencies_supported = { 4800 * KHz }, + .default_frame_rate = 48 * KHz, + .default_frame_row_size = 50, + .default_frame_col_size = 4, + .dynamic_frame_shape = 1, + .command_error_threshold = 16, +}; + +static const struct soundwire_link link_xtal_24 = { + .clock_stop_mode0_supported = 1, + .clock_stop_mode1_supported = 1, + .clock_frequencies_supported_count = 1, + .clock_frequencies_supported = { 6 * MHz }, + .default_frame_rate = 48 * KHz, + .default_frame_row_size = 125, + .default_frame_col_size = 2, + .dynamic_frame_shape = 1, + .command_error_threshold = 16, +}; + +static struct intel_soundwire_controller intel_controller = { + .acpi_address = 0x40000000, + .sdw = { + /* TODO: Verified Audio in nocodec mode, add codec support */ + .master_list_count = 0 + } +}; + +int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) +{ + const struct soundwire_link *link; + enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); + size_t i; + + /* Select link config based on XTAL frequency and set IP clock. */ + switch (xtal) { + case XTAL_24_MHZ: + link = &link_xtal_24; + intel_controller.ip_clock = 24 * MHz; + break; + case XTAL_38_4_MHZ: + link = &link_xtal_38_4; + intel_controller.ip_clock = 38400 * KHz; + break; + case XTAL_19_2_MHZ: + default: + printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); + return -1; + } + + /* Fill link config in controller map based on selected XTAL. */ + for (i = 0; i < intel_controller.sdw.master_list_count; i++) + memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); + + *controller = &intel_controller; + return 0; +} diff --git a/src/soc/intel/alderlake/spi.c b/src/soc/intel/alderlake/spi.c new file mode 100644 index 0000000..2940de1 --- /dev/null +++ b/src/soc/intel/alderlake/spi.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 7 + */ + +#include <intelblocks/spi.h> +#include <soc/pci_devs.h> + +int spi_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { + case PCH_DEVFN_SPI: + return 0; + case PCH_DEVFN_GSPI0: + return 1; + case PCH_DEVFN_GSPI1: + return 2; + case PCH_DEVFN_GSPI2: + return 3; + case PCH_DEVFN_GSPI3: + return 4; + } + return -1; +} diff --git a/src/soc/intel/alderlake/systemagent.c b/src/soc/intel/alderlake/systemagent.c new file mode 100644 index 0000000..3e7a404 --- /dev/null +++ b/src/soc/intel/alderlake/systemagent.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor SA Datasheet + * Document number: 619503 + * Chapter number: 3 + */ + +#include <device/device.h> +#include <device/pci.h> +#include <intelblocks/systemagent.h> +#include <soc/iomap.h> +#include <soc/systemagent.h> + +/* + * SoC implementation + * + * Add all known fixed memory ranges for Host Controller/Memory + * controller. + */ +void soc_add_fixed_mmio_resources(struct device *dev, int *index) +{ + static const struct sa_mmio_descriptor soc_fixed_resources[] = { + { PCIEXBAR, CONFIG_MMCONF_BASE_ADDRESS, CONFIG_SA_PCIEX_LENGTH, + "PCIEXBAR" }, + { MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" }, + { DMIBAR, DMI_BASE_ADDRESS, DMI_BASE_SIZE, "DMIBAR" }, + { EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" }, + { REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" }, + { EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" }, + }; + + sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources, + ARRAY_SIZE(soc_fixed_resources)); + + /* Add Vt-d resources if VT-d is enabled */ + if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE)) + return; + + sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources, + ARRAY_SIZE(soc_vtd_resources)); +} + +/* + * SoC implementation + * + * Perform System Agent Initialization during Ramstage phase. + */ +void soc_systemagent_init(struct device *dev) +{ + /* Enable Power Aware Interrupt Routing */ + enable_power_aware_intr(); + + /* Enable BIOS Reset CPL */ + enable_bios_reset_cpl(); + /* TODO: Add set_power_limits() */ +} + +uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz) +{ + switch (capid0_a_ddrsz) { + case 1: + return 8192; + case 2: + return 4096; + case 3: + return 2048; + default: + return 65536; + } +} diff --git a/src/soc/intel/alderlake/uart.c b/src/soc/intel/alderlake/uart.c new file mode 100644 index 0000000..cdbf8ec --- /dev/null +++ b/src/soc/intel/alderlake/uart.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on Intel Alder Lake Processor PCH Datasheet + * Document number: 621483 + * Chapter number: 9 + */ + +#include <console/console.h> +#include <device/pci_def.h> +#include <intelblocks/gpio.h> +#include <intelblocks/lpss.h> +#include <intelblocks/pcr.h> +#include <intelblocks/uart.h> +#include <soc/iomap.h> +#include <soc/pch.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> + +const struct uart_gpio_pad_config uart_gpio_pads[] = { + { + .console_index = 0, + .gpios = { + PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0 RX */ + PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0 TX */ + }, + }, + { + .console_index = 1, + .gpios = { + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* UART1 RX */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1), /* UART1 TX */ + }, + }, + { + .console_index = 2, + .gpios = { + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* UART2 RX */ + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* UART2 TX */ + }, + } +}; + +const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); + +DEVTREE_CONST struct device *soc_uart_console_to_device(int uart_console) +{ + /* + * if index is valid, this function will return corresponding structure + * for uart console else will return NULL. + */ + switch (uart_console) { + case 0: + return pcidev_path_on_root(PCH_DEVFN_UART0); + case 1: + return pcidev_path_on_root(PCH_DEVFN_UART1); + case 2: + return pcidev_path_on_root(PCH_DEVFN_UART2); + default: + printk(BIOS_ERR, "Invalid UART console index\n"); + return NULL; + } +}