diff options
Diffstat (limited to 'src/soc')
82 files changed, 8747 insertions, 0 deletions
diff --git a/src/soc/intel/Kconfig b/src/soc/intel/Kconfig index 5b4a9a2095..2c24596dcc 100644 --- a/src/soc/intel/Kconfig +++ b/src/soc/intel/Kconfig @@ -10,6 +10,7 @@ source "src/soc/intel/fsp_broadwell_de/Kconfig" source "src/soc/intel/quark/Kconfig" source "src/soc/intel/sch/Kconfig" source "src/soc/intel/skylake/Kconfig" +source "src/soc/intel/icelake/Kconfig" # Load common config source "src/soc/intel/common/Kconfig" diff --git a/src/soc/intel/icelake/Kconfig b/src/soc/intel/icelake/Kconfig new file mode 100644 index 0000000000..bc13f4f6e5 --- /dev/null +++ b/src/soc/intel/icelake/Kconfig @@ -0,0 +1,211 @@ +config SOC_INTEL_ICELAKE + bool + help + Intel Icelake support + +if SOC_INTEL_ICELAKE + +config CPU_SPECIFIC_OPTIONS + 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 C_ENVIRONMENT_BOOTBLOCK + select CACHE_MRC_SETTINGS + select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM + select COMMON_FADT + select CPU_INTEL_FIRMWARE_INTERFACE_TABLE + select GENERIC_GPIO_LIB + select HAVE_FSP_GOP + select INTEL_DESCRIPTOR_MODE_CAPABLE + select HAVE_MONOTONIC_TIMER + select HAVE_SMI_HANDLER + select IDT_IN_EVERY_STAGE + 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 PLATFORM_USES_FSP2_0 + select POSTCAR_CONSOLE + select POSTCAR_STAGE + select REG_SCRIPT + select SMM_TSEG + select SMP + select SOC_AHCI_PORT_IMPLEMENTED_INVERT + select PMC_GLOBAL_RESET_ENABLE_LOCK + select SOC_INTEL_COMMON + select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE + select SOC_INTEL_COMMON_BLOCK + select SOC_INTEL_COMMON_BLOCK_ACPI + select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG + select SOC_INTEL_COMMON_BLOCK_CPU + select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT + select SOC_INTEL_COMMON_BLOCK_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 SSE2 + select SUPPORT_CPU_UCODE_IN_CBFS + select TSC_CONSTANT_RATE + select TSC_MONOTONIC_TIMER + select UDELAY_TSC + select UDK_2017_BINDING + select DISPLAY_FSP_VERSION_INFO + +config UART_DEBUG + bool "Enable UART debug port." + default n + select CONSOLE_SERIAL + select BOOTBLOCK_CONSOLE + select DRIVERS_UART + select DRIVERS_UART_8250MEM_32 + select NO_UART_ON_SUPERIO + +config UART_FOR_CONSOLE + int "Index for LPSS UART port to use for console" + default 2 if DRIVERS_UART_8250MEM_32 + default 0 + help + Index for LPSS UART port to use for console: + 0 = LPSS UART0, 1 = LPSS UART1, 2 = LPSS UART2 + +config DCACHE_RAM_BASE + default 0xfef00000 + +config DCACHE_RAM_SIZE + default 0x40000 + help + The size of the cache-as-ram region required during bootblock + and/or romstage. + +config DCACHE_BSP_STACK_SIZE + hex + default 0x4000 + help + The amount of anticipated stack usage in CAR by bootblock and + other stages. + +config IFD_CHIPSET + string + default "icl" + +config IED_REGION_SIZE + hex + default 0x400000 + +config HEAP_SIZE + hex + default 0x8000 + +config MAX_ROOT_PORTS + int + default 16 + +config SMM_TSEG_SIZE + hex + default 0x800000 + +config SMM_RESERVED_SIZE + hex + default 0x200000 + +config PCR_BASE_ADDRESS + hex + default 0xfd000000 + help + This option allows you to select MMIO Base Address of sideband bus. + +config CPU_BCLK_MHZ + int + default 100 + +config SOC_INTEL_COMMON_BLOCK_GSPI_CLOCK_MHZ + int + default 120 + +config DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ + int + default 133 + +config SOC_INTEL_COMMON_BLOCK_GSPI_MAX + int + default 3 + +config SOC_INTEL_I2C_DEV_MAX + int + default 6 + +# Clock divider parameters for 115200 baud rate +config SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL + hex + default 0x30 + +config SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL + hex + default 0xc35 + +config CHROMEOS + select CHROMEOS_RAMOOPS_DYNAMIC + +config VBOOT + select VBOOT_SEPARATE_VERSTAGE + select VBOOT_OPROM_MATTERS + select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT + select VBOOT_STARTS_IN_BOOTBLOCK + select VBOOT_VBNV_CMOS + select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH + +config C_ENV_BOOTBLOCK_SIZE + hex + default 0x8000 + +config CBFS_SIZE + hex + default 0x200000 + +choice + prompt "Cache-as-ram implementation" + default USE_ICELAKE_CAR_NEM_ENHANCED if MAINBOARD_HAS_CHROMEOS + default USE_ICELAKE_FSP_CAR + help + This option allows you to select how cache-as-ram (CAR) is set up. + +config USE_ICELAKE_CAR_NEM_ENHANCED + bool "Enhanced Non-evict mode" + select SOC_INTEL_COMMON_BLOCK_CAR + select INTEL_CAR_NEM_ENHANCED + help + A current limitation of NEM (Non-Evict mode) is that code and data + sizes are derived from the requirement to not write out any modified + cache line. With NEM, if there is no physical memory behind the + cached area, the modified data will be lost and NEM results will be + inconsistent. ENHANCED NEM guarantees that modified data is always + kept in cache while clean data is replaced. + +config USE_ICELAKE_FSP_CAR + bool "Use FSP CAR" + select FSP_CAR + help + Use FSP APIs to initialize and tear down the Cache-As-Ram. + +endchoice + +config FSP_HEADER_PATH + string + default "src/vendorcode/intel/fsp/fsp2_0/icelake/" + +config FSP_FD_PATH + string + depends on FSP_USE_REPO + default "3rdparty/fsp/IceLakeFspBinPkg/Fsp.fd" + +endif diff --git a/src/soc/intel/icelake/Makefile.inc b/src/soc/intel/icelake/Makefile.inc new file mode 100644 index 0000000000..a81edd46a0 --- /dev/null +++ b/src/soc/intel/icelake/Makefile.inc @@ -0,0 +1,80 @@ +ifeq ($(CONFIG_SOC_INTEL_ICELAKE),y) + +subdirs-y += romstage +subdirs-y += ../../../cpu/intel/microcode +subdirs-y += ../../../cpu/intel/turbo +subdirs-y += ../../../cpu/x86/lapic +subdirs-y += ../../../cpu/x86/mtrr +subdirs-y += ../../../cpu/x86/smm +subdirs-y += ../../../cpu/x86/tsc + +bootblock-y += bootblock/bootblock.c +bootblock-y += bootblock/cpu.c +bootblock-y += bootblock/pch.c +bootblock-y += pmutil.c +bootblock-y += bootblock/report_platform.c +bootblock-y += gpio.c +bootblock-y += gspi.c +bootblock-y += i2c.c +bootblock-y += memmap.c +bootblock-y += spi.c +bootblock-y += lpc.c +bootblock-y += p2sb.c +bootblock-$(CONFIG_UART_DEBUG) += uart.c + +romstage-y += gpio.c +romstage-y += gspi.c +romstage-y += i2c.c +romstage-y += lpc.c +romstage-y += memmap.c +romstage-y += pmutil.c +romstage-y += reset.c +romstage-y += spi.c +romstage-$(CONFIG_UART_DEBUG) += uart.c + +ramstage-y += acpi.c +ramstage-y += chip.c +ramstage-y += cpu.c +ramstage-y += finalize.c +ramstage-y += fsp_params.c +ramstage-y += gpio.c +ramstage-y += graphics.c +ramstage-y += gspi.c +ramstage-y += gpio.c +ramstage-y += i2c.c +ramstage-y += lockdown.c +ramstage-y += lpc.c +ramstage-y += memmap.c +ramstage-y += p2sb.c +ramstage-y += pmc.c +ramstage-y += pmutil.c +ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c +ramstage-y += smmrelocate.c +ramstage-y += spi.c +ramstage-y += systemagent.c +ramstage-$(CONFIG_UART_DEBUG) += uart.c +ramstage-y += sd.c + +smm-y += gpio.c +smm-y += p2sb.c +smm-y += pmutil.c +smm-y += smihandler.c +smm-$(CONFIG_UART_DEBUG) += uart.c + +postcar-y += memmap.c +postcar-y += pmutil.c +postcar-y += i2c.c +postcar-y += gspi.c +postcar-y += spi.c +postcar-$(CONFIG_UART_DEBUG) += uart.c + +verstage-y += gspi.c +verstage-y += i2c.c +verstage-y += pmutil.c +verstage-y += spi.c +verstage-$(CONFIG_UART_DEBUG) += uart.c + +CPPFLAGS_common += -I$(src)/soc/intel/icelake +CPPFLAGS_common += -I$(src)/soc/intel/icelake/include + +endif diff --git a/src/soc/intel/icelake/acpi.c b/src/soc/intel/icelake/acpi.c new file mode 100644 index 0000000000..e691fe2343 --- /dev/null +++ b/src/soc/intel/icelake/acpi.c @@ -0,0 +1,251 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/acpi.h> +#include <arch/acpigen.h> +#include <arch/cpu.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/smp/mpspec.h> +#include <cbmem.h> +#include <chip.h> +#include <cpu/cpu.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 <string.h> +#include <vendorcode/google/chromeos/gnvs.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 = 0, + .power = C1_POWER, + .resource = MWAIT_RES(0, 0), + }, + [C_STATE_C1E] = { + .latency = 0, + .power = C1_POWER, + .resource = MWAIT_RES(0, 1), + }, + [C_STATE_C6_SHORT_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C6_POWER, + .resource = MWAIT_RES(2, 0), + }, + [C_STATE_C6_LONG_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C6_POWER, + .resource = MWAIT_RES(2, 1), + }, + [C_STATE_C7_SHORT_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 0), + }, + [C_STATE_C7_LONG_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 1), + }, + [C_STATE_C7S_SHORT_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 2), + }, + [C_STATE_C7S_LONG_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 3), + }, + [C_STATE_C8] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C8_POWER, + .resource = MWAIT_RES(4, 0), + }, + [C_STATE_C9] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C9_POWER, + .resource = MWAIT_RES(5, 0), + }, + [C_STATE_C10] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C10_POWER, + .resource = MWAIT_RES(6, 0), + }, +}; + +static int cstate_set_s0ix[] = { + C_STATE_C1E, + C_STATE_C6_LONG_LAT, + C_STATE_C7S_LONG_LAT +}; + +static int cstate_set_non_s0ix[] = { + C_STATE_C1E, + 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; + struct device *dev = SA_DEV_ROOT; + config_t *config = dev->chip_info; + 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) +{ + struct device *dev = SA_DEV_ROOT; + config_t *config = dev->chip_info; + 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; + const struct device *dev = PCH_DEV_LPC; + const struct soc_intel_icelake_config *config = dev->chip_info; + + if (!config->PmTimerDisabled) { + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->pm_tmr_len = 4; + fadt->x_pm_tmr_blk.space_id = 1; + 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.resv = 0; + 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); +} + +void acpi_create_gnvs(struct global_nvs_t *gnvs) +{ + const struct device *dev = PCH_DEV_LPC; + const struct soc_intel_icelake_config *config = dev->chip_info; + + /* Set unknown wake source */ + gnvs->pm1i = -1; + + /* CPU core count */ + gnvs->pcnt = dev_count_cpu(); + + if (IS_ENABLED(CONFIG_CONSOLE_CBMEM)) + /* Update the mem console pointer. */ + gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE); + + if (IS_ENABLED(CONFIG_CHROMEOS)) { + /* Initialize Verified Boot data */ + chromeos_init_chromeos_acpi(&(gnvs->chromeos)); + if (IS_ENABLED(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; +} + +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; +} diff --git a/src/soc/intel/icelake/acpi/cnvi.asl b/src/soc/intel/icelake/acpi/cnvi.asl new file mode 100644 index 0000000000..634c6090ad --- /dev/null +++ b/src/soc/intel/icelake/acpi/cnvi.asl @@ -0,0 +1,32 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <soc/pm.h> + +/* CNVi Controller 0:14.3 */ +Device (CNVI) { + Name(_ADR, 0x00140003) + + Name (_S3D, 3) /* D3 supported in S3 */ + Name (_S0W, 3) /* D3 can wake device in S0 */ + Name (_S3W, 3) /* D3 can wake system from S3 */ + + Name (_PRW, Package() { PME_B0_EN_BIT, 3 }) + + Method (_STA, 0) + { + Return (0xF) + } +} diff --git a/src/soc/intel/icelake/acpi/cpu.asl b/src/soc/intel/icelake/acpi/cpu.asl new file mode 100644 index 0000000000..be6e793ab9 --- /dev/null +++ b/src/soc/intel/icelake/acpi/cpu.asl @@ -0,0 +1,43 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* These devices are created at runtime */ +External (\_PR.CP00, DeviceObj) +External (\_PR.CP01, DeviceObj) +External (\_PR.CP02, DeviceObj) +External (\_PR.CP03, DeviceObj) +External (\_PR.CP04, DeviceObj) +External (\_PR.CP05, DeviceObj) +External (\_PR.CP06, DeviceObj) +External (\_PR.CP07, DeviceObj) + +/* Notify OS to re-read CPU tables, assuming ^2 CPU count */ +Method (PNOT) +{ + If (LGreaterEqual (\PCNT, 2)) { + Notify (\_PR.CP00, 0x81) // _CST + Notify (\_PR.CP01, 0x81) // _CST + } + If (LGreaterEqual (\PCNT, 4)) { + Notify (\_PR.CP02, 0x81) // _CST + Notify (\_PR.CP03, 0x81) // _CST + } + If (LGreaterEqual (\PCNT, 8)) { + Notify (\_PR.CP04, 0x81) // _CST + Notify (\_PR.CP05, 0x81) // _CST + Notify (\_PR.CP06, 0x81) // _CST + Notify (\_PR.CP07, 0x81) // _CST + } +} diff --git a/src/soc/intel/icelake/acpi/globalnvs.asl b/src/soc/intel/icelake/acpi/globalnvs.asl new file mode 100644 index 0000000000..678ce5ac23 --- /dev/null +++ b/src/soc/intel/icelake/acpi/globalnvs.asl @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Global Variables */ + +Name (\PICM, 0) // IOAPIC/8259 + +/* + * Global ACPI memory region. This region is used for passing information + * between coreboot (aka "the system bios"), ACPI, and the SMI handler. + * Since we don't know where this will end up in memory at ACPI compile time, + * we have to fix it up in coreboot's ACPI creation phase. + */ + +External (NVSA) + +OperationRegion (GNVS, SystemMemory, NVSA, 0x2000) +Field (GNVS, ByteAcc, NoLock, Preserve) +{ + /* Miscellaneous */ + Offset (0x00), + OSYS, 16, // 0x00 - Operating System + SMIF, 8, // 0x02 - SMI function + PCNT, 8, // 0x03 - Processor Count + PPCM, 8, // 0x04 - Max PPC State + TLVL, 8, // 0x05 - Throttle Level Limit + LIDS, 8, // 0x06 - LID State + PWRS, 8, // 0x07 - AC Power State + CBMC, 32, // 0x08 - 0x0b AC Power State + PM1I, 64, // 0x0c - 0x13 PM1 wake status bit + GPEI, 64, // 0x14 - 0x17 GPE wake status bit + DPTE, 8, // 0x1c - Enable DPTF + NHLA, 64, // 0x1d - 0x24 NHLT Address + NHLL, 32, // 0x25 - 0x28 NHLT Length + CID1, 16, // 0x29 - 0x2a Wifi Country Identifier + U2WE, 16, // 0x2b - 0x2c USB2 Wake Enable Bitmap + U3WE, 16, // 0x2d - 0x2e USB3 Wake Enable Bitmap + UIOR, 8, // 0x2f - UART debug controller init on S3 resume + + /* ChromeOS specific */ + Offset (0x100), + #include <vendorcode/google/chromeos/acpi/gnvs.asl> +} diff --git a/src/soc/intel/icelake/acpi/gpio.asl b/src/soc/intel/icelake/acpi/gpio.asl new file mode 100644 index 0000000000..5784fb150e --- /dev/null +++ b/src/soc/intel/icelake/acpi/gpio.asl @@ -0,0 +1,134 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include <soc/gpio_defs.h> +#include <soc/irq.h> +#include <soc/pcr_ids.h> + + +Device (GPIO) +{ + Name (_HID, "INT34BB") + Name (_UID, 0) + Name (_DDN, "GPIO Controller") + + Name (RBUF, ResourceTemplate() + { + Memory32Fixed (ReadWrite, 0, 0, COM0) + Memory32Fixed (ReadWrite, 0, 0, COM1) + Memory32Fixed (ReadWrite, 0, 0, COM2) + Memory32Fixed (ReadWrite, 0, 0, COM3) + Memory32Fixed (ReadWrite, 0, 0, COM4) + Interrupt (ResourceConsumer, Level, ActiveLow, Shared,,, GIRQ) + { GPIO_IRQ14 } + }) + + Method (_CRS, 0, NotSerialized) + { + /* GPIO Community 0 */ + CreateDWordField (^RBUF, ^COM0._BAS, BAS0) + CreateDWordField (^RBUF, ^COM0._LEN, LEN0) + Store (^^PCRB (PID_GPIOCOM0), BAS0) + Store (GPIO_BASE_SIZE, LEN0) + + /* GPIO Community 1 */ + CreateDWordField (^RBUF, ^COM1._BAS, BAS1) + CreateDWordField (^RBUF, ^COM1._LEN, LEN1) + Store (^^PCRB (PID_GPIOCOM1), BAS1) + Store (GPIO_BASE_SIZE, LEN1) + + /* GPIO Community 2 */ + CreateDWordField (^RBUF, ^COM2._BAS, BAS2) + CreateDWordField (^RBUF, ^COM2._LEN, LEN2) + Store (^^PCRB (PID_GPIOCOM2), BAS2) + Store (GPIO_BASE_SIZE, LEN2) + + /* GPIO Community 3 */ + CreateDWordField (^RBUF, ^COM3._BAS, BAS3) + CreateDWordField (^RBUF, ^COM3._LEN, LEN3) + Store (^^PCRB (PID_GPIOCOM3), BAS3) + Store (GPIO_BASE_SIZE, LEN3) + + + /* GPIO Community 4 */ + CreateDWordField (^RBUF, ^COM4._BAS, BAS4) + CreateDWordField (^RBUF, ^COM4._LEN, LEN4) + Store (^^PCRB (PID_GPIOCOM4), BAS4) + Store (GPIO_BASE_SIZE, LEN4) + + Return (RBUF) + } + + Method (_STA, 0, NotSerialized) + { + Return (0xF) + } +} + +/* + * Get GPIO DW0 Address + * Arg0 - GPIO Number + */ +Method (GADD, 1, NotSerialized) +{ + /* GPIO Community 0 */ + If (LAnd (LGreaterEqual (Arg0, GPP_A0), LLessEqual (Arg0, GPIO_RSVD_11))) + { + Store (PID_GPIOCOM0, Local0) + Subtract (Arg0, GPP_A0, Local1) + } + /* GPIO Community 1 */ + If (LAnd (LGreaterEqual (Arg0, GPP_D0), LLessEqual (Arg0, GPIO_RSVD_52))) + { + Store (PID_GPIOCOM1, Local0) + Subtract (Arg0, GPP_D0, Local1) + } + /* GPIO Community 2 */ + If (LAnd (LGreaterEqual (Arg0, GPD0), LLessEqual (Arg0, GPD11))) + { + Store (PID_GPIOCOM1, Local0) + Subtract (Arg0, GPD0, Local1) + } + /* GPIO Community 3 */ + If (LAnd (LGreaterEqual (Arg0, HDA_BCLK), LLessEqual (Arg0, GPIO_RSVD_78))) + { + Store (PID_GPIOCOM1, Local0) + Subtract (Arg0, HDA_BCLK, Local1) + } + /* GPIO Community 04*/ + If (LAnd (LGreaterEqual (Arg0, GPP_C0), LLessEqual (Arg0, GPIO_RSVD_67))) + { + Store (PID_GPIOCOM4, Local0) + Subtract (Arg0, GPP_C0, Local1) + } + Store (PCRB (Local0), Local2) + Add (Local2, PAD_CFG_BASE, Local2) + Return (Add (Local2, Multiply (Local1, 16))) +} + +/* + * Get GPIO Value + * Arg0 - GPIO Number + */ +Method (GRXS, 1, Serialized) +{ + OperationRegion (PREG, SystemMemory, GADD (Arg0), 4) + Field (PREG, AnyAcc, NoLock, Preserve) + { + VAL0, 32 + } + And (GPIORXSTATE_MASK, ShiftRight (VAL0, GPIORXSTATE_SHIFT), Local0) + + Return (Local0) +} diff --git a/src/soc/intel/icelake/acpi/ipu.asl b/src/soc/intel/icelake/acpi/ipu.asl new file mode 100644 index 0000000000..2c550edcbb --- /dev/null +++ b/src/soc/intel/icelake/acpi/ipu.asl @@ -0,0 +1,23 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* IPU3 input system - Device 05, Function 0 */ +Device (IMGU) +{ + Name (_ADR, 0x00050000) + Name (_DDN, "Imaging Unit") + Name (_CCA, ZERO) + Name (CAMD, 0x01) +} diff --git a/src/soc/intel/icelake/acpi/irqlinks.asl b/src/soc/intel/icelake/acpi/irqlinks.asl new file mode 100644 index 0000000000..0403ea06f3 --- /dev/null +++ b/src/soc/intel/icelake/acpi/irqlinks.asl @@ -0,0 +1,282 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * PIRQ routing control is in PCR ITSS region. + * + * Due to what appears to be an ACPI interpreter bug we do not use + * the PCRB() method here as it may not be defined yet because the method + * definiton depends on the order of the include files in pch.asl. + * + * https://bugs.acpica.org/show_bug.cgi?id=1201 + */ +OperationRegion (ITSS, SystemMemory, + Add (PCR_ITSS_PIRQA_ROUT, + Add (CONFIG_PCR_BASE_ADDRESS, + ShiftLeft (PID_ITSS, PCR_PORTID_SHIFT))), 8) +Field (ITSS, ByteAcc, NoLock, Preserve) +{ + PIRA, 8, /* PIRQA Routing Control */ + PIRB, 8, /* PIRQB Routing Control */ + PIRC, 8, /* PIRQC Routing Control */ + PIRD, 8, /* PIRQD Routing Control */ + PIRE, 8, /* PIRQE Routing Control */ + PIRF, 8, /* PIRQF Routing Control */ + PIRG, 8, /* PIRQG Routing Control */ + PIRH, 8, /* PIRQH Routing Control */ +} + +Name (IREN, 0x80) /* Interrupt Routing Enable */ +Name (IREM, 0x0f) /* Interrupt Routing Mask */ + +Device (LNKA) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 1) + + Method (_CRS, 0, Serialized) + { + Name (RTLA, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {11} + }) + CreateWordField (RTLA, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRA, ^^IREM), IRQ0) + + Return (RTLA) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRA, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKB) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 2) + + Method (_CRS, 0, Serialized) + { + Name (RTLB, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {10} + }) + CreateWordField (RTLB, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRB, ^^IREM), IRQ0) + + Return (RTLB) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRB, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKC) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 3) + + Method (_CRS, 0, Serialized) + { + Name (RTLC, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {11} + }) + CreateWordField (RTLC, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRC, ^^IREM), IRQ0) + + Return (RTLC) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRC, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKD) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 4) + + Method (_CRS, 0, Serialized) + { + Name (RTLD, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {11} + }) + CreateWordField (RTLD, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRD, ^^IREM), IRQ0) + + Return (RTLD) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRD, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKE) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 5) + + Method (_CRS, 0, Serialized) + { + Name (RTLE, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {11} + }) + CreateWordField (RTLE, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRE, ^^IREM), IRQ0) + + Return (RTLE) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRE, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKF) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 6) + + Method (_CRS, 0, Serialized) + { + Name (RTLF, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {11} + }) + CreateWordField (RTLF, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRF, ^^IREM), IRQ0) + + Return (RTLF) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRF, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKG) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 7) + + Method (_CRS, 0, Serialized) + { + Name (RTLG, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {11} + }) + CreateWordField (RTLG, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRG, ^^IREM), IRQ0) + + Return (RTLG) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRG, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} + +Device (LNKH) +{ + Name (_HID, EISAID ("PNP0C0F")) + Name (_UID, 8) + + Method (_CRS, 0, Serialized) + { + Name (RTLH, ResourceTemplate () + { + IRQ (Level, ActiveLow, Shared) {11} + }) + CreateWordField (RTLH, 1, IRQ0) + Store (Zero, IRQ0) + + /* Set the bit from PIRQ Routing Register */ + ShiftLeft (1, And (^^PIRH, ^^IREM), IRQ0) + + Return (RTLH) + } + + Method (_STA, 0, Serialized) + { + If (And (^^PIRH, ^^IREN)) { + Return (0x9) + } Else { + Return (0xb) + } + } +} diff --git a/src/soc/intel/icelake/acpi/lpc.asl b/src/soc/intel/icelake/acpi/lpc.asl new file mode 100644 index 0000000000..f936392ea3 --- /dev/null +++ b/src/soc/intel/icelake/acpi/lpc.asl @@ -0,0 +1,115 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +Device (LPCB) +{ + Name (_ADR, 0x001f0000) + Name (_DDN, "LPC Bus Device") + + Device (FWH) + { + Name (_HID, EISAID ("INT0800")) + Name (_DDN, "Firmware Hub") + Name (_CRS, ResourceTemplate () + { + Memory32Fixed (ReadOnly, 0xff000000, 0x01000000) + }) + } + + Device (HPET) + { + Name (_HID, EISAID ("PNP0103")) + Name (_DDN, "High Precision Event Timer") + Name (_CRS, ResourceTemplate () + { + Memory32Fixed (ReadWrite, HPET_BASE_ADDRESS, 0x400) + }) + Method (_STA, 0) + { + Return (0xf) + } + } + + Device (PIC) + { + Name (_HID, EISAID ("PNP0000")) + Name (_DDN, "8259 Interrupt Controller") + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x20, 0x20, 0x01, 0x02) + IO (Decode16, 0x24, 0x24, 0x01, 0x02) + IO (Decode16, 0x28, 0x28, 0x01, 0x02) + IO (Decode16, 0x2c, 0x2c, 0x01, 0x02) + IO (Decode16, 0x30, 0x30, 0x01, 0x02) + IO (Decode16, 0x34, 0x34, 0x01, 0x02) + IO (Decode16, 0x38, 0x38, 0x01, 0x02) + IO (Decode16, 0x3c, 0x3c, 0x01, 0x02) + IO (Decode16, 0xa0, 0xa0, 0x01, 0x02) + IO (Decode16, 0xa4, 0xa4, 0x01, 0x02) + IO (Decode16, 0xa8, 0xa8, 0x01, 0x02) + IO (Decode16, 0xac, 0xac, 0x01, 0x02) + IO (Decode16, 0xb0, 0xb0, 0x01, 0x02) + IO (Decode16, 0xb4, 0xb4, 0x01, 0x02) + IO (Decode16, 0xb8, 0xb8, 0x01, 0x02) + IO (Decode16, 0xbc, 0xbc, 0x01, 0x02) + IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02) + IRQNoFlags () { 2 } + }) + } + + Device (LDRC) + { + Name (_HID, EISAID ("PNP0C02")) + Name (_UID, 2) + Name (_DDN, "Legacy Device Resources") + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x2e, 0x2e, 0x1, 0x02) // First SuperIO + IO (Decode16, 0x4e, 0x4e, 0x1, 0x02) // Second SuperIO + IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status + IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post + IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved + IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI + IO (Decode16, ACPI_BASE_ADDRESS, ACPI_BASE_ADDRESS, + 0x1, 0xff) + }) + } + + Device (RTC) + { + Name (_HID, EISAID ("PNP0B00")) + Name (_DDN, "Real Time Clock") + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x70, 0x70, 1, 8) + }) + } + + Device (TIMR) + { + Name (_HID, EISAID ("PNP0100")) + Name (_DDN, "8254 Timer") + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x40, 0x40, 0x01, 0x04) + IO (Decode16, 0x50, 0x50, 0x10, 0x04) + IRQNoFlags () {0} + }) + } + +} diff --git a/src/soc/intel/icelake/acpi/northbridge.asl b/src/soc/intel/icelake/acpi/northbridge.asl new file mode 100644 index 0000000000..efd0f9ab8c --- /dev/null +++ b/src/soc/intel/icelake/acpi/northbridge.asl @@ -0,0 +1,340 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <soc/iomap.h> + +#define BASE_32GB 0x800000000 +#define SIZE_16GB 0x400000000 + +Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID +Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID +Name (_SEG, Zero) // _SEG: PCI Segment +Name (_ADR, Zero) // _ADR: Address +Name (_UID, Zero) // _UID: Unique ID + +Device (MCHC) +{ + Name (_ADR, 0x00000000) + + OperationRegion (MCHP, PCI_Config, 0x00, 0x100) + Field (MCHP, DWordAcc, NoLock, Preserve) + { + Offset(0x40), /* EPBAR (0:0:0:40) */ + EPEN, 1, /* Enable */ + , 11, + EPBR, 20, /* EPBAR [31:12] */ + + Offset(0x48), /* MCHBAR (0:0:0:48) */ + MHEN, 1, /* Enable */ + , 14, + MHBR, 17, /* MCHBAR [31:15] */ + + Offset(0x60), /* PCIEXBAR (0:0:0:60) */ + PXEN, 1, /* Enable */ + PXSZ, 2, /* PCI Express Size */ + , 23, + PXBR, 6, /* PCI Express BAR [31:26] */ + + Offset(0x68), /* DMIBAR (0:0:0:68) */ + DIEN, 1, /* Enable */ + , 11, + DIBR, 20, /* DMIBAR [31:12] */ + + Offset (0xa0), /* Top of Used Memory */ + TOM, 64, + + Offset (0xa8), /* Top of Upper Used Memory */ + TUUD, 64, + + Offset (0xbc), /* Top of Low Used Memory */ + TLUD, 32, + } +} + +Name (MCRS, ResourceTemplate () +{ + /* Bus Numbers */ + WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, 0x0000, 0x00ff, 0x0000, 0x0100) + + /* IO Region 0 */ + DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, + EntireRange, + 0x0000, 0x0000, 0x0cf7, 0x0000, 0x0cf8) + + /* PCI Config Space */ + Io (Decode16, 0x0cf8, 0x0cf8, 0x0001, 0x0008) + + /* IO Region 1 */ + DWordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, + EntireRange, + 0x0000, 0x0d00, 0xffff, 0x0000, 0xf300) + + /* VGA memory (0xa0000-0xbffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000a0000, 0x000bffff, 0x00000000, + 0x00020000) + + /* OPROM reserved (0xc0000-0xc3fff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c0000, 0x000c3fff, 0x00000000, + 0x00004000) + + /* OPROM reserved (0xc4000-0xc7fff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c4000, 0x000c7fff, 0x00000000, + 0x00004000) + + /* OPROM reserved (0xc8000-0xcbfff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000c8000, 0x000cbfff, 0x00000000, + 0x00004000) + + /* OPROM reserved (0xcc000-0xcffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000cc000, 0x000cffff, 0x00000000, + 0x00004000) + + /* OPROM reserved (0xd0000-0xd3fff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d0000, 0x000d3fff, 0x00000000, + 0x00004000) + + /* OPROM reserved (0xd4000-0xd7fff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d4000, 0x000d7fff, 0x00000000, + 0x00004000) + + /* OPROM reserved (0xd8000-0xdbfff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000d8000, 0x000dbfff, 0x00000000, + 0x00004000) + + /* OPROM reserved (0xdc000-0xdffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000dc000, 0x000dffff, 0x00000000, + 0x00004000) + + /* BIOS Extension (0xe0000-0xe3fff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e0000, 0x000e3fff, 0x00000000, + 0x00004000) + + /* BIOS Extension (0xe4000-0xe7fff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e4000, 0x000e7fff, 0x00000000, + 0x00004000) + + /* BIOS Extension (0xe8000-0xebfff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000e8000, 0x000ebfff, 0x00000000, + 0x00004000) + + /* BIOS Extension (0xec000-0xeffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000ec000, 0x000effff, 0x00000000, + 0x00004000) + + /* System BIOS (0xf0000-0xfffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0x000f0000, 0x000fffff, 0x00000000, + 0x00010000) + + /* PCI Memory Region (TLUD - 0xdfffffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x00000000, 0x00000000, 0xdfffffff, 0x00000000, + 0xE0000000,,, PM01) + + /* PCI Memory Region (TUUD - (TUUD + ABOVE_4G_MMIO_SIZE)) */ + QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x00000000, 0x10000, 0x1ffff, 0x00000000, + 0x10000,,, PM02) + + /* PCH reserved resource (0xfc800000-0xfe7fffff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, PCH_PRESERVED_BASE_ADDRESS, 0xfe7fffff, + 0x00000000, PCH_PRESERVED_BASE_SIZE) + + /* TPM Area (0xfed40000-0xfed47fff) */ + DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, 0xfed40000, 0xfed47fff, 0x00000000, + 0x00008000) +}) + +Method (_CRS, 0, Serialized) +{ + /* Find PCI resource area in MCRS */ + CreateDwordField (^MCRS, ^PM01._MIN, PMIN) + CreateDwordField (^MCRS, ^PM01._MAX, PMAX) + CreateDwordField (^MCRS, ^PM01._LEN, PLEN) + + /* + * Fix up PCI memory region + * Start with Top of Lower Usable DRAM + */ + Store (^MCHC.TLUD, PMIN) + Add (Subtract (PMAX, PMIN), 1, PLEN) + + /* Patch PM02 range based on Memory Size */ + CreateQwordField (^MCRS, ^PM02._MIN, MMIN) + CreateQwordField (^MCRS, ^PM02._MAX, MMAX) + CreateQwordField (^MCRS, ^PM02._LEN, MLEN) + + Store (^MCHC.TUUD, Local0) + + If (LLessEqual (Local0, BASE_32GB)) { + Store (BASE_32GB, MMIN) + Store (SIZE_16GB, MLEN) + } Else { + Store (0, MMIN) + Store (0, MLEN) + } + Subtract (Add (MMIN, MLEN), 1, MMAX) + + Return (^MCRS) +} + +Name (EP_B, 0) /* to store EP BAR */ +Name (MH_B, 0) /* to store MCH BAR */ +Name (PC_B, 0) /* to store PCIe BAR */ +Name (PC_L, 0) /* to store PCIe BAR Length */ +Name (DM_B, 0) /* to store DMI BAR */ + +/* Get MCH BAR */ +Method (GMHB, 0, Serialized) +{ + If (LEqual (MH_B, 0)) { + ShiftLeft (\_SB.PCI0.MCHC.MHBR, 15, MH_B) + } + Return (MH_B) +} + +/* Get EP BAR */ +Method (GEPB, 0, Serialized) +{ + If (LEqual (EP_B, 0)) { + ShiftLeft (\_SB.PCI0.MCHC.EPBR, 12, EP_B) + } + Return (EP_B) +} + +/* Get PCIe BAR */ +Method (GPCB, 0, Serialized) +{ + If (LEqual (PC_B, 0)) { + ShiftLeft (\_SB.PCI0.MCHC.PXBR, 26, PC_B) + } + Return (PC_B) +} + +/* Get PCIe Length */ +Method (GPCL, 0, Serialized) +{ + If (LEqual (PC_L, 0)) { + ShiftRight (0x10000000, \_SB.PCI0.MCHC.PXSZ, PC_L) + } + Return (PC_L) +} + +/* Get DMI BAR */ +Method (GDMB, 0, Serialized) +{ + If (LEqual (DM_B, 0)) { + ShiftLeft (\_SB.PCI0.MCHC.DIBR, 12, DM_B) + } + Return (DM_B) +} + +/* PCI Device Resource Consumption */ +Device (PDRC) +{ + Name (_HID, EISAID ("PNP0C02")) + Name (_UID, 1) + + Name (BUF0, ResourceTemplate () + { + /* MCH BAR _BAS will be updated in _CRS below according to + * B0:D0:F0:Reg.48h + */ + Memory32Fixed (ReadWrite, 0, 0x08000, MCHB) + + /* DMI BAR _BAS will be updated in _CRS below according to + * B0:D0:F0:Reg.68h + */ + Memory32Fixed (ReadWrite, 0, 0x01000, DMIB) + + /* EP BAR _BAS will be updated in _CRS below according to + * B0:D0:F0:Reg.40h + */ + Memory32Fixed (ReadWrite, 0, 0x01000, EGPB) + + /* PCI Express BAR _BAS and _LEN will be updated in + * _CRS below according to B0:D0:F0:Reg.60h + */ + Memory32Fixed (ReadWrite, 0, 0, PCIX) + + /* VTD engine memory range. + */ + Memory32Fixed (ReadOnly, VTD_BASE_ADDRESS, VTD_BASE_SIZE) + + /* FLASH range */ + Memory32Fixed (ReadOnly, 0xFFF00000, 0x1000000, FIOH) + + /* Local APIC range(0xFEE0_0000 to 0xFEEF_FFFF) */ + Memory32Fixed (ReadOnly, 0xFEE00000, 0x100000, LIOH) + + /* HPET address decode range */ + Memory32Fixed (ReadWrite, HPET_BASE_ADDRESS, 0x400) + }) + + Method (_CRS, 0, Serialized) + { + CreateDwordField (BUF0, ^MCHB._BAS, MBR0) + Store (\_SB.PCI0.GMHB (), MBR0) + + CreateDwordField (BUF0, ^DMIB._BAS, DBR0) + Store (\_SB.PCI0.GDMB (), DBR0) + + CreateDwordField (BUF0, ^EGPB._BAS, EBR0) + Store (\_SB.PCI0.GEPB (), EBR0) + + CreateDwordField (BUF0, ^PCIX._BAS, XBR0) + Store (\_SB.PCI0.GPCB (), XBR0) + + CreateDwordField (BUF0, ^PCIX._LEN, XSZ0) + Store (\_SB.PCI0.GPCL (), XSZ0) + + Return (BUF0) + } +} diff --git a/src/soc/intel/icelake/acpi/pch_glan.asl b/src/soc/intel/icelake/acpi/pch_glan.asl new file mode 100644 index 0000000000..260dd44962 --- /dev/null +++ b/src/soc/intel/icelake/acpi/pch_glan.asl @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2017-2108 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Intel Gigabit Ethernet Controller 0:1f.6 */ + +Device (GLAN) +{ + Name (_ADR, 0x001f0006) + + Name (_S0W, 3) + + Name (_PRW, Package() {GPE0_PME_B0, 4}) + + Method (_DSW, 3) {} +} diff --git a/src/soc/intel/icelake/acpi/pch_hda.asl b/src/soc/intel/icelake/acpi/pch_hda.asl new file mode 100644 index 0000000000..67223295a7 --- /dev/null +++ b/src/soc/intel/icelake/acpi/pch_hda.asl @@ -0,0 +1,83 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Audio Controller - Device 31, Function 3 */ + +Device (HDAS) +{ + Name (_ADR, 0x001f0003) + Name (_DDN, "Audio Controller") + Name (UUID, ToUUID ("A69F886E-6CEB-4594-A41F-7B5DCE24C553")) + + /* Device is D3 wake capable */ + Name (_S0W, 3) + + /* NHLT Table Address populated from GNVS values */ + Name (NBUF, ResourceTemplate () { + QWordMemory (ResourceConsumer, PosDecode, MinFixed, + MaxFixed, NonCacheable, ReadOnly, + 0, 0, 0, 0, 1,,, NHLT, AddressRangeACPI) + }) + + /* + * Device Specific Method + * Arg0 - UUID + * Arg1 - Revision + * Arg2 - Function Index + */ + Method (_DSM, 4) + { + If (LEqual (Arg0, ^UUID)) { + /* + * Function 0: Function Support Query + * Returns a bitmask of functions supported. + */ + If (LEqual (Arg2, Zero)) { + /* + * NHLT Query only supported for revision 1 and + * if NHLT address and length are set in NVS. + */ + If (LAnd (LEqual (Arg1, One), + LAnd (LNotEqual (NHLA, Zero), + LNotEqual (NHLL, Zero)))) { + Return (Buffer (One) { 0x03 }) + } Else { + Return (Buffer (One) { 0x01 }) + } + } + + /* + * Function 1: Query NHLT memory address used by + * Intel Offload Engine Driver to discover any non-HDA + * devices that are supported by the DSP. + * + * Returns a pointer to NHLT table in memory. + */ + If (LEqual (Arg2, One)) { + CreateQWordField (NBUF, ^NHLT._MIN, NBAS) + CreateQWordField (NBUF, ^NHLT._MAX, NMAS) + CreateQWordField (NBUF, ^NHLT._LEN, NLEN) + + Store (NHLA, NBAS) + Store (NHLA, NMAS) + Store (NHLL, NLEN) + + Return (NBUF) + } + } + + Return (Buffer (One) { 0x00 }) + } +} diff --git a/src/soc/intel/icelake/acpi/pci_irqs.asl b/src/soc/intel/icelake/acpi/pci_irqs.asl new file mode 100644 index 0000000000..d346ce2269 --- /dev/null +++ b/src/soc/intel/icelake/acpi/pci_irqs.asl @@ -0,0 +1,141 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017-2018 Intel Corp. + * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <soc/irq.h> + +Name (PICP, Package () { + /* PCI Bridge */ + /* cAVS, SMBus, GbE, Nothpeak */ + Package(){0x001FFFFF, 0, 0, cAVS_INTA_IRQ }, + Package(){0x001FFFFF, 1, 0, SMBUS_INTB_IRQ }, + Package(){0x001FFFFF, 2, 0, GbE_INTC_IRQ }, + Package(){0x001FFFFF, 3, 0, TRACE_HUB_INTD_IRQ }, + /* SerialIo and SCS */ + Package(){0x001EFFFF, 0, 0, LPSS_UART0_IRQ }, + Package(){0x001EFFFF, 1, 0, LPSS_UART1_IRQ }, + Package(){0x001EFFFF, 2, 0, LPSS_SPI0_IRQ }, + Package(){0x001EFFFF, 3, 0, LPSS_SPI1_IRQ }, + /* PCI Express Port 9-16 */ + Package(){0x001DFFFF, 0, 0, PCIE_9_IRQ }, + Package(){0x001DFFFF, 1, 0, PCIE_10_IRQ }, + Package(){0x001DFFFF, 2, 0, PCIE_11_IRQ }, + Package(){0x001DFFFF, 3, 0, PCIE_12_IRQ }, + /* PCI Express Port 1-8 */ + Package(){0x001CFFFF, 0, 0, PCIE_1_IRQ }, + Package(){0x001CFFFF, 1, 0, PCIE_2_IRQ }, + Package(){0x001CFFFF, 2, 0, PCIE_3_IRQ }, + Package(){0x001CFFFF, 3, 0, PCIE_4_IRQ }, + /* eMMC */ + Package(){0x001AFFFF, 0, 0, eMMC_IRQ }, + /* SerialIo */ + Package(){0x0019FFFF, 0, 0, LPSS_I2C4_IRQ }, + Package(){0x0019FFFF, 1, 0, LPSS_I2C5_IRQ }, + Package(){0x0019FFFF, 2, 0, LPSS_UART2_IRQ }, + /* SATA controller */ + Package(){0x0017FFFF, 0, 0, SATA_IRQ }, + /* CSME (HECI, IDE-R, Keyboard and Text redirection */ + Package(){0x0016FFFF, 0, 0, HECI_1_IRQ }, + Package(){0x0016FFFF, 1, 0, HECI_2_IRQ }, + Package(){0x0016FFFF, 2, 0, IDER_IRQ }, + Package(){0x0016FFFF, 3, 0, KT_IRQ }, + /* SerialIo */ + Package(){0x0015FFFF, 0, 0, LPSS_I2C0_IRQ }, + Package(){0x0015FFFF, 1, 0, LPSS_I2C1_IRQ }, + Package(){0x0015FFFF, 2, 0, LPSS_I2C2_IRQ }, + Package(){0x0015FFFF, 3, 0, LPSS_I2C3_IRQ }, + /* D20: xHCI, OTG, SRAM, CNVi WiFi */ + Package(){0x0014FFFF, 0, 0, XHCI_IRQ }, + Package(){0x0014FFFF, 1, 0, OTG_IRQ }, + Package(){0x0014FFFF, 2, 0, PMC_SRAM_IRQ }, + Package(){0x0014FFFF, 3, 0, CNViWIFI_IRQ }, + /* Integrated Sensor Hub */ + Package(){0x0013FFFF, 0, 0, ISH_IRQ }, + /* Thermal */ + Package(){0x0012FFFF, 0, 0, THERMAL_IRQ }, + /* Host Bridge */ + /* Root Port D1F0 */ + Package(){0x0001FFFF, 0, 0, PEG_RP_INTA_IRQ }, + Package(){0x0001FFFF, 1, 0, PEG_RP_INTB_IRQ }, + Package(){0x0001FFFF, 2, 0, PEG_RP_INTC_IRQ }, + Package(){0x0001FFFF, 3, 0, PEG_RP_INTD_IRQ }, + /* SA IGFX Device */ + Package(){0x0002FFFF, 0, 0, IGFX_IRQ }, + /* SA Thermal Device */ + Package(){0x0004FFFF, 0, 0, SA_THERMAL_IRQ }, + /* SA IPU Device */ + Package(){0x0005FFFF, 0, 0, IPU_IRQ }, + /* SA GNA Device */ + Package(){0x0008FFFF, 0, 0, GNA_IRQ }, +}) + +Name (PICN, Package () { + /* D31: cAVS, SMBus, GbE, Nothpeak */ + Package () { 0x001FFFFF, 0, \_SB.PCI0.LNKA, 0 }, + Package () { 0x001FFFFF, 1, \_SB.PCI0.LNKB, 0 }, + Package () { 0x001FFFFF, 2, \_SB.PCI0.LNKC, 0 }, + Package () { 0x001FFFFF, 3, \_SB.PCI0.LNKD, 0 }, + /* D32: Can't use PIC*/ + /* D29: PCI Express Port 9-16 */ + Package () { 0x001DFFFF, 0, \_SB.PCI0.LNKA, 0 }, + Package () { 0x001DFFFF, 1, \_SB.PCI0.LNKB, 0 }, + Package () { 0x001DFFFF, 2, \_SB.PCI0.LNKC, 0 }, + Package () { 0x001DFFFF, 3, \_SB.PCI0.LNKD, 0 }, + /* D28: PCI Express Port 1-8 */ + Package () { 0x001CFFFF, 0, \_SB.PCI0.LNKA, 0 }, + Package () { 0x001CFFFF, 1, \_SB.PCI0.LNKB, 0 }, + Package () { 0x001CFFFF, 2, \_SB.PCI0.LNKC, 0 }, + Package () { 0x001CFFFF, 3, \_SB.PCI0.LNKD, 0 }, + /* D25: Can't use PIC*/ + /* D23 */ + Package () { 0x0017FFFF, 0, \_SB.PCI0.LNKA, 0 }, + /* D22: CSME (HECI, IDE-R, KT redirection */ + Package () { 0x0016FFFF, 0, \_SB.PCI0.LNKA, 0 }, + Package () { 0x0016FFFF, 1, \_SB.PCI0.LNKB, 0 }, + Package () { 0x0016FFFF, 2, \_SB.PCI0.LNKC, 0 }, + Package () { 0x0016FFFF, 3, \_SB.PCI0.LNKD, 0 }, + /* D21: Can't use PIC*/ + /* D20: xHCI, OTG, SRAM, CNVi WiFi */ + Package () { 0x0014FFFF, 0, \_SB.PCI0.LNKA, 0 }, + Package () { 0x0014FFFF, 1, \_SB.PCI0.LNKB, 0 }, + Package () { 0x0014FFFF, 2, \_SB.PCI0.LNKC, 0 }, + Package () { 0x0014FFFF, 3, \_SB.PCI0.LNKD, 0 }, + /* D19: Can't use PIC*/ + /* Thermal */ + Package () { 0x0012FFFF, 0, \_SB.PCI0.LNKA, 0 }, + /* P.E.G. Root Port D1F0 */ + Package () { 0x0001FFFF, 0, \_SB.PCI0.LNKA, 0 }, + Package () { 0x0001FFFF, 1, \_SB.PCI0.LNKB, 0 }, + Package () { 0x0001FFFF, 2, \_SB.PCI0.LNKC, 0 }, + Package () { 0x0001FFFF, 3, \_SB.PCI0.LNKD, 0 }, + /* SA IGFX Device */ + Package () { 0x0002FFFF, 0, \_SB.PCI0.LNKA, 0 }, + /* SA Thermal Device */ + Package () { 0x0004FFFF, 0, \_SB.PCI0.LNKA, 0 }, + /* SA IPU Device */ + Package () { 0x0005FFFF, 0, \_SB.PCI0.LNKA, 0 }, + /* SA GNA Device */ + Package () { 0x0008FFFF, 0, \_SB.PCI0.LNKA, 0 }, +}) + +Method (_PRT) +{ + If (PICM) { + Return (^PICP) + } Else { + Return (^PICN) + } +} diff --git a/src/soc/intel/icelake/acpi/pcie.asl b/src/soc/intel/icelake/acpi/pcie.asl new file mode 100644 index 0000000000..69e16ca075 --- /dev/null +++ b/src/soc/intel/icelake/acpi/pcie.asl @@ -0,0 +1,382 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Intel PCH PCIe support */ + +Method (IRQM, 1, Serialized) { + + /* Interrupt Map INTA->INTA, INTB->INTB, INTC->INTC, INTD->INTD */ + Name (IQAA, Package () { + Package () { 0x0000ffff, 0, 0, 16 }, + Package () { 0x0000ffff, 1, 0, 17 }, + Package () { 0x0000ffff, 2, 0, 18 }, + Package () { 0x0000ffff, 3, 0, 19 } }) + Name (IQAP, Package () { + Package () { 0x0000ffff, 0, \_SB.PCI0.LNKA, 0 }, + Package () { 0x0000ffff, 1, \_SB.PCI0.LNKB, 0 }, + Package () { 0x0000ffff, 2, \_SB.PCI0.LNKC, 0 }, + Package () { 0x0000ffff, 3, \_SB.PCI0.LNKD, 0 } }) + + /* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */ + Name (IQBA, Package () { + Package () { 0x0000ffff, 0, 0, 17 }, + Package () { 0x0000ffff, 1, 0, 18 }, + Package () { 0x0000ffff, 2, 0, 19 }, + Package () { 0x0000ffff, 3, 0, 16 } }) + Name (IQBP, Package () { + Package () { 0x0000ffff, 0, \_SB.PCI0.LNKB, 0 }, + Package () { 0x0000ffff, 1, \_SB.PCI0.LNKC, 0 }, + Package () { 0x0000ffff, 2, \_SB.PCI0.LNKD, 0 }, + Package () { 0x0000ffff, 3, \_SB.PCI0.LNKA, 0 } }) + + /* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */ + Name (IQCA, Package () { + Package () { 0x0000ffff, 0, 0, 18 }, + Package () { 0x0000ffff, 1, 0, 19 }, + Package () { 0x0000ffff, 2, 0, 16 }, + Package () { 0x0000ffff, 3, 0, 17 } }) + Name (IQCP, Package () { + Package () { 0x0000ffff, 0, \_SB.PCI0.LNKC, 0 }, + Package () { 0x0000ffff, 1, \_SB.PCI0.LNKD, 0 }, + Package () { 0x0000ffff, 2, \_SB.PCI0.LNKA, 0 }, + Package () { 0x0000ffff, 3, \_SB.PCI0.LNKB, 0 } }) + + /* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */ + Name (IQDA, Package () { + Package () { 0x0000ffff, 0, 0, 19 }, + Package () { 0x0000ffff, 1, 0, 16 }, + Package () { 0x0000ffff, 2, 0, 17 }, + Package () { 0x0000ffff, 3, 0, 18 } }) + Name (IQDP, Package () { + Package () { 0x0000ffff, 0, \_SB.PCI0.LNKD, 0 }, + Package () { 0x0000ffff, 1, \_SB.PCI0.LNKA, 0 }, + Package () { 0x0000ffff, 2, \_SB.PCI0.LNKB, 0 }, + Package () { 0x0000ffff, 3, \_SB.PCI0.LNKC, 0 } }) + + Switch (ToInteger (Arg0)) + { + Case (Package () { 1, 5, 9, 13 }) { + If (PICM) { + Return (IQAA) + } Else { + Return (IQAP) + } + } + + Case (Package () { 2, 6, 10, 14 }) { + If (PICM) { + Return (IQBA) + } Else { + Return (IQBP) + } + } + + Case (Package () { 3, 7, 11, 15 }) { + If (PICM) { + Return (IQCA) + } Else { + Return (IQCP) + } + } + + Case (Package () { 4, 8, 12, 16 }) { + If (PICM) { + Return (IQDA) + } Else { + Return (IQDP) + } + } + + Default { + If (PICM) { + Return (IQDA) + } Else { + Return (IQDP) + } + } + } +} + +Device (RP01) +{ + Name (_ADR, 0x001C0000) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP02) +{ + Name (_ADR, 0x001C0001) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP03) +{ + Name (_ADR, 0x001C0002) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP04) +{ + Name (_ADR, 0x001C0003) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP05) +{ + Name (_ADR, 0x001C0004) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP06) +{ + Name (_ADR, 0x001C0005) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP07) +{ + Name (_ADR, 0x001C0006) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP08) +{ + Name (_ADR, 0x001C0007) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP09) +{ + Name (_ADR, 0x001D0000) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP10) +{ + Name (_ADR, 0x001D0001) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP11) +{ + Name (_ADR, 0x001D0002) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP12) +{ + Name (_ADR, 0x001D0003) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP13) +{ + Name (_ADR, 0x001D0004) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP14) +{ + Name (_ADR, 0x001D0005) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP15) +{ + Name (_ADR, 0x001D0006) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} + +Device (RP16) +{ + Name (_ADR, 0x001D0007) + + OperationRegion (RPCS, PCI_Config, 0x4c, 4) + Field (RPCS, AnyAcc, NoLock, Preserve) + { + , 24, + RPPN, 8, /* Root Port Number */ + } + + Method (_PRT) + { + Return (IRQM (RPPN)) + } +} diff --git a/src/soc/intel/icelake/acpi/platform.asl b/src/soc/intel/icelake/acpi/platform.asl new file mode 100644 index 0000000000..080bf7b960 --- /dev/null +++ b/src/soc/intel/icelake/acpi/platform.asl @@ -0,0 +1,42 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Enable ACPI _SWS methods */ +#include <soc/intel/common/acpi/acpi_wake_source.asl> +/* Generic indicator for sleep state */ +#include <soc/intel/common/acpi/platform.asl> + +/* The APM port can be used for generating software SMIs */ + +OperationRegion (APMP, SystemIO, 0xb2, 2) +Field (APMP, ByteAcc, NoLock, Preserve) +{ + APMC, 8, // APM command + APMS, 8 // APM status +} + +/* + * The _PIC method is called by the OS to choose between interrupt + * routing via the i8259 interrupt controller or the APIC. + * + * _PIC is called with a parameter of 0 for i8259 configuration and + * with a parameter of 1 for Local Apic/IOAPIC configuration. + */ + +Method (_PIC, 1) +{ + /* Remember the OS' IRQ routing choice. */ + Store (Arg0, PICM) +} diff --git a/src/soc/intel/icelake/acpi/scs.asl b/src/soc/intel/icelake/acpi/scs.asl new file mode 100644 index 0000000000..896fd77c19 --- /dev/null +++ b/src/soc/intel/icelake/acpi/scs.asl @@ -0,0 +1,134 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017-2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <soc/pcr_ids.h> + +Scope (\_SB.PCI0) { + + /* + * Clear register 0x1C20/0x4820 + * Arg0 - PCR Port ID + */ + Method(SCSC, 1, Serialized) + { + ^PCRA (Arg0, 0x1C20, 0x0) + ^PCRA (Arg0, 0x4820, 0x0) + } + + /* EMMC */ + Device(PEMC) { + Name(_ADR, 0x001A0000) + Name (_DDN, "eMMC Controller") + Name (TEMP, 0) + + OperationRegion(SCSR, PCI_Config, 0x00, 0x100) + Field(SCSR, WordAcc, NoLock, Preserve) { + Offset (0x84), /* PMECTRLSTATUS */ + PMCR, 16, + Offset (0xA2), /* PG_CONFIG */ + , 2, + PGEN, 1, /* PG_ENABLE */ + } + + Method(_INI) { + /* Clear register 0x1C20/0x4820 */ + ^^SCSC (PID_EMMC) + } + + Method(_PS0, 0, Serialized) { + Stall (50) // Sleep 50 us + + Store(0, PGEN) // Disable PG + + /* Clear register 0x1C20/0x4820 */ + ^^SCSC (PID_EMMC) + + /* Set Power State to D0 */ + And (PMCR, 0xFFFC, PMCR) + Store (PMCR, ^TEMP) + } + + Method(_PS3, 0, Serialized) { + Store(1, PGEN) // Enable PG + + /* Set Power State to D3 */ + Or (PMCR, 0x0003, PMCR) + Store (PMCR, ^TEMP) + } + + Device (CARD) + { + Name (_ADR, 0x00000008) + Method (_RMV, 0, NotSerialized) + { + Return (0) + } + } + } + + /* SD CARD */ + Device (SDXC) + { + Name (_ADR, 0x00140005) + Name (_DDN, "SD Controller") + Name (TEMP, 0) + + OperationRegion (SDPC, PCI_Config, 0x00, 0x100) + Field (SDPC, WordAcc, NoLock, Preserve) + { + Offset (0x84), /* PMECTRLSTATUS */ + PMCR, 16, + Offset (0xA2), /* PG_CONFIG */ + , 2, + PGEN, 1, /* PG_ENABLE */ + } + + Method(_INI) + { + /* Clear register 0x1C20/0x4820 */ + ^^SCSC (PID_SDX) + } + + Method (_PS0, 0, Serialized) + { + Store (0, PGEN) /* Disable PG */ + + /* Clear register 0x1C20/0x4820 */ + ^^SCSC (PID_SDX) + + /* Set Power State to D0 */ + And (PMCR, 0xFFFC, PMCR) + Store (PMCR, ^TEMP) + } + + Method (_PS3, 0, Serialized) + { + Store (1, PGEN) /* Enable PG */ + + /* Set Power State to D3 */ + Or (PMCR, 0x0003, PMCR) + Store (PMCR, ^TEMP) + } + + Device (CARD) + { + Name (_ADR, 0x00000008) + Method (_RMV, 0, NotSerialized) + { + Return (1) + } + } + } /* Device (SDXC) */ +} diff --git a/src/soc/intel/icelake/acpi/serialio.asl b/src/soc/intel/icelake/acpi/serialio.asl new file mode 100644 index 0000000000..3abf383c8a --- /dev/null +++ b/src/soc/intel/icelake/acpi/serialio.asl @@ -0,0 +1,88 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Intel Serial IO Devices */ + +Device (I2C0) +{ + Name (_ADR, 0x00150000) + Name (_DDN, "Serial IO I2C Controller 0") +} + +Device (I2C1) +{ + Name (_ADR, 0x00150001) + Name (_DDN, "Serial IO I2C Controller 1") +} + +Device (I2C2) +{ + Name (_ADR, 0x00150002) + Name (_DDN, "Serial IO I2C Controller 2") +} + +Device (I2C3) +{ + Name (_ADR, 0x00150003) + Name (_DDN, "Serial IO I2C Controller 3") +} + +Device (I2C4) +{ + Name (_ADR, 0x00190000) + Name (_DDN, "Serial IO I2C Controller 4") +} + +Device (I2C5) +{ + Name (_ADR, 0x00190001) + Name (_DDN, "Serial IO I2C Controller 5") +} + +Device (SPI0) +{ + Name (_ADR, 0x001e0002) + Name (_DDN, "Serial IO SPI Controller 0") +} + +Device (SPI1) +{ + Name (_ADR, 0x001e0003) + Name (_DDN, "Serial IO SPI Controller 1") +} + +Device (SPI2) +{ + Name (_ADR, 0x00120006) + Name (_DDN, "Serial IO SPI Controller 2") +} + +Device (UAR0) +{ + Name (_ADR, 0x001e0000) + Name (_DDN, "Serial IO UART Controller 0") +} + +Device (UAR1) +{ + Name (_ADR, 0x001e0001) + Name (_DDN, "Serial IO UART Controller 1") +} + +Device (UAR2) +{ + Name (_ADR, 0x00190002) + Name (_DDN, "Serial IO UART Controller 2") +} diff --git a/src/soc/intel/icelake/acpi/sleepstates.asl b/src/soc/intel/icelake/acpi/sleepstates.asl new file mode 100644 index 0000000000..13cc3582aa --- /dev/null +++ b/src/soc/intel/icelake/acpi/sleepstates.asl @@ -0,0 +1,20 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +Name (\_S0, Package () { 0x0, 0x0, 0x0, 0x0 }) +Name (\_S3, Package () { 0x5, 0x5, 0x0, 0x0 }) +Name (\_S5, Package () { 0x7, 0x7, 0x0, 0x0 }) diff --git a/src/soc/intel/icelake/acpi/smbus.asl b/src/soc/intel/icelake/acpi/smbus.asl new file mode 100644 index 0000000000..c654fe2087 --- /dev/null +++ b/src/soc/intel/icelake/acpi/smbus.asl @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +// Intel SMBus Controller 0:1f.4 + +Device (SBUS) +{ + Name (_ADR, 0x001f0004) +} diff --git a/src/soc/intel/icelake/acpi/southbridge.asl b/src/soc/intel/icelake/acpi/southbridge.asl new file mode 100644 index 0000000000..ff323c40a3 --- /dev/null +++ b/src/soc/intel/icelake/acpi/southbridge.asl @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017-2018 Intel Corp. + * (Written by Bora Guvendik <bora.guvendik@intel.com> for Intel Corp.) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <intelblocks/itss.h> +#include <intelblocks/pcr.h> +#include <soc/itss.h> +#include <soc/pcr_ids.h> + +/* Interrupt Routing */ +#include "irqlinks.asl" + +/* PCI IRQ assignment */ +#include "pci_irqs.asl" + +/* PCR access */ +#include <soc/intel/common/acpi/pcr.asl> + +/* eMMC, SD Card */ +#include "scs.asl" + +/* GPIO controller */ +#include "gpio.asl" + +/* LPC 0:1f.0 */ +#include "lpc.asl" + +/* PCH HDA */ +#include "pch_hda.asl" + +/* PCIE Ports */ +#include "pcie.asl" + +/* Serial IO */ +#include "serialio.asl" + +/* SMBus 0:1f.4 */ +#include "smbus.asl" + +/* USB XHCI 0:14.0 */ +#include "xhci.asl" + +/* PCI _OSC */ +#include <soc/intel/common/acpi/pci_osc.asl> + +/* CNVi */ +#include "cnvi.asl" + +/* GBe 0:1f.6 */ +#include "pch_glan.asl" diff --git a/src/soc/intel/icelake/acpi/xhci.asl b/src/soc/intel/icelake/acpi/xhci.asl new file mode 100644 index 0000000000..9c624e4f48 --- /dev/null +++ b/src/soc/intel/icelake/acpi/xhci.asl @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <soc/gpe.h> + +/* XHCI Controller 0:14.0 */ + +Device (XHCI) +{ + Name (_ADR, 0x00140000) + + Name (_PRW, Package () { GPE0_PME_B0, 3 }) + + Name (_S3D, 3) /* D3 supported in S3 */ + Name (_S0W, 3) /* D3 can wake device in S0 */ + Name (_S3W, 3) /* D3 can wake system from S3 */ + + Method (_PS0, 0, Serialized) + { + + } + + Method (_PS3, 0, Serialized) + { + + } + + /* Root Hub for Icelake-LP PCH */ + Device (RHUB) + { + Name (_ADR, Zero) + + /* USB2 */ + Device (HS01) { Name (_ADR, 1) } + Device (HS02) { Name (_ADR, 2) } + Device (HS03) { Name (_ADR, 3) } + Device (HS04) { Name (_ADR, 4) } + Device (HS05) { Name (_ADR, 5) } + Device (HS06) { Name (_ADR, 6) } + Device (HS07) { Name (_ADR, 7) } + Device (HS08) { Name (_ADR, 8) } + Device (HS09) { Name (_ADR, 9) } + Device (HS10) { Name (_ADR, 10) } + Device (HS11) { Name (_ADR, 11) } + Device (HS12) { Name (_ADR, 12) } + + /* USBr */ + Device (USR1) { Name (_ADR, 11) } + Device (USR2) { Name (_ADR, 12) } + + /* USB3 */ + Device (SS01) { Name (_ADR, 13) } + Device (SS02) { Name (_ADR, 14) } + Device (SS03) { Name (_ADR, 15) } + Device (SS04) { Name (_ADR, 16) } + Device (SS05) { Name (_ADR, 17) } + Device (SS06) { Name (_ADR, 18) } + } +} diff --git a/src/soc/intel/icelake/bootblock/bootblock.c b/src/soc/intel/icelake/bootblock/bootblock.c new file mode 100644 index 0000000000..40c2d41b7a --- /dev/null +++ b/src/soc/intel/icelake/bootblock/bootblock.c @@ -0,0 +1,43 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <bootblock_common.h> +#include <intelblocks/gspi.h> +#include <intelblocks/uart.h> +#include <soc/bootblock.h> +#include <soc/iomap.h> +#include <soc/pch.h> + +asmlinkage void bootblock_c_entry(uint64_t base_timestamp) +{ + /* Call lib/bootblock.c main */ + bootblock_main_with_timestamp(base_timestamp, NULL, 0); +} + +void bootblock_soc_early_init(void) +{ + bootblock_systemagent_early_init(); + bootblock_pch_early_init(); + bootblock_cpu_init(); + pch_early_iorange_init(); + if (IS_ENABLED(CONFIG_UART_DEBUG)) + uart_bootblock_init(); +} + +void bootblock_soc_init(void) +{ + report_platform_info(); + pch_early_init(); +} diff --git a/src/soc/intel/icelake/bootblock/cpu.c b/src/soc/intel/icelake/bootblock/cpu.c new file mode 100644 index 0000000000..f02b09027a --- /dev/null +++ b/src/soc/intel/icelake/bootblock/cpu.c @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <intelblocks/cpulib.h> +#include <intelblocks/fast_spi.h> +#include <soc/bootblock.h> + +void bootblock_cpu_init(void) +{ + /* Temporarily cache the memory-mapped boot media. */ + if (IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED) && + IS_ENABLED(CONFIG_BOOT_DEVICE_SPI_FLASH)) + fast_spi_cache_bios_region(); +} diff --git a/src/soc/intel/icelake/bootblock/pch.c b/src/soc/intel/icelake/bootblock/pch.c new file mode 100644 index 0000000000..269e2a3c2b --- /dev/null +++ b/src/soc/intel/icelake/bootblock/pch.c @@ -0,0 +1,210 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pci_ids.h> +#include <intelblocks/fast_spi.h> +#include <intelblocks/gspi.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/p2sb.h> +#include <intelblocks/pcr.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/rtc.h> +#include <intelblocks/smbus.h> +#include <soc/bootblock.h> +#include <soc/iomap.h> +#include <soc/lpc.h> +#include <soc/p2sb.h> +#include <soc/pch.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> +#include <soc/pm.h> +#include <soc/smbus.h> + +#define PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_LP 0x1400 +#define PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_H 0x0980 + +#define PCR_PSFX_TO_SHDW_BAR0 0 +#define PCR_PSFX_TO_SHDW_BAR1 0x4 +#define PCR_PSFX_TO_SHDW_BAR2 0x8 +#define PCR_PSFX_TO_SHDW_BAR3 0xC +#define PCR_PSFX_TO_SHDW_BAR4 0x10 +#define PCR_PSFX_TO_SHDW_PCIEN_IOEN 0x01 +#define PCR_PSFX_T0_SHDW_PCIEN 0x1C + +#define PCR_DMI_ACPIBA 0x27B4 +#define PCR_DMI_ACPIBDID 0x27B8 +#define PCR_DMI_PMBASEA 0x27AC +#define PCR_DMI_PMBASEC 0x27B0 +#define PCR_DMI_TCOBASE 0x2778 +/* Enable TCO I/O range decode. */ +#define TCOEN (1 << 1) + +#define PCR_DMI_LPCIOD 0x2770 +#define PCR_DMI_LPCIOE 0x2774 + +static uint32_t get_pmc_reg_base(void) +{ + uint8_t pch_series; + + pch_series = get_pch_series(); + + if (pch_series == PCH_H) + return PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_H; + else if (pch_series == PCH_LP) + return PCR_PSF3_TO_SHDW_PMC_REG_BASE_CNP_LP; + else + return 0; +} + +static void soc_config_pwrmbase(void) +{ + uint32_t reg32; + + /* + * Assign Resources to PWRMBASE + * Clear BIT 1-2 Command Register + */ + reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND); + reg32 &= ~(PCI_COMMAND_MEMORY); + pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32); + + /* Program PWRM Base */ + pci_write_config32(PCH_DEV_PMC, PWRMBASE, PCH_PWRM_BASE_ADDRESS); + + /* Enable Bus Master and MMIO Space */ + reg32 = pci_read_config32(PCH_DEV_PMC, PCI_COMMAND); + reg32 |= PCI_COMMAND_MEMORY; + pci_write_config32(PCH_DEV_PMC, PCI_COMMAND, reg32); + + /* Enable PWRM in PMC */ + reg32 = read32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL)); + write32((void *)(PCH_PWRM_BASE_ADDRESS + ACTL), reg32 | PWRM_EN); +} + +void bootblock_pch_early_init(void) +{ + fast_spi_early_init(SPI_BASE_ADDRESS); + gspi_early_bar_init(); + p2sb_enable_bar(); + p2sb_configure_hpet(); + + /* + * Enabling PWRM Base for accessing + * Global Reset Cause Register. + */ + soc_config_pwrmbase(); +} + + +static void soc_config_acpibase(void) +{ + uint32_t pmc_reg_value; + uint32_t pmc_base_reg; + + pmc_base_reg = get_pmc_reg_base(); + if (!pmc_base_reg) + die("Invalid PMC base address\n"); + + pmc_reg_value = pcr_read32(PID_PSF3, pmc_base_reg + + PCR_PSFX_TO_SHDW_BAR4); + + if (pmc_reg_value != 0xFFFFFFFF) { + /* Disable Io Space before changing the address */ + pcr_rmw32(PID_PSF3, pmc_base_reg + + PCR_PSFX_T0_SHDW_PCIEN, + ~PCR_PSFX_TO_SHDW_PCIEN_IOEN, 0); + /* Program ABASE in PSF3 PMC space BAR4*/ + pcr_write32(PID_PSF3, pmc_base_reg + + PCR_PSFX_TO_SHDW_BAR4, + ACPI_BASE_ADDRESS); + /* Enable IO Space */ + pcr_rmw32(PID_PSF3, pmc_base_reg + + PCR_PSFX_T0_SHDW_PCIEN, + ~0, PCR_PSFX_TO_SHDW_PCIEN_IOEN); + } +} + +static void soc_config_tco(void) +{ + uint32_t reg32; + uint16_t tcobase; + uint16_t tcocnt; + + /* Disable TCO in SMBUS Device first before changing Base Address */ + reg32 = pci_read_config32(PCH_DEV_SMBUS, TCOCTL); + reg32 &= ~TCO_BASE_EN; + pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32); + + /* Program TCO Base */ + tcobase = TCO_BASE_ADDRESS; + pci_write_config32(PCH_DEV_SMBUS, TCOBASE, tcobase); + + /* Enable TCO in SMBUS */ + pci_write_config32(PCH_DEV_SMBUS, TCOCTL, reg32 | TCO_BASE_EN); + + /* + * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] + */ + pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN); + + /* Program TCO timer halt */ + tcocnt = inw(tcobase + TCO1_CNT); + tcocnt |= TCO_TMR_HLT; + outw(tcocnt, tcobase + TCO1_CNT); +} + +void pch_early_iorange_init(void) +{ + uint16_t dec_rng, dec_en = 0; + + /* IO Decode Range */ + if (IS_ENABLED(CONFIG_DRIVERS_UART_8250IO) && + IS_ENABLED(CONFIG_UART_DEBUG)) { + dec_rng = COMA_RANGE | (COMB_RANGE << 4); + dec_en = COMA_LPC_EN | COMB_LPC_EN; + pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, dec_rng); + pcr_write16(PID_DMI, PCR_DMI_LPCIOD, dec_rng); + } + + /* IO Decode Enable */ + dec_en |= SE_LPC_EN | KBC_LPC_EN | MC1_LPC_EN | GAMEL_LPC_EN; + pci_write_config16(PCH_DEV_LPC, LPC_EN, dec_en); + pcr_write16(PID_DMI, PCR_DMI_LPCIOE, dec_en); + + /* Program generic IO Decode Range */ + pch_enable_lpc(); +} + +void pch_early_init(void) +{ + /* + * Enabling ABASE for accessing PM1_STS, PM1_EN, PM1_CNT, + * GPE0_STS, GPE0_EN registers. + */ + soc_config_acpibase(); + + /* Programming TCO_BASE_ADDRESS and TCO Timer Halt */ + soc_config_tco(); + + /* Program SMBUS_BASE_ADDRESS and Enable it */ + smbus_common_init(); + + /* Set up GPE configuration */ + pmc_gpe_init(); + + enable_rtc_upper_bank(); +} diff --git a/src/soc/intel/icelake/bootblock/report_platform.c b/src/soc/intel/icelake/bootblock/report_platform.c new file mode 100644 index 0000000000..9df6a1ef84 --- /dev/null +++ b/src/soc/intel/icelake/bootblock/report_platform.c @@ -0,0 +1,212 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/cpu.h> +#include <arch/io.h> +#include <console/console.h> +#include <cpu/x86/msr.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <intelblocks/mp_init.h> +#include <soc/bootblock.h> +#include <soc/pch.h> +#include <soc/pci_devs.h> +#include <string.h> + +#define BIOS_SIGN_ID 0x8B + +static struct { + u32 cpuid; + const char *name; +} cpu_table[] = { + { CPUID_CANNONLAKE_A0, "Cannonlake A0" }, + { CPUID_CANNONLAKE_B0, "Cannonlake B0" }, + { CPUID_CANNONLAKE_C0, "Cannonlake C0" }, + { CPUID_CANNONLAKE_D0, "Cannonlake D0" }, + { CPUID_COFFEELAKE_D0, "Coffeelake D0" }, + { CPUID_WHISKEYLAKE_W0, "Whiskeylake W0"}, + { CPUID_COFFEELAKE_U0, "Coffeelake U0 (6+2)" }, +}; + +static struct { + u16 mchid; + const char *name; +} mch_table[] = { + { PCI_DEVICE_ID_INTEL_CNL_ID_U, "Cannonlake-U" }, + { PCI_DEVICE_ID_INTEL_CNL_ID_Y, "Cannonlake-Y" }, + { PCI_DEVICE_ID_INTEL_CFL_ID_U, "Coffeelake U (4+3e)"}, + { PCI_DEVICE_ID_INTEL_WHL_ID_Wx4, "Whiskeylake W (4+2)"}, + { PCI_DEVICE_ID_INTEL_WHL_ID_Wx2, "Whiskeylake W (2+2)"}, + { PCI_DEVICE_ID_INTEL_CFL_ID_H, "Coffeelake-H" }, + { PCI_DEVICE_ID_INTEL_CFL_ID_S, "Coffeelake-S" }, +}; + +static struct { + u16 lpcid; + const char *name; +} pch_table[] = { + { PCI_DEVICE_ID_INTEL_CNL_BASE_U_LPC, "Cannonlake-U Base" }, + { PCI_DEVICE_ID_INTEL_CNL_U_PREMIUM_LPC, "Cannonlake-U Premium" }, + { PCI_DEVICE_ID_INTEL_CNL_Y_PREMIUM_LPC, "Cannonlake-Y Premium" }, + { PCI_DEVICE_ID_INTEL_CNP_H_LPC_Q370, "Cannonlake-H Q370" }, + { PCI_DEVICE_ID_INTEL_CNP_H_LPC_QM370, "Cannonlake-H QM370" }, +}; + +static struct { + u16 igdid; + const char *name; +} igd_table[] = { + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_1, "Cannonlake ULX GT2" }, + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_2, "Cannonlake ULX GT1.5" }, + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_3, "Cannonlake ULX GT1" }, + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULX_4, "Cannonlake ULX GT0.5" }, + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_1, "Cannonlake ULT GT2" }, + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_2, "Cannonlake ULT GT1.5" }, + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_3, "Cannonlake ULT GT1" }, + { PCI_DEVICE_ID_INTEL_CNL_GT2_ULT_4, "Cannonlake ULT GT0.5" }, + { PCI_DEVICE_ID_INTEL_CFL_GT2_ULT, "Coffeelake ULT GT2"}, + { PCI_DEVICE_ID_INTEL_WHL_GT2_ULT_1, "Whiskeylake ULT GT1"}, + { PCI_DEVICE_ID_INTEL_CFL_H_GT2, "Coffeelake-H GT2" }, + { PCI_DEVICE_ID_INTEL_CFL_S_GT2, "Coffeelake-S GT2" }, +}; + +static uint8_t get_dev_revision(pci_devfn_t dev) +{ + return pci_read_config8(dev, PCI_REVISION_ID); +} + +static uint16_t get_dev_id(pci_devfn_t dev) +{ + return pci_read_config16(dev, PCI_DEVICE_ID); +} + +static void report_cpu_info(void) +{ + struct cpuid_result cpuidr; + u32 i, index; + char cpu_string[50], *cpu_name = cpu_string; /* 48 bytes are reported */ + int vt, txt, aes; + msr_t microcode_ver; + static const char *const mode[] = {"NOT ", ""}; + const char *cpu_type = "Unknown"; + u32 p[13]; + + index = 0x80000000; + cpuidr = cpuid(index); + if (cpuidr.eax < 0x80000004) { + strcpy(cpu_string, "Platform info not available"); + } else { + int j = 0; + + for (i = 2; i <= 4; i++) { + cpuidr = cpuid(index + i); + p[j++] = cpuidr.eax; + p[j++] = cpuidr.ebx; + p[j++] = cpuidr.ecx; + p[j++] = cpuidr.edx; + } + p[12] = 0; + cpu_name = (char *)p; + } + /* Skip leading spaces in CPU name string */ + while (cpu_name[0] == ' ') + cpu_name++; + + microcode_ver.lo = 0; + microcode_ver.hi = 0; + wrmsr(BIOS_SIGN_ID, microcode_ver); + cpuidr = cpuid(1); + microcode_ver = rdmsr(BIOS_SIGN_ID); + + /* Look for string to match the name */ + for (i = 0; i < ARRAY_SIZE(cpu_table); i++) { + if (cpu_table[i].cpuid == cpuidr.eax) { + cpu_type = cpu_table[i].name; + break; + } + } + + printk(BIOS_DEBUG, "CPU: %s\n", cpu_name); + printk(BIOS_DEBUG, "CPU: ID %x, %s, ucode: %08x\n", + cpuidr.eax, cpu_type, microcode_ver.hi); + + aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0; + txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0; + vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0; + printk(BIOS_DEBUG, + "CPU: AES %ssupported, TXT %ssupported, VT %ssupported\n", + mode[aes], mode[txt], mode[vt]); +} + +static void report_mch_info(void) +{ + int i; + pci_devfn_t dev = SA_DEV_ROOT; + uint16_t mchid = get_dev_id(dev); + uint8_t mch_revision = get_dev_revision(dev); + const char *mch_type = "Unknown"; + + for (i = 0; i < ARRAY_SIZE(mch_table); i++) { + if (mch_table[i].mchid == mchid) { + mch_type = mch_table[i].name; + break; + } + } + + printk(BIOS_DEBUG, "MCH: device id %04x (rev %02x) is %s\n", + mchid, mch_revision, mch_type); +} + +static void report_pch_info(void) +{ + int i; + pci_devfn_t dev = PCH_DEV_LPC; + uint16_t lpcid = get_dev_id(dev); + const char *pch_type = "Unknown"; + + for (i = 0; i < ARRAY_SIZE(pch_table); i++) { + if (pch_table[i].lpcid == lpcid) { + pch_type = pch_table[i].name; + break; + } + } + printk(BIOS_DEBUG, "PCH: device id %04x (rev %02x) is %s\n", + lpcid, get_dev_revision(dev), pch_type); +} + +static void report_igd_info(void) +{ + int i; + pci_devfn_t dev = SA_DEV_IGD; + uint16_t igdid = get_dev_id(dev); + const char *igd_type = "Unknown"; + + for (i = 0; i < ARRAY_SIZE(igd_table); i++) { + if (igd_table[i].igdid == igdid) { + igd_type = igd_table[i].name; + break; + } + } + printk(BIOS_DEBUG, "IGD: device id %04x (rev %02x) is %s\n", + igdid, get_dev_revision(dev), igd_type); +} + +void report_platform_info(void) +{ + report_cpu_info(); + report_mch_info(); + report_pch_info(); + report_igd_info(); +} diff --git a/src/soc/intel/icelake/cbmem.c b/src/soc/intel/icelake/cbmem.c new file mode 100644 index 0000000000..4f447773ac --- /dev/null +++ b/src/soc/intel/icelake/cbmem.c @@ -0,0 +1,22 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <cbmem.h> + +void *cbmem_top(void) +{ + /* not implemented yet */ + return (void *) NULL; +} diff --git a/src/soc/intel/icelake/chip.c b/src/soc/intel/icelake/chip.c new file mode 100644 index 0000000000..0fb0b0ecec --- /dev/null +++ b/src/soc/intel/icelake/chip.c @@ -0,0 +1,158 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <chip.h> +#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/chip.h> +#include <intelblocks/itss.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 <string.h> + +#if IS_ENABLED(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_PCI) + return NULL; + + switch (dev->path.pci.devfn) { + case SA_DEVFN_ROOT: return "MCHC"; + case SA_DEVFN_IGD: return "GFX0"; + case PCH_DEVFN_ISH: return "ISHB"; + case PCH_DEVFN_XHCI: return "XHCI"; + case PCH_DEVFN_USBOTG: return "XDCI"; + case PCH_DEVFN_THERMAL: return "THRM"; + 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_CSE: return "CSE1"; + case PCH_DEVFN_CSE_2: return "CSE2"; + case PCH_DEVFN_CSE_IDER: return "CSED"; + case PCH_DEVFN_CSE_KT: return "CSKT"; + case PCH_DEVFN_CSE_3: return "CSE3"; + case PCH_DEVFN_SATA: return "SATA"; + case PCH_DEVFN_UART2: return "UAR2"; + case PCH_DEVFN_I2C4: return "I2C4"; + case PCH_DEVFN_I2C5: return "I2C5"; + 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_PCIE13: return "RP13"; + case PCH_DEVFN_PCIE14: return "RP14"; + case PCH_DEVFN_PCIE15: return "RP15"; + case PCH_DEVFN_PCIE16: return "RP16"; + case PCH_DEVFN_PCIE17: return "RP17"; + case PCH_DEVFN_PCIE18: return "RP18"; + case PCH_DEVFN_PCIE19: return "RP19"; + case PCH_DEVFN_PCIE20: return "RP20"; + case PCH_DEVFN_PCIE21: return "RP21"; + case PCH_DEVFN_PCIE22: return "RP22"; + case PCH_DEVFN_PCIE23: return "RP23"; + case PCH_DEVFN_PCIE24: return "RP24"; + case PCH_DEVFN_UART0: return "UAR0"; + case PCH_DEVFN_UART1: return "UAR1"; + case PCH_DEVFN_GSPI0: return "SPI0"; + case PCH_DEVFN_GSPI1: return "SPI1"; + case PCH_DEVFN_GSPI2: return "SPI2"; + case PCH_DEVFN_EMMC: return "EMMC"; + case PCH_DEVFN_SDCARD: return "SDXC"; + case PCH_DEVFN_LPC: return "LPCB"; + case PCH_DEVFN_P2SB: return "P2SB"; + case PCH_DEVFN_PMC: return "PMC_"; + case PCH_DEVFN_HDA: return "HDAS"; + case PCH_DEVFN_SMBUS: return "SBUS"; + case PCH_DEVFN_SPI: return "FSPI"; + case PCH_DEVFN_GBE: return "IGBE"; + case PCH_DEVFN_TRACEHUB:return "THUB"; + } + + return NULL; +} +#endif + +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); +} + +static void pci_domain_set_resources(struct device *dev) +{ + assign_resources(dev->link_list); +} + +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 IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) + .acpi_name = &soc_acpi_name, + #endif +}; + +static struct device_operations cpu_bus_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, + .enable_resources = DEVICE_NOOP, + .init = DEVICE_NOOP, + .acpi_fill_ssdt_generator = generate_cpu_entries, +}; + +static void soc_enable(struct device *dev) +{ + /* Set the operations if it is a special bus type */ + 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; +} + +struct chip_operations soc_intel_icelake_ops = { + CHIP_NAME("Intel Icelake") + .enable_dev = &soc_enable, + .init = &soc_init_pre_device, +}; diff --git a/src/soc/intel/icelake/chip.h b/src/soc/intel/icelake/chip.h new file mode 100644 index 0000000000..bd31946ba7 --- /dev/null +++ b/src/soc/intel/icelake/chip.h @@ -0,0 +1,268 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_CHIP_H_ +#define _SOC_CHIP_H_ + +#include <intelblocks/chip.h> +#include <drivers/i2c/designware/dw_i2c.h> +#include <intelblocks/gspi.h> +#include <stdint.h> +#include <soc/gpio.h> +#include <soc/pch.h> +#include <soc/gpio_defs.h> +#include <soc/pci_devs.h> +#include <soc/pmc.h> +#include <soc/serialio.h> +#include <soc/usb.h> + +struct soc_intel_icelake_config { + + /* Common struct containing soc config data required by common code */ + struct soc_intel_common_config common_soc_config; + + /* Interrupt Routing configuration. + * If bit7 is 1, the interrupt is disabled. */ + uint8_t pirqa_routing; + uint8_t pirqb_routing; + uint8_t pirqc_routing; + uint8_t pirqd_routing; + uint8_t pirqe_routing; + uint8_t pirqf_routing; + uint8_t pirqg_routing; + uint8_t pirqh_routing; + + /* GPE configuration */ + uint32_t gpe0_en_1; /* GPE0_EN_31_0 */ + uint32_t gpe0_en_2; /* GPE0_EN_63_32 */ + uint32_t gpe0_en_3; /* GPE0_EN_95_64 */ + uint32_t gpe0_en_4; /* GPE0_EN_127_96 / GPE_STD */ + + /* Gpio group routed to each dword of the GPE0 block. Values are + * of the form GPP_[A:G] or GPD. */ + uint8_t gpe0_dw0; /* GPE0_31_0 STS/EN */ + uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */ + uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */ + + /* Generic IO decode ranges */ + uint32_t gen1_dec; + uint32_t gen2_dec; + uint32_t gen3_dec; + uint32_t gen4_dec; + + /* Enable S0iX support */ + int s0ix_enable; + /* Enable DPTF support */ + int dptf_enable; + + /* Deep SX enable for both AC and DC */ + int deep_s3_enable_ac; + int deep_s3_enable_dc; + int deep_s5_enable_ac; + int deep_s5_enable_dc; + + /* Deep Sx Configuration + * DSX_EN_WAKE_PIN - Enable WAKE# pin + * DSX_EN_LAN_WAKE_PIN - Enable LAN_WAKE# pin + * DSX_DIS_AC_PRESENT_PD - Disable pull-down on AC_PRESENT pin */ + uint32_t deep_sx_config; + + /* TCC activation offset */ + uint32_t tcc_offset; + + uint64_t PlatformMemorySize; + uint8_t SmramMask; + uint8_t MrcFastBoot; + uint32_t TsegSize; + uint16_t MmioSize; + + /* DDR Frequency Limit. Maximum Memory Frequency Selections in Mhz. + * Options : 1067, 1333, 1600, 1867, 2133, 2400, 2667, 2933, 0(Auto) */ + uint16_t DdrFreqLimit; + + /* SAGV Low Frequency Selections in Mhz. + * Options : 1067, 1333, 1600, 1867, 2133, 2400, 2667, 2933, 0(Auto) */ + uint16_t FreqSaGvLow; + + /* SAGV Mid Frequency Selections in Mhz. + * Options : 1067, 1333, 1600, 1867, 2133, 2400, 2667, 2933, 0(Auto) */ + uint16_t FreqSaGvMid; + + /* System Agent dynamic frequency support. Only effects ULX/ULT CPUs. + * When enabled memory will be training at two different frequencies. + * 0:Disabled, 1:FixedLow, 2:FixedMid, 3:FixedHigh, 4:Enabled */ + enum { + SaGv_Disabled, + SaGv_FixedLow, + SaGv_FixedMid, + SaGv_FixedHigh, + SaGv_Enabled, + } SaGv; + + + /* Rank Margin Tool. 1:Enable, 0:Disable */ + uint8_t RMT; + + /* USB related */ + struct usb2_port_config usb2_ports[16]; + struct usb3_port_config usb3_ports[10]; + uint8_t SsicPortEnable; + /* Wake Enable Bitmap for USB2 ports */ + uint16_t usb2_wake_enable_bitmap; + /* Wake Enable Bitmap for USB3 ports */ + uint16_t usb3_wake_enable_bitmap; + + /* SATA related */ + uint8_t SataMode; + uint8_t SataSalpSupport; + uint8_t SataPortsEnable[8]; + uint8_t SataPortsDevSlp[8]; + + /* Audio related */ + uint8_t PchHdaEnable; + uint8_t PchHdaDspEnable; + + /* Enable/Disable HD Audio Link. Muxed with SSP0/SSP1/SNDW1 */ + uint8_t PchHdaAudioLinkHda; + uint8_t PchHdaAudioLinkDmic0; + uint8_t PchHdaAudioLinkDmic1; + uint8_t PchHdaAudioLinkSsp0; + uint8_t PchHdaAudioLinkSsp1; + uint8_t PchHdaAudioLinkSsp2; + uint8_t PchHdaAudioLinkSndw1; + uint8_t PchHdaAudioLinkSndw2; + uint8_t PchHdaAudioLinkSndw3; + uint8_t PchHdaAudioLinkSndw4; + + /* PCIe Root Ports */ + uint8_t PcieRpEnable[CONFIG_MAX_ROOT_PORTS]; + /* PCIe output clocks type to Pcie devices. + * 0-23: PCH rootport, 0x70: LAN, 0x80: unspecified but in use, + * 0xFF: not used */ + uint8_t PcieClkSrcUsage[CONFIG_MAX_ROOT_PORTS]; + /* PCIe ClkReq-to-ClkSrc mapping, number of clkreq signal assigned to + * clksrc. */ + uint8_t PcieClkSrcClkReq[CONFIG_MAX_ROOT_PORTS]; + + /* SMBus */ + uint8_t SmbusEnable; + + /* eMMC and SD */ + uint8_t ScsEmmcHs400Enabled; + /* Need to update DLL setting to get Emmc running at HS400 speed */ + uint8_t EmmcHs400DllNeed; + /* 0-39: number of active delay for RX strobe, unit is 125 psec */ + uint8_t EmmcHs400RxStrobeDll1; + /* 0-78: number of active delay for TX data, unit is 125 psec */ + uint8_t EmmcHs400TxDataDll; + + /* Integrated Sensor */ + uint8_t PchIshEnable; + + /* Heci related */ + uint8_t Heci3Enabled; + + /* Gfx related */ + uint8_t IgdDvmt50PreAlloc; + uint8_t InternalGfx; + uint8_t SkipExtGfxScan; + + uint32_t GraphicsConfigPtr; + uint8_t Device4Enable; + + /* GPIO IRQ Select. The valid value is 14 or 15 */ + uint8_t GpioIrqRoute; + /* SCI IRQ Select. The valid value is 9, 10, 11, 20, 21, 22, 23 */ + uint8_t SciIrqSelect; + /* TCO IRQ Select. The valid value is 9, 10, 11, 20, 21, 22, 23 */ + uint8_t TcoIrqSelect; + uint8_t TcoIrqEnable; + + /* HeciEnabled decides the state of Heci1 at end of boot + * Setting to 0 (default) disables Heci1 and hides the device from OS */ + uint8_t HeciEnabled; + /* PL2 Override value in Watts */ + uint32_t tdp_pl2_override; + /* Intel Speed Shift Technology */ + uint8_t speed_shift_enable; + /* Enable VR specific mailbox command + * 00b - no VR specific cmd sent + * 01b - VR mailbox cmd specifically for the MPS IMPV8 VR will be sent + * 10b - VR specific cmd sent for PS4 exit issue + * 11b - Reserved */ + uint8_t SendVrMbxCmd; + + /* Enable/Disable EIST. 1b:Enabled, 0b:Disabled */ + uint8_t eist_enable; + + /* Statically clock gate 8254 PIT. */ + uint8_t clock_gate_8254; + /* Enable C6 DRAM */ + uint8_t enable_c6dram; + /* + * PRMRR size setting with below options + * 0x00100000 - 1MiB + * 0x02000000 - 32MiB and beyond + */ + uint32_t PrmrrSize; + uint8_t PmTimerDisabled; + /* Desired platform debug type. */ + enum { + DebugConsent_Disabled, + DebugConsent_DCI_DBC, + DebugConsent_DCI, + DebugConsent_USB3_DBC, + DebugConsent_XDP, /* XDP/Mipi60 */ + DebugConsent_USB2_DBC, + } DebugConsent; + /* + * SerialIO device mode selection: + * + * Device index: + * PchSerialIoIndexI2C0 + * PchSerialIoIndexI2C1 + * PchSerialIoIndexI2C2 + * PchSerialIoIndexI2C3 + * PchSerialIoIndexI2C4 + * PchSerialIoIndexI2C5 + * PchSerialIoIndexSPI0 + * PchSerialIoIndexSPI1 + * PchSerialIoIndexSPI2 + * PchSerialIoIndexUART0 + * PchSerialIoIndexUART1 + * PchSerialIoIndexUART2 + * + * Mode select: + * PchSerialIoDisabled + * PchSerialIoPci + * PchSerialIoAcpi + * PchSerialIoHidden + */ + uint8_t SerialIoDevMode[PchSerialIoIndexMAX]; + + /* GPIO SD card detect pin */ + unsigned int sdcard_cd_gpio; + + /* Enable Pch iSCLK */ + uint8_t pch_isclk; + + /* Intel VT configuration */ + uint8_t VtdDisable; + uint8_t VmxEnable; +}; + +typedef struct soc_intel_icelake_config config_t; + +#endif diff --git a/src/soc/intel/icelake/cpu.c b/src/soc/intel/icelake/cpu.c new file mode 100644 index 0000000000..bfe9f7beb9 --- /dev/null +++ b/src/soc/intel/icelake/cpu.c @@ -0,0 +1,243 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <device/pci.h> +#include <chip.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/intel/turbo.h> +#include <fsp/api.h> +#include <intelblocks/cpulib.h> +#include <intelblocks/mp_init.h> +#include <intelblocks/smm.h> +#include <romstage_handoff.h> +#include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/smm.h> + +static void soc_fsp_load(void) +{ + fsps_load(romstage_handoff_is_resume()); +} + +static void configure_isst(void) +{ + struct device *dev = SA_DEV_ROOT; + config_t *conf = dev->chip_info; + 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) +{ + struct device *dev = SA_DEV_ROOT; + config_t *conf = dev->chip_info; + msr_t msr; + + msr = rdmsr(IA32_MISC_ENABLE); + msr.lo |= (1 << 0); /* Fast String enable */ + msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */ + if (conf->eist_enable) + cpu_enable_eist(); + else + cpu_disable_eist(); + wrmsr(IA32_MISC_ENABLE, msr); + + /* 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) +{ + struct cpuid_result cpuid_regs; + msr_t msr; + + /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */ + cpuid_regs = cpuid(1); + if (cpuid_regs.ecx & (1 << 18)) { + msr = rdmsr(IA32_PLATFORM_DCA_CAP); + msr.lo |= 1; + wrmsr(IA32_PLATFORM_DCA_CAP, 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); +} + +static void configure_c_states(void) +{ + msr_t msr; + + /* C-state Interrupt Response Latency Control 1 - package C6/C7 short */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_32768_NS | C_STATE_LATENCY_CONTROL_1_LIMIT; + wrmsr(MSR_C_STATE_LATENCY_CONTROL_1, msr); + + /* C-state Interrupt Response Latency Control 2 - package C6/C7 long */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_32768_NS | C_STATE_LATENCY_CONTROL_2_LIMIT; + wrmsr(MSR_C_STATE_LATENCY_CONTROL_2, msr); + + /* C-state Interrupt Response Latency Control 3 - package C8 */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_32768_NS | + C_STATE_LATENCY_CONTROL_3_LIMIT; + wrmsr(MSR_C_STATE_LATENCY_CONTROL_3, msr); + + /* C-state Interrupt Response Latency Control 4 - package C9 */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_32768_NS | + C_STATE_LATENCY_CONTROL_4_LIMIT; + wrmsr(MSR_C_STATE_LATENCY_CONTROL_4, msr); + + /* C-state Interrupt Response Latency Control 5 - package C10 */ + msr.hi = 0; + msr.lo = IRTL_VALID | IRTL_32768_NS | + C_STATE_LATENCY_CONTROL_5_LIMIT; + wrmsr(MSR_C_STATE_LATENCY_CONTROL_5, 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(NULL); + + /* Enable the local CPU apics */ + enable_lapic_tpr(); + setup_lapic(); + + /* Configure c-state interrupt response time */ + configure_c_states(); + + /* Configure Enhanced SpeedStep and Thermal Sensors */ + configure_misc(); + + /* Configure Intel Speed Shift */ + configure_isst(); + + /* 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. + */ + smm_southbridge_enable(PWRBTN_EN | GBL_EN); + + /* Lock down the SMRAM space. */ + smm_lock(); +} + +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"); +} diff --git a/src/soc/intel/icelake/finalize.c b/src/soc/intel/icelake/finalize.c new file mode 100644 index 0000000000..fb78350709 --- /dev/null +++ b/src/soc/intel/icelake/finalize.c @@ -0,0 +1,107 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <bootstate.h> +#include <chip.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 <reg_script.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/systemagent.h> +#include <stdlib.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) +{ + struct device *dev; + uint32_t reg32; + uint16_t tcobase, tcocnt; + uint8_t *pmcbase; + config_t *config; + uint8_t reg8; + + /* TCO Lock down */ + tcobase = smbus_tco_regs(); + tcocnt = inw(tcobase + TCO1_CNT); + tcocnt |= TCO_LOCK; + outw(tcocnt, tcobase + TCO1_CNT); + + /* + * 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 + */ + dev = PCH_DEV_PMC; + config = dev->chip_info; + 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); +} + +static void soc_finalize(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); + + printk(BIOS_DEBUG, "Finalizing SMM.\n"); + outb(APM_CNT_FINALIZE, APM_CNT); + + /* 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/icelake/fsp_params.c b/src/soc/intel/icelake/fsp_params.c new file mode 100644 index 0000000000..513ef0014c --- /dev/null +++ b/src/soc/intel/icelake/fsp_params.c @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <fsp/api.h> +#include <soc/ramstage.h> + +/* UPD parameters to be initialized before SiliconInit */ +void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) +{ + /* ToDo: update with UPD override as FSP matures */ +} + +/* Mainboard GPIO Configuration */ +__weak void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__); +} diff --git a/src/soc/intel/icelake/gpio.c b/src/soc/intel/icelake/gpio.c new file mode 100644 index 0000000000..e965494274 --- /dev/null +++ b/src/soc/intel/icelake/gpio.c @@ -0,0 +1,170 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <intelblocks/gpio.h> +#include <intelblocks/pcr.h> +#include <soc/pcr_ids.h> +#include <soc/pmc.h> + +static const struct reset_mapping rst_map[] = { + { .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 0U << 30 }, + { .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30 }, + { .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30 }, +}; + +static const struct reset_mapping rst_map_com0[] = { + { .logical = PAD_CFG0_LOGICAL_RESET_PWROK, .chipset = 0U << 30 }, + { .logical = PAD_CFG0_LOGICAL_RESET_DEEP, .chipset = 1U << 30 }, + { .logical = PAD_CFG0_LOGICAL_RESET_PLTRST, .chipset = 2U << 30 }, + { .logical = PAD_CFG0_LOGICAL_RESET_RSMRST, .chipset = 3U << 30 }, +}; + +static const struct pad_group icl_community0_groups[] = { + INTEL_GPP(GPP_A0, GPP_A0, GPIO_RSVD_0), /* GPP_A */ + INTEL_GPP(GPP_A0, GPP_B0, GPIO_RSVD_2), /* GPP_B */ + INTEL_GPP(GPP_A0, GPP_G0, GPP_G7), /* GPP_G */ + INTEL_GPP(GPP_A0, GPIO_RSVD_3, GPIO_RSVD_11), /* SPI */ +}; + +static const struct pad_group icl_community1_groups[] = { + INTEL_GPP(GPP_D0, GPP_D0, GPIO_RSVD_12), /* GPP_D */ + INTEL_GPP(GPP_D0, GPP_F0, GPP_F23), /* GPP_F */ + INTEL_GPP(GPP_D0, GPP_H0, GPP_H23), /* GPP_H */ + INTEL_GPP(GPP_D0, GPIO_RSVD_12, GPIO_RSVD_52), /* VGPIO */ +}; + +static const struct pad_group icl_community2_groups[] = { + INTEL_GPP(GPD0, GPD0, GPD11), /* GPD */ +}; + +static const struct pad_group icl_community3_groups[] = { + INTEL_GPP(HDA_BCLK, HDA_BCLK, SSP1_TXD), /* AZA */ + INTEL_GPP(HDA_BCLK, GPIO_RSVD_68, GPIO_RSVD_78), /* CPU */ +}; + +static const struct pad_group icl_community4_groups[] = { + INTEL_GPP(GPP_C0, GPP_C0, GPP_C23), /* GPP_C */ + INTEL_GPP(GPP_C0, GPP_E0, GPP_E23), /* GPP_E */ + INTEL_GPP(GPP_C0, GPIO_RSVD_53, GPIO_RSVD_61), /* JTAG */ + INTEL_GPP(GPP_C0, GPIO_RSVD_62, GPIO_RSVD_67), /* HVMOS */ +}; + +static const struct pad_community icl_communities[] = { + { /* GPP A, B, G, SPI */ + .port = PID_GPIOCOM0, + .first_pad = GPP_A0, + .last_pad = GPIO_RSVD_11, + .num_gpi_regs = NUM_GPIO_COM0_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPP_ABG", + .acpi_path = "\\_SB.PCI0.GPIO", + .reset_map = rst_map_com0, + .num_reset_vals = ARRAY_SIZE(rst_map_com0), + .groups = icl_community0_groups, + .num_groups = ARRAY_SIZE(icl_community0_groups), + }, { /* GPP D, F, H, VGPIO */ + .port = PID_GPIOCOM1, + .first_pad = GPP_D0, + .last_pad = GPIO_RSVD_52, + .num_gpi_regs = NUM_GPIO_COM1_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPP_DFH", + .acpi_path = "\\_SB.PCI0.GPIO", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = icl_community1_groups, + .num_groups = ARRAY_SIZE(icl_community1_groups), + }, { /* GPD */ + .port = PID_GPIOCOM2, + .first_pad = GPD0, + .last_pad = GPD11, + .num_gpi_regs = NUM_GPIO_COM2_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPD", + .acpi_path = "\\_SB.PCI0.GPIO", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = icl_community2_groups, + .num_groups = ARRAY_SIZE(icl_community2_groups), + }, { /* AZA, CPU */ + .port = PID_GPIOCOM3, + .first_pad = HDA_BCLK, + .last_pad = GPIO_RSVD_78, + .num_gpi_regs = NUM_GPIO_COM3_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GP_AC", + .acpi_path = "\\_SB.PCI0.GPIO", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = icl_community3_groups, + .num_groups = ARRAY_SIZE(icl_community3_groups), + }, { /* GPP C, E, JTAG, HVMOS */ + .port = PID_GPIOCOM4, + .first_pad = GPP_C0, + .last_pad = GPIO_RSVD_67, + .num_gpi_regs = NUM_GPIO_COM4_GPI_REGS, + .pad_cfg_base = PAD_CFG_BASE, + .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, + .gpi_smi_en_reg_0 = GPI_SMI_EN_0, + .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, + .name = "GPP_CEJ", + .acpi_path = "\\_SB.PCI0.GPIO", + .reset_map = rst_map, + .num_reset_vals = ARRAY_SIZE(rst_map), + .groups = icl_community4_groups, + .num_groups = ARRAY_SIZE(icl_community4_groups), + } +}; + +const struct pad_community *soc_gpio_get_community(size_t *num_communities) +{ + *num_communities = ARRAY_SIZE(icl_communities); + return icl_communities; +} + +const struct pmc_to_gpio_route *soc_pmc_gpio_routes(size_t *num) +{ + static const struct pmc_to_gpio_route routes[] = { + { PMC_GPP_A, GPP_A }, + { PMC_GPP_B, GPP_B }, + { PMC_GPP_C, GPP_C }, + { PMC_GPP_D, GPP_D }, + { PMC_GPP_E, GPP_E }, + { PMC_GPP_F, GPP_F }, + { PMC_GPP_G, GPP_G }, + { PMC_GPP_H, GPP_H }, + { PMC_GPD, GPD }, + }; + *num = ARRAY_SIZE(routes); + return routes; +} diff --git a/src/soc/intel/icelake/graphics.c b/src/soc/intel/icelake/graphics.c new file mode 100644 index 0000000000..1c22f49a7b --- /dev/null +++ b/src/soc/intel/icelake/graphics.c @@ -0,0 +1,82 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/acpigen.h> +#include <console/console.h> +#include <fsp/util.h> +#include <device/device.h> +#include <device/pci.h> +#include <drivers/intel/gma/i915_reg.h> +#include <drivers/intel/gma/opregion.h> +#include <intelblocks/graphics.h> + +uintptr_t fsp_soc_get_igd_bar(void) +{ + return graphics_get_memory_base(); +} + +void graphics_soc_init(struct device *dev) +{ + uint32_t ddi_buf_ctl; + + /* + * Enable DDI-A (eDP) 4-lane operation if the link is not up yet. + * This will allow the kernel to use 4-lane eDP links properly + * if the VBIOS or GOP driver do not execute. + */ + ddi_buf_ctl = graphics_gtt_read(DDI_BUF_CTL_A); + if (!acpi_is_wakeup_s3() && !(ddi_buf_ctl & DDI_BUF_CTL_ENABLE)) { + ddi_buf_ctl |= (DDI_A_4_LANES | DDI_INIT_DISPLAY_DETECTED | + DDI_BUF_IS_IDLE); + graphics_gtt_write(DDI_BUF_CTL_A, ddi_buf_ctl); + } + + /* + * GFX PEIM module inside FSP binary is taking care of graphics + * initialization based on INTEL_GMA_ADD_VBT Kconfig + * option and input VBT file. Hence no need to load/execute legacy VGA + * OpROM in order to initialize GFX. + * + * In case of non-FSP solution, SoC need to select VGA_ROM_RUN + * Kconfig to perform GFX initialization through VGA OpRom. + */ + if (IS_ENABLED(CONFIG_INTEL_GMA_ADD_VBT)) + return; + + /* IGD needs to Bus Master */ + uint32_t reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; + pci_write_config32(dev, PCI_COMMAND, reg32); + + /* Initialize PCI device, load/execute BIOS Option ROM */ + pci_dev_init(dev); +} + +uintptr_t graphics_soc_write_acpi_opregion(struct device *device, + uintptr_t current, struct acpi_rsdp *rsdp) +{ + igd_opregion_t *opregion; + + printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n"); + opregion = (igd_opregion_t *)current; + + if (intel_gma_init_igd_opregion(opregion) != CB_SUCCESS) + return current; + + current += sizeof(igd_opregion_t); + + return acpi_align_current(current); +} diff --git a/src/soc/intel/icelake/gspi.c b/src/soc/intel/icelake/gspi.c new file mode 100644 index 0000000000..cd5dc8e6bb --- /dev/null +++ b/src/soc/intel/icelake/gspi.c @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#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; + } + return -1; +} diff --git a/src/soc/intel/icelake/i2c.c b/src/soc/intel/icelake/i2c.c new file mode 100644 index 0000000000..2820a85e68 --- /dev/null +++ b/src/soc/intel/icelake/i2c.c @@ -0,0 +1,56 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#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/icelake/include/soc/bootblock.h b/src/soc/intel/icelake/include/soc/bootblock.h new file mode 100644 index 0000000000..2f6473da02 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/bootblock.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_BOOTBLOCK_H_ +#define _SOC_ICELAKE_BOOTBLOCK_H_ + +#include <intelblocks/systemagent.h> + +/* Bootblock pre console init programming */ +void bootblock_cpu_init(void); +void bootblock_pch_early_init(void); + +/* Bootblock post console init programming */ +void pch_early_init(void); +void pch_early_iorange_init(void); +void report_platform_info(void); + +#endif diff --git a/src/soc/intel/icelake/include/soc/cpu.h b/src/soc/intel/icelake/include/soc/cpu.h new file mode 100644 index 0000000000..856d685890 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/cpu.h @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_CPU_H_ +#define _SOC_ICELAKE_CPU_H_ + +#include <arch/cpu.h> +#include <device/device.h> +#include <intelblocks/msr.h> + +/* Latency times in units of 32768ns */ +#define C_STATE_LATENCY_CONTROL_0_LIMIT 0x9d +#define C_STATE_LATENCY_CONTROL_1_LIMIT 0x9d +#define C_STATE_LATENCY_CONTROL_2_LIMIT 0x9d +#define C_STATE_LATENCY_CONTROL_3_LIMIT 0x9d +#define C_STATE_LATENCY_CONTROL_4_LIMIT 0x9d +#define C_STATE_LATENCY_CONTROL_5_LIMIT 0x9d + +/* 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 + +#define C_STATE_LATENCY_MICRO_SECONDS(limit, base) \ + (((1 << ((base)*5)) * (limit)) / 1000) +#define C_STATE_LATENCY_FROM_LAT_REG(reg) \ + C_STATE_LATENCY_MICRO_SECONDS(C_STATE_LATENCY_CONTROL_ ##reg## _LIMIT, \ + (IRTL_1024_NS >> 10)) + +/* Configure power limits for turbo mode */ +void set_power_limits(u8 power_limit_1_time); + +#endif diff --git a/src/soc/intel/icelake/include/soc/ebda.h b/src/soc/intel/icelake/include/soc/ebda.h new file mode 100644 index 0000000000..9c44a50831 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/ebda.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_EBDA_H +#define SOC_EBDA_H + +struct ebda_config { + uint32_t signature; /* 0x00 - EBDA signature */ + uint32_t tolum_base; /* 0x04 - coreboot memory start */ + uint32_t reserved_mem_size; /* 0x08 - chipset reserved memory size */ +}; + +#endif diff --git a/src/soc/intel/icelake/include/soc/gpe.h b/src/soc/intel/icelake/include/soc/gpe.h new file mode 100644 index 0000000000..d946e2af13 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/gpe.h @@ -0,0 +1,134 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_GPE_H_ +#define _SOC_GPE_H_ + +/* GPE_31_0 */ +#define GPE0_DW0_00 0 +#define GPE0_DW0_01 1 +#define GPE0_DW0_02 2 +#define GPE0_DW0_03 3 +#define GPE0_DW0_04 4 +#define GPE0_DW0_05 5 +#define GPE0_DW0_06 6 +#define GPE0_DW0_07 7 +#define GPE0_DW0_08 8 +#define GPE0_DW0_09 9 +#define GPE0_DW0_10 10 +#define GPE0_DW0_11 11 +#define GPE0_DW0_12 12 +#define GPE0_DW0_13 13 +#define GPE0_DW0_14 14 +#define GPE0_DW0_15 15 +#define GPE0_DW0_16 16 +#define GPE0_DW0_17 17 +#define GPE0_DW0_18 18 +#define GPE0_DW0_19 19 +#define GPE0_DW0_20 20 +#define GPE0_DW0_21 21 +#define GPE0_DW0_22 22 +#define GPE0_DW0_23 23 +#define GPE0_DW0_24 24 +#define GPE0_DW0_25 25 +#define GPE0_DW0_26 26 +#define GPE0_DW0_27 27 +#define GPE0_DW0_28 28 +#define GPE0_DW0_29 29 +#define GPE0_DW0_30 30 +#define GPE0_DW0_31 31 +/* GPE_63_32 */ +#define GPE0_DW1_00 32 +#define GPE0_DW1_01 33 +#define GPE0_DW1_02 34 +#define GPE0_DW1_03 36 +#define GPE0_DW1_04 36 +#define GPE0_DW1_05 37 +#define GPE0_DW1_06 38 +#define GPE0_DW1_07 39 +#define GPE0_DW1_08 40 +#define GPE0_DW1_09 41 +#define GPE0_DW1_10 42 +#define GPE0_DW1_11 43 +#define GPE0_DW1_12 44 +#define GPE0_DW1_13 45 +#define GPE0_DW1_14 46 +#define GPE0_DW1_15 47 +#define GPE0_DW1_16 48 +#define GPE0_DW1_17 49 +#define GPE0_DW1_18 50 +#define GPE0_DW1_19 51 +#define GPE0_DW1_20 52 +#define GPE0_DW1_21 53 +#define GPE0_DW1_22 54 +#define GPE0_DW1_23 55 +#define GPE0_DW1_24 56 +#define GPE0_DW1_25 57 +#define GPE0_DW1_26 58 +#define GPE0_DW1_27 59 +#define GPE0_DW1_28 60 +#define GPE0_DW1_29 61 +#define GPE0_DW1_30 62 +#define GPE0_DW1_31 63 +/* GPE_95_64 */ +#define GPE0_DW2_00 64 +#define GPE0_DW2_01 65 +#define GPE0_DW2_02 66 +#define GPE0_DW2_03 67 +#define GPE0_DW2_04 68 +#define GPE0_DW2_05 69 +#define GPE0_DW2_06 70 +#define GPE0_DW2_07 71 +#define GPE0_DW2_08 72 +#define GPE0_DW2_09 73 +#define GPE0_DW2_10 74 +#define GPE0_DW2_11 75 +#define GPE0_DW2_12 76 +#define GPE0_DW2_13 77 +#define GPE0_DW2_14 78 +#define GPE0_DW2_15 79 +#define GPE0_DW2_16 80 +#define GPE0_DW2_17 81 +#define GPE0_DW2_18 82 +#define GPE0_DW2_19 83 +#define GPE0_DW2_20 84 +#define GPE0_DW2_21 85 +#define GPE0_DW2_22 86 +#define GPE0_DW2_23 87 +#define GPE0_DW2_24 88 +#define GPE0_DW2_25 89 +#define GPE0_DW2_26 90 +#define GPE0_DW2_27 91 +#define GPE0_DW2_28 92 +#define GPE0_DW2_29 93 +#define GPE0_DW2_30 94 +#define GPE0_DW2_31 95 +/* GPE_STD */ +#define GPE0_HOT_PLUG 97 +#define GPE0_SWGPE 98 +#define GPE0_TCOSCI 102 +#define GPE0_SMB_WAK 103 +#define GPE0_PCI_EXP 105 +#define GPE0_BATLOW 106 +#define GPE0_PME 107 +#define GPE0_ME_SCI 108 +#define GPE0_PME_B0 109 +#define GPE0_ESPI 110 +#define GPE0_GPIO_T2 111 +#define GPE0_LAN_WAK 112 +#define GPE0_WADT 114 + +#define GPE_MAX GPE0_WADT +#endif /* _SOC_GPE_H_ */ diff --git a/src/soc/intel/icelake/include/soc/gpio.h b/src/soc/intel/icelake/include/soc/gpio.h new file mode 100644 index 0000000000..2e55e74b51 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/gpio.h @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_GPIO_H_ +#define _SOC_ICELAKE_GPIO_H_ + +#include <soc/gpio_defs.h> +#include <intelblocks/gpio.h> + +#define CROS_GPIO_DEVICE_NAME "INT34BB:00" + +#endif diff --git a/src/soc/intel/icelake/include/soc/gpio_defs.h b/src/soc/intel/icelake/include/soc/gpio_defs.h new file mode 100644 index 0000000000..44425f4b2e --- /dev/null +++ b/src/soc/intel/icelake/include/soc/gpio_defs.h @@ -0,0 +1,255 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_GPIO_DEFS_H_ +#define _SOC_ICELAKE_GPIO_DEFS_H_ + +#ifndef __ACPI__ +#include <stddef.h> +#endif +#include <soc/gpio_soc_defs.h> + + +#define GPIO_NUM_PAD_CFG_REGS 4 /* DW0, DW1, DW2, DW3 */ + +#define NUM_GPIO_COMx_GPI_REGS(n) \ + (ALIGN_UP((n), GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP) + +#define NUM_GPIO_COM0_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM0_PADS) +#define NUM_GPIO_COM1_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM1_PADS) +#define NUM_GPIO_COM2_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM2_PADS) +#define NUM_GPIO_COM3_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM3_PADS) +#define NUM_GPIO_COM4_GPI_REGS NUM_GPIO_COMx_GPI_REGS(NUM_GPIO_COM4_PADS) + +#define NUM_GPI_STATUS_REGS \ + ((NUM_GPIO_COM0_GPI_REGS) +\ + (NUM_GPIO_COM1_GPI_REGS) +\ + (NUM_GPIO_COM2_GPI_REGS) +\ + (NUM_GPIO_COM3_GPI_REGS) +\ + (NUM_GPIO_COM4_GPI_REGS)) +/* + * IOxAPIC IRQs for the GPIOs + */ + +/* Group A */ +#define GPP_A0_IRQ 0x18 +#define GPP_A1_IRQ 0x19 +#define GPP_A2_IRQ 0x1a +#define GPP_A3_IRQ 0x1b +#define GPP_A4_IRQ 0x1c +#define GPP_A5_IRQ 0x1d +#define GPP_A6_IRQ 0x1e +#define GPP_A7_IRQ 0x1f +#define GPP_A8_IRQ 0x20 +#define GPP_A9_IRQ 0x21 +#define GPP_A10_IRQ 0x22 +#define GPP_A11_IRQ 0x23 +#define GPP_A12_IRQ 0x24 +#define GPP_A13_IRQ 0x25 +#define GPP_A14_IRQ 0x26 +#define GPP_A15_IRQ 0x27 +#define GPP_A16_IRQ 0x28 +#define GPP_A17_IRQ 0x29 +#define GPP_A18_IRQ 0x2a +#define GPP_A19_IRQ 0x2b +#define GPP_A20_IRQ 0x2c +#define GPP_A21_IRQ 0x2d +#define GPP_A22_IRQ 0x2e +#define GPP_A23_IRQ 0x2f +/* Group B */ +#define GPP_B0_IRQ 0x30 +#define GPP_B1_IRQ 0x31 +#define GPP_B2_IRQ 0x32 +#define GPP_B3_IRQ 0x33 +#define GPP_B4_IRQ 0x34 +#define GPP_B5_IRQ 0x35 +#define GPP_B6_IRQ 0x36 +#define GPP_B7_IRQ 0x37 +#define GPP_B8_IRQ 0x38 +#define GPP_B9_IRQ 0x39 +#define GPP_B10_IRQ 0x3a +#define GPP_B11_IRQ 0x3b +#define GPP_B12_IRQ 0x3c +#define GPP_B13_IRQ 0x3d +#define GPP_B14_IRQ 0x3e +#define GPP_B15_IRQ 0x3f +#define GPP_B16_IRQ 0x40 +#define GPP_B17_IRQ 0x41 +#define GPP_B18_IRQ 0x42 +#define GPP_B19_IRQ 0x43 +#define GPP_B20_IRQ 0x44 +#define GPP_B21_IRQ 0x45 +#define GPP_B22_IRQ 0x46 +#define GPP_B23_IRQ 0x47 +/* Group C */ +#define GPP_C0_IRQ 0x48 +#define GPP_C1_IRQ 0x49 +#define GPP_C2_IRQ 0x4a +#define GPP_C3_IRQ 0x4b +#define GPP_C4_IRQ 0x4c +#define GPP_C5_IRQ 0x4d +#define GPP_C6_IRQ 0x4e +#define GPP_C7_IRQ 0x4f +#define GPP_C8_IRQ 0x50 +#define GPP_C9_IRQ 0x51 +#define GPP_C10_IRQ 0x52 +#define GPP_C11_IRQ 0x53 +#define GPP_C12_IRQ 0x54 +#define GPP_C13_IRQ 0x55 +#define GPP_C14_IRQ 0x56 +#define GPP_C15_IRQ 0x57 +#define GPP_C16_IRQ 0x58 +#define GPP_C17_IRQ 0x59 +#define GPP_C18_IRQ 0x5a +#define GPP_C19_IRQ 0x5b +#define GPP_C20_IRQ 0x5c +#define GPP_C21_IRQ 0x5d +#define GPP_C22_IRQ 0x5e +#define GPP_C23_IRQ 0x5f +/* Group D */ +#define GPP_D0_IRQ 0x60 +#define GPP_D1_IRQ 0x61 +#define GPP_D2_IRQ 0x62 +#define GPP_D3_IRQ 0x63 +#define GPP_D4_IRQ 0x64 +#define GPP_D5_IRQ 0x65 +#define GPP_D6_IRQ 0x66 +#define GPP_D7_IRQ 0x67 +#define GPP_D8_IRQ 0x68 +#define GPP_D9_IRQ 0x69 +#define GPP_D10_IRQ 0x6a +#define GPP_D11_IRQ 0x6b +#define GPP_D12_IRQ 0x6c +#define GPP_D13_IRQ 0x6d +#define GPP_D14_IRQ 0x6e +#define GPP_D15_IRQ 0x6f +#define GPP_D16_IRQ 0x70 +#define GPP_D17_IRQ 0x71 +#define GPP_D18_IRQ 0x72 +#define GPP_D19_IRQ 0x73 +#define GPP_D20_IRQ 0x74 +#define GPP_D21_IRQ 0x75 +#define GPP_D22_IRQ 0x76 +#define GPP_D23_IRQ 0x77 +/* Group E */ +#define GPP_E0_IRQ 0x18 +#define GPP_E1_IRQ 0x19 +#define GPP_E2_IRQ 0x1a +#define GPP_E3_IRQ 0x1b +#define GPP_E4_IRQ 0x1c +#define GPP_E5_IRQ 0x1d +#define GPP_E6_IRQ 0x1e +#define GPP_E7_IRQ 0x1f +#define GPP_E8_IRQ 0x20 +#define GPP_E9_IRQ 0x21 +#define GPP_E10_IRQ 0x22 +#define GPP_E11_IRQ 0x23 +#define GPP_E12_IRQ 0x24 +#define GPP_E13_IRQ 0x25 +#define GPP_E14_IRQ 0x26 +#define GPP_E15_IRQ 0x27 +#define GPP_E16_IRQ 0x28 +#define GPP_E17_IRQ 0x29 +#define GPP_E18_IRQ 0x2a +#define GPP_E19_IRQ 0x2b +#define GPP_E20_IRQ 0x2c +#define GPP_E21_IRQ 0x2d +#define GPP_E22_IRQ 0x2e +#define GPP_E23_IRQ 0x2f +/* Group F */ +#define GPP_F0_IRQ 0x30 +#define GPP_F1_IRQ 0x31 +#define GPP_F2_IRQ 0x32 +#define GPP_F3_IRQ 0x33 +#define GPP_F4_IRQ 0x34 +#define GPP_F5_IRQ 0x35 +#define GPP_F6_IRQ 0x36 +#define GPP_F7_IRQ 0x37 +#define GPP_F8_IRQ 0x38 +#define GPP_F9_IRQ 0x39 +#define GPP_F10_IRQ 0x3a +#define GPP_F11_IRQ 0x3b +#define GPP_F12_IRQ 0x3c +#define GPP_F13_IRQ 0x3d +#define GPP_F14_IRQ 0x3e +#define GPP_F15_IRQ 0x3f +#define GPP_F16_IRQ 0x40 +#define GPP_F17_IRQ 0x41 +#define GPP_F18_IRQ 0x42 +#define GPP_F19_IRQ 0x43 +#define GPP_F20_IRQ 0x44 +#define GPP_F21_IRQ 0x45 +#define GPP_F22_IRQ 0x46 +#define GPP_F23_IRQ 0x47 +/* Group G */ +#define GPP_G0_IRQ 0x6c +#define GPP_G1_IRQ 0x6d +#define GPP_G2_IRQ 0x6e +#define GPP_G3_IRQ 0x6f +#define GPP_G4_IRQ 0x70 +#define GPP_G5_IRQ 0x71 +#define GPP_G6_IRQ 0x72 +#define GPP_G7_IRQ 0x73 +/* Group GPD */ +#define GPD0_IRQ 0x60 +#define GPD1_IRQ 0x61 +#define GPD2_IRQ 0x62 +#define GPD3_IRQ 0x63 +#define GPD4_IRQ 0x64 +#define GPD5_IRQ 0x65 +#define GPD6_IRQ 0x66 +#define GPD7_IRQ 0x67 +#define GPD8_IRQ 0x68 +#define GPD9_IRQ 0x69 +#define GPD10_IRQ 0x6a +#define GPD11_IRQ 0x6b +/* Group H */ +#define GPP_H0_IRQ 0x48 +#define GPP_H1_IRQ 0x49 +#define GPP_H2_IRQ 0x4a +#define GPP_H3_IRQ 0x4b +#define GPP_H4_IRQ 0x4c +#define GPP_H5_IRQ 0x4d +#define GPP_H6_IRQ 0x4e +#define GPP_H7_IRQ 0x4f +#define GPP_H8_IRQ 0x50 +#define GPP_H9_IRQ 0x51 +#define GPP_H10_IRQ 0x52 +#define GPP_H11_IRQ 0x53 +#define GPP_H12_IRQ 0x54 +#define GPP_H13_IRQ 0x55 +#define GPP_H14_IRQ 0x56 +#define GPP_H15_IRQ 0x57 +#define GPP_H16_IRQ 0x58 +#define GPP_H17_IRQ 0x59 +#define GPP_H18_IRQ 0x5a +#define GPP_H19_IRQ 0x5b +#define GPP_H20_IRQ 0x5c +#define GPP_H21_IRQ 0x5d +#define GPP_H22_IRQ 0x5e +#define GPP_H23_IRQ 0x5f + +/* Register defines. */ +#define GPIO_MISCCFG 0x10 +#define GPE_DW_SHIFT 8 +#define GPE_DW_MASK 0xfff00 +#define HOSTSW_OWN_REG_0 0xb0 +#define GPI_SMI_STS_0 0x180 +#define GPI_SMI_EN_0 0x1A0 +#define PAD_CFG_BASE 0x600 + +#define GPIORXSTATE_MASK 0x1 +#define GPIORXSTATE_SHIFT 1 +#endif diff --git a/src/soc/intel/icelake/include/soc/gpio_soc_defs.h b/src/soc/intel/icelake/include/soc/gpio_soc_defs.h new file mode 100644 index 0000000000..34216bc307 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/gpio_soc_defs.h @@ -0,0 +1,354 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_GPIO_SOC_DEFS_H_ +#define _SOC_ICELAKE_GPIO_SOC_DEFS_H_ + +/* + * Most of the fixed numbers and macros are based on the GPP groups. + * The GPIO groups are accessed through register blocks called + * communities. + */ +#define GPP_A 0 +#define GPP_B 1 +#define GPP_G 2 +#define GROUP_SPI 3 +#define GPP_D 4 +#define GPP_F 5 +#define GPP_H 6 +#define GROUP_VGPIO 7 +#define GPD 9 +#define GROUP_AZA 0xA +#define GROUP_CPU 0xB +#define GPP_C 0xC +#define GPP_E 0xD +#define GROUP_JTAG 0xE +#define GROUP_HVMOS 0xF + +#define GPIO_NUM_GROUPS 15 +#define GPIO_MAX_NUM_PER_GROUP 24 + +/* + * GPIOs are ordered monotonically increasing to match ACPI/OS driver. + */ + +/* Group A */ +#define GPP_A0 0 +#define GPP_A1 1 +#define GPP_A2 2 +#define GPP_A3 3 +#define GPP_A4 4 +#define GPP_A5 5 +#define GPP_A6 6 +#define GPP_A7 7 +#define GPP_A8 8 +#define GPP_A9 9 +#define GPP_A10 10 +#define GPP_A11 11 +#define GPP_A12 12 +#define GPP_A13 13 +#define GPP_A14 14 +#define GPP_A15 15 +#define GPP_A16 16 +#define GPP_A17 17 +#define GPP_A18 18 +#define GPP_A19 19 +#define GPP_A20 20 +#define GPP_A21 21 +#define GPP_A22 22 +#define GPP_A23 23 +#define GPIO_RSVD_0 24 +/* Group B */ +#define GPP_B0 25 +#define GPP_B1 26 +#define GPP_B2 27 +#define GPP_B3 28 +#define GPP_B4 29 +#define GPP_B5 30 +#define GPP_B6 31 +#define GPP_B7 32 +#define GPP_B8 33 +#define GPP_B9 34 +#define GPP_B10 35 +#define GPP_B11 36 +#define GPP_B12 37 +#define GPP_B13 38 +#define GPP_B14 39 +#define GPP_B15 40 +#define GPP_B16 41 +#define GPP_B17 42 +#define GPP_B18 43 +#define GPP_B19 44 +#define GPP_B20 45 +#define GPP_B21 46 +#define GPP_B22 47 +#define GPP_B23 48 +#define GPIO_RSVD_1 49 +#define GPIO_RSVD_2 50 +/* Group G */ +#define GPP_G0 51 +#define GPP_G1 52 +#define GPP_G2 53 +#define GPP_G3 54 +#define GPP_G4 55 +#define GPP_G5 56 +#define GPP_G6 57 +#define GPP_G7 58 +/* Group SPI */ +#define GPIO_RSVD_3 59 +#define GPIO_RSVD_4 60 +#define GPIO_RSVD_5 61 +#define GPIO_RSVD_6 62 +#define GPIO_RSVD_7 63 +#define GPIO_RSVD_8 64 +#define GPIO_RSVD_9 65 +#define GPIO_RSVD_10 66 +#define GPIO_RSVD_11 67 + +#define NUM_GPIO_COM0_PADS (GPIO_RSVD_11 - GPP_A0 + 1) + +/* Group D */ +#define GPP_D0 68 +#define GPP_D1 69 +#define GPP_D2 70 +#define GPP_D3 71 +#define GPP_D4 72 +#define GPP_D5 73 +#define GPP_D6 74 +#define GPP_D7 75 +#define GPP_D8 76 +#define GPP_D9 77 +#define GPP_D10 78 +#define GPP_D11 79 +#define GPP_D12 80 +#define GPP_D13 81 +#define GPP_D14 82 +#define GPP_D15 83 +#define GPP_D16 84 +#define GPP_D17 85 +#define GPP_D18 86 +#define GPP_D19 87 +#define GPP_D20 88 +#define GPP_D21 89 +#define GPP_D22 90 +#define GPP_D23 91 +#define GPIO_RSVD_12 92 +/* Group F */ +#define GPP_F0 93 +#define GPP_F1 94 +#define GPP_F2 95 +#define GPP_F3 96 +#define GPP_F4 97 +#define GPP_F5 98 +#define GPP_F6 99 +#define GPP_F7 100 +#define GPP_F8 101 +#define GPP_F9 102 +#define GPP_F10 103 +#define GPP_F11 104 +#define GPP_F12 105 +#define GPP_F13 106 +#define GPP_F14 107 +#define GPP_F15 108 +#define GPP_F16 109 +#define GPP_F17 110 +#define GPP_F18 111 +#define GPP_F19 112 +#define GPP_F20 113 +#define GPP_F21 114 +#define GPP_F22 115 +#define GPP_F23 116 +/* Group H */ +#define GPP_H0 117 +#define GPP_H1 118 +#define GPP_H2 119 +#define GPP_H3 120 +#define GPP_H4 121 +#define GPP_H5 122 +#define GPP_H6 123 +#define GPP_H7 124 +#define GPP_H8 125 +#define GPP_H9 126 +#define GPP_H10 127 +#define GPP_H11 128 +#define GPP_H12 129 +#define GPP_H13 130 +#define GPP_H14 131 +#define GPP_H15 132 +#define GPP_H16 133 +#define GPP_H17 134 +#define GPP_H18 135 +#define GPP_H19 136 +#define GPP_H20 137 +#define GPP_H21 138 +#define GPP_H22 139 +#define GPP_H23 140 +/* Group VGOIO */ +#define GPIO_RSVD_13 141 +#define GPIO_RSVD_14 142 +#define GPIO_RSVD_15 143 +#define GPIO_RSVD_16 144 +#define GPIO_RSVD_17 145 +#define GPIO_RSVD_18 146 +#define GPIO_RSVD_19 147 +#define GPIO_RSVD_20 148 +#define GPIO_RSVD_21 149 +#define GPIO_RSVD_22 150 +#define GPIO_RSVD_23 151 +#define GPIO_RSVD_24 152 +#define GPIO_RSVD_25 153 +#define GPIO_RSVD_26 154 +#define GPIO_RSVD_27 155 +#define GPIO_RSVD_28 156 +#define GPIO_RSVD_29 157 +#define GPIO_RSVD_30 158 +#define GPIO_RSVD_31 159 +#define GPIO_RSVD_32 160 +#define GPIO_RSVD_33 161 +#define GPIO_RSVD_34 162 +#define GPIO_RSVD_35 163 +#define GPIO_RSVD_36 164 +#define GPIO_RSVD_37 165 +#define GPIO_RSVD_38 166 +#define GPIO_RSVD_39 167 +#define GPIO_RSVD_40 168 +#define GPIO_RSVD_41 169 +#define GPIO_RSVD_42 170 +#define GPIO_RSVD_43 171 +#define GPIO_RSVD_44 172 +#define GPIO_RSVD_45 173 +#define GPIO_RSVD_46 174 +#define GPIO_RSVD_47 175 +#define GPIO_RSVD_48 176 +#define GPIO_RSVD_49 177 +#define GPIO_RSVD_50 178 +#define GPIO_RSVD_51 179 +#define GPIO_RSVD_52 180 + +#define NUM_GPIO_COM1_PADS (GPIO_RSVD_52 - GPP_D0 + 1) + +/* Group C */ +#define GPP_C0 181 +#define GPP_C1 182 +#define GPP_C2 183 +#define GPP_C3 184 +#define GPP_C4 185 +#define GPP_C5 186 +#define GPP_C6 187 +#define GPP_C7 188 +#define GPP_C8 189 +#define GPP_C9 190 +#define GPP_C10 191 +#define GPP_C11 192 +#define GPP_C12 193 +#define GPP_C13 194 +#define GPP_C14 195 +#define GPP_C15 196 +#define GPP_C16 197 +#define GPP_C17 198 +#define GPP_C18 199 +#define GPP_C19 200 +#define GPP_C20 201 +#define GPP_C21 202 +#define GPP_C22 203 +#define GPP_C23 204 +/* Group E */ +#define GPP_E0 205 +#define GPP_E1 206 +#define GPP_E2 207 +#define GPP_E3 208 +#define GPP_E4 209 +#define GPP_E5 210 +#define GPP_E6 211 +#define GPP_E7 212 +#define GPP_E8 213 +#define GPP_E9 214 +#define GPP_E10 215 +#define GPP_E11 216 +#define GPP_E12 217 +#define GPP_E13 218 +#define GPP_E14 219 +#define GPP_E15 220 +#define GPP_E16 221 +#define GPP_E17 222 +#define GPP_E18 223 +#define GPP_E19 224 +#define GPP_E20 225 +#define GPP_E21 226 +#define GPP_E22 227 +#define GPP_E23 228 +/* Group Jtag */ +#define GPIO_RSVD_53 229 +#define GPIO_RSVD_54 230 +#define GPIO_RSVD_55 231 +#define GPIO_RSVD_56 232 +#define GPIO_RSVD_57 233 +#define GPIO_RSVD_58 234 +#define GPIO_RSVD_59 235 +#define GPIO_RSVD_60 236 +#define GPIO_RSVD_61 237 +/* Group HVMOS */ +#define GPIO_RSVD_62 238 +#define GPIO_RSVD_63 239 +#define GPIO_RSVD_64 240 +#define GPIO_RSVD_65 241 +#define GPIO_RSVD_66 242 +#define GPIO_RSVD_67 243 + +#define NUM_GPIO_COM4_PADS (GPIO_RSVD_67 - GPP_C0 + 1) + +/* Group GPD */ +#define GPD0 244 +#define GPD1 245 +#define GPD2 246 +#define GPD3 247 +#define GPD4 248 +#define GPD5 249 +#define GPD6 250 +#define GPD7 251 +#define GPD8 252 +#define GPD9 253 +#define GPD10 254 +#define GPD11 255 + +#define NUM_GPIO_COM2_PADS (GPD11 - GPD0 + 1) + + +/* Group AZA */ +#define HDA_BCLK 256 +#define HDA_RSTB 257 +#define HDA_SYNC 258 +#define HDA_SDO 259 +#define HDA_SDI_0 260 +#define HDA_SDI_1 261 +#define SSP1_SFRM 262 +#define SSP1_TXD 263 +/* Group CPU */ +#define GPIO_RSVD_68 264 +#define GPIO_RSVD_69 265 +#define GPIO_RSVD_70 266 +#define GPIO_RSVD_71 267 +#define GPIO_RSVD_72 268 +#define GPIO_RSVD_73 269 +#define GPIO_RSVD_74 270 +#define GPIO_RSVD_75 271 +#define GPIO_RSVD_76 272 +#define GPIO_RSVD_77 273 +#define GPIO_RSVD_78 274 + +#define NUM_GPIO_COM3_PADS (GPIO_RSVD_78 - HDA_BCLK + 1) + +#define TOTAL_PADS 275 +#endif diff --git a/src/soc/intel/icelake/include/soc/iomap.h b/src/soc/intel/icelake/include/soc/iomap.h new file mode 100644 index 0000000000..7c42b57730 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/iomap.h @@ -0,0 +1,86 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_IOMAP_H_ +#define _SOC_ICELAKE_IOMAP_H_ + +/* + * Memory-mapped I/O registers. + */ +#define MCFG_BASE_ADDRESS CONFIG_MMCONF_BASE_ADDRESS +#define MCFG_BASE_SIZE 0x4000000 + +#define PCH_PRESERVED_BASE_ADDRESS 0xfc800000 +#define PCH_PRESERVED_BASE_SIZE 0x02000000 + +#define PCH_TRACE_HUB_BASE_ADDRESS 0xfc800000 +#define PCH_TRACE_HUB_BASE_SIZE 0x00800000 + +#define UART_BASE_SIZE 0x1000 + +#define UART_BASE_0_ADDRESS 0xfe032000 +/* Both UART BAR 0 and 1 are 4KB in size */ +#define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ + UART_BASE_SIZE * (x))) +#define UART_BASE(x) UART_BASE_0_ADDR(x) + +#define EARLY_I2C_BASE_ADDRESS 0xfe040000 +#define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) + +#define MCH_BASE_ADDRESS 0xfed10000 +#define MCH_BASE_SIZE 0x8000 + +#define DMI_BASE_ADDRESS 0xfeda0000 +#define DMI_BASE_SIZE 0x1000 + +#define EP_BASE_ADDRESS 0xfeda1000 +#define EP_BASE_SIZE 0x1000 + +#define EDRAM_BASE_ADDRESS 0xfed80000 +#define EDRAM_BASE_SIZE 0x4000 + +#define REG_BASE_ADDRESS 0xfc000000 +#define REG_BASE_SIZE 0x1000 + +#define HPET_BASE_ADDRESS 0xfed00000 + +#define PCH_PWRM_BASE_ADDRESS 0xfe000000 +#define PCH_PWRM_BASE_SIZE 0x10000 + +#define SPI_BASE_ADDRESS 0xfe010000 +#define EARLY_GSPI_BASE_ADDRESS 0xfe011000 + +#define GPIO_BASE_SIZE 0x10000 + +#define HECI1_BASE_ADDRESS 0xfeda2000 + +#define VTD_BASE_ADDRESS 0xFED90000 +#define VTD_BASE_SIZE 0x00004000 +/* + * I/O port address space + */ +#define SMBUS_BASE_ADDRESS 0x0efa0 +#define SMBUS_BASE_SIZE 0x20 + +#define ACPI_BASE_ADDRESS 0x1800 +#define ACPI_BASE_SIZE 0x100 + +#define TCO_BASE_ADDRESS 0x400 +#define TCO_BASE_SIZE 0x20 + +#define P2SB_BAR CONFIG_PCR_BASE_ADDRESS +#define P2SB_SIZE (16 * MiB) + +#endif diff --git a/src/soc/intel/icelake/include/soc/irq.h b/src/soc/intel/icelake/include/soc/irq.h new file mode 100644 index 0000000000..2f980ff472 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/irq.h @@ -0,0 +1,106 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#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 SCI_IRQ9 9 +#define SCI_IRQ10 10 +#define SCI_IRQ11 11 +#define SCI_IRQ20 20 +#define SCI_IRQ21 21 +#define SCI_IRQ22 22 +#define SCI_IRQ23 23 + +#define TCO_IRQ9 9 +#define TCO_IRQ10 10 +#define TCO_IRQ11 11 +#define TCO_IRQ20 20 +#define TCO_IRQ21 21 +#define TCO_IRQ22 22 +#define TCO_IRQ23 23 + +#define LPSS_I2C0_IRQ 16 +#define LPSS_I2C1_IRQ 17 +#define LPSS_I2C2_IRQ 18 +#define LPSS_I2C3_IRQ 19 +#define LPSS_I2C4_IRQ 32 +#define LPSS_I2C5_IRQ 33 +#define LPSS_SPI0_IRQ 22 +#define LPSS_SPI1_IRQ 23 +#define LPSS_SPI2_IRQ 24 +#define LPSS_UART0_IRQ 20 +#define LPSS_UART1_IRQ 21 +#define LPSS_UART2_IRQ 34 +#define SDIO_IRQ 22 + +#define cAVS_INTA_IRQ 16 +#define SMBUS_INTA_IRQ 16 +#define SMBUS_INTB_IRQ 17 +#define GbE_INTA_IRQ 16 +#define GbE_INTC_IRQ 18 +#define TRACE_HUB_INTA_IRQ 16 +#define TRACE_HUB_INTD_IRQ 19 + +#define eMMC_IRQ 16 +#define SD_IRQ 19 + +#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 HECI_1_IRQ 16 +#define HECI_2_IRQ 17 +#define IDER_IRQ 18 +#define KT_IRQ 19 +#define HECI_3_IRQ 16 + +#define XHCI_IRQ 16 +#define OTG_IRQ 17 +#define PMC_SRAM_IRQ 18 +#define THERMAL_IRQ 16 +#define CNViWIFI_IRQ 19 +#define UFS_IRQ 16 +#define CIO_INTA_IRQ 16 +#define CIO_INTD_IRQ 19 +#define ISH_IRQ 20 + +#define PEG_RP_INTA_IRQ 16 +#define PEG_RP_INTB_IRQ 17 +#define PEG_RP_INTC_IRQ 18 +#define PEG_RP_INTD_IRQ 19 + +#define IGFX_IRQ 16 +#define SA_THERMAL_IRQ 16 +#define IPU_IRQ 16 +#define GNA_IRQ 16 +#endif /* _SOC_IRQ_H_ */ diff --git a/src/soc/intel/icelake/include/soc/itss.h b/src/soc/intel/icelake/include/soc/itss.h new file mode 100644 index 0000000000..d846ce099e --- /dev/null +++ b/src/soc/intel/icelake/include/soc/itss.h @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_INTEL_ICL_ITSS_H +#define SOC_INTEL_ICL_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_ICL_ITSS_H */ diff --git a/src/soc/intel/icelake/include/soc/lpc.h b/src/soc/intel/icelake/include/soc/lpc.h new file mode 100644 index 0000000000..df781be54d --- /dev/null +++ b/src/soc/intel/icelake/include/soc/lpc.h @@ -0,0 +1,66 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_LPC_H_ +#define _SOC_ICELAKE_LPC_H_ + +/* PCI Configuration Space (D31:F0): LPC */ +#define SCI_IRQ_SEL (7 << 0) +#define SCIS_IRQ9 0 +#define SCIS_IRQ10 1 +#define SCIS_IRQ11 2 +#define SCIS_IRQ20 4 +#define SCIS_IRQ21 5 +#define SCIS_IRQ22 6 +#define SCIS_IRQ23 7 +#define SERIRQ_CNTL 0x64 +#define LPC_IO_DEC 0x80 /* IO Decode Ranges Register */ +#define COMA_RANGE 0x0 /* 0x3F8 - 0x3FF COM1*/ +#define COMB_RANGE 0x1 /* 0x2F8 - 0x2FF COM2*/ +#define LPC_EN 0x82 /* LPC IF Enables Register */ +#define MC2_LPC_EN (1 << 13) /* 0x4e/0x4f */ +#define SE_LPC_EN (1 << 12) /* 0x2e/0x2f */ +#define MC1_LPC_EN (1 << 11) /* 0x62/0x66 */ +#define KBC_LPC_EN (1 << 10) /* 0x60/0x64 */ +#define GAMEH_LPC_EN (1 << 9) /* 0x208/0x20f */ +#define GAMEL_LPC_EN (1 << 8) /* 0x200/0x207 */ +#define FDD_LPC_EN (1 << 3) /* Floppy Drive Enable */ +#define LPT_LPC_EN (1 << 2) /* Parallel Port Enable */ +#define COMB_LPC_EN (1 << 1) /* Com Port B Enable */ +#define COMA_LPC_EN (1 << 0) /* Com Port A Enable */ +#define LPC_GEN1_DEC 0x84 /* LPC IF Generic Decode Range 1 */ +#define LPC_GEN2_DEC 0x88 /* LPC IF Generic Decode Range 2 */ +#define LPC_GEN3_DEC 0x8c /* LPC IF Generic Decode Range 3 */ +#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */ +#define LGMR 0x98 /* LPC Generic Memory Range */ +#define BIOS_CNTL 0xdc +#define LPC_BC_BILD (1 << 7) /* BILD */ +#define LPC_BC_LE (1 << 1) /* LE */ +#define LPC_BC_EISS (1 << 5) /* EISS */ +#define PCCTL 0xE0 /* PCI Clock Control */ +#define CLKRUN_EN (1 << 0) + +/* + * This function will help to differentiate between 2 PCH on single type of soc. + * Since same soc may have LP series pch or H series PCH, we need to + * differentiate by reading upper 8 bits of PCH device ids. + * + * Return: + * Return PCH_LP or PCH_H macro in case of respective device ID found. + * PCH_UNKNOWN_SERIES in case of invalid device ID. + */ +uint8_t get_pch_series(void); + +#endif diff --git a/src/soc/intel/icelake/include/soc/msr.h b/src/soc/intel/icelake/include/soc/msr.h new file mode 100644 index 0000000000..2aa79af3d7 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/msr.h @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_MSR_H_ +#define _SOC_MSR_H_ + +#include <intelblocks/msr.h> + +#define MSR_PIC_MSG_CONTROL 0x2e +#define MSR_VR_MISC_CONFIG2 0x636 + +#endif diff --git a/src/soc/intel/icelake/include/soc/nvs.h b/src/soc/intel/icelake/include/soc/nvs.h new file mode 100644 index 0000000000..b2d903a4f5 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/nvs.h @@ -0,0 +1,49 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_NVS_H_ +#define _SOC_NVS_H_ + +#include <commonlib/helpers.h> +#include <vendorcode/google/chromeos/gnvs.h> + +typedef struct global_nvs_t { + /* Miscellaneous */ + u16 osys; /* 0x00 - 0x01 Operating System */ + u8 smif; /* 0x02 - SMI function call ("TRAP") */ + u8 pcnt; /* 0x03 - Processor Count */ + u8 ppcm; /* 0x04 - Max PPC State */ + u8 tlvl; /* 0x05 - Throttle Level Limit */ + u8 lids; /* 0x06 - LID State */ + u8 pwrs; /* 0x07 - AC Power State */ + u32 cbmc; /* 0x08 - 0xb AC Power State */ + u64 pm1i; /* 0x0c - 0x13 PM1 wake status bit */ + u64 gpei; /* 0x14 - 0x1b GPE wake status bit */ + u8 dpte; /* 0x1c - Enable DPTF */ + u64 nhla; /* 0x1d - 0x24 NHLT Address */ + u32 nhll; /* 0x25 - 0x28 NHLT Length */ + u16 cid1; /* 0x29 - 0x2a Wifi Country Identifier */ + u16 u2we; /* 0x2b - 0x2c USB2 Wake Enable Bitmap */ + u16 u3we; /* 0x2d - 0x2e USB3 Wake Enable Bitmap */ + u8 uior; /* 0x2f - UART debug controller init on S3 resume */ + u8 unused[208]; + + /* ChromeOS specific (0x100 - 0xfff) */ + chromeos_acpi_t chromeos; +} __packed global_nvs_t; +check_member(global_nvs_t, chromeos, GNVS_CHROMEOS_ACPI_OFFSET); + + +#endif diff --git a/src/soc/intel/icelake/include/soc/p2sb.h b/src/soc/intel/icelake/include/soc/p2sb.h new file mode 100644 index 0000000000..253b54ce11 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/p2sb.h @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_P2SB_H_ +#define _SOC_ICELAKE_P2SB_H_ + +#define HPTC_OFFSET 0x60 +#define HPTC_ADDR_ENABLE_BIT (1 << 7) + +#define PCH_P2SB_EPMASK0 0x220 + +#endif diff --git a/src/soc/intel/icelake/include/soc/pch.h b/src/soc/intel/icelake/include/soc/pch.h new file mode 100644 index 0000000000..d5478d26e9 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/pch.h @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_PCH_H_ +#define _SOC_ICELAKE_PCH_H_ + +#include <stdint.h> + +#define PCH_H 1 +#define PCH_LP 2 +#define PCH_UNKNOWN_SERIES 0xFF + +#define PCIE_CLK_NOTUSED 0xFF +#define PCIE_CLK_LAN 0x70 +#define PCIE_CLK_FREE 0x80 + +void pch_log_state(void); + +#endif diff --git a/src/soc/intel/icelake/include/soc/pci_devs.h b/src/soc/intel/icelake/include/soc/pci_devs.h new file mode 100644 index 0000000000..9b9e4345b8 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/pci_devs.h @@ -0,0 +1,195 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_PCI_DEVS_H_ +#define _SOC_ICELAKE_PCI_DEVS_H_ + +#include <device/pci_def.h> +#include <rules.h> + +#define _SA_DEVFN(slot) PCI_DEVFN(SA_DEV_SLOT_ ## slot, 0) +#define _PCH_DEVFN(slot, func) PCI_DEVFN(PCH_DEV_SLOT_ ## slot, func) + +#if !defined(__SIMPLE_DEVICE__) +#include <device/device.h> +#include <device/pci_def.h> +#define _SA_DEV(slot) dev_find_slot(0, _SA_DEVFN(slot)) +#define _PCH_DEV(slot, func) dev_find_slot(0, _PCH_DEVFN(slot, func)) +#else +#include <arch/io.h> +#define _SA_DEV(slot) PCI_DEV(0, SA_DEV_SLOT_ ## slot, 0) +#define _PCH_DEV(slot, func) PCI_DEV(0, PCH_DEV_SLOT_ ## slot, func) +#endif + +/* System Agent Devices */ + +#define SA_DEV_SLOT_ROOT 0x00 +#define SA_DEVFN_ROOT _SA_DEVFN(ROOT) +#define SA_DEV_ROOT _SA_DEV(ROOT) + +#define SA_DEV_SLOT_IGD 0x02 +#define SA_DEVFN_IGD _SA_DEVFN(IGD) +#define SA_DEV_IGD _SA_DEV(IGD) + +#define SA_DEV_SLOT_DSP 0x04 +#define SA_DEVFN_DSP _SA_DEVFN(DSP) +#define SA_DEV_DSP _SA_DEV(DSP) + +/* PCH Devices */ +#define PCH_DEV_SLOT_THERMAL 0x12 +#define PCH_DEVFN_THERMAL _PCH_DEVFN(THERMAL, 0) +#define PCH_DEVFN_UFS _PCH_DEVFN(THERMAL, 5) +#define PCH_DEVFN_GSPI2 _PCH_DEVFN(THERMAL, 6) +#define PCH_DEV_THERMAL _PCH_DEV(THERMAL, 0) +#define PCH_DEV_UFS _PCH_DEV(THERMAL, 5) +#define PCH_DEV_GSPI2 _PCH_DEV(THERMAL, 6) + +#define PCH_DEV_SLOT_ISH 0x13 +#define PCH_DEVFN_ISH _PCH_DEVFN(ISH, 0) +#define PCH_DEV_ISH _PCH_DEV(ISH, 0) + +#define PCH_DEV_SLOT_XHCI 0x14 +#define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0) +#define PCH_DEVFN_USBOTG _PCH_DEVFN(XHCI, 1) +#define PCH_DEVFN_CNViWIFI _PCH_DEVFN(XHCI, 3) +#define PCH_DEVFN_SDCARD _PCH_DEVFN(XHCI, 5) +#define PCH_DEV_XHCI _PCH_DEV(XHCI, 0) +#define PCH_DEV_USBOTG _PCH_DEV(XHCI, 1) +#define PCH_DEV_CNViWIFI _PCH_DEV(XHCI, 3) +#define PCH_DEV_SDCARD _PCH_DEV(XHCI, 5) + +#define PCH_DEV_SLOT_SIO1 0x15 +#define PCH_DEVFN_I2C0 _PCH_DEVFN(SIO1, 0) +#define PCH_DEVFN_I2C1 _PCH_DEVFN(SIO1, 1) +#define PCH_DEVFN_I2C2 _PCH_DEVFN(SIO1, 2) +#define PCH_DEVFN_I2C3 _PCH_DEVFN(SIO1, 3) +#define PCH_DEV_I2C0 _PCH_DEV(SIO1, 0) +#define PCH_DEV_I2C1 _PCH_DEV(SIO1, 1) +#define PCH_DEV_I2C2 _PCH_DEV(SIO1, 2) +#define PCH_DEV_I2C3 _PCH_DEV(SIO1, 3) + +#define PCH_DEV_SLOT_CSE 0x16 +#define PCH_DEVFN_CSE _PCH_DEVFN(CSE, 0) +#define PCH_DEVFN_CSE_2 _PCH_DEVFN(CSE, 1) +#define PCH_DEVFN_CSE_IDER _PCH_DEVFN(CSE, 2) +#define PCH_DEVFN_CSE_KT _PCH_DEVFN(CSE, 3) +#define PCH_DEVFN_CSE_3 _PCH_DEVFN(CSE, 4) +#define PCH_DEVFN_CSE_4 _PCH_DEVFN(CSE, 5) +#define PCH_DEV_CSE _PCH_DEV(CSE, 0) +#define PCH_DEV_CSE_2 _PCH_DEV(CSE, 1) +#define PCH_DEV_CSE_IDER _PCH_DEV(CSE, 2) +#define PCH_DEV_CSE_KT _PCH_DEV(CSE, 3) +#define PCH_DEV_CSE_3 _PCH_DEV(CSE, 4) +#define PCH_DEV_CSE_4 _PCH_DEV(CSE, 5) + +#define PCH_DEV_SLOT_SATA 0x17 +#define PCH_DEVFN_SATA _PCH_DEVFN(SATA, 0) +#define PCH_DEV_SATA _PCH_DEV(SATA, 0) + +#define PCH_DEV_SLOT_SIO2 0x19 +#define PCH_DEVFN_I2C4 _PCH_DEVFN(SIO2, 0) +#define PCH_DEVFN_I2C5 _PCH_DEVFN(SIO2, 1) +#define PCH_DEVFN_UART2 _PCH_DEVFN(SIO2, 2) +#define PCH_DEV_I2C4 _PCH_DEV(SIO2, 0) +#define PCH_DEV_I2C5 _PCH_DEV(SIO2, 1) +#define PCH_DEV_UART2 _PCH_DEV(SIO2, 2) + +#define PCH_DEV_SLOT_STORAGE 0x1A +#define PCH_DEVFN_EMMC _PCH_DEVFN(STORAGE, 0) +#define PCH_DEV_EMMC _PCH_DEV(STORAGE, 0) + +#define PCH_DEV_SLOT_PCIE 0x1c +#define PCH_DEVFN_PCIE1 _PCH_DEVFN(PCIE, 0) +#define PCH_DEVFN_PCIE2 _PCH_DEVFN(PCIE, 1) +#define PCH_DEVFN_PCIE3 _PCH_DEVFN(PCIE, 2) +#define PCH_DEVFN_PCIE4 _PCH_DEVFN(PCIE, 3) +#define PCH_DEVFN_PCIE5 _PCH_DEVFN(PCIE, 4) +#define PCH_DEVFN_PCIE6 _PCH_DEVFN(PCIE, 5) +#define PCH_DEVFN_PCIE7 _PCH_DEVFN(PCIE, 6) +#define PCH_DEVFN_PCIE8 _PCH_DEVFN(PCIE, 7) +#define PCH_DEV_PCIE1 _PCH_DEV(PCIE, 0) +#define PCH_DEV_PCIE2 _PCH_DEV(PCIE, 1) +#define PCH_DEV_PCIE3 _PCH_DEV(PCIE, 2) +#define PCH_DEV_PCIE4 _PCH_DEV(PCIE, 3) +#define PCH_DEV_PCIE5 _PCH_DEV(PCIE, 4) +#define PCH_DEV_PCIE6 _PCH_DEV(PCIE, 5) +#define PCH_DEV_PCIE7 _PCH_DEV(PCIE, 6) +#define PCH_DEV_PCIE8 _PCH_DEV(PCIE, 7) + +#define PCH_DEV_SLOT_PCIE_1 0x1d +#define PCH_DEVFN_PCIE9 _PCH_DEVFN(PCIE_1, 0) +#define PCH_DEVFN_PCIE10 _PCH_DEVFN(PCIE_1, 1) +#define PCH_DEVFN_PCIE11 _PCH_DEVFN(PCIE_1, 2) +#define PCH_DEVFN_PCIE12 _PCH_DEVFN(PCIE_1, 3) +#define PCH_DEVFN_PCIE13 _PCH_DEVFN(PCIE_1, 4) +#define PCH_DEVFN_PCIE14 _PCH_DEVFN(PCIE_1, 5) +#define PCH_DEVFN_PCIE15 _PCH_DEVFN(PCIE_1, 6) +#define PCH_DEVFN_PCIE16 _PCH_DEVFN(PCIE_1, 7) +#define PCH_DEV_PCIE9 _PCH_DEV(PCIE_1, 0) +#define PCH_DEV_PCIE10 _PCH_DEV(PCIE_1, 1) +#define PCH_DEV_PCIE11 _PCH_DEV(PCIE_1, 2) +#define PCH_DEV_PCIE12 _PCH_DEV(PCIE_1, 3) +#define PCH_DEV_PCIE13 _PCH_DEV(PCIE_1, 4) +#define PCH_DEV_PCIE14 _PCH_DEV(PCIE_1, 5) +#define PCH_DEV_PCIE15 _PCH_DEV(PCIE_1, 6) +#define PCH_DEV_PCIE16 _PCH_DEV(PCIE_1, 7) + +#define PCH_DEV_SLOT_PCIE_2 0x1b +#define PCH_DEVFN_PCIE17 _PCH_DEVFN(PCIE_2, 0) +#define PCH_DEVFN_PCIE18 _PCH_DEVFN(PCIE_2, 1) +#define PCH_DEVFN_PCIE19 _PCH_DEVFN(PCIE_2, 2) +#define PCH_DEVFN_PCIE20 _PCH_DEVFN(PCIE_2, 3) +#define PCH_DEVFN_PCIE21 _PCH_DEVFN(PCIE_2, 4) +#define PCH_DEVFN_PCIE22 _PCH_DEVFN(PCIE_2, 5) +#define PCH_DEVFN_PCIE23 _PCH_DEVFN(PCIE_2, 6) +#define PCH_DEVFN_PCIE24 _PCH_DEVFN(PCIE_2, 7) +#define PCH_DEV_PCIE17 _PCH_DEV(PCIE_2, 0) +#define PCH_DEV_PCIE18 _PCH_DEV(PCIE_2, 1) +#define PCH_DEV_PCIE19 _PCH_DEV(PCIE_2, 2) +#define PCH_DEV_PCIE20 _PCH_DEV(PCIE_2, 3) +#define PCH_DEV_PCIE21 _PCH_DEV(PCIE_2, 4) +#define PCH_DEV_PCIE22 _PCH_DEV(PCIE_2, 5) +#define PCH_DEV_PCIE23 _PCH_DEV(PCIE_2, 6) +#define PCH_DEV_PCIE24 _PCH_DEV(PCIE_2, 7) + +#define PCH_DEV_SLOT_SIO3 0x1e +#define PCH_DEVFN_UART0 _PCH_DEVFN(SIO3, 0) +#define PCH_DEVFN_UART1 _PCH_DEVFN(SIO3, 1) +#define PCH_DEVFN_GSPI0 _PCH_DEVFN(SIO3, 2) +#define PCH_DEVFN_GSPI1 _PCH_DEVFN(SIO3, 3) +#define PCH_DEV_UART0 _PCH_DEV(SIO3, 0) +#define PCH_DEV_UART1 _PCH_DEV(SIO3, 1) +#define PCH_DEV_GSPI0 _PCH_DEV(SIO3, 2) +#define PCH_DEV_GSPI1 _PCH_DEV(SIO3, 3) + +#define PCH_DEV_SLOT_LPC 0x1f +#define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0) +#define PCH_DEVFN_P2SB _PCH_DEVFN(LPC, 1) +#define PCH_DEVFN_PMC _PCH_DEVFN(LPC, 2) +#define PCH_DEVFN_HDA _PCH_DEVFN(LPC, 3) +#define PCH_DEVFN_SMBUS _PCH_DEVFN(LPC, 4) +#define PCH_DEVFN_SPI _PCH_DEVFN(LPC, 5) +#define PCH_DEVFN_GBE _PCH_DEVFN(LPC, 6) +#define PCH_DEVFN_TRACEHUB _PCH_DEVFN(LPC, 7) +#define PCH_DEV_LPC _PCH_DEV(LPC, 0) +#define PCH_DEV_P2SB _PCH_DEV(LPC, 1) +#define PCH_DEV_PMC _PCH_DEV(LPC, 2) +#define PCH_DEV_HDA _PCH_DEV(LPC, 3) +#define PCH_DEV_SMBUS _PCH_DEV(LPC, 4) +#define PCH_DEV_SPI _PCH_DEV(LPC, 5) +#define PCH_DEV_GBE _PCH_DEV(LPC, 6) +#define PCH_DEV_TRACEHUB _PCH_DEV(LPC, 7) + +#endif diff --git a/src/soc/intel/icelake/include/soc/pcr_ids.h b/src/soc/intel/icelake/include/soc/pcr_ids.h new file mode 100644 index 0000000000..b75bf67036 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/pcr_ids.h @@ -0,0 +1,42 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_ICELAKE_PCR_H +#define SOC_ICELAKE_PCR_H +/* + * Port ids + */ +#define PID_EMMC 0x52 +#define PID_SDX 0x53 +#define PID_GPIOCOM4 0x6a +#define PID_GPIOCOM3 0x6b +#define PID_GPIOCOM2 0x6c +#define PID_GPIOCOM1 0x6d +#define PID_GPIOCOM0 0x6e +#define PID_DMI 0x88 +#define PID_PSTH 0x89 +#define PID_CSME0 0x90 +#define PID_ISCLK 0xad +#define PID_PSF1 0xba +#define PID_PSF2 0xbb +#define PID_PSF3 0xbc +#define PID_PSF4 0xbd +#define PID_SCS 0xc0 +#define PID_RTC 0xc3 +#define PID_ITSS 0xc2 +#define PID_LPC 0xc7 +#define PID_SERIALIO 0xcb + +#endif diff --git a/src/soc/intel/icelake/include/soc/pm.h b/src/soc/intel/icelake/include/soc/pm.h new file mode 100644 index 0000000000..6b1b2989c9 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/pm.h @@ -0,0 +1,173 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_PM_H_ +#define _SOC_PM_H_ + +#define PM1_STS 0x00 +#define WAK_STS (1 << 15) +#define PCIEXPWAK_STS (1 << 14) +#define PRBTNOR_STS (1 << 11) +#define RTC_STS (1 << 10) +#define PWRBTN_STS (1 << 8) +#define GBL_STS (1 << 5) +#define BM_STS (1 << 4) +#define TMROF_STS (1 << 0) +#define PM1_EN 0x02 +#define PCIEXPWAK_DIS (1 << 14) +#define RTC_EN (1 << 10) +#define PWRBTN_EN (1 << 8) +#define GBL_EN (1 << 5) +#define TMROF_EN (1 << 0) +#define PM1_CNT 0x04 +#define GBL_RLS (1 << 2) +#define BM_RLD (1 << 1) +#define SCI_EN (1 << 0) +#define PM1_TMR 0x08 +#define SMI_EN 0x30 +#define XHCI_SMI_EN (1 << 31) +#define ME_SMI_EN (1 << 30) +#define ESPI_SMI_EN (1 << 28) +#define GPIO_UNLOCK_SMI_EN (1 << 27) +#define INTEL_USB2_EN (1 << 18) +#define LEGACY_USB2_EN (1 << 17) +#define PERIODIC_EN (1 << 14) +#define TCO_SMI_EN (1 << 13) +#define MCSMI_EN (1 << 11) +#define BIOS_RLS (1 << 7) +#define SWSMI_TMR_EN (1 << 6) +#define APMC_EN (1 << 5) +#define SLP_SMI_EN (1 << 4) +#define LEGACY_USB_EN (1 << 3) +#define BIOS_EN (1 << 2) +#define EOS (1 << 1) +#define GBL_SMI_EN (1 << 0) +#define SMI_STS 0x34 +#define SMI_STS_BITS 32 +#define XHCI_SMI_STS_BIT 31 +#define ME_SMI_STS_BIT 30 +#define ESPI_SMI_STS_BIT 28 +#define GPIO_UNLOCK_SMI_STS_BIT 27 +#define SPI_SMI_STS_BIT 26 +#define SCC_SMI_STS_BIT 25 +#define MONITOR_STS_BIT 21 +#define PCI_EXP_SMI_STS_BIT 20 +#define SMBUS_SMI_STS_BIT 16 +#define SERIRQ_SMI_STS_BIT 15 +#define PERIODIC_STS_BIT 14 +#define TCO_STS_BIT 13 +#define DEVMON_STS_BIT 12 +#define MCSMI_STS_BIT 11 +#define GPIO_STS_BIT 10 +#define GPE0_STS_BIT 9 +#define PM1_STS_BIT 8 +#define SWSMI_TMR_STS_BIT 6 +#define APM_STS_BIT 5 +#define SMI_ON_SLP_EN_STS_BIT 4 +#define LEGACY_USB_STS_BIT 3 +#define BIOS_STS_BIT 2 +#define GPE_CNTL 0x42 +#define SWGPE_CTRL (1 << 1) +#define DEVACT_STS 0x44 +#define PM2_CNT 0x50 + +#define GPE0_REG_MAX 4 +#define GPE0_REG_SIZE 32 +#define GPE0_STS(x) (0x60 + ((x) * 4)) +#define GPE_31_0 0 /* 0x60/0x70 = GPE[31:0] */ +#define GPE_63_32 1 /* 0x64/0x74 = GPE[63:32] */ +#define GPE_95_64 2 /* 0x68/0x78 = GPE[95:64] */ +#define GPE_STD 3 /* 0x6c/0x7c = Standard GPE */ +#define GPE_STS_RSVD GPE_STD +#define WADT_STS (1 << 18) +#define GPIO_T2_STS (1 << 15) +#define ESPI_STS (1 << 14) +#define PME_B0_STS (1 << 13) +#define ME_SCI_STS (1 << 12) +#define PME_STS (1 << 11) +#define BATLOW_STS (1 << 10) +#define PCI_EXP_STS (1 << 9) +#define SMB_WAK_STS (1 << 7) +#define TCOSCI_STS (1 << 6) +#define SWGPE_STS (1 << 2) +#define HOT_PLUG_STS (1 << 1) +#define GPE0_EN(x) (0x70 + ((x) * 4)) +#define WADT_EN (1 << 18) +#define GPIO_T2_EN (1 << 15) +#define ESPI_EN (1 << 14) +#define PME_B0_EN_BIT 13 +#define PME_B0_EN (1 << PME_B0_EN_BIT) +#define ME_SCI_EN (1 << 12) +#define PME_EN (1 << 11) +#define BATLOW_EN (1 << 10) +#define PCI_EXP_EN (1 << 9) +#define TCOSCI_EN (1 << 6) +#define SWGPE_EN (1 << 2) +#define HOT_PLUG_EN (1 << 1) + +#define EN_BLOCK 3 + +/* + * Enable SMI generation: + * - on APMC writes (io 0xb2) + * - on writes to SLP_EN (sleep states) + * - on writes to GBL_RLS (bios commands) + * - on eSPI events (does nothing on LPC systems) + * No SMIs: + * - on microcontroller writes (io 0x62/0x66) + * - on TCO events + */ +#define ENABLE_SMI_PARAMS \ + (APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS) + +#define PSS_RATIO_STEP 2 +#define PSS_MAX_ENTRIES 8 +#define PSS_LATENCY_TRANSITION 10 +#define PSS_LATENCY_BUSMASTER 10 + +#if !defined(__ACPI__) + +#include <arch/acpi.h> +#include <arch/io.h> +#include <soc/gpe.h> +#include <soc/iomap.h> +#include <soc/smbus.h> +#include <soc/pmc.h> + +struct chipset_power_state { + uint16_t pm1_sts; + uint16_t pm1_en; + uint32_t pm1_cnt; + uint16_t tco1_sts; + uint16_t tco2_sts; + uint32_t gpe0_sts[4]; + uint32_t gpe0_en[4]; + uint32_t gen_pmcon_a; + uint32_t gen_pmcon_b; + uint32_t gblrst_cause[2]; + uint32_t prev_sleep_state; +} __packed; + +/* Get base address PMC memory mapped registers. */ +uint8_t *pmc_mmio_regs(void); + +/* Get base address of TCO I/O registers. */ +uint16_t smbus_tco_regs(void); + +/* Set the DISB after DRAM init */ +void pmc_set_disb(void); + +#endif /* !defined(__ACPI__) */ +#endif diff --git a/src/soc/intel/icelake/include/soc/pmc.h b/src/soc/intel/icelake/include/soc/pmc.h new file mode 100644 index 0000000000..9418c73bfe --- /dev/null +++ b/src/soc/intel/icelake/include/soc/pmc.h @@ -0,0 +1,149 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_PMC_H_ +#define _SOC_ICELAKE_PMC_H_ + +/* PCI Configuration Space (D31:F2): PMC */ +#define PWRMBASE 0x10 +#define ABASE 0x20 + +/* Memory mapped IO registers in PMC */ +#define GEN_PMCON_A 0x1020 +#define DC_PP_DIS (1 << 30) +#define DSX_PP_DIS (1 << 29) +#define AG3_PP_EN (1 << 28) +#define SX_PP_EN (1 << 27) +#define ALLOW_ICLK_PLL_SD_INC0 (1 << 26) +#define GBL_RST_STS (1 << 24) +#define DISB (1 << 23) +#define ALLOW_OPI_PLL_SD_INC0 (1 << 22) +#define MEM_SR (1 << 21) +#define ALLOW_SPXB_CG_INC0 (1 << 20) +#define ALLOW_L1LOW_C0 (1 << 19) +#define MS4V (1 << 18) +#define ALLOW_L1LOW_OPI_ON (1 << 17) +#define SUS_PWR_FLR (1 << 16) +#define PME_B0_S5_DIS (1 << 15) +#define PWR_FLR (1 << 14) +#define ALLOW_L1LOW_BCLKREQ_ON (1 << 13) +#define DIS_SLP_X_STRCH_SUS_UP (1 << 12) +#define SLP_S3_MIN_ASST_WDTH_MASK (3 << 10) +#define SLP_S3_MIN_ASST_WDTH_60USEC (0 << 10) +#define SLP_S3_MIN_ASST_WDTH_1MS (1 << 10) +#define SLP_S3_MIN_ASST_WDTH_50MS (2 << 10) +#define SLP_S3_MIN_ASST_WDTH_2S (3 << 10) +#define HOST_RST_STS (1 << 9) +#define ESPI_SMI_LOCK (1 << 8) +#define S4MAW_MASK (3 << 4) +#define S4MAW_1S (1 << 4) +#define S4MAW_2S (2 << 4) +#define S4MAW_3S (3 << 4) +#define S4MAW_4S (0 << 4) +#define S4ASE (1 << 3) +#define PER_SMI_SEL_MASK (3 << 1) +#define SMI_RATE_64S (0 << 1) +#define SMI_RATE_32S (1 << 1) +#define SMI_RATE_16S (2 << 1) +#define SMI_RATE_8S (3 << 1) +#define SLEEP_AFTER_POWER_FAIL (1 << 0) + +#define GEN_PMCON_B 0x1024 +#define SLP_STR_POL_LOCK (1 << 18) +#define ACPI_BASE_LOCK (1 << 17) +#define PM_DATA_BAR_DIS (1 << 16) +#define WOL_EN_OVRD (1 << 13) +#define BIOS_PCI_EXP_EN (1 << 10) +#define PWRBTN_LVL (1 << 9) +#define SMI_LOCK (1 << 4) +#define RTC_BATTERY_DEAD (1 << 2) + +#define ETR 0x1048 +#define CF9_LOCK (1 << 31) +#define CF9_GLB_RST (1 << 20) + +#define SSML 0x104C +#define SSML_SSL_DS (0 << 0) +#define SSML_SSL_EN (1 << 0) + +#define SSMC 0x1050 +#define SSMC_SSMS (1 << 0) + +#define SSMD 0x1054 +#define SSMD_SSD_MASK (0xffff << 0) + +#define PRSTS 0x1810 + +#define S3_PWRGATE_POL 0x1828 +#define S3DC_GATE_SUS (1 << 1) +#define S3AC_GATE_SUS (1 << 0) + +#define S4_PWRGATE_POL 0x182c +#define S4DC_GATE_SUS (1 << 1) +#define S4AC_GATE_SUS (1 << 0) + +#define S5_PWRGATE_POL 0x1830 +#define S5DC_GATE_SUS (1 << 15) +#define S5AC_GATE_SUS (1 << 14) + +#define DSX_CFG 0x1834 +#define REQ_CNV_NOWAKE_DSX (1 << 4) +#define REQ_BATLOW_DSX (1 << 3) +#define DSX_EN_WAKE_PIN (1 << 2) +#define DSX_DIS_AC_PRESENT_PD (1 << 1) +#define DSX_EN_LAN_WAKE_PIN (1 << 0) +#define DSX_CFG_MASK (0x1f << 0) + +#define PMSYNC_TPR_CFG 0x18C4 +#define PCH2CPU_TPR_CFG_LOCK (1 << 31) +#define PCH2CPU_TT_EN (1 << 26) + +#define PCH_PWRM_ACPI_TMR_CTL 0x18FC +#define GPIO_GPE_CFG 0x1920 +#define GPE0_DWX_MASK 0xf +#define GPE0_DW_SHIFT(x) (4*(x)) + +#define PMC_GPP_A 0x0 +#define PMC_GPP_B 0x1 +#define PMC_GPP_C 0xD +#define PMC_GPP_D 0x4 +#define PMC_GPP_E 0xE +#define PMC_GPP_F 0x5 +#define PMC_GPP_G 0x2 +#define PMC_GPP_H 0x6 +#define PMC_GPD 0xA + +#define GBLRST_CAUSE0 0x1924 +#define GBLRST_CAUSE0_THERMTRIP (1 << 5) +#define GBLRST_CAUSE1 0x1928 + +#define CPPMVRIC 0x1B1C +#define XTALSDQDIS (1 << 22) + +#define IRQ_REG ACTL +#define SCI_IRQ_ADJUST 0 +#define ACTL 0x1BD8 +#define PWRM_EN (1 << 8) +#define ACPI_EN (1 << 7) +#define SCI_IRQ_SEL (7 << 0) + +#define SCIS_IRQ9 0 +#define SCIS_IRQ10 1 +#define SCIS_IRQ11 2 +#define SCIS_IRQ20 4 +#define SCIS_IRQ21 5 +#define SCIS_IRQ22 6 +#define SCIS_IRQ23 7 +#endif diff --git a/src/soc/intel/icelake/include/soc/ramstage.h b/src/soc/intel/icelake/include/soc/ramstage.h new file mode 100644 index 0000000000..d0b500d135 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/ramstage.h @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_RAMSTAGE_H_ +#define _SOC_RAMSTAGE_H_ + +#include <chip.h> +#include <device/device.h> +#include <fsp/api.h> +#include <fsp/util.h> + +void mainboard_silicon_init_params(FSP_S_CONFIG *params); +void soc_init_pre_device(void *chip_info); + +#endif diff --git a/src/soc/intel/icelake/include/soc/romstage.h b/src/soc/intel/icelake/include/soc/romstage.h new file mode 100644 index 0000000000..1517264d10 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/romstage.h @@ -0,0 +1,33 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ROMSTAGE_H_ +#define _SOC_ROMSTAGE_H_ + +#include <arch/cpu.h> +#include <fsp/api.h> + +void mainboard_memory_init_params(FSPM_UPD *mupd); +void systemagent_early_init(void); + +/* Board type */ +enum board_type { + BOARD_TYPE_MOBILE = 0, + BOARD_TYPE_DESKTOP = 1, + BOARD_TYPE_ULT_ULX = 5, + BOARD_TYPE_SERVER = 7 +}; + +#endif /* _SOC_ROMSTAGE_H_ */ diff --git a/src/soc/intel/icelake/include/soc/serialio.h b/src/soc/intel/icelake/include/soc/serialio.h new file mode 100644 index 0000000000..30a48a146f --- /dev/null +++ b/src/soc/intel/icelake/include/soc/serialio.h @@ -0,0 +1,42 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SERIALIO_H_ +#define _SERIALIO_H_ + +typedef enum { + PchSerialIoDisabled, + PchSerialIoPci, + PchSerialIoAcpi, + PchSerialIoHidden, +} PCH_SERIAL_IO_MODE; + +typedef enum { + PchSerialIoIndexI2C0, + PchSerialIoIndexI2C1, + PchSerialIoIndexI2C2, + PchSerialIoIndexI2C3, + PchSerialIoIndexI2C4, + PchSerialIoIndexI2C5, + PchSerialIoIndexSPI0, + PchSerialIoIndexSPI1, + PchSerialIoIndexSPI2, + PchSerialIoIndexUART0, + PchSerialIoIndexUART1, + PchSerialIoIndexUART2, + PchSerialIoIndexMAX +} PCH_SERIAL_IO_CONTROLLER; + +#endif diff --git a/src/soc/intel/icelake/include/soc/smbus.h b/src/soc/intel/icelake/include/soc/smbus.h new file mode 100644 index 0000000000..64c3eb3f3a --- /dev/null +++ b/src/soc/intel/icelake/include/soc/smbus.h @@ -0,0 +1,44 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_SMBUS_H_ +#define _SOC_ICELAKE_SMBUS_H_ + +/* PCI registers */ +#define TCOBASE 0x50 /* TCO base address. */ +#define TCOCTL 0x54 +#define TCO_BASE_EN (1 << 8) /* TCO base enable. */ + +/* IO and MMIO registers under primary BAR */ +/* Set address for PCH as SMBus slave role */ +#define SMB_RCV_SLVA 0x09 + +/* TCO registers and fields live behind TCOBASE I/O bar in SMBus device. */ +#define TCO1_STS 0x04 +#define TCO_TIMEOUT (1 << 3) +#define TCO2_STS 0x06 +#define TCO2_STS_SECOND_TO (1 << 1) +#define TCO1_CNT 0x08 +#define TCO_LOCK (1 << 12) +#define TCO_TMR_HLT (1 << 11) + +/* + * Default slave address value for PCH. This value is set to match default + * value set by hardware. It is useful since PCH is able to respond even + * before CPU is up. This is reset by RSMRST# but not by PLTRST#. + */ +#define SMBUS_SLAVE_ADDR 0x44 + +#endif diff --git a/src/soc/intel/icelake/include/soc/smm.h b/src/soc/intel/icelake/include/soc/smm.h new file mode 100644 index 0000000000..a9cd748b0c --- /dev/null +++ b/src/soc/intel/icelake/include/soc/smm.h @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_SMM_H_ +#define _SOC_SMM_H_ + +#include <stdint.h> +#include <cpu/x86/msr.h> +#include <fsp/memmap.h> +#include <soc/gpio.h> + +struct ied_header { + char signature[10]; + u32 size; + u8 reserved[34]; +} __packed; + +struct smm_relocation_params { + u32 smram_base; + u32 smram_size; + u32 ied_base; + u32 ied_size; + msr_t smrr_base; + msr_t smrr_mask; + msr_t emrr_base; + msr_t emrr_mask; + msr_t uncore_emrr_base; + msr_t uncore_emrr_mask; + /* + * The smm_save_state_in_msrs field indicates if SMM save state + * locations live in MSRs. This indicates to the CPUs how to adjust + * the SMMBASE and IEDBASE + */ + int smm_save_state_in_msrs; +}; + +/* Mainboard handler for eSPI SMIs */ +void mainboard_smi_espi_handler(void); + +#if IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) +void smm_relocation_handler(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase); +void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, + size_t *smm_save_state_size); +void smm_initialize(void); +void smm_relocate(void); + +#else /* CONFIG_HAVE_SMI_HANDLER */ +static inline void smm_relocation_handler(int cpu, uintptr_t curr_smbase, + uintptr_t staggered_smbase) {} +static inline void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, + size_t *smm_save_state_size) {} +static inline void smm_initialize(void) {} + +static inline void smm_relocate(void) {} +#endif /* CONFIG_HAVE_SMI_HANDLER */ + +#endif diff --git a/src/soc/intel/icelake/include/soc/soc_chip.h b/src/soc/intel/icelake/include/soc/soc_chip.h new file mode 100644 index 0000000000..2d996e9e5b --- /dev/null +++ b/src/soc/intel/icelake/include/soc/soc_chip.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_ICELAKE_SOC_CHIP_H_ +#define _SOC_ICELAKE_SOC_CHIP_H_ + +#include "../../chip.h" + +#endif /* _SOC_ICELAKE_SOC_CHIP_H_ */ diff --git a/src/soc/intel/icelake/include/soc/systemagent.h b/src/soc/intel/icelake/include/soc/systemagent.h new file mode 100644 index 0000000000..4e78ceb898 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/systemagent.h @@ -0,0 +1,44 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_ICELAKE_SYSTEMAGENT_H +#define SOC_ICELAKE_SYSTEMAGENT_H + +#include <intelblocks/systemagent.h> + +/* Device 0:0.0 PCI configuration space */ + +#define EPBAR 0x40 +#define DMIBAR 0x68 +#define SMRAM 0x88 /* System Management RAM Control */ +#define D_OPEN (1 << 6) +#define D_CLS (1 << 5) +#define D_LCK (1 << 4) +#define G_SMRAME (1 << 3) +#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0)) + +#define BIOS_RESET_CPL 0x5da8 +#define EDRAMBAR 0x5408 +#define REGBAR 0x5420 + +#define MCH_PKG_POWER_LIMIT_LO 0x59a0 +#define MCH_PKG_POWER_LIMIT_HI 0x59a4 +#define MCH_DDR_POWER_LIMIT_LO 0x58e0 +#define MCH_DDR_POWER_LIMIT_HI 0x58e4 + +#define IMRBASE 0x6A40 +#define IMRLIMIT 0x6A48 + +#endif diff --git a/src/soc/intel/icelake/include/soc/usb.h b/src/soc/intel/icelake/include/soc/usb.h new file mode 100644 index 0000000000..d2e50ef1e8 --- /dev/null +++ b/src/soc/intel/icelake/include/soc/usb.h @@ -0,0 +1,152 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#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_PRE_EMP_ON, \ + .pre_emp_bias = USB2_BIAS_56P3MV, \ + .pre_emp_bit = USB2_HALF_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/icelake/lockdown.c b/src/soc/intel/icelake/lockdown.c new file mode 100644 index 0000000000..5581e1657f --- /dev/null +++ b/src/soc/intel/icelake/lockdown.c @@ -0,0 +1,72 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <intelblocks/chip.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/icelake/lpc.c b/src/soc/intel/icelake/lpc.c new file mode 100644 index 0000000000..8859c5d473 --- /dev/null +++ b/src/soc/intel/icelake/lpc.c @@ -0,0 +1,257 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "chip.h" +#include <console/console.h> +#include <delay.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <pc80/isa-dma.h> +#include <pc80/i8259.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <intelblocks/itss.h> +#include <intelblocks/lpc_lib.h> +#include <intelblocks/pcr.h> +#include <reg_script.h> +#include <soc/iomap.h> +#include <soc/lpc.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> + +/* +* As per the BWG, Chapter 5.9.1. "PCH BIOS component will reserve +* certain memory range as reserved range for BIOS usage. +* For this SOC, the range will be from 0FC800000h till FE7FFFFFh" +*/ +static const struct lpc_mmio_range icl_lpc_fixed_mmio_ranges[] = { + { PCH_PRESERVED_BASE_ADDRESS, PCH_PRESERVED_BASE_SIZE }, + { 0, 0 } +}; + +const struct lpc_mmio_range *soc_get_fixed_mmio_ranges() +{ + return icl_lpc_fixed_mmio_ranges; +} + +void soc_get_gen_io_dec_range(const struct device *dev, uint32_t *gen_io_dec) +{ + const config_t *config = dev->chip_info; + + gen_io_dec[0] = config->gen1_dec; + gen_io_dec[1] = config->gen2_dec; + gen_io_dec[2] = config->gen3_dec; + gen_io_dec[3] = config->gen4_dec; +} + +void soc_setup_dmi_pcr_io_dec(uint32_t *gen_io_dec) +{ + /* Mirror these same settings in DMI PCR */ + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR1, gen_io_dec[0]); + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR2, gen_io_dec[1]); + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR3, gen_io_dec[2]); + pcr_write32(PID_DMI, PCR_DMI_LPCLGIR4, gen_io_dec[3]); +} + +uint8_t get_pch_series(void) +{ + uint16_t lpc_did_hi_byte; + + /* + * Fetch upper 8 bits on LPC device ID to determine PCH type + * Adding 1 to the offset to fetch upper 8 bits + */ + lpc_did_hi_byte = pci_read_config8(PCH_DEV_LPC, PCI_DEVICE_ID + 1); + + if (lpc_did_hi_byte == 0x9D) + return PCH_LP; + else if (lpc_did_hi_byte == 0xA3) + return PCH_H; + else + return PCH_UNKNOWN_SERIES; +} + +#if ENV_RAMSTAGE +static void soc_mirror_dmi_pcr_io_dec(void) +{ + uint32_t io_dec_arr[] = { + pci_read_config32(PCH_DEV_LPC, LPC_GEN1_DEC), + pci_read_config32(PCH_DEV_LPC, LPC_GEN2_DEC), + pci_read_config32(PCH_DEV_LPC, LPC_GEN3_DEC), + pci_read_config32(PCH_DEV_LPC, LPC_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) +{ + const config_t *config = dev->chip_info; + uint8_t pch_interrupt_routing[MAX_PXRC_CONFIG]; + + pch_interrupt_routing[0] = config->pirqa_routing; + pch_interrupt_routing[1] = config->pirqb_routing; + pch_interrupt_routing[2] = config->pirqc_routing; + pch_interrupt_routing[3] = config->pirqd_routing; + pch_interrupt_routing[4] = config->pirqe_routing; + pch_interrupt_routing[5] = config->pirqf_routing; + pch_interrupt_routing[6] = config->pirqg_routing; + pch_interrupt_routing[7] = config->pirqh_routing; + + itss_irq_init(pch_interrupt_routing); +#if defined(__SIMPLE_DEVICE__) + pci_devfn_t irq_dev; +#else + struct device *irq_dev; +#endif + 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 = config->pirqa_routing; + break; + case 2: /* INTB# */ + int_line = config->pirqb_routing; + break; + case 3: /* INTC# */ + int_line = config->pirqc_routing; + break; + case 4: /* INTD# */ + int_line = config->pirqd_routing; + 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(0x61, (reg8 | (1 << 2))); + + /* Disable NMI sources */ + outb(0x70, (1 << 7)); +}; + +static void clock_gate_8254(const struct device *dev) +{ + const config_t *config = dev->chip_info; + + if (!config->clock_gate_8254) + return; + + itss_clock_gate_8254(); +} + +void lpc_soc_init(struct device *dev) +{ + /* Legacy initialization */ + isa_dma_init(); + pch_misc_init(); + + /* Enable CLKRUN_EN for power gating LPC */ + lpc_enable_pci_clk_cntl(); + + /* Set LPC Serial IRQ mode */ + if (IS_ENABLED(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); + clock_gate_8254(dev); + soc_mirror_dmi_pcr_io_dec(); +} + +/* Fill up LPC IO resource structure inside SoC directory */ +void pch_lpc_soc_fill_io_resources(struct device *dev) +{ + /* + * PMC pci device gets hidden from PCI bus due to Silicon + * policy hence bind ACPI BASE aka ABASE (offset 0x20) with + * LPC IO resources to ensure that ABASE falls under PCI reserved + * IO memory range. + * + * Note: Don't add any more resource with same offset 0x20 + * under this device space. + */ + pch_lpc_add_new_resource(dev, PCI_BASE_ADDRESS_4, + ACPI_BASE_ADDRESS, ACPI_BASE_SIZE, IORESOURCE_IO | + IORESOURCE_ASSIGNED | IORESOURCE_FIXED); +} + +#endif diff --git a/src/soc/intel/icelake/memmap.c b/src/soc/intel/icelake/memmap.c new file mode 100644 index 0000000000..027b8b0ffa --- /dev/null +++ b/src/soc/intel/icelake/memmap.c @@ -0,0 +1,312 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/ebda.h> +#include <arch/io.h> +#include <cbmem.h> +#include <chip.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <fsp/util.h> +#include <intelblocks/ebda.h> +#include <intelblocks/systemagent.h> +#include <soc/pci_devs.h> +#include <soc/smm.h> +#include <soc/systemagent.h> +#include <stdlib.h> + +void smm_region(void **start, size_t *size) +{ + *start = (void *)sa_get_tseg_base(); + *size = sa_get_tseg_size(); +} + +/* + * Subregions within SMM + * +-------------------------+ BGSM + * | IED | IED_REGION_SIZE + * +-------------------------+ + * | External Stage Cache | SMM_RESERVED_SIZE + * +-------------------------+ + * | code and data | + * | (TSEG) | + * +-------------------------+ TSEG + */ +int smm_subregion(int sub, void **start, size_t *size) +{ + uintptr_t sub_base; + size_t sub_size; + void *smm_base; + const size_t ied_size = CONFIG_IED_REGION_SIZE; + const size_t cache_size = CONFIG_SMM_RESERVED_SIZE; + + smm_region(&smm_base, &sub_size); + sub_base = (uintptr_t)smm_base; + + switch (sub) { + case SMM_SUBREGION_HANDLER: + /* Handler starts at the base of TSEG. */ + sub_size -= ied_size; + sub_size -= cache_size; + break; + case SMM_SUBREGION_CACHE: + /* External cache is in the middle of TSEG. */ + sub_base += sub_size - (ied_size + cache_size); + sub_size = cache_size; + break; + case SMM_SUBREGION_CHIPSET: + /* IED is at the top. */ + sub_base += sub_size - ied_size; + sub_size = ied_size; + break; + default: + return -1; + } + + *start = (void *)sub_base; + *size = sub_size; + + return 0; +} + +/* Calculate ME Stolen size */ +static size_t get_imr_size(void) +{ + size_t imr_size; + + /* ME stolen memory */ + imr_size = MCHBAR32(IMRLIMIT) - MCHBAR32(IMRBASE); + + return imr_size; +} + +/* Calculate PRMRR size based on user input PRMRR size and alignment */ +static size_t get_prmrr_size(uintptr_t dram_base, + const struct soc_intel_icelake_config *config) +{ + uintptr_t prmrr_base = dram_base; + size_t prmrr_size; + + prmrr_size = config->PrmrrSize; + + /* Allocate PRMRR memory for C6DRAM */ + if (!prmrr_size) { + if (config->enable_c6dram) + prmrr_size = 1*MiB; + else + return 0; + } + + /* + * PRMRR Sizes that are > 1MB and < 32MB are + * not supported and will fail out. + */ + if ((prmrr_size > 1*MiB) && (prmrr_size < 32*MiB)) + die("PRMRR Sizes that are > 1MB and < 32MB are not" + "supported!\n"); + + prmrr_base -= prmrr_size; + if (prmrr_size >= 32*MiB) + prmrr_base = ALIGN_DOWN(prmrr_base, 128*MiB); + else + prmrr_base = ALIGN_DOWN(prmrr_base, 16*MiB); + /* PRMRR Area Size */ + prmrr_size = dram_base - prmrr_base; + + return prmrr_size; +} + +/* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */ +static size_t calculate_traditional_mem_size(uintptr_t dram_base, + const struct device *dev) +{ + uintptr_t traditional_mem_base = dram_base; + size_t traditional_mem_size; + + if (dev->enabled) { + /* Read BDSM from Host Bridge */ + traditional_mem_base -= sa_get_dsm_size(); + + /* Read BGSM from Host Bridge */ + traditional_mem_base -= sa_get_gsm_size(); + } + /* Get TSEG size */ + traditional_mem_base -= sa_get_tseg_size(); + + /* Get DPR size */ + if (IS_ENABLED(CONFIG_SA_ENABLE_DPR)) + traditional_mem_base -= sa_get_dpr_size(); + + /* Traditional Area Size */ + traditional_mem_size = dram_base - traditional_mem_base; + + return traditional_mem_size; +} + +/* + * Calculate Intel Reserved Memory size based on + * PRMRR size, Me stolen memory and PTT selection. + */ +static size_t calculate_reserved_mem_size(uintptr_t dram_base, + const struct device *dev) +{ + uintptr_t reserve_mem_base = dram_base; + size_t reserve_mem_size; + const struct soc_intel_icelake_config *config; + + config = dev->chip_info; + + /* Get PRMRR size */ + reserve_mem_base -= get_prmrr_size(reserve_mem_base, config); + + /* Get Tracehub size */ + reserve_mem_base -= get_imr_size(); + + /* Traditional Area Size */ + reserve_mem_size = dram_base - reserve_mem_base; + + return reserve_mem_size; +} + +/* + * Host Memory Map: + * + * +--------------------------+ TOUUD + * | | + * +--------------------------+ 4GiB + * | PCI Address Space | + * +--------------------------+ TOLUD (also maps into MC address space) + * | iGD | + * +--------------------------+ BDSM + * | GTT | + * +--------------------------+ BGSM + * | TSEG | + * +--------------------------+ TSEGMB + * | DMA Protected Region | + * +--------------------------+ DPR + * | PRM (C6DRAM/SGX) | + * +--------------------------+ PRMRR + * | ME Stolen Memory | + * +--------------------------+ ME Stolen + * | PTT | + * +--------------------------+ top_of_ram + * | Reserved - FSP/CBMEM | + * +--------------------------+ TOLUM + * | Usage DRAM | + * +--------------------------+ 0 + * + * Some of the base registers above can be equal making the size of those + * regions 0. The reason is because the memory controller internally subtracts + * the base registers from each other to determine sizes of the regions. In + * other words, the memory map is in a fixed order no matter what. + */ +static uintptr_t calculate_dram_base(size_t *reserved_mem_size) +{ + uintptr_t dram_base; + const struct device *dev; + + dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_IGD, 0)); + if (!dev) + die("ERROR - IGD device not found!"); + + /* Read TOLUD from Host Bridge offset */ + dram_base = sa_get_tolud_base(); + + /* Get Intel Traditional Memory Range Size */ + dram_base -= calculate_traditional_mem_size(dram_base, dev); + + /* Get Intel Reserved Memory Range Size */ + *reserved_mem_size = calculate_reserved_mem_size(dram_base, dev); + + dram_base -= *reserved_mem_size; + + return dram_base; +} + +/* + * SoC implementation + * + * SoC call to summarize all Intel Reserve MMIO size and report to SA + */ +size_t soc_reserved_mmio_size(void) +{ + struct ebda_config cfg; + + retrieve_ebda_object(&cfg); + + /* Get Intel Reserved Memory Range Size */ + return cfg.reserved_mem_size; +} + +/* Fill up memory layout information */ +void fill_soc_memmap_ebda(struct ebda_config *cfg) +{ + size_t chipset_mem_size; + + cfg->tolum_base = calculate_dram_base(&chipset_mem_size); + cfg->reserved_mem_size = chipset_mem_size; +} + +void cbmem_top_init(void) +{ + /* Fill up EBDA area */ + fill_ebda_area(); +} + +/* + * +-------------------------+ Top of RAM (aligned) + * | System Management Mode | + * | code and data | Length: CONFIG_TSEG_SIZE + * | (TSEG) | + * +-------------------------+ SMM base (aligned) + * | | + * | Chipset Reserved Memory | + * | | + * +-------------------------+ top_of_ram (aligned) + * | | + * | CBMEM Root | + * | | + * +-------------------------+ + * | | + * | FSP Reserved Memory | + * | | + * +-------------------------+ + * | | + * | Various CBMEM Entries | + * | | + * +-------------------------+ top_of_stack (8 byte aligned) + * | | + * | stack (CBMEM Entry) | + * | | + * +-------------------------+ + */ +void *cbmem_top(void) +{ + struct ebda_config ebda_cfg; + + /* + * Check if Tseg has been initialized, we will use this as a flag + * to check if the MRC is done, and only then continue to read the + * PRMMR_BASE MSR. The system hangs if PRMRR_BASE MSR is read before + * PRMRR_MASK MSR lock bit is set. + */ + if (sa_get_tseg_base() == 0) + return NULL; + + retrieve_ebda_object(&ebda_cfg); + + return (void *)(uintptr_t)ebda_cfg.tolum_base; +} diff --git a/src/soc/intel/icelake/p2sb.c b/src/soc/intel/icelake/p2sb.c new file mode 100644 index 0000000000..6a7fac4963 --- /dev/null +++ b/src/soc/intel/icelake/p2sb.c @@ -0,0 +1,43 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <intelblocks/p2sb.h> + +void p2sb_soc_get_sb_mask(uint32_t *ep_mask, size_t count) +{ + uint32_t mask; + + if (count != P2SB_EP_MASK_MAX_REG) { + printk(BIOS_ERR, "Unable to program EPMASK registers\n"); + return; + } + + /* Remove the host accessing right to PSF register range. + * Set p2sb PCI offset EPMASK5 [29, 28, 27, 26] to disable Sideband + * access for PCI Root Bridge. + */ + mask = (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26); + + ep_mask[P2SB_EP_MASK_5_REG] = mask; + + /* + * Set p2sb PCI offset EPMASK7 [31, 30] to disable Sideband + * access for Broadcast and Multicast. + */ + mask = (1 << 31) | (1 << 30); + + ep_mask[P2SB_EP_MASK_7_REG] = mask; +} diff --git a/src/soc/intel/icelake/pmc.c b/src/soc/intel/icelake/pmc.c new file mode 100644 index 0000000000..24532104d8 --- /dev/null +++ b/src/soc/intel/icelake/pmc.c @@ -0,0 +1,160 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <bootstate.h> +#include <chip.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci_ops.h> +#include <intelblocks/pmc.h> +#include <intelblocks/pmclib.h> +#include <intelblocks/rtc.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> + +/* + * Set which power state system will be after reapplying + * the power (from G3 State) + */ +static void pmc_set_afterg3(struct device *dev, int s5pwr) +{ + uint8_t reg8; + + reg8 = pci_read_config8(dev, GEN_PMCON_B); + + switch (s5pwr) { + case MAINBOARD_POWER_STATE_OFF: + reg8 |= 1; + break; + case MAINBOARD_POWER_STATE_ON: + reg8 &= ~1; + break; + case MAINBOARD_POWER_STATE_PREVIOUS: + default: + break; + } + + pci_write_config8(dev, GEN_PMCON_B, reg8); +} + +/* + * Set PMC register to know which state system should be after + * power reapplied + */ +void pmc_soc_restore_power_failure(void) +{ + pmc_set_afterg3(PCH_DEV_PMC, + pmc_get_mainboard_power_failure_state_choice()); +} + +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 pch_power_options(struct device *dev) +{ + const char *state; + + /* Get the chip configuration */ + int pwr_on = pmc_get_mainboard_power_failure_state_choice(); + + /* + * Which state do we want to goto after g3 (power restored)? + * 0 == S5 Soft Off + * 1 == S0 Full On + * 2 == Keep Previous State + */ + switch (pwr_on) { + case MAINBOARD_POWER_STATE_OFF: + state = "off"; + break; + case MAINBOARD_POWER_STATE_ON: + state = "on"; + break; + case MAINBOARD_POWER_STATE_PREVIOUS: + state = "state keep"; + break; + default: + state = "undefined"; + } + pmc_set_afterg3(dev, pwr_on); + printk(BIOS_INFO, "Set power %s after power failure.\n", state); + + /* Set up GPE configuration. */ + pmc_gpe_init(); +} + +static void pmc_init(void *unused) +{ + struct device *dev = PCH_DEV_PMC; + config_t *config = dev->chip_info; + + rtc_init(); + + /* Initialize power management */ + pch_power_options(dev); + + pmc_set_acpi_mode(); + + 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); +} + +/* +* Initialize PMC controller. +* +* PMC controller gets hidden from PCI bus during FSP-Silicon init call. +* Hence PCI enumeration can't be used to initialize bus device and +* allocate resources. +*/ +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, pmc_init, NULL); diff --git a/src/soc/intel/icelake/pmutil.c b/src/soc/intel/icelake/pmutil.c new file mode 100644 index 0000000000..c020bf61d6 --- /dev/null +++ b/src/soc/intel/icelake/pmutil.c @@ -0,0 +1,231 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Helper functions for dealing with power management registers + * and the differences between PCH variants. + */ + +#define __SIMPLE_DEVICE__ + +#include <arch/io.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 <halt.h> +#include <rules.h> +#include <stdlib.h> +#include <soc/gpe.h> +#include <soc/gpio.h> +#include <soc/iomap.h> +#include <soc/lpc.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/smbus.h> +#include <timer.h> +#include <security/vboot/vbnv.h> +#include "chip.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 = (void *)(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); +} + +/* + * 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; +} + +uint16_t smbus_tco_regs(void) +{ + uint16_t reg16; + + reg16 = pci_read_config16(PCH_DEV_SMBUS, TCOBASE); + + return ALIGN_DOWN(reg16, 0x20); +} + +uint32_t soc_reset_tco_status(void) +{ + u16 tco1_sts; + u16 tco2_sts; + u16 tcobase; + + tcobase = smbus_tco_regs(); + + /* TCO Status 2 register */ + tco2_sts = inw(tcobase + TCO2_STS); + tco2_sts |= TCO2_STS_SECOND_TO; + outw(tco2_sts, tcobase + TCO2_STS); + + /* TCO Status 1 register */ + tco1_sts = inw(tcobase + TCO1_STS); + + /* Clear SECOND_TO_STS bit */ + if (tco2_sts & TCO2_STS_SECOND_TO) + outw(tco2_sts & ~TCO2_STS_SECOND_TO, tcobase + TCO2_STS); + + return (tco2_sts << 16) | tco1_sts; +} + +uintptr_t soc_read_pmc_base(void) +{ + return (uintptr_t)pmc_mmio_regs(); +} + +void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) +{ + DEVTREE_CONST struct soc_intel_icelake_config *config; + + /* Look up the device in devicetree */ + DEVTREE_CONST struct device *dev = dev_find_slot(0, PCH_DEVFN_PMC); + if (!dev || !dev->chip_info) { + printk(BIOS_ERR, "BUG! Could not find SOC devicetree config\n"); + return; + } + config = dev->chip_info; + + /* Assign to out variable */ + *dw0 = config->gpe0_dw0; + *dw1 = config->gpe0_dw1; + *dw2 = config->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)); +} diff --git a/src/soc/intel/icelake/reset.c b/src/soc/intel/icelake/reset.c new file mode 100644 index 0000000000..854723ca07 --- /dev/null +++ b/src/soc/intel/icelake/reset.c @@ -0,0 +1,104 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <cf9_reset.h> +#include <console/console.h> +#include <intelblocks/cse.h> +#include <intelblocks/pmclib.h> +#include <fsp/util.h> +#include <soc/intel/common/reset.h> +#include <string.h> +#include <timer.h> +#include <soc/pci_devs.h> + +/* Reset Request */ +#define MKHI_GLOBAL_RESET 0x0b +#define MKHI_STATUS_SUCCESS 0 + +#define GR_ORIGIN_BIOS_MEM_INIT 0x01 +#define GR_ORIGIN_BIOS_POST 0x02 +#define GR_ORIGIN_MEBX 0x03 + +#define GLOBAL_RST_TYPE 0x01 + +#define BIOS_HOST_ADD 0x00 +#define HECI_MKHI_ADD 0x07 + +static int send_heci_reset_message(void) +{ + int status; + struct reset_reply { + u8 group_id; + u8 command; + u8 reserved; + u8 result; + } __packed reply; + struct reset_message { + u8 group_id; + u8 cmd; + u8 reserved; + u8 result; + u8 req_origin; + u8 reset_type; + } __packed; + struct reset_message msg = { + .cmd = MKHI_GLOBAL_RESET, + .req_origin = GR_ORIGIN_BIOS_POST, + .reset_type = GLOBAL_RST_TYPE + }; + size_t reply_size; + + heci_reset(); + + status = heci_send(&msg, sizeof(msg), BIOS_HOST_ADD, HECI_MKHI_ADD); + if (status != 1) + return -1; + + reply_size = sizeof(reply); + memset(&reply, 0, reply_size); + if (!heci_receive(&reply, &reply_size)) + return -1; + if (reply.result != MKHI_STATUS_SUCCESS) { + printk(BIOS_DEBUG, "Returned Mkhi Status is not success!\n"); + return -1; + } + printk(BIOS_DEBUG, "Heci receive success!\n"); + return 0; +} + +void do_global_reset(void) +{ + /* Ask CSE to do the global reset */ + if (!send_heci_reset_message()) + return; + + /* global reset if CSE fail to reset */ + pmc_global_reset_enable(1); + do_full_reset(); +} + +void chipset_handle_reset(uint32_t status) +{ + switch (status) { + case FSP_STATUS_RESET_REQUIRED_3: /* Global Reset */ + printk(BIOS_DEBUG, "GLOBAL RESET!!\n"); + global_reset(); + break; + default: + printk(BIOS_ERR, "unhandled reset type %x\n", status); + die("unknown reset type"); + break; + } +} diff --git a/src/soc/intel/icelake/romstage/Makefile.inc b/src/soc/intel/icelake/romstage/Makefile.inc new file mode 100644 index 0000000000..9fc199deee --- /dev/null +++ b/src/soc/intel/icelake/romstage/Makefile.inc @@ -0,0 +1,19 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2018 Intel Corporation +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +romstage-y += fsp_params.c +romstage-y += power_state.c +romstage-y += romstage.c +romstage-y += systemagent.c diff --git a/src/soc/intel/icelake/romstage/fsp_params.c b/src/soc/intel/icelake/romstage/fsp_params.c new file mode 100644 index 0000000000..69b5b7a7ad --- /dev/null +++ b/src/soc/intel/icelake/romstage/fsp_params.c @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <fsp/util.h> +#include <soc/romstage.h> + +void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) +{ + /* ToDo: update with UPD override as FSP matures */ +} + +__weak void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__); +} diff --git a/src/soc/intel/icelake/romstage/power_state.c b/src/soc/intel/icelake/romstage/power_state.c new file mode 100644 index 0000000000..3b6d5f25de --- /dev/null +++ b/src/soc/intel/icelake/romstage/power_state.c @@ -0,0 +1,91 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/early_variables.h> +#include <arch/io.h> +#include <cbmem.h> +#include <console/console.h> +#include <device/device.h> +#include <intelblocks/pmclib.h> +#include <string.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> + +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_b & (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_b & mask) + prev_sleep_state = ACPI_S5; + } + + return prev_sleep_state; +} + +void soc_fill_power_state(struct chipset_power_state *ps) +{ + uint16_t tcobase; + uint8_t *pmc; + + tcobase = smbus_tco_regs(); + + ps->tco1_sts = inw(tcobase + TCO1_STS); + ps->tco2_sts = inw(tcobase + 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); + + 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]); +} diff --git a/src/soc/intel/icelake/romstage/romstage.c b/src/soc/intel/icelake/romstage/romstage.c new file mode 100644 index 0000000000..432cae5f33 --- /dev/null +++ b/src/soc/intel/icelake/romstage/romstage.c @@ -0,0 +1,148 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/io.h> +#include <arch/early_variables.h> +#include <assert.h> +#include <chip.h> +#include <cpu/x86/mtrr.h> +#include <cbmem.h> +#include <console/console.h> +#include <fsp/util.h> +#include <intelblocks/chip.h> +#include <intelblocks/cse.h> +#include <intelblocks/pmclib.h> +#include <memory_info.h> +#include <soc/intel/common/smbios.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <soc/romstage.h> +#include <string.h> +#include <timestamp.h> + +static struct chipset_power_state power_state CAR_GLOBAL; + +#define FSP_SMBIOS_MEMORY_INFO_GUID \ +{ \ + 0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \ + 0x8d, 0x09, 0x11, 0xcf, 0x8b, 0x9f, 0x03, 0x23 \ +} + +/* Save the DIMM information for SMBIOS table 17 */ +static void save_dimm_info(void) +{ + int channel, dimm, dimm_max, index; + size_t hob_size; + const CONTROLLER_INFO *ctrlr_info; + const CHANNEL_INFO *channel_info; + const DIMM_INFO *src_dimm; + struct dimm_info *dest_dimm; + struct memory_info *mem_info; + const MEMORY_INFO_DATA_HOB *memory_info_hob; + const uint8_t smbios_memory_info_guid[16] = + FSP_SMBIOS_MEMORY_INFO_GUID; + + /* Locate the memory info HOB, presence validated by raminit */ + memory_info_hob = fsp_find_extension_hob_by_guid( + smbios_memory_info_guid, + &hob_size); + if (memory_info_hob == NULL || hob_size == 0) { + printk(BIOS_ERR, "SMBIOS MEMORY_INFO_DATA_HOB not found\n"); + return; + } + + /* + * Allocate CBMEM area for DIMM information used to populate SMBIOS + * table 17 + */ + mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info)); + if (mem_info == NULL) { + printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n"); + return; + } + memset(mem_info, 0, sizeof(*mem_info)); + + /* Describe the first N DIMMs in the system */ + index = 0; + dimm_max = ARRAY_SIZE(mem_info->dimm); + ctrlr_info = &memory_info_hob->Controller[0]; + for (channel = 0; channel < MAX_CH && index < dimm_max; channel++) { + channel_info = &ctrlr_info->ChannelInfo[channel]; + if (channel_info->Status != CHANNEL_PRESENT) + continue; + for (dimm = 0; dimm < MAX_DIMM && index < dimm_max; dimm++) { + src_dimm = &channel_info->DimmInfo[dimm]; + dest_dimm = &mem_info->dimm[index]; + + if (src_dimm->Status != DIMM_PRESENT) + continue; + + /* Populate the DIMM information */ + dimm_info_fill(dest_dimm, + src_dimm->DimmCapacity, + memory_info_hob->MemoryType, + memory_info_hob->ConfiguredMemoryClockSpeed, + channel_info->ChannelId, + src_dimm->DimmId, + (const char *)src_dimm->ModulePartNum, + sizeof(src_dimm->ModulePartNum), + memory_info_hob->DataWidth); + index++; + } + } + mem_info->dimm_cnt = index; + printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt); +} + +asmlinkage void car_stage_entry(void) +{ + bool s3wake; + struct postcar_frame pcf; + uintptr_t top_of_ram; + struct chipset_power_state *ps = car_get_var_ptr(&power_state); + + console_init(); + + /* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */ + systemagent_early_init(); + /* initialize Heci interface */ + heci_init(HECI1_BASE_ADDRESS); + + timestamp_add_now(TS_START_ROMSTAGE); + s3wake = pmc_fill_power_state(ps) == ACPI_S3; + fsp_memory_init(s3wake); + pmc_set_disb(); + if (!s3wake) + save_dimm_info(); + if (postcar_frame_init(&pcf, 1 * KiB)) + die("Unable to initialize postcar frame.\n"); + + /* + * We need to make sure ramstage will be run cached. At this + * point exact location of ramstage in cbmem is not known. + * Instruct postcar to cache 16 megs under cbmem top which is + * a safe bet to cover ramstage. + */ + top_of_ram = (uintptr_t) cbmem_top(); + printk(BIOS_DEBUG, "top_of_ram = 0x%lx\n", top_of_ram); + top_of_ram -= 16*MiB; + postcar_frame_add_mtrr(&pcf, top_of_ram, 16*MiB, MTRR_TYPE_WRBACK); + + /* Cache the ROM as WP just below 4GiB. */ + postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRPROT); + + run_postcar_phase(&pcf); +} diff --git a/src/soc/intel/icelake/romstage/systemagent.c b/src/soc/intel/icelake/romstage/systemagent.c new file mode 100644 index 0000000000..fc046a62fa --- /dev/null +++ b/src/soc/intel/icelake/romstage/systemagent.c @@ -0,0 +1,43 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <device/device.h> +#include <intelblocks/systemagent.h> +#include <soc/iomap.h> +#include <soc/romstage.h> +#include <soc/systemagent.h> + +void systemagent_early_init(void) +{ + static const struct sa_mmio_descriptor soc_fixed_pci_resources[] = { + { MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" }, + { DMIBAR, DMI_BASE_ADDRESS, DMI_BASE_SIZE, "DMIBAR" }, + { EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" }, + }; + + static const struct sa_mmio_descriptor soc_fixed_mch_resources[] = { + { REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" }, + { EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" }, + }; + + /* Set Fixed MMIO address into PCI configuration space */ + sa_set_pci_bar(soc_fixed_pci_resources, + ARRAY_SIZE(soc_fixed_pci_resources)); + /* Set Fixed MMIO address into MCH base address */ + sa_set_mch_bar(soc_fixed_mch_resources, + ARRAY_SIZE(soc_fixed_mch_resources)); + /* Enable PAM registers */ + enable_pam_region(); +} diff --git a/src/soc/intel/icelake/sd.c b/src/soc/intel/icelake/sd.c new file mode 100644 index 0000000000..19c3bca459 --- /dev/null +++ b/src/soc/intel/icelake/sd.c @@ -0,0 +1,37 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <intelblocks/sd.h> +#include "chip.h" + +int sd_fill_soc_gpio_info(struct acpi_gpio *gpio, struct device *dev) +{ + config_t *config = dev->chip_info; + + if (!config->sdcard_cd_gpio) + return -1; + + gpio->type = ACPI_GPIO_TYPE_INTERRUPT; + gpio->pull = ACPI_GPIO_PULL_NONE; + gpio->irq.mode = ACPI_IRQ_EDGE_TRIGGERED; + gpio->irq.polarity = ACPI_IRQ_ACTIVE_BOTH; + gpio->irq.shared = ACPI_IRQ_SHARED; + gpio->irq.wake = ACPI_IRQ_WAKE; + gpio->interrupt_debounce_timeout = 10000; /* 100ms */ + gpio->pin_count = 1; + gpio->pins[0] = config->sdcard_cd_gpio; + + return 0; +} diff --git a/src/soc/intel/icelake/smihandler.c b/src/soc/intel/icelake/smihandler.c new file mode 100644 index 0000000000..0c35d722fa --- /dev/null +++ b/src/soc/intel/icelake/smihandler.c @@ -0,0 +1,133 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <chip.h> +#include <console/console.h> +#include <device/pci_def.h> +#include <intelblocks/fast_spi.h> +#include <intelblocks/p2sb.h> +#include <intelblocks/pcr.h> +#include <intelblocks/smihandler.h> +#include <soc/p2sb.h> +#include <soc/pci_devs.h> +#include <soc/pcr_ids.h> +#include <soc/pm.h> + +#define CSME0_FBE 0xf +#define CSME0_BAR 0x0 +#define CSME0_FID 0xb0 + +const struct smm_save_state_ops *get_smm_save_state_ops(void) +{ + return &em64t101_smm_ops; +} + +static void pch_disable_heci(void) +{ + struct pcr_sbi_msg msg = { + .pid = PID_CSME0, + .offset = 0, + .opcode = PCR_WRITE, + .is_posted = false, + .fast_byte_enable = CSME0_FBE, + .bar = CSME0_BAR, + .fid = CSME0_FID + }; + /* Bit 0: Set to make HECI#1 Function disable */ + uint32_t data32 = 1; + uint8_t response; + int status; + + /* unhide p2sb device */ + p2sb_unhide(); + + /* Send SBI command to make HECI#1 function disable */ + status = pcr_execute_sideband_msg(&msg, &data32, &response); + if (status && response) + printk(BIOS_ERR, "Fail to make CSME function disable\n"); + + /* Ensure to Lock SBI interface after this command */ + p2sb_disable_sideband_access(); + + /* hide p2sb device */ + p2sb_hide(); +} + +/* + * 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 ICP chipset. Hence create SMI Handler to + * perform CSME function disabling logic during SMM mode. + */ +void smihandler_soc_at_finalize(void) +{ + const struct soc_intel_icelake_config *config; + const struct device *dev = dev_find_slot(0, PCH_DEVFN_CSE); + + if (!dev || !dev->chip_info) { + printk(BIOS_ERR, "%s: Could not find SoC devicetree config!\n", + __func__); + return; + } + + config = dev->chip_info; + + if (config->HeciEnabled == 0) + pch_disable_heci(); +} + +void smihandler_soc_check_illegal_access(uint32_t tco_sts) +{ + if (!((tco_sts & (1 << 8)) && IS_ENABLED(CONFIG_SPI_FLASH_SMM) + && fast_spi_wpd_status())) + return; + + /* + * BWE is RW, so the SMI was caused by a + * write to BWE, not by a write to the BIOS + * + * This is the place where we notice someone + * is trying to tinker with the BIOS. We are + * trying to be nice and just ignore it. A more + * resolute answer would be to power down the + * box. + */ + printk(BIOS_DEBUG, "Switching back to RO\n"); + fast_spi_enable_wp(); +} + +/* SMI handlers that should be serviced in SCI mode too. */ +uint32_t smihandler_soc_get_sci_mask(void) +{ + uint32_t sci_mask = + SMI_HANDLER_SCI_EN(APM_STS_BIT) | + SMI_HANDLER_SCI_EN(SMI_ON_SLP_EN_STS_BIT); + + return sci_mask; +} + +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, + [TCO_STS_BIT] = smihandler_southbridge_tco, + [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, + [MONITOR_STS_BIT] = smihandler_southbridge_monitor, +}; diff --git a/src/soc/intel/icelake/smmrelocate.c b/src/soc/intel/icelake/smmrelocate.c new file mode 100644 index 0000000000..57a366a906 --- /dev/null +++ b/src/soc/intel/icelake/smmrelocate.c @@ -0,0 +1,309 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <types.h> +#include <string.h> +#include <device/device.h> +#include <device/pci.h> +#include <cpu/cpu.h> +#include <cpu/x86/cache.h> +#include <cpu/x86/lapic.h> +#include <cpu/x86/mp.h> +#include <cpu/x86/msr.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/smm.h> +#include <console/console.h> +#include <intelblocks/smm.h> +#include <soc/cpu.h> +#include <soc/msr.h> +#include <soc/pci_devs.h> +#include <soc/smm.h> +#include <soc/systemagent.h> +#include "chip.h" + +/* This gets filled in and used during relocation. */ +static struct smm_relocation_params smm_reloc_params; + +static inline void write_smrr(struct smm_relocation_params *relo_params) +{ + printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n", + relo_params->smrr_base.lo, relo_params->smrr_mask.lo); + wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base); + wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask); +} + +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); + + /* Write EMRR and SMRR MSRs based on indicated support. */ + mtrr_cap = rdmsr(MTRR_CAP_MSR); + if (mtrr_cap.lo & SMRR_SUPPORTED) + write_smrr(relo_params); +} + +static void fill_in_relocation_params(struct device *dev, + struct smm_relocation_params *params) +{ + void *handler_base; + size_t handler_size; + void *ied_base; + size_t ied_size; + void *tseg_base; + size_t tseg_size; + u32 emrr_base; + u32 emrr_size; + int phys_bits; + /* All range registers are aligned to 4KiB */ + const u32 rmask = ~(4 * KiB - 1); + + /* + * Some of the range registers are dependent on the number of physical + * address bits supported. + */ + phys_bits = cpu_phys_address_size(); + + smm_region(&tseg_base, &tseg_size); + smm_subregion(SMM_SUBREGION_HANDLER, &handler_base, &handler_size); + smm_subregion(SMM_SUBREGION_CHIPSET, &ied_base, &ied_size); + + params->smram_size = handler_size; + params->smram_base = (uintptr_t)handler_base; + + params->ied_base = (uintptr_t)ied_base; + params->ied_size = ied_size; + + /* SMRR has 32-bits of valid address aligned to 4KiB. */ + params->smrr_base.lo = (params->smram_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; + + /* The EMRR and UNCORE_EMRR are at IEDBASE + 2MiB */ + emrr_base = (params->ied_base + 2 * MiB) & rmask; + emrr_size = params->ied_size - 2 * MiB; + + /* + * EMRR has 46 bits of valid address aligned to 4KiB. It's dependent + * on the number of physical address bits supported. + */ + params->emrr_base.lo = emrr_base | MTRR_TYPE_WRBACK; + params->emrr_base.hi = 0; + params->emrr_mask.lo = (~(emrr_size - 1) & rmask) + | MTRR_PHYS_MASK_VALID; + params->emrr_mask.hi = (1 << (phys_bits - 32)) - 1; + + /* UNCORE_EMRR has 39 bits of valid address aligned to 4KiB. */ + params->uncore_emrr_base.lo = emrr_base; + params->uncore_emrr_base.hi = 0; + params->uncore_emrr_mask.lo = (~(emrr_size - 1) & rmask) | + MTRR_PHYS_MASK_VALID; + params->uncore_emrr_mask.hi = (1 << (39 - 32)) - 1; +} + +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", params->ied_base); + printk(BIOS_DEBUG, "IED size = 0x%08x\n", 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) +{ + struct device *dev = SA_DEV_ROOT; + + printk(BIOS_DEBUG, "Setting up SMI for CPU\n"); + + fill_in_relocation_params(dev, &smm_reloc_params); + + if (smm_reloc_params.ied_size) + setup_ied_area(&smm_reloc_params); + + *perm_smbase = smm_reloc_params.smram_base; + *perm_smsize = smm_reloc_params.smram_size; + *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(); +} + +void smm_lock(void) +{ + /* + * LOCK the SMM memory window and enable normal SMM. + * After running this function, only a full reset can + * make the SMM registers writable again. + */ + printk(BIOS_DEBUG, "Locking SMM.\n"); + pci_write_config8(SA_DEV_ROOT, SMRAM, D_LCK | G_SMRAME | C_BASE_SEG); +} diff --git a/src/soc/intel/icelake/spi.c b/src/soc/intel/icelake/spi.c new file mode 100644 index 0000000000..8e4f089c2d --- /dev/null +++ b/src/soc/intel/icelake/spi.c @@ -0,0 +1,33 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#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; + } + return -1; +} diff --git a/src/soc/intel/icelake/systemagent.c b/src/soc/intel/icelake/systemagent.c new file mode 100644 index 0000000000..7903667e9e --- /dev/null +++ b/src/soc/intel/icelake/systemagent.c @@ -0,0 +1,68 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#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" }, + /* + * PMC pci device gets hidden from PCI bus due to Silicon + * policy hence binding PMCBAR aka PWRMBASE (offset 0x10) with + * SA resources to ensure that PMCBAR falls under PCI reserved + * memory range. + * + * Note: Don't add any more resource with same offset 0x10 + * under this device space. + */ + { PCI_BASE_ADDRESS_0, PCH_PWRM_BASE_ADDRESS, PCH_PWRM_BASE_SIZE, + "PMCBAR" }, + }; + + sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources, + ARRAY_SIZE(soc_fixed_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(); +} diff --git a/src/soc/intel/icelake/uart.c b/src/soc/intel/icelake/uart.c new file mode 100644 index 0000000000..d03d21e3c1 --- /dev/null +++ b/src/soc/intel/icelake/uart.c @@ -0,0 +1,86 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017-2018 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <assert.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> +#include <string.h> + +/* Serial IO UART controller legacy mode */ +#define PCR_SERIAL_IO_GPPRVRW7 0x618 +#define PCR_SIO_PCH_LEGACY_UART(idx) (1 << (idx)) + +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); + +void soc_uart_set_legacy_mode(void) +{ + pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, + PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); + /* + * Dummy read after setting any of GPPRVRW7. + * Required for UART 16550 8-bit Legacy mode to become active + */ + lpss_clk_read(UART_BASE(CONFIG_UART_FOR_CONSOLE)); +} + +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 (struct device *)PCH_DEV_UART0; + case 1: + return (struct device *)PCH_DEV_UART1; + case 2: + return (struct device *)PCH_DEV_UART2; + default: + printk(BIOS_ERR, "Invalid UART console index\n"); + return NULL; + } +} |