soc/intel/alderlake/ramstage: Do initial SoC commit till ramstage
List of changes: 1. Add required SoC programming till ramstage 2. Include only required headers into include/soc 3. Add CPU, PCH and SA EDS document number and chapter number 4. Fill required FSP-S UPD to call FSP-S API Change-Id: I3394f585d66b14ece67cde9e45ffa1177406f35f Signed-off-by: Subrata Banik <subrata.banik@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/45759 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
parent
95bab4077e
commit
2871e0e78c
|
@ -8,25 +8,44 @@ if SOC_INTEL_ALDERLAKE
|
|||
config CPU_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
select ACPI_INTEL_HARDWARE_SLEEP_VALUES
|
||||
select ARCH_BOOTBLOCK_X86_32
|
||||
select ARCH_ROMSTAGE_X86_32
|
||||
select ARCH_VERSTAGE_X86_32
|
||||
select ARCH_ALL_STAGES_X86_32
|
||||
select BOOT_DEVICE_SUPPORTS_WRITES
|
||||
select CACHE_MRC_SETTINGS
|
||||
select CPU_INTEL_COMMON
|
||||
select CPU_INTEL_COMMON_HYPERTHREADING
|
||||
select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
|
||||
select FSP_COMPRESS_FSP_S_LZ4
|
||||
select FSP_M_XIP
|
||||
select GENERIC_GPIO_LIB
|
||||
select HAVE_FSP_GOP
|
||||
select INTEL_DESCRIPTOR_MODE_CAPABLE
|
||||
select HAVE_SMI_HANDLER
|
||||
select IDT_IN_EVERY_STAGE
|
||||
select INTEL_CAR_NEM #TODO - Enable INTEL_CAR_NEM_ENHANCED
|
||||
select INTEL_GMA_ACPI
|
||||
select INTEL_GMA_ADD_VBT if RUN_FSP_GOP
|
||||
select IOAPIC
|
||||
select MRC_SETTINGS_PROTECT
|
||||
select PARALLEL_MP
|
||||
select PARALLEL_MP_AP_WORK
|
||||
select MICROCODE_BLOB_UNDISCLOSED
|
||||
select PLATFORM_USES_FSP2_2
|
||||
select FSP_PEIM_TO_PEIM_INTERFACE
|
||||
select REG_SCRIPT
|
||||
select PMC_GLOBAL_RESET_ENABLE_LOCK
|
||||
select PMC_LOW_POWER_MODE_PROGRAM
|
||||
select SOC_INTEL_COMMON
|
||||
select SOC_INTEL_COMMON_BLOCK
|
||||
select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG
|
||||
select SOC_INTEL_COMMON_BLOCK_CPU
|
||||
select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT
|
||||
select SOC_INTEL_COMMON_BLOCK_DTT
|
||||
select SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT
|
||||
select SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2
|
||||
select SOC_INTEL_COMMON_BLOCK_HDA
|
||||
select SOC_INTEL_COMMON_BLOCK_SA
|
||||
select SOC_INTEL_COMMON_BLOCK_SMM
|
||||
select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP
|
||||
select SOC_INTEL_COMMON_PCH_BASE
|
||||
select SOC_INTEL_COMMON_RESET
|
||||
select SOC_INTEL_COMMON_BLOCK_CAR
|
||||
|
@ -35,6 +54,12 @@ config CPU_SPECIFIC_OPTIONS
|
|||
select TSC_MONOTONIC_TIMER
|
||||
select UDELAY_TSC
|
||||
select UDK_202005_BINDING
|
||||
select DISPLAY_FSP_VERSION_INFO
|
||||
select HECI_DISABLE_USING_SMM
|
||||
|
||||
config MAX_CPUS
|
||||
int
|
||||
default 24
|
||||
|
||||
config DCACHE_RAM_BASE
|
||||
default 0xfef00000
|
||||
|
@ -74,6 +99,22 @@ config HEAP_SIZE
|
|||
hex
|
||||
default 0x10000
|
||||
|
||||
config MAX_ROOT_PORTS
|
||||
int
|
||||
default 12
|
||||
|
||||
config MAX_PCIE_CLOCKS
|
||||
int
|
||||
default 12
|
||||
|
||||
config SMM_TSEG_SIZE
|
||||
hex
|
||||
default 0x800000
|
||||
|
||||
config SMM_RESERVED_SIZE
|
||||
hex
|
||||
default 0x200000
|
||||
|
||||
config PCR_BASE_ADDRESS
|
||||
hex
|
||||
default 0xfd000000
|
||||
|
@ -145,6 +186,7 @@ config CBFS_SIZE
|
|||
config PRERAM_CBMEM_CONSOLE_SIZE
|
||||
hex
|
||||
default 0x1400
|
||||
|
||||
config FSP_HEADER_PATH
|
||||
string "Location of FSP headers"
|
||||
default "src/vendorcode/intel/fsp/fsp2_0/alderlake/"
|
||||
|
|
|
@ -7,6 +7,13 @@ subdirs-y += ../../../cpu/x86/mtrr
|
|||
subdirs-y += ../../../cpu/x86/smm
|
||||
subdirs-y += ../../../cpu/x86/tsc
|
||||
|
||||
# all (bootblock, verstage, romstage, postcar, ramstage)
|
||||
all-y += gspi.c
|
||||
all-y += i2c.c
|
||||
all-y += pmutil.c
|
||||
all-y += spi.c
|
||||
all-y += uart.c
|
||||
|
||||
bootblock-y += bootblock/bootblock.c
|
||||
bootblock-y += bootblock/cpu.c
|
||||
bootblock-y += bootblock/pch.c
|
||||
|
@ -20,9 +27,28 @@ romstage-y += gpio.c
|
|||
romstage-y += meminit.c
|
||||
romstage-y += reset.c
|
||||
|
||||
ramstage-y += acpi.c
|
||||
ramstage-y += chip.c
|
||||
ramstage-y += cpu.c
|
||||
ramstage-y += elog.c
|
||||
ramstage-y += espi.c
|
||||
ramstage-y += finalize.c
|
||||
ramstage-y += fsp_params.c
|
||||
ramstage-y += gpio.c
|
||||
ramstage-y += lockdown.c
|
||||
ramstage-y += me.c
|
||||
ramstage-y += p2sb.c
|
||||
ramstage-y += pmc.c
|
||||
ramstage-y += reset.c
|
||||
ramstage-y += smmrelocate.c
|
||||
ramstage-y += soundwire.c
|
||||
ramstage-y += systemagent.c
|
||||
|
||||
smm-y += gpio.c
|
||||
smm-y += p2sb.c
|
||||
smm-y += pmutil.c
|
||||
smm-y += smihandler.c
|
||||
smm-y += uart.c
|
||||
|
||||
CPPFLAGS_common += -I$(src)/soc/intel/alderlake
|
||||
CPPFLAGS_common += -I$(src)/soc/intel/alderlake/include
|
||||
|
|
|
@ -0,0 +1,375 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_gnvs.h>
|
||||
#include <acpi/acpigen.h>
|
||||
#include <device/mmio.h>
|
||||
#include <arch/smp/mpspec.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <ec/google/chromeec/ec.h>
|
||||
#include <intelblocks/cpulib.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <intelblocks/acpi.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/nvs.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/soc_chip.h>
|
||||
#include <soc/systemagent.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include <wrdd.h>
|
||||
|
||||
/*
|
||||
* List of supported C-states in this processor.
|
||||
*/
|
||||
enum {
|
||||
C_STATE_C0, /* 0 */
|
||||
C_STATE_C1, /* 1 */
|
||||
C_STATE_C1E, /* 2 */
|
||||
C_STATE_C6_SHORT_LAT, /* 3 */
|
||||
C_STATE_C6_LONG_LAT, /* 4 */
|
||||
C_STATE_C7_SHORT_LAT, /* 5 */
|
||||
C_STATE_C7_LONG_LAT, /* 6 */
|
||||
C_STATE_C7S_SHORT_LAT, /* 7 */
|
||||
C_STATE_C7S_LONG_LAT, /* 8 */
|
||||
C_STATE_C8, /* 9 */
|
||||
C_STATE_C9, /* 10 */
|
||||
C_STATE_C10, /* 11 */
|
||||
NUM_C_STATES
|
||||
};
|
||||
|
||||
#define MWAIT_RES(state, sub_state) \
|
||||
{ \
|
||||
.addrl = (((state) << 4) | (sub_state)), \
|
||||
.space_id = ACPI_ADDRESS_SPACE_FIXED, \
|
||||
.bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \
|
||||
.bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \
|
||||
.access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \
|
||||
}
|
||||
|
||||
static const acpi_cstate_t cstate_map[NUM_C_STATES] = {
|
||||
[C_STATE_C0] = {},
|
||||
[C_STATE_C1] = {
|
||||
.latency = C1_LATENCY,
|
||||
.power = C1_POWER,
|
||||
.resource = MWAIT_RES(0, 0),
|
||||
},
|
||||
[C_STATE_C1E] = {
|
||||
.latency = C1_LATENCY,
|
||||
.power = C1_POWER,
|
||||
.resource = MWAIT_RES(0, 1),
|
||||
},
|
||||
[C_STATE_C6_SHORT_LAT] = {
|
||||
.latency = C6_LATENCY,
|
||||
.power = C6_POWER,
|
||||
.resource = MWAIT_RES(2, 0),
|
||||
},
|
||||
[C_STATE_C6_LONG_LAT] = {
|
||||
.latency = C6_LATENCY,
|
||||
.power = C6_POWER,
|
||||
.resource = MWAIT_RES(2, 1),
|
||||
},
|
||||
[C_STATE_C7_SHORT_LAT] = {
|
||||
.latency = C7_LATENCY,
|
||||
.power = C7_POWER,
|
||||
.resource = MWAIT_RES(3, 0),
|
||||
},
|
||||
[C_STATE_C7_LONG_LAT] = {
|
||||
.latency = C7_LATENCY,
|
||||
.power = C7_POWER,
|
||||
.resource = MWAIT_RES(3, 1),
|
||||
},
|
||||
[C_STATE_C7S_SHORT_LAT] = {
|
||||
.latency = C7_LATENCY,
|
||||
.power = C7_POWER,
|
||||
.resource = MWAIT_RES(3, 2),
|
||||
},
|
||||
[C_STATE_C7S_LONG_LAT] = {
|
||||
.latency = C7_LATENCY,
|
||||
.power = C7_POWER,
|
||||
.resource = MWAIT_RES(3, 3),
|
||||
},
|
||||
[C_STATE_C8] = {
|
||||
.latency = C8_LATENCY,
|
||||
.power = C8_POWER,
|
||||
.resource = MWAIT_RES(4, 0),
|
||||
},
|
||||
[C_STATE_C9] = {
|
||||
.latency = C9_LATENCY,
|
||||
.power = C9_POWER,
|
||||
.resource = MWAIT_RES(5, 0),
|
||||
},
|
||||
[C_STATE_C10] = {
|
||||
.latency = C10_LATENCY,
|
||||
.power = C10_POWER,
|
||||
.resource = MWAIT_RES(6, 0),
|
||||
},
|
||||
};
|
||||
|
||||
static int cstate_set_non_s0ix[] = {
|
||||
C_STATE_C1,
|
||||
C_STATE_C6_LONG_LAT,
|
||||
C_STATE_C7S_LONG_LAT
|
||||
};
|
||||
|
||||
static int cstate_set_s0ix[] = {
|
||||
C_STATE_C1,
|
||||
C_STATE_C7S_LONG_LAT,
|
||||
C_STATE_C10
|
||||
};
|
||||
|
||||
acpi_cstate_t *soc_get_cstate_map(size_t *entries)
|
||||
{
|
||||
static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix),
|
||||
ARRAY_SIZE(cstate_set_non_s0ix))];
|
||||
int *set;
|
||||
int i;
|
||||
|
||||
config_t *config = config_of_soc();
|
||||
|
||||
int is_s0ix_enable = config->s0ix_enable;
|
||||
|
||||
if (is_s0ix_enable) {
|
||||
*entries = ARRAY_SIZE(cstate_set_s0ix);
|
||||
set = cstate_set_s0ix;
|
||||
} else {
|
||||
*entries = ARRAY_SIZE(cstate_set_non_s0ix);
|
||||
set = cstate_set_non_s0ix;
|
||||
}
|
||||
|
||||
for (i = 0; i < *entries; i++) {
|
||||
memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t));
|
||||
map[i].ctype = i + 1;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
void soc_power_states_generation(int core_id, int cores_per_package)
|
||||
{
|
||||
config_t *config = config_of_soc();
|
||||
|
||||
if (config->eist_enable)
|
||||
/* Generate P-state tables */
|
||||
generate_p_state_entries(core_id, cores_per_package);
|
||||
}
|
||||
|
||||
void soc_fill_fadt(acpi_fadt_t *fadt)
|
||||
{
|
||||
const uint16_t pmbase = ACPI_BASE_ADDRESS;
|
||||
|
||||
config_t *config = config_of_soc();
|
||||
|
||||
fadt->pm_tmr_blk = pmbase + PM1_TMR;
|
||||
fadt->pm_tmr_len = 4;
|
||||
fadt->x_pm_tmr_blk.space_id = ACPI_ADDRESS_SPACE_IO;
|
||||
fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
|
||||
fadt->x_pm_tmr_blk.bit_offset = 0;
|
||||
fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
|
||||
fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR;
|
||||
fadt->x_pm_tmr_blk.addrh = 0x0;
|
||||
|
||||
if (config->s0ix_enable)
|
||||
fadt->flags |= ACPI_FADT_LOW_PWR_IDLE_S0;
|
||||
}
|
||||
|
||||
uint32_t soc_read_sci_irq_select(void)
|
||||
{
|
||||
return read32((void *)soc_read_pmc_base() + IRQ_REG);
|
||||
}
|
||||
|
||||
static unsigned long soc_fill_dmar(unsigned long current)
|
||||
{
|
||||
const struct device *const igfx_dev = pcidev_path_on_root(SA_DEVFN_IGD);
|
||||
const uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
|
||||
const bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
|
||||
|
||||
if (is_dev_enabled(igfx_dev) && gfxvtbar && gfxvten) {
|
||||
const unsigned long tmp = current;
|
||||
|
||||
current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
|
||||
current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
|
||||
|
||||
acpi_dmar_drhd_fixup(tmp, current);
|
||||
}
|
||||
|
||||
const struct device *const ipu_dev = pcidev_path_on_root(SA_DEVFN_IPU);
|
||||
const uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK;
|
||||
const bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED;
|
||||
|
||||
if (is_dev_enabled(ipu_dev) && ipuvtbar && ipuvten) {
|
||||
const unsigned long tmp = current;
|
||||
|
||||
current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar);
|
||||
current += acpi_create_dmar_ds_pci(current, 0, 5, 0);
|
||||
|
||||
acpi_dmar_drhd_fixup(tmp, current);
|
||||
}
|
||||
|
||||
const uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK;
|
||||
const bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED;
|
||||
|
||||
if (vtvc0bar && vtvc0en) {
|
||||
const unsigned long tmp = current;
|
||||
|
||||
current += acpi_create_dmar_drhd(current,
|
||||
DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
|
||||
current += acpi_create_dmar_ds_ioapic(current,
|
||||
2, V_P2SB_CFG_IBDF_BUS, V_P2SB_CFG_IBDF_DEV,
|
||||
V_P2SB_CFG_IBDF_FUNC);
|
||||
current += acpi_create_dmar_ds_msi_hpet(current,
|
||||
0, V_P2SB_CFG_HBDF_BUS, V_P2SB_CFG_HBDF_DEV,
|
||||
V_P2SB_CFG_HBDF_FUNC);
|
||||
|
||||
acpi_dmar_drhd_fixup(tmp, current);
|
||||
}
|
||||
|
||||
/* TCSS Thunderbolt root ports */
|
||||
for (unsigned int i = 0; i < MAX_TBT_PCIE_PORT; i++) {
|
||||
const struct device *const tbt_dev = pcidev_path_on_root(SA_DEVFN_TBT(i));
|
||||
if (is_dev_enabled(tbt_dev)) {
|
||||
const uint64_t tbtbar = MCHBAR64(TBTxBAR(i)) & VTBAR_MASK;
|
||||
const bool tbten = MCHBAR32(TBTxBAR(i)) & VTBAR_ENABLED;
|
||||
if (tbtbar && tbten) {
|
||||
const unsigned long tmp = current;
|
||||
|
||||
current += acpi_create_dmar_drhd(current, 0, 0, tbtbar);
|
||||
current += acpi_create_dmar_ds_pci_br(current, 0, 7, i);
|
||||
|
||||
acpi_dmar_drhd_fixup(tmp, current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add RMRR entry */
|
||||
if (is_dev_enabled(igfx_dev)) {
|
||||
const unsigned long tmp = current;
|
||||
current += acpi_create_dmar_rmrr(current, 0,
|
||||
sa_get_gsm_base(), sa_get_tolud_base() - 1);
|
||||
current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
|
||||
acpi_dmar_rmrr_fixup(tmp, current);
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
|
||||
struct acpi_rsdp *rsdp)
|
||||
{
|
||||
acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
|
||||
|
||||
/*
|
||||
* Create DMAR table only if we have VT-d capability and FSP does not override its
|
||||
* feature.
|
||||
*/
|
||||
if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) ||
|
||||
!(MCHBAR32(VTVC0BAR) & VTBAR_ENABLED))
|
||||
return current;
|
||||
|
||||
printk(BIOS_DEBUG, "ACPI: * DMAR\n");
|
||||
acpi_create_dmar(dmar, DMAR_INTR_REMAP | DMA_CTRL_PLATFORM_OPT_IN_FLAG, soc_fill_dmar);
|
||||
current += dmar->header.length;
|
||||
current = acpi_align_current(current);
|
||||
acpi_add_table(rsdp, dmar);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
void acpi_create_gnvs(struct global_nvs *gnvs)
|
||||
{
|
||||
config_t *config = config_of_soc();
|
||||
|
||||
/* Set unknown wake source */
|
||||
gnvs->pm1i = -1;
|
||||
|
||||
/* CPU core count */
|
||||
gnvs->pcnt = dev_count_cpu();
|
||||
|
||||
if (CONFIG(CONSOLE_CBMEM))
|
||||
/* Update the mem console pointer. */
|
||||
gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE);
|
||||
|
||||
if (CONFIG(CHROMEOS)) {
|
||||
/* Initialize Verified Boot data */
|
||||
chromeos_init_chromeos_acpi(&(gnvs->chromeos));
|
||||
if (CONFIG(EC_GOOGLE_CHROMEEC)) {
|
||||
gnvs->chromeos.vbt2 = google_ec_running_ro() ?
|
||||
ACTIVE_ECFW_RO : ACTIVE_ECFW_RW;
|
||||
} else
|
||||
gnvs->chromeos.vbt2 = ACTIVE_ECFW_RO;
|
||||
}
|
||||
|
||||
/* Enable DPTF based on mainboard configuration */
|
||||
gnvs->dpte = config->dptf_enable;
|
||||
|
||||
/* Fill in the Wifi Region id */
|
||||
gnvs->cid1 = wifi_regulatory_domain();
|
||||
|
||||
/* Set USB2/USB3 wake enable bitmaps. */
|
||||
gnvs->u2we = config->usb2_wake_enable_bitmap;
|
||||
gnvs->u3we = config->usb3_wake_enable_bitmap;
|
||||
|
||||
/* Fill in Above 4GB MMIO resource */
|
||||
sa_fill_gnvs(gnvs);
|
||||
}
|
||||
|
||||
uint32_t acpi_fill_soc_wake(uint32_t generic_pm1_en,
|
||||
const struct chipset_power_state *ps)
|
||||
{
|
||||
/*
|
||||
* WAK_STS bit is set when the system is in one of the sleep states
|
||||
* (via the SLP_EN bit) and an enabled wake event occurs. Upon setting
|
||||
* this bit, the PMC will transition the system to the ON state and
|
||||
* can only be set by hardware and can only be cleared by writing a one
|
||||
* to this bit position.
|
||||
*/
|
||||
|
||||
generic_pm1_en |= WAK_STS | RTC_EN | PWRBTN_EN;
|
||||
return generic_pm1_en;
|
||||
}
|
||||
|
||||
int soc_madt_sci_irq_polarity(int sci)
|
||||
{
|
||||
return MP_IRQ_POLARITY_HIGH;
|
||||
}
|
||||
|
||||
static int acpigen_soc_gpio_op(const char *op, unsigned int gpio_num)
|
||||
{
|
||||
/* op (gpio_num) */
|
||||
acpigen_emit_namestring(op);
|
||||
acpigen_write_integer(gpio_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpigen_soc_get_gpio_state(const char *op, unsigned int gpio_num)
|
||||
{
|
||||
/* Store (op (gpio_num), Local0) */
|
||||
acpigen_write_store();
|
||||
acpigen_soc_gpio_op(op, gpio_num);
|
||||
acpigen_emit_byte(LOCAL0_OP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpigen_soc_read_rx_gpio(unsigned int gpio_num)
|
||||
{
|
||||
return acpigen_soc_get_gpio_state("\\_SB.PCI0.GRXS", gpio_num);
|
||||
}
|
||||
|
||||
int acpigen_soc_get_tx_gpio(unsigned int gpio_num)
|
||||
{
|
||||
return acpigen_soc_get_gpio_state("\\_SB.PCI0.GTXS", gpio_num);
|
||||
}
|
||||
|
||||
int acpigen_soc_set_tx_gpio(unsigned int gpio_num)
|
||||
{
|
||||
return acpigen_soc_gpio_op("\\_SB.PCI0.STXS", gpio_num);
|
||||
}
|
||||
|
||||
int acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
|
||||
{
|
||||
return acpigen_soc_gpio_op("\\_SB.PCI0.CTXS", gpio_num);
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <fsp/api.h>
|
||||
#include <fsp/util.h>
|
||||
#include <intelblocks/acpi.h>
|
||||
#include <intelblocks/cfg.h>
|
||||
#include <intelblocks/itss.h>
|
||||
#include <intelblocks/pcie_rp.h>
|
||||
#include <intelblocks/xdci.h>
|
||||
#include <romstage_handoff.h>
|
||||
#include <soc/intel/common/vbt.h>
|
||||
#include <soc/itss.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/soc_chip.h>
|
||||
|
||||
static const struct pcie_rp_group pch_lp_rp_groups[] = {
|
||||
{ .slot = PCH_DEV_SLOT_PCIE, .count = 8 },
|
||||
{ .slot = PCH_DEV_SLOT_PCIE_1, .count = 4 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
const char *soc_acpi_name(const struct device *dev)
|
||||
{
|
||||
if (dev->path.type == DEVICE_PATH_DOMAIN)
|
||||
return "PCI0";
|
||||
|
||||
if (dev->path.type == DEVICE_PATH_USB) {
|
||||
switch (dev->path.usb.port_type) {
|
||||
case 0:
|
||||
/* Root Hub */
|
||||
return "RHUB";
|
||||
case 2:
|
||||
/* USB2 ports */
|
||||
switch (dev->path.usb.port_id) {
|
||||
case 0: return "HS01";
|
||||
case 1: return "HS02";
|
||||
case 2: return "HS03";
|
||||
case 3: return "HS04";
|
||||
case 4: return "HS05";
|
||||
case 5: return "HS06";
|
||||
case 6: return "HS07";
|
||||
case 7: return "HS08";
|
||||
case 8: return "HS09";
|
||||
case 9: return "HS10";
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* USB3 ports */
|
||||
switch (dev->path.usb.port_id) {
|
||||
case 0: return "SS01";
|
||||
case 1: return "SS02";
|
||||
case 2: return "SS03";
|
||||
case 3: return "SS04";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (dev->path.type != DEVICE_PATH_PCI)
|
||||
return NULL;
|
||||
|
||||
switch (dev->path.pci.devfn) {
|
||||
case SA_DEVFN_ROOT: return "MCHC";
|
||||
case SA_DEVFN_TCSS_XHCI: return "TXHC";
|
||||
case SA_DEVFN_TCSS_XDCI: return "TXDC";
|
||||
case SA_DEVFN_TCSS_DMA0: return "TDM0";
|
||||
case SA_DEVFN_TCSS_DMA1: return "TDM1";
|
||||
case SA_DEVFN_TBT0: return "TRP0";
|
||||
case SA_DEVFN_TBT1: return "TRP1";
|
||||
case SA_DEVFN_TBT2: return "TRP2";
|
||||
case SA_DEVFN_TBT3: return "TRP3";
|
||||
case SA_DEVFN_IPU: return "IPU0";
|
||||
case PCH_DEVFN_ISH: return "ISHB";
|
||||
case PCH_DEVFN_XHCI: return "XHCI";
|
||||
case PCH_DEVFN_I2C0: return "I2C0";
|
||||
case PCH_DEVFN_I2C1: return "I2C1";
|
||||
case PCH_DEVFN_I2C2: return "I2C2";
|
||||
case PCH_DEVFN_I2C3: return "I2C3";
|
||||
case PCH_DEVFN_I2C4: return "I2C4";
|
||||
case PCH_DEVFN_I2C5: return "I2C5";
|
||||
case PCH_DEVFN_SATA: return "SATA";
|
||||
case PCH_DEVFN_PCIE1: return "RP01";
|
||||
case PCH_DEVFN_PCIE2: return "RP02";
|
||||
case PCH_DEVFN_PCIE3: return "RP03";
|
||||
case PCH_DEVFN_PCIE4: return "RP04";
|
||||
case PCH_DEVFN_PCIE5: return "RP05";
|
||||
case PCH_DEVFN_PCIE6: return "RP06";
|
||||
case PCH_DEVFN_PCIE7: return "RP07";
|
||||
case PCH_DEVFN_PCIE8: return "RP08";
|
||||
case PCH_DEVFN_PCIE9: return "RP09";
|
||||
case PCH_DEVFN_PCIE10: return "RP10";
|
||||
case PCH_DEVFN_PCIE11: return "RP11";
|
||||
case PCH_DEVFN_PCIE12: return "RP12";
|
||||
case PCH_DEVFN_PMC: return "PMC";
|
||||
case PCH_DEVFN_UART0: return "UAR0";
|
||||
case PCH_DEVFN_UART1: return "UAR1";
|
||||
case PCH_DEVFN_UART2: return "UAR2";
|
||||
case PCH_DEVFN_GSPI0: return "SPI0";
|
||||
case PCH_DEVFN_GSPI1: return "SPI1";
|
||||
case PCH_DEVFN_GSPI2: return "SPI2";
|
||||
case PCH_DEVFN_GSPI3: return "SPI3";
|
||||
/* Keeping ACPI device name coherent with ec.asl */
|
||||
case PCH_DEVFN_ESPI: return "LPCB";
|
||||
case PCH_DEVFN_HDA: return "HDAS";
|
||||
case PCH_DEVFN_SMBUS: return "SBUS";
|
||||
case PCH_DEVFN_GBE: return "GLAN";
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* SoC routine to fill GPIO PM mask and value for GPIO_MISCCFG register */
|
||||
static void soc_fill_gpio_pm_configuration(void)
|
||||
{
|
||||
uint8_t value[TOTAL_GPIO_COMM];
|
||||
const config_t *config = config_of_soc();
|
||||
|
||||
if (config->gpio_override_pm)
|
||||
memcpy(value, config->gpio_pm, sizeof(uint8_t) *
|
||||
TOTAL_GPIO_COMM);
|
||||
else
|
||||
memset(value, MISCCFG_ENABLE_GPIO_PM_CONFIG, sizeof(uint8_t) *
|
||||
TOTAL_GPIO_COMM);
|
||||
|
||||
gpio_pm_configure(value, TOTAL_GPIO_COMM);
|
||||
}
|
||||
|
||||
void soc_init_pre_device(void *chip_info)
|
||||
{
|
||||
/* TODO: A bug has been filed, remove this W/A once FSP is updated */
|
||||
/* Snapshot the current GPIO IRQ polarities. FSP is setting a
|
||||
* default policy that doesn't honor boards' requirements. */
|
||||
itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
|
||||
|
||||
/* Perform silicon specific init. */
|
||||
fsp_silicon_init(romstage_handoff_is_resume());
|
||||
|
||||
/* Display FIRMWARE_VERSION_INFO_HOB */
|
||||
fsp_display_fvi_version_hob();
|
||||
|
||||
/* Restore GPIO IRQ polarities back to previous settings. */
|
||||
itss_restore_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END);
|
||||
|
||||
soc_fill_gpio_pm_configuration();
|
||||
|
||||
/* Swap enabled PCI ports in device tree if needed. */
|
||||
pcie_rp_update_devicetree(pch_lp_rp_groups);
|
||||
}
|
||||
|
||||
static struct device_operations pci_domain_ops = {
|
||||
.read_resources = &pci_domain_read_resources,
|
||||
.set_resources = &pci_domain_set_resources,
|
||||
.scan_bus = &pci_domain_scan_bus,
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
.acpi_name = &soc_acpi_name,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct device_operations cpu_bus_ops = {
|
||||
.read_resources = noop_read_resources,
|
||||
.set_resources = noop_set_resources,
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
.acpi_fill_ssdt = generate_cpu_entries,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void soc_enable(struct device *dev)
|
||||
{
|
||||
/*
|
||||
* Set the operations if it is a special bus type or a hidden PCI
|
||||
* device.
|
||||
*/
|
||||
if (dev->path.type == DEVICE_PATH_DOMAIN)
|
||||
dev->ops = &pci_domain_ops;
|
||||
else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
|
||||
dev->ops = &cpu_bus_ops;
|
||||
else if (dev->path.type == DEVICE_PATH_PCI &&
|
||||
dev->path.pci.devfn == PCH_DEVFN_PMC)
|
||||
dev->ops = &pmc_ops;
|
||||
}
|
||||
|
||||
struct chip_operations soc_intel_alderlake_ops = {
|
||||
CHIP_NAME("Intel Alderlake")
|
||||
.enable_dev = &soc_enable,
|
||||
.init = &soc_init_pre_device,
|
||||
};
|
|
@ -11,6 +11,8 @@
|
|||
#include <soc/pch.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/serialio.h>
|
||||
#include <soc/usb.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_HD_AUDIO_DMIC_LINKS 2
|
||||
|
@ -177,7 +179,6 @@ struct soc_intel_alderlake_config {
|
|||
uint8_t SkipExtGfxScan;
|
||||
|
||||
uint32_t GraphicsConfigPtr;
|
||||
uint8_t Device4Enable;
|
||||
|
||||
/* HeciEnabled decides the state of Heci1 at end of boot
|
||||
* Setting to 0 (default) disables Heci1 and hides the device from OS */
|
||||
|
@ -239,16 +240,25 @@ struct soc_intel_alderlake_config {
|
|||
/* Enable Pch iSCLK */
|
||||
uint8_t pch_isclk;
|
||||
|
||||
/* CNVi */
|
||||
uint8_t CnviMode;
|
||||
uint8_t CnviBtCore;
|
||||
|
||||
/* CNVi BT Audio Offload: Enable/Disable BT Audio Offload. */
|
||||
enum {
|
||||
FORCE_DISABLE,
|
||||
FORCE_ENABLE,
|
||||
} CnviBtAudioOffload;
|
||||
|
||||
/*
|
||||
* IOM Port Config
|
||||
* If a port orientation needs to be controlled by the SOC this setting must be
|
||||
* updated to reflect the correct GPIOs being used for the SOC port flipping.
|
||||
* There are 4 ports each with a pair of GPIOs for Pull Up and Pull Down
|
||||
* 0,1 are pull up and pull down for port 0
|
||||
* 2,3 are pull up and pull down for port 1
|
||||
* 4,5 are pull up and pull down for port 2
|
||||
* 6,7 are pull up and pull down for port 3
|
||||
* values to be programmed correspond to the GPIO family and offsets
|
||||
*/
|
||||
uint32_t IomTypeCPortPadCfg[8];
|
||||
|
||||
/*
|
||||
* SOC Aux orientation override:
|
||||
* This is a bitfield that corresponds to up to 4 TCSS ports on ADL.
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor CPU Datasheet
|
||||
* Document number: 619501
|
||||
* Chapter number: 14
|
||||
*/
|
||||
|
||||
#include <arch/cpu.h>
|
||||
#include <console/console.h>
|
||||
#include <device/pci.h>
|
||||
#include <cpu/x86/lapic.h>
|
||||
#include <cpu/x86/mp.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/intel/smm_reloc.h>
|
||||
#include <cpu/intel/turbo.h>
|
||||
#include <fsp/api.h>
|
||||
#include <intelblocks/cpulib.h>
|
||||
#include <intelblocks/mp_init.h>
|
||||
#include <intelblocks/msr.h>
|
||||
#include <romstage_handoff.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/msr.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/soc_chip.h>
|
||||
|
||||
static void soc_fsp_load(void)
|
||||
{
|
||||
fsps_load(romstage_handoff_is_resume());
|
||||
}
|
||||
|
||||
static void configure_isst(void)
|
||||
{
|
||||
config_t *conf = config_of_soc();
|
||||
msr_t msr;
|
||||
|
||||
if (conf->speed_shift_enable) {
|
||||
/*
|
||||
* Kernel driver checks CPUID.06h:EAX[Bit 7] to determine if HWP
|
||||
* is supported or not. coreboot needs to configure MSR 0x1AA
|
||||
* which is then reflected in the CPUID register.
|
||||
*/
|
||||
msr = rdmsr(MSR_MISC_PWR_MGMT);
|
||||
msr.lo |= MISC_PWR_MGMT_ISST_EN; /* Enable Speed Shift */
|
||||
msr.lo |= MISC_PWR_MGMT_ISST_EN_INT; /* Enable Interrupt */
|
||||
msr.lo |= MISC_PWR_MGMT_ISST_EN_EPP; /* Enable EPP */
|
||||
wrmsr(MSR_MISC_PWR_MGMT, msr);
|
||||
} else {
|
||||
msr = rdmsr(MSR_MISC_PWR_MGMT);
|
||||
msr.lo &= ~MISC_PWR_MGMT_ISST_EN; /* Disable Speed Shift */
|
||||
msr.lo &= ~MISC_PWR_MGMT_ISST_EN_INT; /* Disable Interrupt */
|
||||
msr.lo &= ~MISC_PWR_MGMT_ISST_EN_EPP; /* Disable EPP */
|
||||
wrmsr(MSR_MISC_PWR_MGMT, msr);
|
||||
}
|
||||
}
|
||||
|
||||
static void configure_misc(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
config_t *conf = config_of_soc();
|
||||
|
||||
msr = rdmsr(IA32_MISC_ENABLE);
|
||||
msr.lo |= (1 << 0); /* Fast String enable */
|
||||
msr.lo |= (1 << 3); /* TM1/TM2/EMTTM enable */
|
||||
wrmsr(IA32_MISC_ENABLE, msr);
|
||||
|
||||
/* Set EIST status */
|
||||
cpu_set_eist(conf->eist_enable);
|
||||
|
||||
/* Disable Thermal interrupts */
|
||||
msr.lo = 0;
|
||||
msr.hi = 0;
|
||||
wrmsr(IA32_THERM_INTERRUPT, msr);
|
||||
|
||||
/* Enable package critical interrupt only */
|
||||
msr.lo = 1 << 4;
|
||||
msr.hi = 0;
|
||||
wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
|
||||
|
||||
/* Enable PROCHOT */
|
||||
msr = rdmsr(MSR_POWER_CTL);
|
||||
msr.lo |= (1 << 0); /* Enable Bi-directional PROCHOT as an input*/
|
||||
msr.lo |= (1 << 23); /* Lock it */
|
||||
wrmsr(MSR_POWER_CTL, msr);
|
||||
}
|
||||
|
||||
static void enable_lapic_tpr(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
msr = rdmsr(MSR_PIC_MSG_CONTROL);
|
||||
msr.lo &= ~(1 << 10); /* Enable APIC TPR updates */
|
||||
wrmsr(MSR_PIC_MSG_CONTROL, msr);
|
||||
}
|
||||
|
||||
static void configure_dca_cap(void)
|
||||
{
|
||||
uint32_t feature_flag;
|
||||
msr_t msr;
|
||||
|
||||
/* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
|
||||
feature_flag = cpu_get_feature_flags_ecx();
|
||||
if (feature_flag & CPUID_DCA) {
|
||||
msr = rdmsr(IA32_PLATFORM_DCA_CAP);
|
||||
msr.lo |= 1;
|
||||
wrmsr(IA32_PLATFORM_DCA_CAP, msr);
|
||||
}
|
||||
}
|
||||
|
||||
static void enable_pm_timer_emulation(void)
|
||||
{
|
||||
/* ACPI PM timer emulation */
|
||||
msr_t msr;
|
||||
/*
|
||||
* The derived frequency is calculated as follows:
|
||||
* (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
|
||||
* Back solve the multiplier so the 3.579545MHz ACPI timer
|
||||
* frequency is used.
|
||||
*/
|
||||
msr.hi = (3579545ULL << 32) / CTC_FREQ;
|
||||
/* Set PM1 timer IO port and enable */
|
||||
msr.lo = (EMULATE_DELAY_VALUE << EMULATE_DELAY_OFFSET_VALUE) |
|
||||
EMULATE_PM_TMR_EN | (ACPI_BASE_ADDRESS + PM1_TMR);
|
||||
wrmsr(MSR_EMULATE_PM_TIMER, msr);
|
||||
}
|
||||
|
||||
static void set_energy_perf_bias(u8 policy)
|
||||
{
|
||||
msr_t msr;
|
||||
int ecx;
|
||||
|
||||
/* Determine if energy efficient policy is supported. */
|
||||
ecx = cpuid_ecx(0x6);
|
||||
if (!(ecx & (1 << 3)))
|
||||
return;
|
||||
|
||||
/* Energy Policy is bits 3:0 */
|
||||
msr = rdmsr(IA32_ENERGY_PERF_BIAS);
|
||||
msr.lo &= ~0xf;
|
||||
msr.lo |= policy & 0xf;
|
||||
wrmsr(IA32_ENERGY_PERF_BIAS, msr);
|
||||
}
|
||||
|
||||
/* All CPUs including BSP will run the following function. */
|
||||
void soc_core_init(struct device *cpu)
|
||||
{
|
||||
/* Clear out pending MCEs */
|
||||
/* TODO(adurbin): This should only be done on a cold boot. Also, some
|
||||
* of these banks are core vs package scope. For now every CPU clears
|
||||
* every bank. */
|
||||
mca_configure();
|
||||
|
||||
/* Enable the local CPU apics */
|
||||
enable_lapic_tpr();
|
||||
setup_lapic();
|
||||
|
||||
/* Configure Enhanced SpeedStep and Thermal Sensors */
|
||||
configure_misc();
|
||||
|
||||
/* Configure Intel Speed Shift */
|
||||
configure_isst();
|
||||
|
||||
/* Enable PM timer emulation */
|
||||
enable_pm_timer_emulation();
|
||||
|
||||
/* Enable Direct Cache Access */
|
||||
configure_dca_cap();
|
||||
|
||||
/* Set energy policy */
|
||||
set_energy_perf_bias(ENERGY_POLICY_NORMAL);
|
||||
|
||||
/* Enable Turbo */
|
||||
enable_turbo();
|
||||
}
|
||||
|
||||
static void per_cpu_smm_trigger(void)
|
||||
{
|
||||
/* Relocate the SMM handler. */
|
||||
smm_relocate();
|
||||
}
|
||||
|
||||
static void post_mp_init(void)
|
||||
{
|
||||
/* Set Max Ratio */
|
||||
cpu_set_max_ratio();
|
||||
|
||||
/*
|
||||
* Now that all APs have been relocated as well as the BSP let SMIs
|
||||
* start flowing.
|
||||
*/
|
||||
global_smi_enable();
|
||||
}
|
||||
|
||||
static const struct mp_ops mp_ops = {
|
||||
/*
|
||||
* Skip Pre MP init MTRR programming as MTRRs are mirrored from BSP,
|
||||
* that are set prior to ramstage.
|
||||
* Real MTRRs programming are being done after resource allocation.
|
||||
*/
|
||||
.pre_mp_init = soc_fsp_load,
|
||||
.get_cpu_count = get_cpu_count,
|
||||
.get_smm_info = smm_info,
|
||||
.get_microcode_info = get_microcode_info,
|
||||
.pre_mp_smm_init = smm_initialize,
|
||||
.per_cpu_smm_trigger = per_cpu_smm_trigger,
|
||||
.relocation_handler = smm_relocation_handler,
|
||||
.post_mp_init = post_mp_init,
|
||||
};
|
||||
|
||||
void soc_init_cpus(struct bus *cpu_bus)
|
||||
{
|
||||
if (mp_init_with_smm(cpu_bus, &mp_ops))
|
||||
printk(BIOS_ERR, "MP initialization failure.\n");
|
||||
|
||||
/* Thermal throttle activation offset */
|
||||
configure_tcc_thermal_target();
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <bootstate.h>
|
||||
#include <console/console.h>
|
||||
#include <stdint.h>
|
||||
#include <elog.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
|
||||
static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start)
|
||||
{
|
||||
int i;
|
||||
|
||||
gpe0_sts &= gpe0_en;
|
||||
|
||||
for (i = 0; i <= 31; i++) {
|
||||
if (gpe0_sts & (1 << i))
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_GPE, i + start);
|
||||
}
|
||||
}
|
||||
|
||||
static void pch_log_wake_source(struct chipset_power_state *ps)
|
||||
{
|
||||
/* Power Button */
|
||||
if (ps->pm1_sts & PWRBTN_STS)
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0);
|
||||
|
||||
/* RTC */
|
||||
if (ps->pm1_sts & RTC_STS)
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0);
|
||||
|
||||
/* PCI Express (TODO: determine wake device) */
|
||||
if (ps->pm1_sts & PCIEXPWAK_STS)
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0);
|
||||
|
||||
/* PME (TODO: determine wake device) */
|
||||
if (ps->gpe0_sts[GPE_STD] & PME_STS)
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0);
|
||||
|
||||
/* Internal PME (TODO: determine wake device) */
|
||||
if (ps->gpe0_sts[GPE_STD] & PME_B0_STS)
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0);
|
||||
|
||||
/* SMBUS Wake */
|
||||
if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS)
|
||||
elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0);
|
||||
|
||||
/* Log GPIO events in set 1-3 */
|
||||
pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0);
|
||||
pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32);
|
||||
pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64);
|
||||
/* Treat the STD as an extension of GPIO to obtain visibility. */
|
||||
pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96);
|
||||
}
|
||||
|
||||
static void pch_log_power_and_resets(struct chipset_power_state *ps)
|
||||
{
|
||||
/* Thermal Trip */
|
||||
if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP)
|
||||
elog_add_event(ELOG_TYPE_THERM_TRIP);
|
||||
|
||||
/* CSME-Initiated Host Reset with power down */
|
||||
if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPD)
|
||||
elog_add_event(ELOG_TYPE_MI_HRPD);
|
||||
|
||||
/* CSME-Initiated Host Reset with power cycle */
|
||||
if (ps->hpr_cause0 & HPR_CAUSE0_MI_HRPC)
|
||||
elog_add_event(ELOG_TYPE_MI_HRPC);
|
||||
|
||||
/* CSME-Initiated Host Reset without power cycle */
|
||||
if (ps->hpr_cause0 & HPR_CAUSE0_MI_HR)
|
||||
elog_add_event(ELOG_TYPE_MI_HR);
|
||||
|
||||
/* PWR_FLR Power Failure */
|
||||
if (ps->gen_pmcon_a & PWR_FLR)
|
||||
elog_add_event(ELOG_TYPE_POWER_FAIL);
|
||||
|
||||
/* SUS Well Power Failure */
|
||||
if (ps->gen_pmcon_a & SUS_PWR_FLR)
|
||||
elog_add_event(ELOG_TYPE_SUS_POWER_FAIL);
|
||||
|
||||
/* TCO Timeout */
|
||||
if (ps->prev_sleep_state != ACPI_S3 &&
|
||||
ps->tco2_sts & TCO_STS_SECOND_TO)
|
||||
elog_add_event(ELOG_TYPE_TCO_RESET);
|
||||
|
||||
/* Power Button Override */
|
||||
if (ps->pm1_sts & PRBTNOR_STS)
|
||||
elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE);
|
||||
|
||||
/* RTC reset */
|
||||
if (ps->gen_pmcon_b & RTC_BATTERY_DEAD)
|
||||
elog_add_event(ELOG_TYPE_RTC_RESET);
|
||||
|
||||
/* Host Reset Status */
|
||||
if (ps->gen_pmcon_a & HOST_RST_STS)
|
||||
elog_add_event(ELOG_TYPE_SYSTEM_RESET);
|
||||
|
||||
/* ACPI Wake Event */
|
||||
if (ps->prev_sleep_state != ACPI_S0)
|
||||
elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state);
|
||||
}
|
||||
|
||||
static void pch_log_state(void *unused)
|
||||
{
|
||||
struct chipset_power_state *ps = pmc_get_power_state();
|
||||
|
||||
if (!ps) {
|
||||
printk(BIOS_ERR, "chipset_power_state not found!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Power and Reset */
|
||||
pch_log_power_and_resets(ps);
|
||||
|
||||
/* Wake Sources */
|
||||
if (ps->prev_sleep_state > ACPI_S0)
|
||||
pch_log_wake_source(ps);
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pch_log_state, NULL);
|
||||
|
||||
void elog_gsmi_cb_platform_log_wake_source(void)
|
||||
{
|
||||
struct chipset_power_state ps;
|
||||
pmc_fill_pm_reg_info(&ps);
|
||||
pch_log_wake_source(&ps);
|
||||
}
|
|
@ -9,10 +9,14 @@
|
|||
#include <device/pci.h>
|
||||
#include <pc80/isa-dma.h>
|
||||
#include <pc80/i8259.h>
|
||||
#include <arch/ioapic.h>
|
||||
#include <intelblocks/itss.h>
|
||||
#include <intelblocks/lpc_lib.h>
|
||||
#include <intelblocks/pcr.h>
|
||||
#include <soc/espi.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/irq.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pcr_ids.h>
|
||||
#include <soc/soc_chip.h>
|
||||
|
||||
|
@ -49,3 +53,27 @@ void soc_setup_dmi_pcr_io_dec(uint32_t *gen_io_dec)
|
|||
pcr_write32(PID_DMI, PCR_DMI_LPCLGIR3, gen_io_dec[2]);
|
||||
pcr_write32(PID_DMI, PCR_DMI_LPCLGIR4, gen_io_dec[3]);
|
||||
}
|
||||
|
||||
#if ENV_RAMSTAGE
|
||||
void lpc_soc_init(struct device *dev)
|
||||
{
|
||||
/* Legacy initialization */
|
||||
isa_dma_init();
|
||||
lpc_pch_misc_init();
|
||||
|
||||
/* Enable CLKRUN_EN for power gating ESPI */
|
||||
lpc_enable_pci_clk_cntl();
|
||||
|
||||
/* Set ESPI Serial IRQ mode */
|
||||
if (CONFIG(SERIRQ_CONTINUOUS_MODE))
|
||||
lpc_set_serirq_mode(SERIRQ_CONTINUOUS);
|
||||
else
|
||||
lpc_set_serirq_mode(SERIRQ_QUIET);
|
||||
|
||||
/* Interrupt configuration */
|
||||
lpc_pch_enable_ioapic();
|
||||
lpc_pch_pirq_init();
|
||||
setup_i8259();
|
||||
i8259_configure_irq_trigger(9, 1);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 4, 29
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <device/mmio.h>
|
||||
#include <bootstate.h>
|
||||
#include <console/console.h>
|
||||
#include <console/post_codes.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <device/pci.h>
|
||||
#include <intelblocks/lpc_lib.h>
|
||||
#include <intelblocks/pcr.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <intelblocks/tco.h>
|
||||
#include <intelblocks/thermal.h>
|
||||
#include <spi-generic.h>
|
||||
#include <soc/p2sb.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pcr_ids.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/smbus.h>
|
||||
#include <soc/soc_chip.h>
|
||||
#include <soc/systemagent.h>
|
||||
|
||||
#define CAMERA1_CLK 0x8000 /* Camera 1 Clock */
|
||||
#define CAMERA2_CLK 0x8080 /* Camera 2 Clock */
|
||||
#define CAM_CLK_EN (1 << 1)
|
||||
#define MIPI_CLK (1 << 0)
|
||||
#define HDPLL_CLK (0 << 0)
|
||||
|
||||
static void pch_enable_isclk(void)
|
||||
{
|
||||
pcr_or32(PID_ISCLK, CAMERA1_CLK, CAM_CLK_EN | MIPI_CLK);
|
||||
pcr_or32(PID_ISCLK, CAMERA2_CLK, CAM_CLK_EN | MIPI_CLK);
|
||||
}
|
||||
|
||||
static void pch_handle_sideband(config_t *config)
|
||||
{
|
||||
if (config->pch_isclk)
|
||||
pch_enable_isclk();
|
||||
}
|
||||
|
||||
static void pch_finalize(void)
|
||||
{
|
||||
config_t *config;
|
||||
|
||||
/* TCO Lock down */
|
||||
tco_lockdown();
|
||||
|
||||
/* TODO: Add Thermal Configuration */
|
||||
|
||||
/*
|
||||
* Disable ACPI PM timer based on dt policy
|
||||
*
|
||||
* Disabling ACPI PM timer is necessary for XTAL OSC shutdown.
|
||||
* Disabling ACPI PM timer also switches off TCO
|
||||
*/
|
||||
config = config_of_soc();
|
||||
if (config->PmTimerDisabled)
|
||||
pmc_disable_acpi_timer();
|
||||
|
||||
/* Disable XTAL shutdown qualification for low power idle. */
|
||||
if (config->s0ix_enable)
|
||||
pmc_ignore_xtal_shutdown();
|
||||
|
||||
pch_handle_sideband(config);
|
||||
|
||||
pmc_clear_pmcon_sts();
|
||||
}
|
||||
|
||||
static void tbt_finalize(void)
|
||||
{
|
||||
int i;
|
||||
const struct device *dev;
|
||||
|
||||
/* Disable Thunderbolt PCIe root ports bus master */
|
||||
for (i = 0; i < NUM_TBT_FUNCTIONS; i++) {
|
||||
dev = pcidev_path_on_root(SA_DEVFN_TBT(i));
|
||||
if (dev)
|
||||
pci_dev_disable_bus_master(dev);
|
||||
}
|
||||
}
|
||||
|
||||
static void soc_finalize(void *unused)
|
||||
{
|
||||
printk(BIOS_DEBUG, "Finalizing chipset.\n");
|
||||
|
||||
pch_finalize();
|
||||
apm_control(APM_CNT_FINALIZE);
|
||||
tbt_finalize();
|
||||
|
||||
/* Indicate finalize step with post code */
|
||||
post_code(POST_OS_BOOT);
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);
|
||||
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);
|
|
@ -0,0 +1,317 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <assert.h>
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <fsp/api.h>
|
||||
#include <fsp/ppi/mp_service_ppi.h>
|
||||
#include <fsp/util.h>
|
||||
#include <intelblocks/lpss.h>
|
||||
#include <intelblocks/xdci.h>
|
||||
#include <intelpch/lockdown.h>
|
||||
#include <intelblocks/mp_init.h>
|
||||
#include <soc/gpio_soc_defs.h>
|
||||
#include <soc/intel/common/vbt.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <soc/soc_chip.h>
|
||||
#include <string.h>
|
||||
|
||||
/* THC assignment definition */
|
||||
#define THC_NONE 0
|
||||
#define THC_0 1
|
||||
#define THC_1 2
|
||||
|
||||
/* SATA DEVSLP idle timeout default values */
|
||||
#define DEF_DMVAL 15
|
||||
#define DEF_DITOVAL 625
|
||||
|
||||
/*
|
||||
* Chip config parameter PcieRpL1Substates uses (UPD value + 1)
|
||||
* because UPD value of 0 for PcieRpL1Substates means disabled for FSP.
|
||||
* In order to ensure that mainboard setting does not disable L1 substates
|
||||
* incorrectly, chip config parameter values are offset by 1 with 0 meaning
|
||||
* use FSP UPD default. get_l1_substate_control() ensures that the right UPD
|
||||
* value is set in fsp_params.
|
||||
* 0: Use FSP UPD default
|
||||
* 1: Disable L1 substates
|
||||
* 2: Use L1.1
|
||||
* 3: Use L1.2 (FSP UPD default)
|
||||
*/
|
||||
static int get_l1_substate_control(enum L1_substates_control ctl)
|
||||
{
|
||||
if ((ctl > L1_SS_L1_2) || (ctl == L1_SS_FSP_DEFAULT))
|
||||
ctl = L1_SS_L1_2;
|
||||
return ctl - 1;
|
||||
}
|
||||
|
||||
static void parse_devicetree(FSP_S_CONFIG *params)
|
||||
{
|
||||
const struct soc_intel_alderlake_config *config;
|
||||
config = config_of_soc();
|
||||
|
||||
for (int i = 0; i < CONFIG_SOC_INTEL_I2C_DEV_MAX; i++)
|
||||
params->SerialIoI2cMode[i] = config->SerialIoI2cMode[i];
|
||||
|
||||
for (int i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++) {
|
||||
params->SerialIoSpiMode[i] = config->SerialIoGSpiMode[i];
|
||||
params->SerialIoSpiCsMode[i] = config->SerialIoGSpiCsMode[i];
|
||||
params->SerialIoSpiCsState[i] = config->SerialIoGSpiCsState[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < CONFIG_SOC_INTEL_UART_DEV_MAX; i++)
|
||||
params->SerialIoUartMode[i] = config->SerialIoUartMode[i];
|
||||
}
|
||||
|
||||
static const pci_devfn_t serial_io_dev[] = {
|
||||
PCH_DEVFN_I2C0,
|
||||
PCH_DEVFN_I2C1,
|
||||
PCH_DEVFN_I2C2,
|
||||
PCH_DEVFN_I2C3,
|
||||
PCH_DEVFN_I2C4,
|
||||
PCH_DEVFN_I2C5,
|
||||
PCH_DEVFN_GSPI0,
|
||||
PCH_DEVFN_GSPI1,
|
||||
PCH_DEVFN_GSPI2,
|
||||
PCH_DEVFN_GSPI3,
|
||||
PCH_DEVFN_UART0,
|
||||
PCH_DEVFN_UART1,
|
||||
PCH_DEVFN_UART2
|
||||
};
|
||||
|
||||
__weak void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config)
|
||||
{
|
||||
/* Override settings per board. */
|
||||
}
|
||||
|
||||
/* UPD parameters to be initialized before SiliconInit */
|
||||
void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
|
||||
{
|
||||
int i;
|
||||
FSP_S_CONFIG *params = &supd->FspsConfig;
|
||||
|
||||
struct device *dev;
|
||||
struct soc_intel_alderlake_config *config;
|
||||
config = config_of_soc();
|
||||
mainboard_update_soc_chip_config(config);
|
||||
|
||||
/* Parse device tree and enable/disable Serial I/O devices */
|
||||
parse_devicetree(params);
|
||||
|
||||
/* Load VBT before devicetree-specific config. */
|
||||
params->GraphicsConfigPtr = (uintptr_t)vbt_get();
|
||||
|
||||
/* Check if IGD is present and fill Graphics init param accordingly */
|
||||
dev = pcidev_path_on_root(SA_DEVFN_IGD);
|
||||
params->PeiGraphicsPeimInit = CONFIG(RUN_FSP_GOP) && is_dev_enabled(dev);
|
||||
|
||||
/* Use coreboot MP PPI services if Kconfig is enabled */
|
||||
if (CONFIG(USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI))
|
||||
params->CpuMpPpi = (uintptr_t) mp_fill_ppi_services_data();
|
||||
|
||||
/* D3Hot and D3Cold for TCSS */
|
||||
params->D3HotEnable = !config->TcssD3HotDisable;
|
||||
params->D3ColdEnable = !config->TcssD3ColdDisable;
|
||||
|
||||
params->TcssAuxOri = config->TcssAuxOri;
|
||||
for (i = 0; i < 8; i++)
|
||||
params->IomTypeCPortPadCfg[i] = config->IomTypeCPortPadCfg[i];
|
||||
|
||||
/*
|
||||
* Set FSPS UPD ITbtConnectTopologyTimeoutInMs with value 0. FSP will
|
||||
* evaluate this UPD value and skip sending command. There will be no
|
||||
* delay for command completion.
|
||||
*/
|
||||
params->ITbtConnectTopologyTimeoutInMs = 0;
|
||||
|
||||
/* Chipset Lockdown */
|
||||
if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) {
|
||||
params->PchLockDownGlobalSmi = 0;
|
||||
params->PchLockDownBiosInterface = 0;
|
||||
params->PchUnlockGpioPads = 1;
|
||||
params->RtcMemoryLock = 0;
|
||||
} else {
|
||||
params->PchLockDownGlobalSmi = 1;
|
||||
params->PchLockDownBiosInterface = 1;
|
||||
params->PchUnlockGpioPads = 0;
|
||||
params->RtcMemoryLock = 1;
|
||||
}
|
||||
|
||||
/* USB */
|
||||
for (i = 0; i < ARRAY_SIZE(config->usb2_ports); i++) {
|
||||
params->PortUsb20Enable[i] = config->usb2_ports[i].enable;
|
||||
params->Usb2PhyPetxiset[i] = config->usb2_ports[i].pre_emp_bias;
|
||||
params->Usb2PhyTxiset[i] = config->usb2_ports[i].tx_bias;
|
||||
params->Usb2PhyPredeemp[i] = config->usb2_ports[i].tx_emp_enable;
|
||||
params->Usb2PhyPehalfbit[i] = config->usb2_ports[i].pre_emp_bit;
|
||||
|
||||
if (config->usb2_ports[i].enable)
|
||||
params->Usb2OverCurrentPin[i] = config->usb2_ports[i].ocpin;
|
||||
else
|
||||
params->Usb2OverCurrentPin[i] = OC_SKIP;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(config->usb3_ports); i++) {
|
||||
params->PortUsb30Enable[i] = config->usb3_ports[i].enable;
|
||||
if (config->usb3_ports[i].enable)
|
||||
params->Usb3OverCurrentPin[i] = config->usb3_ports[i].ocpin;
|
||||
else
|
||||
params->Usb3OverCurrentPin[i] = OC_SKIP;
|
||||
|
||||
if (config->usb3_ports[i].tx_de_emp) {
|
||||
params->Usb3HsioTxDeEmphEnable[i] = 1;
|
||||
params->Usb3HsioTxDeEmph[i] = config->usb3_ports[i].tx_de_emp;
|
||||
}
|
||||
if (config->usb3_ports[i].tx_downscale_amp) {
|
||||
params->Usb3HsioTxDownscaleAmpEnable[i] = 1;
|
||||
params->Usb3HsioTxDownscaleAmp[i] =
|
||||
config->usb3_ports[i].tx_downscale_amp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable xDCI controller if enabled in devicetree and allowed */
|
||||
dev = pcidev_path_on_root(PCH_DEVFN_USBOTG);
|
||||
if (dev) {
|
||||
if (!xdci_can_enable())
|
||||
dev->enabled = 0;
|
||||
params->XdciEnable = dev->enabled;
|
||||
} else {
|
||||
params->XdciEnable = 0;
|
||||
}
|
||||
|
||||
/* PCH UART selection for FSP Debug */
|
||||
params->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE;
|
||||
ASSERT(ARRAY_SIZE(params->SerialIoUartAutoFlow) > CONFIG_UART_FOR_CONSOLE);
|
||||
params->SerialIoUartAutoFlow[CONFIG_UART_FOR_CONSOLE] = 0;
|
||||
|
||||
/* SATA */
|
||||
dev = pcidev_path_on_root(PCH_DEVFN_SATA);
|
||||
params->SataEnable = is_dev_enabled(dev);
|
||||
if (params->SataEnable) {
|
||||
params->SataMode = config->SataMode;
|
||||
params->SataSalpSupport = config->SataSalpSupport;
|
||||
memcpy(params->SataPortsEnable, config->SataPortsEnable,
|
||||
sizeof(params->SataPortsEnable));
|
||||
memcpy(params->SataPortsDevSlp, config->SataPortsDevSlp,
|
||||
sizeof(params->SataPortsDevSlp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Power Optimizer for DMI and SATA.
|
||||
* DmiPwrOptimizeDisable and SataPwrOptimizeDisable is default to 0.
|
||||
* Boards not needing the optimizers explicitly disables them by setting
|
||||
* these disable variables to 1 in devicetree overrides.
|
||||
*/
|
||||
params->PchPwrOptEnable = !(config->DmiPwrOptimizeDisable);
|
||||
params->SataPwrOptEnable = !(config->SataPwrOptimizeDisable);
|
||||
|
||||
/*
|
||||
* Enable DEVSLP Idle Timeout settings DmVal and DitoVal.
|
||||
* SataPortsDmVal is the DITO multiplier. Default is 15.
|
||||
* SataPortsDitoVal is the DEVSLP Idle Timeout (DITO), Default is 625ms.
|
||||
* The default values can be changed from devicetree.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(config->SataPortsEnableDitoConfig); i++) {
|
||||
if (config->SataPortsEnableDitoConfig[i]) {
|
||||
params->SataPortsDmVal[i] = config->SataPortsDmVal[i];
|
||||
params->SataPortsDitoVal[i] = config->SataPortsDitoVal[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable TCPU for processor thermal control */
|
||||
dev = pcidev_path_on_root(SA_DEVFN_DPTF);
|
||||
params->Device4Enable = is_dev_enabled(dev);
|
||||
|
||||
/* Set TccActivationOffset */
|
||||
params->TccActivationOffset = config->tcc_offset;
|
||||
|
||||
/* LAN */
|
||||
dev = pcidev_path_on_root(PCH_DEVFN_GBE);
|
||||
params->PchLanEnable = is_dev_enabled(dev);
|
||||
|
||||
/* CNVi */
|
||||
dev = pcidev_path_on_root(PCH_DEVFN_CNVI_WIFI);
|
||||
params->CnviMode = is_dev_enabled(dev);
|
||||
|
||||
/* CNVi BT Core */
|
||||
dev = pcidev_path_on_root(PCH_DEVFN_CNVI_BT);
|
||||
params->CnviBtCore = is_dev_enabled(dev);
|
||||
|
||||
/* CNVi BT Audio Offload */
|
||||
params->CnviBtAudioOffload = config->CnviBtAudioOffload;
|
||||
|
||||
/* VMD */
|
||||
dev = pcidev_path_on_root(SA_DEVFN_VMD);
|
||||
params->VmdEnable = is_dev_enabled(dev);
|
||||
|
||||
/* THC */
|
||||
dev = pcidev_path_on_root(PCH_DEVFN_THC0);
|
||||
params->ThcPort0Assignment = is_dev_enabled(dev) ? THC_0 : THC_NONE;
|
||||
|
||||
dev = pcidev_path_on_root(PCH_DEVFN_THC1);
|
||||
params->ThcPort1Assignment = is_dev_enabled(dev) ? THC_1 : THC_NONE;
|
||||
|
||||
/* Legacy 8254 timer support */
|
||||
params->Enable8254ClockGating = !CONFIG(USE_LEGACY_8254_TIMER);
|
||||
params->Enable8254ClockGatingOnS3 = !CONFIG(USE_LEGACY_8254_TIMER);
|
||||
|
||||
/* Enable Hybrid storage auto detection */
|
||||
params->HybridStorageMode = config->HybridStorageMode;
|
||||
|
||||
for (i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) {
|
||||
params->PcieRpL1Substates[i] =
|
||||
get_l1_substate_control(config->PcieRpL1Substates[i]);
|
||||
params->PcieRpLtrEnable[i] = config->PcieRpLtrEnable[i];
|
||||
params->PcieRpAdvancedErrorReporting[i] =
|
||||
config->PcieRpAdvancedErrorReporting[i];
|
||||
params->PcieRpHotPlug[i] = config->PcieRpHotPlug[i];
|
||||
}
|
||||
|
||||
/* Enable ClkReqDetect for enabled port */
|
||||
memcpy(params->PcieRpClkReqDetect, config->PcieRpClkReqDetect,
|
||||
sizeof(config->PcieRpClkReqDetect));
|
||||
|
||||
params->PmSupport = 1;
|
||||
params->Hwp = 1;
|
||||
params->Cx = 1;
|
||||
params->PsOnEnable = 1;
|
||||
|
||||
mainboard_silicon_init_params(params);
|
||||
}
|
||||
|
||||
int soc_fsp_multi_phase_init_is_enable(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callbacks for SoC/Mainboard specific overrides for FspMultiPhaseSiInit
|
||||
* This platform supports below MultiPhaseSIInit Phase(s):
|
||||
* Phase | FSP return point | Purpose
|
||||
* ------- + ------------------------------------------------ + -------------------------------
|
||||
* 1 | After TCSS initialization completed | for TCSS specific init
|
||||
*/
|
||||
void platform_fsp_multi_phase_init_cb(uint32_t phase_index)
|
||||
{
|
||||
switch (phase_index) {
|
||||
case 1:
|
||||
/* TCSS specific initialization here */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mainboard GPIO Configuration */
|
||||
__weak void mainboard_silicon_init_params(FSP_S_CONFIG *params)
|
||||
{
|
||||
printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
|
||||
}
|
||||
|
||||
/* Return list of SOC LPSS controllers */
|
||||
const pci_devfn_t *soc_lpss_controllers_list(size_t *size)
|
||||
{
|
||||
*size = ARRAY_SIZE(serial_io_dev);
|
||||
return serial_io_dev;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 11
|
||||
*/
|
||||
|
||||
#include <intelblocks/gspi.h>
|
||||
#include <soc/pci_devs.h>
|
||||
|
||||
int gspi_soc_bus_to_devfn(unsigned int gspi_bus)
|
||||
{
|
||||
switch (gspi_bus) {
|
||||
case 0:
|
||||
return PCH_DEVFN_GSPI0;
|
||||
case 1:
|
||||
return PCH_DEVFN_GSPI1;
|
||||
case 2:
|
||||
return PCH_DEVFN_GSPI2;
|
||||
case 3:
|
||||
return PCH_DEVFN_GSPI3;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 13
|
||||
*/
|
||||
|
||||
#include <device/device.h>
|
||||
#include <drivers/i2c/designware/dw_i2c.h>
|
||||
#include <soc/pci_devs.h>
|
||||
|
||||
int dw_i2c_soc_devfn_to_bus(unsigned int devfn)
|
||||
{
|
||||
switch (devfn) {
|
||||
case PCH_DEVFN_I2C0:
|
||||
return 0;
|
||||
case PCH_DEVFN_I2C1:
|
||||
return 1;
|
||||
case PCH_DEVFN_I2C2:
|
||||
return 2;
|
||||
case PCH_DEVFN_I2C3:
|
||||
return 3;
|
||||
case PCH_DEVFN_I2C4:
|
||||
return 4;
|
||||
case PCH_DEVFN_I2C5:
|
||||
return 5;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int dw_i2c_soc_bus_to_devfn(unsigned int bus)
|
||||
{
|
||||
switch (bus) {
|
||||
case 0:
|
||||
return PCH_DEVFN_I2C0;
|
||||
case 1:
|
||||
return PCH_DEVFN_I2C1;
|
||||
case 2:
|
||||
return PCH_DEVFN_I2C2;
|
||||
case 3:
|
||||
return PCH_DEVFN_I2C3;
|
||||
case 4:
|
||||
return PCH_DEVFN_I2C4;
|
||||
case 5:
|
||||
return PCH_DEVFN_I2C5;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _SOC_ALDERLAKE_CPU_H_
|
||||
#define _SOC_ALDERLAKE_CPU_H_
|
||||
|
||||
/* Latency times in us */
|
||||
#define C1_LATENCY 1
|
||||
#define C6_LATENCY 127
|
||||
#define C7_LATENCY 253
|
||||
#define C8_LATENCY 260
|
||||
#define C9_LATENCY 487
|
||||
#define C10_LATENCY 1048
|
||||
|
||||
/* Power in units of mW */
|
||||
#define C1_POWER 0x3e8
|
||||
#define C6_POWER 0x15e
|
||||
#define C7_POWER 0xc8
|
||||
#define C8_POWER 0xc8
|
||||
#define C9_POWER 0xc8
|
||||
#define C10_POWER 0xc8
|
||||
|
||||
/* Common Timer Copy (CTC) frequency - 38.4MHz. */
|
||||
#define CTC_FREQ 38400000
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _SOC_IRQ_H_
|
||||
#define _SOC_IRQ_H_
|
||||
|
||||
#define GPIO_IRQ14 14
|
||||
#define GPIO_IRQ15 15
|
||||
|
||||
#define PCH_IRQ10 10
|
||||
#define PCH_IRQ11 11
|
||||
|
||||
#define LPSS_I2C0_IRQ 27
|
||||
#define LPSS_I2C1_IRQ 40
|
||||
#define LPSS_I2C2_IRQ 29
|
||||
#define LPSS_I2C3_IRQ 30
|
||||
#define LPSS_I2C4_IRQ 31
|
||||
#define LPSS_I2C5_IRQ 32
|
||||
#define LPSS_SPI0_IRQ 36
|
||||
#define LPSS_SPI1_IRQ 37
|
||||
#define LPSS_SPI2_IRQ 34
|
||||
#define LPSS_SPI3_IRQ 43
|
||||
|
||||
#define LPSS_UART0_IRQ 16
|
||||
#define LPSS_UART1_IRQ 17
|
||||
#define LPSS_UART2_IRQ 33
|
||||
|
||||
#define HDA_IRQ 16
|
||||
#define SMBUS_IRQ 16
|
||||
#define TRACEHUB_IRQ 16
|
||||
|
||||
#define PCIE_1_IRQ 16
|
||||
#define PCIE_2_IRQ 17
|
||||
#define PCIE_3_IRQ 18
|
||||
#define PCIE_4_IRQ 19
|
||||
#define PCIE_5_IRQ 16
|
||||
#define PCIE_6_IRQ 17
|
||||
#define PCIE_7_IRQ 18
|
||||
#define PCIE_8_IRQ 19
|
||||
#define PCIE_9_IRQ 16
|
||||
#define PCIE_10_IRQ 17
|
||||
#define PCIE_11_IRQ 18
|
||||
#define PCIE_12_IRQ 19
|
||||
|
||||
#define SATA_IRQ 16
|
||||
|
||||
#define xHCI_IRQ 16
|
||||
#define xDCI_IRQ 17
|
||||
#define CNVI_WIFI_IRQ 16
|
||||
|
||||
#define CNVI_BT_IRQ 18
|
||||
|
||||
#define THC0_IRQ 23
|
||||
#define THC1_IRQ 24
|
||||
|
||||
#define ISH_IRQ 16
|
||||
|
||||
#define TBT_PCIe0_IRQ 16
|
||||
#define TBT_PCIe1_IRQ 17
|
||||
#define TBT_PCIe2_IRQ 18
|
||||
#define TBT_PCIe3_IRQ 19
|
||||
|
||||
#define HECI_1_IRQ 16
|
||||
#define HECI_2_IRQ 17
|
||||
#define HECI_3_IRQ 16
|
||||
#define HECI_4_IRQ 19
|
||||
|
||||
#define PEG_IRQ 16
|
||||
#define IGFX_IRQ 16
|
||||
#define THERMAL_IRQ 16
|
||||
#define IPU_IRQ 16
|
||||
#define GNA_IRQ 16
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef SOC_INTEL_ADL_ITSS_H
|
||||
#define SOC_INTEL_ADL_ITSS_H
|
||||
|
||||
#define GPIO_IRQ_START 50
|
||||
#define GPIO_IRQ_END ITSS_MAX_IRQ
|
||||
|
||||
#define ITSS_MAX_IRQ 119
|
||||
#define IRQS_PER_IPC 32
|
||||
#define NUM_IPC_REGS ((ITSS_MAX_IRQ + IRQS_PER_IPC - 1)/IRQS_PER_IPC)
|
||||
|
||||
#endif /* SOC_INTEL_ADL_ITSS_H */
|
|
@ -0,0 +1,45 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _ALDERLAKE_ME_H_
|
||||
#define _ALDERLAKE_ME_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* ME Host Firmware Status register 1 */
|
||||
union me_hfsts1 {
|
||||
u32 data;
|
||||
struct {
|
||||
u32 working_state: 4;
|
||||
u32 spi_protection_mode: 1;
|
||||
u32 fpt_bad: 1;
|
||||
u32 operation_state: 3;
|
||||
u32 fw_init_complete: 1;
|
||||
u32 ft_bup_ld_flr: 1;
|
||||
u32 update_in_progress: 1;
|
||||
u32 error_code: 4;
|
||||
u32 operation_mode: 4;
|
||||
u32 reset_count: 4;
|
||||
u32 boot_options_present: 1;
|
||||
u32 invoke_enhance_dbg_mode: 1;
|
||||
u32 bist_test_state: 1;
|
||||
u32 bist_reset_request: 1;
|
||||
u32 current_power_source: 2;
|
||||
u32 reserved: 1;
|
||||
u32 d0i3_support_valid: 1;
|
||||
} __packed fields;
|
||||
};
|
||||
|
||||
/* ME Host Firmware Status Register 3 */
|
||||
union me_hfsts3 {
|
||||
u32 data;
|
||||
struct {
|
||||
u32 reserved_0: 4;
|
||||
u32 fw_sku: 3;
|
||||
u32 reserved_7: 2;
|
||||
u32 reserved_9: 2;
|
||||
u32 resered_11: 3;
|
||||
u32 resered_14: 16;
|
||||
u32 reserved_30: 2;
|
||||
} __packed fields;
|
||||
};
|
||||
#endif /* _ALDERLAKE_ME_H_ */
|
|
@ -0,0 +1,96 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _SOC_ALDERLAKE_MEMINIT_H_
|
||||
#define _SOC_ALDERLAKE_MEMINIT_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <fsp/soc_binding.h>
|
||||
|
||||
#define BYTES_PER_CHANNEL 2
|
||||
#define BITS_PER_BYTE 8
|
||||
#define DQS_PER_CHANNEL 2
|
||||
|
||||
/* 64-bit Channel identification */
|
||||
enum {
|
||||
DDR_CH0,
|
||||
DDR_CH1,
|
||||
DDR_CH2,
|
||||
DDR_CH3,
|
||||
DDR_CH4,
|
||||
DDR_CH5,
|
||||
DDR_CH6,
|
||||
DDR_CH7,
|
||||
DDR_NUM_CHANNELS
|
||||
};
|
||||
/* Number of memory DIMM slots available on Alderlake board */
|
||||
#define NUM_DIMM_SLOT 16
|
||||
|
||||
struct spd_by_pointer {
|
||||
size_t spd_data_len;
|
||||
uintptr_t spd_data_ptr;
|
||||
};
|
||||
|
||||
enum mem_info_read_type {
|
||||
NOT_EXISTING, /* No memory in this slot */
|
||||
READ_SMBUS, /* Read on-module spd by SMBUS. */
|
||||
READ_SPD_CBFS, /* Find SPD file in CBFS. */
|
||||
READ_SPD_MEMPTR /* Find SPD data from pointer. */
|
||||
};
|
||||
|
||||
struct spd_info {
|
||||
enum mem_info_read_type read_type;
|
||||
union spd_data_by {
|
||||
/* To read on-module SPD when read_type is READ_SMBUS. */
|
||||
uint8_t spd_smbus_address[NUM_DIMM_SLOT];
|
||||
|
||||
/* To identify SPD file when read_type is READ_SPD_CBFS. */
|
||||
int spd_index;
|
||||
|
||||
/* To find SPD data when read_type is READ_SPD_MEMPTR. */
|
||||
struct spd_by_pointer spd_data_ptr_info;
|
||||
} spd_spec;
|
||||
};
|
||||
|
||||
/* Board-specific memory configuration information */
|
||||
struct mb_cfg {
|
||||
/* DQ mapping */
|
||||
uint8_t dq_map[DDR_NUM_CHANNELS][BYTES_PER_CHANNEL * BITS_PER_BYTE];
|
||||
|
||||
/*
|
||||
* DQS CPU<>DRAM map. Each array entry represents a
|
||||
* mapping of a dq bit on the CPU to the bit it's connected to on
|
||||
* the memory part. The array index represents the dqs bit number
|
||||
* on the memory part, and the values in the array represent which
|
||||
* pin on the CPU that DRAM pin connects to.
|
||||
*/
|
||||
uint8_t dqs_map[DDR_NUM_CHANNELS][DQS_PER_CHANNEL];
|
||||
|
||||
/*
|
||||
* Rcomp resistor values. These values represent the resistance in
|
||||
* ohms of the three rcomp resistors attached to the DDR_COMP_0,
|
||||
* DDR_COMP_1, and DDR_COMP_2 pins on the DRAM.
|
||||
*/
|
||||
uint16_t rcomp_resistor[3];
|
||||
|
||||
/* Rcomp target values. */
|
||||
uint16_t rcomp_targets[5];
|
||||
|
||||
/*
|
||||
* Early Command Training Enable/Disable Control
|
||||
* TRUE = enable, FALSE = disable
|
||||
*/
|
||||
bool ect;
|
||||
|
||||
/* Board type */
|
||||
uint8_t UserBd;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize default memory configurations for Alder Lake.
|
||||
*/
|
||||
|
||||
void memcfg_init(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *board_cfg,
|
||||
const struct spd_info *spd_info, bool half_populated);
|
||||
|
||||
#endif /* _SOC_ALDERLAKE_MEMINIT_H_ */
|
|
@ -0,0 +1,8 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _SOC_NVS_H_
|
||||
#define _SOC_NVS_H_
|
||||
|
||||
#include <intelblocks/nvs.h>
|
||||
|
||||
#endif
|
|
@ -30,6 +30,10 @@
|
|||
#define SA_DEVFN_DPTF PCI_DEVFN(SA_DEV_SLOT_DPTF, 0)
|
||||
#define SA_DEV_DPTF PCI_DEV(0, SA_DEV_SLOT_DPTF, 0)
|
||||
|
||||
#define SA_DEV_SLOT_IPU 0x05
|
||||
#define SA_DEVFN_IPU PCI_DEVFN(SA_DEV_SLOT_IPU, 0)
|
||||
#define SA_DEV_IPU PCI_DEV(0, SA_DEV_SLOT_IPU, 0)
|
||||
|
||||
#define SA_DEV_SLOT_CPU_PCIE 0x06
|
||||
#define SA_DEVFN_CPU_PCIE PCI_DEVFN(SA_DEV_SLOT_CPU_PCIE, 0)
|
||||
|
||||
|
@ -63,8 +67,10 @@
|
|||
#define PCH_DEV_SLOT_SIO0 0x10
|
||||
#define PCH_DEVFN_THC0 _PCH_DEVFN(SIO0, 0)
|
||||
#define PCH_DEVFN_THC1 _PCH_DEVFN(SIO0, 1)
|
||||
#define PCH_DEVFN_CNVI_BT _PCH_DEVFN(SIO0, 2)
|
||||
#define PCH_DEV_THC0 _PCH_DEV(SIO0, 0)
|
||||
#define PCH_DEV_THC1 _PCH_DEV(SIO0, 1)
|
||||
#define PCH_DEV_CNVI_BT _PCH_DEV(SIO0, 2)
|
||||
|
||||
#define PCH_DEV_SLOT_ISH 0x12
|
||||
#define PCH_DEVFN_ISH _PCH_DEVFN(ISH, 0)
|
||||
|
@ -72,6 +78,10 @@
|
|||
#define PCH_DEV_ISH _PCH_DEV(ISH, 0)
|
||||
#define PCH_DEV_GSPI2 _PCH_DEV(ISH, 6)
|
||||
|
||||
#define PCH_DEV_SLOT_SIO2 0x13
|
||||
#define PCH_DEVFN_GSPI3 _PCH_DEVFN(SIO2, 0)
|
||||
#define PCH_DEV_GSPI3 _PCH_DEV(SIO2, 0)
|
||||
|
||||
#define PCH_DEV_SLOT_XHCI 0x14
|
||||
#define PCH_DEVFN_XHCI _PCH_DEVFN(XHCI, 0)
|
||||
#define PCH_DEVFN_USBOTG _PCH_DEVFN(XHCI, 1)
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
#ifndef _SOC_ALDERLAKE_PMC_H_
|
||||
#define _SOC_ALDERLAKE_PMC_H_
|
||||
#include <device/device.h>
|
||||
|
||||
extern struct device_operations pmc_ops;
|
||||
|
||||
/* PCI Configuration Space (D31:F2): PMC */
|
||||
#define PWRMBASE 0x10
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _SOC_RAMSTAGE_H_
|
||||
#define _SOC_RAMSTAGE_H_
|
||||
|
||||
#include <fsp/api.h>
|
||||
#include <fsp/util.h>
|
||||
#include <soc/soc_chip.h>
|
||||
|
||||
void mainboard_silicon_init_params(FSP_S_CONFIG *params);
|
||||
void mainboard_update_soc_chip_config(struct soc_intel_alderlake_config *config);
|
||||
void soc_init_pre_device(void *chip_info);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _SERIALIO_H_
|
||||
#define _SERIALIO_H_
|
||||
|
||||
enum {
|
||||
PchSerialIoDisabled,
|
||||
PchSerialIoPci,
|
||||
PchSerialIoHidden,
|
||||
PchSerialIoLegacyUart,
|
||||
PchSerialIoSkipInit
|
||||
};
|
||||
|
||||
enum {
|
||||
PchSerialIoIndexI2C0,
|
||||
PchSerialIoIndexI2C1,
|
||||
PchSerialIoIndexI2C2,
|
||||
PchSerialIoIndexI2C3,
|
||||
PchSerialIoIndexI2C4,
|
||||
PchSerialIoIndexI2C5,
|
||||
};
|
||||
|
||||
enum {
|
||||
PchSerialIoIndexGSPI0,
|
||||
PchSerialIoIndexGSPI1,
|
||||
PchSerialIoIndexGSPI2,
|
||||
PchSerialIoIndexGSPI3,
|
||||
};
|
||||
|
||||
enum {
|
||||
PchSerialIoIndexUART0,
|
||||
PchSerialIoIndexUART1,
|
||||
PchSerialIoIndexUART2,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -31,10 +31,7 @@
|
|||
#define IMRBASE 0x6a40
|
||||
#define IMRLIMIT 0x6a48
|
||||
#define IPUVTBAR 0x7880
|
||||
#define TBT0BAR 0x7888
|
||||
#define TBT1BAR 0x7890
|
||||
#define TBT2BAR 0x7898
|
||||
#define TBT3BAR 0x78a0
|
||||
#define TBTxBAR(x) (0x7888 + (x) * 8)
|
||||
|
||||
#define MAX_TBT_PCIE_PORT 4
|
||||
|
||||
|
@ -44,10 +41,10 @@
|
|||
static const struct sa_mmio_descriptor soc_vtd_resources[] = {
|
||||
{ GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" },
|
||||
{ IPUVTBAR, IPUVT_BASE_ADDRESS, IPUVT_BASE_SIZE, "IPUVTBAR" },
|
||||
{ TBT0BAR, TBT0_BASE_ADDRESS, TBT0_BASE_SIZE, "TBT0BAR" },
|
||||
{ TBT1BAR, TBT1_BASE_ADDRESS, TBT1_BASE_SIZE, "TBT1BAR" },
|
||||
{ TBT2BAR, TBT2_BASE_ADDRESS, TBT2_BASE_SIZE, "TBT2BAR" },
|
||||
{ TBT3BAR, TBT3_BASE_ADDRESS, TBT3_BASE_SIZE, "TBT3BAR" },
|
||||
{ TBTxBAR(0), TBT0_BASE_ADDRESS, TBT0_BASE_SIZE, "TBT0BAR" },
|
||||
{ TBTxBAR(1), TBT1_BASE_ADDRESS, TBT1_BASE_SIZE, "TBT1BAR" },
|
||||
{ TBTxBAR(2), TBT2_BASE_ADDRESS, TBT2_BASE_SIZE, "TBT2BAR" },
|
||||
{ TBTxBAR(3), TBT3_BASE_ADDRESS, TBT3_BASE_SIZE, "TBT3BAR" },
|
||||
{ VTVC0BAR, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE, "VTVC0BAR" },
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef _SOC_USB_H_
|
||||
#define _SOC_USB_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Per Port HS Transmitter Emphasis */
|
||||
#define USB2_EMP_OFF 0
|
||||
#define USB2_DE_EMP_ON 1
|
||||
#define USB2_PRE_EMP_ON 2
|
||||
#define USB2_DE_EMP_ON_PRE_EMP_ON 3
|
||||
|
||||
/* Per Port Half Bit Pre-emphasis */
|
||||
#define USB2_FULL_BIT_PRE_EMP 0
|
||||
#define USB2_HALF_BIT_PRE_EMP 1
|
||||
|
||||
/* Per Port HS Preemphasis Bias */
|
||||
#define USB2_BIAS_0MV 0
|
||||
#define USB2_BIAS_11P25MV 1
|
||||
#define USB2_BIAS_16P9MV 2
|
||||
#define USB2_BIAS_28P15MV 3
|
||||
#define USB2_BIAS_39P35MV 5
|
||||
#define USB2_BIAS_45MV 6
|
||||
#define USB2_BIAS_56P3MV 7
|
||||
|
||||
struct usb2_port_config {
|
||||
uint8_t enable;
|
||||
uint8_t ocpin;
|
||||
uint8_t tx_bias;
|
||||
uint8_t tx_emp_enable;
|
||||
uint8_t pre_emp_bias;
|
||||
uint8_t pre_emp_bit;
|
||||
};
|
||||
|
||||
/* USB Overcurrent pins definition */
|
||||
enum {
|
||||
OC0 = 0,
|
||||
OC1,
|
||||
OC2,
|
||||
OC3,
|
||||
OC4,
|
||||
OC5,
|
||||
OC6,
|
||||
OC7,
|
||||
OCMAX,
|
||||
OC_SKIP = 0xff, /* Skip OC programming */
|
||||
};
|
||||
|
||||
/* Standard USB Port based on length:
|
||||
* - External
|
||||
* - Back Panel
|
||||
* - OTG
|
||||
* - M.2
|
||||
* - Internal device down */
|
||||
|
||||
#define USB2_PORT_EMPTY { \
|
||||
.enable = 0, \
|
||||
.ocpin = OC_SKIP, \
|
||||
.tx_bias = USB2_BIAS_0MV, \
|
||||
.tx_emp_enable = USB2_EMP_OFF, \
|
||||
.pre_emp_bias = USB2_BIAS_0MV, \
|
||||
.pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
|
||||
}
|
||||
|
||||
/* Length = 11.5"-12" */
|
||||
#define USB2_PORT_LONG(pin) { \
|
||||
.enable = 1, \
|
||||
.ocpin = (pin), \
|
||||
.tx_bias = USB2_BIAS_39P35MV, \
|
||||
.tx_emp_enable = USB2_PRE_EMP_ON, \
|
||||
.pre_emp_bias = USB2_BIAS_56P3MV, \
|
||||
.pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
|
||||
}
|
||||
|
||||
/* Length = 6"-11.49" */
|
||||
#define USB2_PORT_MID(pin) { \
|
||||
.enable = 1, \
|
||||
.ocpin = (pin), \
|
||||
.tx_bias = USB2_BIAS_0MV, \
|
||||
.tx_emp_enable = USB2_DE_EMP_ON_PRE_EMP_ON, \
|
||||
.pre_emp_bias = USB2_BIAS_45MV, \
|
||||
.pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \
|
||||
}
|
||||
|
||||
/* Length = 3"-5.99" */
|
||||
#define USB2_PORT_SHORT(pin) { \
|
||||
.enable = 1, \
|
||||
.ocpin = (pin), \
|
||||
.tx_bias = USB2_BIAS_39P35MV, \
|
||||
.tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \
|
||||
.pre_emp_bias = USB2_BIAS_39P35MV, \
|
||||
.pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \
|
||||
}
|
||||
|
||||
/* Max TX and Pre-emp settings */
|
||||
#define USB2_PORT_MAX(pin) { \
|
||||
.enable = 1, \
|
||||
.ocpin = (pin), \
|
||||
.tx_bias = USB2_BIAS_56P3MV, \
|
||||
.tx_emp_enable = USB2_PRE_EMP_ON, \
|
||||
.pre_emp_bias = USB2_BIAS_56P3MV, \
|
||||
.pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
|
||||
}
|
||||
|
||||
/* Type-C Port, no BC1.2 charge detect module / MUX
|
||||
* Length = 3.0" - 9.00" */
|
||||
#define USB2_PORT_TYPE_C(pin) { \
|
||||
.enable = 1, \
|
||||
.ocpin = (pin), \
|
||||
.tx_bias = USB2_BIAS_0MV, \
|
||||
.tx_emp_enable = USB2_PRE_EMP_ON, \
|
||||
.pre_emp_bias = USB2_BIAS_56P3MV, \
|
||||
.pre_emp_bit = USB2_HALF_BIT_PRE_EMP, \
|
||||
}
|
||||
|
||||
struct usb3_port_config {
|
||||
uint8_t enable;
|
||||
uint8_t ocpin;
|
||||
uint8_t tx_de_emp;
|
||||
uint8_t tx_downscale_amp;
|
||||
};
|
||||
|
||||
#define USB3_PORT_EMPTY { \
|
||||
.enable = 0, \
|
||||
.ocpin = OC_SKIP, \
|
||||
.tx_de_emp = 0x00, \
|
||||
.tx_downscale_amp = 0x00, \
|
||||
}
|
||||
|
||||
#define USB3_PORT_DEFAULT(pin) { \
|
||||
.enable = 1, \
|
||||
.ocpin = (pin), \
|
||||
.tx_de_emp = 0x0, \
|
||||
.tx_downscale_amp = 0x00, \
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 4
|
||||
*/
|
||||
|
||||
#include <device/mmio.h>
|
||||
#include <intelblocks/cfg.h>
|
||||
#include <intelpch/lockdown.h>
|
||||
#include <soc/pm.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static void pmc_lock_pmsync(void)
|
||||
{
|
||||
uint8_t *pmcbase;
|
||||
uint32_t pmsyncreg;
|
||||
|
||||
pmcbase = pmc_mmio_regs();
|
||||
|
||||
pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG);
|
||||
pmsyncreg |= PCH2CPU_TPR_CFG_LOCK;
|
||||
write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
|
||||
}
|
||||
|
||||
static void pmc_lock_abase(void)
|
||||
{
|
||||
uint8_t *pmcbase;
|
||||
uint32_t reg32;
|
||||
|
||||
pmcbase = pmc_mmio_regs();
|
||||
|
||||
reg32 = read32(pmcbase + GEN_PMCON_B);
|
||||
reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK);
|
||||
write32(pmcbase + GEN_PMCON_B, reg32);
|
||||
}
|
||||
|
||||
static void pmc_lock_smi(void)
|
||||
{
|
||||
uint8_t *pmcbase;
|
||||
uint8_t reg8;
|
||||
|
||||
pmcbase = pmc_mmio_regs();
|
||||
|
||||
reg8 = read8(pmcbase + GEN_PMCON_B);
|
||||
reg8 |= SMI_LOCK;
|
||||
write8(pmcbase + GEN_PMCON_B, reg8);
|
||||
}
|
||||
|
||||
static void pmc_lockdown_cfg(int chipset_lockdown)
|
||||
{
|
||||
/* PMSYNC */
|
||||
pmc_lock_pmsync();
|
||||
/* Lock down ABASE and sleep stretching policy */
|
||||
pmc_lock_abase();
|
||||
|
||||
if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT)
|
||||
pmc_lock_smi();
|
||||
}
|
||||
|
||||
void soc_lockdown_config(int chipset_lockdown)
|
||||
{
|
||||
/* PMC lock down configuration */
|
||||
pmc_lockdown_cfg(chipset_lockdown);
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <bootstate.h>
|
||||
#include <intelblocks/cse.h>
|
||||
#include <console/console.h>
|
||||
#include <soc/me.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Host Firmware Status Register 2 */
|
||||
union me_hfsts2 {
|
||||
uint32_t data;
|
||||
struct {
|
||||
uint32_t nftp_load_failure : 1;
|
||||
uint32_t icc_prog_status : 2;
|
||||
uint32_t invoke_mebx : 1;
|
||||
uint32_t cpu_replaced : 1;
|
||||
uint32_t rsvd0 : 1;
|
||||
uint32_t mfs_failure : 1;
|
||||
uint32_t warm_reset_rqst : 1;
|
||||
uint32_t cpu_replaced_valid : 1;
|
||||
uint32_t low_power_state : 1;
|
||||
uint32_t me_power_gate : 1;
|
||||
uint32_t ipu_needed : 1;
|
||||
uint32_t forced_safe_boot : 1;
|
||||
uint32_t rsvd1 : 2;
|
||||
uint32_t listener_change : 1;
|
||||
uint32_t status_data : 8;
|
||||
uint32_t current_pmevent : 4;
|
||||
uint32_t phase : 4;
|
||||
} __packed fields;
|
||||
};
|
||||
|
||||
/* Host Firmware Status Register 4 */
|
||||
union me_hfsts4 {
|
||||
uint32_t data;
|
||||
struct {
|
||||
uint32_t rsvd0 : 9;
|
||||
uint32_t enforcement_flow : 1;
|
||||
uint32_t sx_resume_type : 1;
|
||||
uint32_t rsvd1 : 1;
|
||||
uint32_t tpms_disconnected : 1;
|
||||
uint32_t rvsd2 : 1;
|
||||
uint32_t fwsts_valid : 1;
|
||||
uint32_t boot_guard_self_test : 1;
|
||||
uint32_t rsvd3 : 16;
|
||||
} __packed fields;
|
||||
};
|
||||
|
||||
/* Host Firmware Status Register 5 */
|
||||
union me_hfsts5 {
|
||||
uint32_t data;
|
||||
struct {
|
||||
uint32_t acm_active : 1;
|
||||
uint32_t valid : 1;
|
||||
uint32_t result_code_source : 1;
|
||||
uint32_t error_status_code : 5;
|
||||
uint32_t acm_done_sts : 1;
|
||||
uint32_t timeout_count : 7;
|
||||
uint32_t scrtm_indicator : 1;
|
||||
uint32_t inc_boot_guard_acm : 4;
|
||||
uint32_t inc_key_manifest : 4;
|
||||
uint32_t inc_boot_policy : 4;
|
||||
uint32_t rsvd0 : 2;
|
||||
uint32_t start_enforcement : 1;
|
||||
} __packed fields;
|
||||
};
|
||||
|
||||
/* Host Firmware Status Register 6 */
|
||||
union me_hfsts6 {
|
||||
uint32_t data;
|
||||
struct {
|
||||
uint32_t force_boot_guard_acm : 1;
|
||||
uint32_t cpu_debug_disable : 1;
|
||||
uint32_t bsp_init_disable : 1;
|
||||
uint32_t protect_bios_env : 1;
|
||||
uint32_t rsvd0 : 2;
|
||||
uint32_t error_enforce_policy : 2;
|
||||
uint32_t measured_boot : 1;
|
||||
uint32_t verified_boot : 1;
|
||||
uint32_t boot_guard_acmsvn : 4;
|
||||
uint32_t kmsvn : 4;
|
||||
uint32_t bpmsvn : 4;
|
||||
uint32_t key_manifest_id : 4;
|
||||
uint32_t boot_policy_status : 1;
|
||||
uint32_t error : 1;
|
||||
uint32_t boot_guard_disable : 1;
|
||||
uint32_t fpf_disable : 1;
|
||||
uint32_t fpf_soc_lock : 1;
|
||||
uint32_t txt_support : 1;
|
||||
} __packed fields;
|
||||
};
|
||||
|
||||
static void dump_me_status(void *unused)
|
||||
{
|
||||
union me_hfsts1 hfsts1;
|
||||
union me_hfsts2 hfsts2;
|
||||
union me_hfsts3 hfsts3;
|
||||
union me_hfsts4 hfsts4;
|
||||
union me_hfsts5 hfsts5;
|
||||
union me_hfsts6 hfsts6;
|
||||
|
||||
if (!is_cse_enabled())
|
||||
return;
|
||||
|
||||
hfsts1.data = me_read_config32(PCI_ME_HFSTS1);
|
||||
hfsts2.data = me_read_config32(PCI_ME_HFSTS2);
|
||||
hfsts3.data = me_read_config32(PCI_ME_HFSTS3);
|
||||
hfsts4.data = me_read_config32(PCI_ME_HFSTS4);
|
||||
hfsts5.data = me_read_config32(PCI_ME_HFSTS5);
|
||||
hfsts6.data = me_read_config32(PCI_ME_HFSTS6);
|
||||
|
||||
printk(BIOS_DEBUG, "ME: HFSTS1 : 0x%08X\n", hfsts1.data);
|
||||
printk(BIOS_DEBUG, "ME: HFSTS2 : 0x%08X\n", hfsts2.data);
|
||||
printk(BIOS_DEBUG, "ME: HFSTS3 : 0x%08X\n", hfsts3.data);
|
||||
printk(BIOS_DEBUG, "ME: HFSTS4 : 0x%08X\n", hfsts4.data);
|
||||
printk(BIOS_DEBUG, "ME: HFSTS5 : 0x%08X\n", hfsts5.data);
|
||||
printk(BIOS_DEBUG, "ME: HFSTS6 : 0x%08X\n", hfsts6.data);
|
||||
|
||||
/*
|
||||
* Lock Descriptor, and Fuses must be programmed on a
|
||||
* production system to indicate ME Manufacturing mode is disabled.
|
||||
*/
|
||||
printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n",
|
||||
((hfsts1.fields.spi_protection_mode == 0) &&
|
||||
(hfsts6.fields.fpf_soc_lock == 1)) ? "NO" : "YES");
|
||||
/*
|
||||
* The SPI Protection Mode bit reflects SPI descriptor
|
||||
* locked(0) or unlocked(1).
|
||||
*/
|
||||
printk(BIOS_DEBUG, "ME: SPI Protection Mode Enabled : %s\n",
|
||||
hfsts1.fields.spi_protection_mode ? "NO" : "YES");
|
||||
printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n",
|
||||
hfsts1.fields.fpt_bad ? "BAD" : "OK");
|
||||
printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n",
|
||||
hfsts1.fields.ft_bup_ld_flr ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n",
|
||||
hfsts1.fields.fw_init_complete ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n",
|
||||
hfsts1.fields.boot_options_present ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: Update In Progress : %s\n",
|
||||
hfsts1.fields.update_in_progress ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n",
|
||||
hfsts1.fields.d0i3_support_valid ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n",
|
||||
hfsts2.fields.low_power_state ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n",
|
||||
hfsts2.fields.cpu_replaced ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n",
|
||||
hfsts2.fields.cpu_replaced_valid ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: Current Working State : %u\n",
|
||||
hfsts1.fields.working_state);
|
||||
printk(BIOS_DEBUG, "ME: Current Operation State : %u\n",
|
||||
hfsts1.fields.operation_state);
|
||||
printk(BIOS_DEBUG, "ME: Current Operation Mode : %u\n",
|
||||
hfsts1.fields.operation_mode);
|
||||
printk(BIOS_DEBUG, "ME: Error Code : %u\n",
|
||||
hfsts1.fields.error_code);
|
||||
printk(BIOS_DEBUG, "ME: Enhanced Debug Mode : %s\n",
|
||||
hfsts1.fields.invoke_enhance_dbg_mode ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: CPU Debug Disabled : %s\n",
|
||||
hfsts6.fields.cpu_debug_disable ? "YES" : "NO");
|
||||
printk(BIOS_DEBUG, "ME: TXT Support : %s\n",
|
||||
hfsts6.fields.txt_support ? "YES" : "NO");
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_EXIT, print_me_fw_version, NULL);
|
||||
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME_CHECK, BS_ON_EXIT, dump_me_status, NULL);
|
|
@ -0,0 +1,153 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 4
|
||||
*/
|
||||
|
||||
#include <acpi/acpigen.h>
|
||||
#include <console/console.h>
|
||||
#include <device/mmio.h>
|
||||
#include <device/device.h>
|
||||
#include <drivers/intel/pmc_mux/chip.h>
|
||||
#include <intelblocks/pmc.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <intelblocks/rtc.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/soc_chip.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PMC_HID "INTC1026"
|
||||
|
||||
enum pch_pmc_xtal pmc_get_xtal_freq(void)
|
||||
{
|
||||
uint8_t *const pmcbase = pmc_mmio_regs();
|
||||
|
||||
return PCH_EPOC_XTAL_FREQ(read32(pmcbase + PCH_PMC_EPOC));
|
||||
}
|
||||
|
||||
static void config_deep_sX(uint32_t offset, uint32_t mask, int sx, int enable)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint8_t *pmcbase = pmc_mmio_regs();
|
||||
|
||||
printk(BIOS_DEBUG, "%sabling Deep S%c\n",
|
||||
enable ? "En" : "Dis", sx + '0');
|
||||
reg = read32(pmcbase + offset);
|
||||
if (enable)
|
||||
reg |= mask;
|
||||
else
|
||||
reg &= ~mask;
|
||||
write32(pmcbase + offset, reg);
|
||||
}
|
||||
|
||||
static void config_deep_s5(int on_ac, int on_dc)
|
||||
{
|
||||
/* Treat S4 the same as S5. */
|
||||
config_deep_sX(S4_PWRGATE_POL, S4AC_GATE_SUS, 4, on_ac);
|
||||
config_deep_sX(S4_PWRGATE_POL, S4DC_GATE_SUS, 4, on_dc);
|
||||
config_deep_sX(S5_PWRGATE_POL, S5AC_GATE_SUS, 5, on_ac);
|
||||
config_deep_sX(S5_PWRGATE_POL, S5DC_GATE_SUS, 5, on_dc);
|
||||
}
|
||||
|
||||
static void config_deep_s3(int on_ac, int on_dc)
|
||||
{
|
||||
config_deep_sX(S3_PWRGATE_POL, S3AC_GATE_SUS, 3, on_ac);
|
||||
config_deep_sX(S3_PWRGATE_POL, S3DC_GATE_SUS, 3, on_dc);
|
||||
}
|
||||
|
||||
static void config_deep_sx(uint32_t deepsx_config)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint8_t *pmcbase = pmc_mmio_regs();
|
||||
|
||||
reg = read32(pmcbase + DSX_CFG);
|
||||
reg &= ~DSX_CFG_MASK;
|
||||
reg |= deepsx_config;
|
||||
write32(pmcbase + DSX_CFG, reg);
|
||||
}
|
||||
|
||||
static void pmc_init(struct device *dev)
|
||||
{
|
||||
const config_t *config = config_of_soc();
|
||||
|
||||
rtc_init();
|
||||
|
||||
pmc_set_power_failure_state(true);
|
||||
pmc_gpe_init();
|
||||
|
||||
config_deep_s3(config->deep_s3_enable_ac, config->deep_s3_enable_dc);
|
||||
config_deep_s5(config->deep_s5_enable_ac, config->deep_s5_enable_dc);
|
||||
config_deep_sx(config->deep_sx_config);
|
||||
}
|
||||
|
||||
static void soc_pmc_read_resources(struct device *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
|
||||
/* Add the fixed MMIO resource */
|
||||
mmio_resource(dev, 0, PCH_PWRM_BASE_ADDRESS / KiB, PCH_PWRM_BASE_SIZE / KiB);
|
||||
|
||||
/* Add the fixed I/O resource */
|
||||
res = new_resource(dev, 1);
|
||||
res->base = (resource_t)ACPI_BASE_ADDRESS;
|
||||
res->size = (resource_t)ACPI_BASE_SIZE;
|
||||
res->limit = res->base + res->size - 1;
|
||||
res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
}
|
||||
|
||||
static void soc_pmc_fill_ssdt(const struct device *dev)
|
||||
{
|
||||
const char *scope = acpi_device_scope(dev);
|
||||
const char *name = acpi_device_name(dev);
|
||||
if (!scope || !name)
|
||||
return;
|
||||
|
||||
acpigen_write_scope(scope);
|
||||
acpigen_write_device(name);
|
||||
|
||||
acpigen_write_name_string("_HID", PMC_HID);
|
||||
acpigen_write_name_string("_DDN", "Intel(R) Alder Lake IPC Controller");
|
||||
|
||||
/*
|
||||
* Part of the PCH's reserved 32 MB MMIO range (0xFC800000 - 0xFE7FFFFF).
|
||||
* The PMC gets 0xFE000000 - 0xFE00FFFF.
|
||||
*/
|
||||
acpigen_write_name("_CRS");
|
||||
acpigen_write_resourcetemplate_header();
|
||||
acpigen_write_mem32fixed(1, PCH_PWRM_BASE_ADDRESS, PCH_PWRM_BASE_SIZE);
|
||||
acpigen_write_resourcetemplate_footer();
|
||||
|
||||
acpigen_pop_len(); /* PMC Device */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
|
||||
printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), dev->chip_ops->name,
|
||||
dev_path(dev));
|
||||
}
|
||||
|
||||
static void soc_acpi_mode_init(struct device *dev)
|
||||
{
|
||||
/*
|
||||
* pmc_set_acpi_mode() should be delayed until BS_DEV_INIT in order
|
||||
* to ensure the ordering does not break the assumptions that other
|
||||
* drivers make about ACPI mode (e.g. Chrome EC). Since it disables
|
||||
* ACPI mode, other drivers may take different actions based on this
|
||||
* (e.g. Chrome EC will flush any pending hostevent bits). Because
|
||||
* TGL has its PMC device available for device_operations, it can be
|
||||
* done from the "ops->init" callback.
|
||||
*/
|
||||
pmc_set_acpi_mode();
|
||||
}
|
||||
|
||||
struct device_operations pmc_ops = {
|
||||
.read_resources = soc_pmc_read_resources,
|
||||
.set_resources = noop_set_resources,
|
||||
.init = soc_acpi_mode_init,
|
||||
.enable = pmc_init,
|
||||
#if CONFIG(HAVE_ACPI_TABLES)
|
||||
.acpi_fill_ssdt = soc_pmc_fill_ssdt,
|
||||
#endif
|
||||
.scan_bus = scan_static_bus,
|
||||
};
|
|
@ -0,0 +1,292 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* Helper functions for dealing with power management registers
|
||||
* and the differences between PCH variants.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 4
|
||||
*/
|
||||
|
||||
#define __SIMPLE_DEVICE__
|
||||
|
||||
#include <device/mmio.h>
|
||||
#include <cbmem.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <console/console.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <intelblocks/rtc.h>
|
||||
#include <intelblocks/tco.h>
|
||||
#include <security/vboot/vbnv.h>
|
||||
#include <soc/espi.h>
|
||||
#include <soc/gpe.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
#include <soc/smbus.h>
|
||||
#include <soc/soc_chip.h>
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
* SMI
|
||||
*/
|
||||
|
||||
const char *const *soc_smi_sts_array(size_t *a)
|
||||
{
|
||||
static const char *const smi_sts_bits[] = {
|
||||
[BIOS_STS_BIT] = "BIOS",
|
||||
[LEGACY_USB_STS_BIT] = "LEGACY_USB",
|
||||
[SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI",
|
||||
[APM_STS_BIT] = "APM",
|
||||
[SWSMI_TMR_STS_BIT] = "SWSMI_TMR",
|
||||
[PM1_STS_BIT] = "PM1",
|
||||
[GPE0_STS_BIT] = "GPE0",
|
||||
[GPIO_STS_BIT] = "GPI",
|
||||
[MCSMI_STS_BIT] = "MCSMI",
|
||||
[DEVMON_STS_BIT] = "DEVMON",
|
||||
[TCO_STS_BIT] = "TCO",
|
||||
[PERIODIC_STS_BIT] = "PERIODIC",
|
||||
[SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI",
|
||||
[SMBUS_SMI_STS_BIT] = "SMBUS_SMI",
|
||||
[PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI",
|
||||
[MONITOR_STS_BIT] = "MONITOR",
|
||||
[SPI_SMI_STS_BIT] = "SPI",
|
||||
[GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK",
|
||||
[ESPI_SMI_STS_BIT] = "ESPI_SMI",
|
||||
};
|
||||
|
||||
*a = ARRAY_SIZE(smi_sts_bits);
|
||||
return smi_sts_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
* TCO
|
||||
*/
|
||||
|
||||
const char *const *soc_tco_sts_array(size_t *a)
|
||||
{
|
||||
static const char *const tco_sts_bits[] = {
|
||||
[0] = "NMI2SMI",
|
||||
[1] = "SW_TCO",
|
||||
[2] = "TCO_INT",
|
||||
[3] = "TIMEOUT",
|
||||
[7] = "NEWCENTURY",
|
||||
[8] = "BIOSWR",
|
||||
[9] = "DMISCI",
|
||||
[10] = "DMISMI",
|
||||
[12] = "DMISERR",
|
||||
[13] = "SLVSEL",
|
||||
[16] = "INTRD_DET",
|
||||
[17] = "SECOND_TO",
|
||||
[18] = "BOOT",
|
||||
[20] = "SMLINK_SLV"
|
||||
};
|
||||
|
||||
*a = ARRAY_SIZE(tco_sts_bits);
|
||||
return tco_sts_bits;
|
||||
}
|
||||
|
||||
/*
|
||||
* GPE0
|
||||
*/
|
||||
|
||||
const char *const *soc_std_gpe_sts_array(size_t *a)
|
||||
{
|
||||
static const char *const gpe_sts_bits[] = {
|
||||
[1] = "HOTPLUG",
|
||||
[2] = "SWGPE",
|
||||
[6] = "TCO_SCI",
|
||||
[7] = "SMB_WAK",
|
||||
[9] = "PCI_EXP",
|
||||
[10] = "BATLOW",
|
||||
[11] = "PME",
|
||||
[12] = "ME",
|
||||
[13] = "PME_B0",
|
||||
[14] = "eSPI",
|
||||
[15] = "GPIO Tier-2",
|
||||
[16] = "LAN_WAKE",
|
||||
[18] = "WADT"
|
||||
};
|
||||
|
||||
*a = ARRAY_SIZE(gpe_sts_bits);
|
||||
return gpe_sts_bits;
|
||||
}
|
||||
|
||||
void pmc_set_disb(void)
|
||||
{
|
||||
/* Set the DISB after DRAM init */
|
||||
uint8_t disb_val;
|
||||
/* Only care about bits [23:16] of register GEN_PMCON_A */
|
||||
uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2);
|
||||
|
||||
disb_val = read8(addr);
|
||||
disb_val |= (DISB >> 16);
|
||||
|
||||
/* Don't clear bits that are write-1-to-clear */
|
||||
disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16);
|
||||
write8(addr, disb_val);
|
||||
}
|
||||
|
||||
void pmc_clear_pmcon_sts(void)
|
||||
{
|
||||
uint32_t reg_val;
|
||||
uint8_t *addr;
|
||||
addr = pmc_mmio_regs();
|
||||
|
||||
reg_val = read32(addr + GEN_PMCON_A);
|
||||
/* Clear SUS_PWR_FLR, GBL_RST_STS, HOST_RST_STS, PWR_FLR bits
|
||||
* while retaining MS4V write-1-to-clear bit */
|
||||
reg_val &= ~(MS4V);
|
||||
|
||||
write32((addr + GEN_PMCON_A), reg_val);
|
||||
}
|
||||
|
||||
/*
|
||||
* PMC controller gets hidden from PCI bus
|
||||
* during FSP-Silicon init call. Hence PWRMBASE
|
||||
* can't be accessible using PCI configuration space
|
||||
* read/write.
|
||||
*/
|
||||
uint8_t *pmc_mmio_regs(void)
|
||||
{
|
||||
return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS;
|
||||
}
|
||||
|
||||
uintptr_t soc_read_pmc_base(void)
|
||||
{
|
||||
return (uintptr_t)pmc_mmio_regs();
|
||||
}
|
||||
|
||||
uint32_t *soc_pmc_etr_addr(void)
|
||||
{
|
||||
return (uint32_t *)(soc_read_pmc_base() + ETR);
|
||||
}
|
||||
|
||||
void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2)
|
||||
{
|
||||
DEVTREE_CONST struct soc_intel_alderlake_config *config;
|
||||
|
||||
config = config_of_soc();
|
||||
|
||||
/* Assign to out variable */
|
||||
*dw0 = config->pmc_gpe0_dw0;
|
||||
*dw1 = config->pmc_gpe0_dw1;
|
||||
*dw2 = config->pmc_gpe0_dw2;
|
||||
}
|
||||
|
||||
static int rtc_failed(uint32_t gen_pmcon_b)
|
||||
{
|
||||
return !!(gen_pmcon_b & RTC_BATTERY_DEAD);
|
||||
}
|
||||
|
||||
int soc_get_rtc_failed(void)
|
||||
{
|
||||
const struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE);
|
||||
|
||||
if (!ps) {
|
||||
printk(BIOS_ERR, "Could not find power state in cbmem, RTC init aborted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return rtc_failed(ps->gen_pmcon_b);
|
||||
}
|
||||
|
||||
int vbnv_cmos_failed(void)
|
||||
{
|
||||
return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B));
|
||||
}
|
||||
|
||||
static inline int deep_s3_enabled(void)
|
||||
{
|
||||
uint32_t deep_s3_pol;
|
||||
|
||||
deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL);
|
||||
return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS));
|
||||
}
|
||||
|
||||
/* Return 0, 3, or 5 to indicate the previous sleep state. */
|
||||
int soc_prev_sleep_state(const struct chipset_power_state *ps,
|
||||
int prev_sleep_state)
|
||||
{
|
||||
|
||||
/*
|
||||
* Check for any power failure to determine if this a wake from
|
||||
* S5 because the PCH does not set the WAK_STS bit when waking
|
||||
* from a true G3 state.
|
||||
*/
|
||||
if (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))
|
||||
prev_sleep_state = ACPI_S5;
|
||||
|
||||
/*
|
||||
* If waking from S3 determine if deep S3 is enabled. If not,
|
||||
* need to check both deep sleep well and normal suspend well.
|
||||
* Otherwise just check deep sleep well.
|
||||
*/
|
||||
if (prev_sleep_state == ACPI_S3) {
|
||||
/* PWR_FLR represents deep sleep power well loss. */
|
||||
uint32_t mask = PWR_FLR;
|
||||
|
||||
/* If deep s3 isn't enabled check the suspend well too. */
|
||||
if (!deep_s3_enabled())
|
||||
mask |= SUS_PWR_FLR;
|
||||
|
||||
if (ps->gen_pmcon_a & mask)
|
||||
prev_sleep_state = ACPI_S5;
|
||||
}
|
||||
|
||||
return prev_sleep_state;
|
||||
}
|
||||
|
||||
void soc_fill_power_state(struct chipset_power_state *ps)
|
||||
{
|
||||
uint8_t *pmc;
|
||||
|
||||
ps->tco1_sts = tco_read_reg(TCO1_STS);
|
||||
ps->tco2_sts = tco_read_reg(TCO2_STS);
|
||||
|
||||
printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts);
|
||||
|
||||
pmc = pmc_mmio_regs();
|
||||
ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A);
|
||||
ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B);
|
||||
ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0);
|
||||
ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1);
|
||||
ps->hpr_cause0 = read32(pmc + HPR_CAUSE0);
|
||||
|
||||
printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n",
|
||||
ps->gen_pmcon_a, ps->gen_pmcon_b);
|
||||
|
||||
printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n",
|
||||
ps->gblrst_cause[0], ps->gblrst_cause[1]);
|
||||
|
||||
printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0);
|
||||
}
|
||||
|
||||
/* STM Support */
|
||||
uint16_t get_pmbase(void)
|
||||
{
|
||||
return (uint16_t) ACPI_BASE_ADDRESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set which power state system will be after reapplying
|
||||
* the power (from G3 State)
|
||||
*/
|
||||
void pmc_soc_set_afterg3_en(const bool on)
|
||||
{
|
||||
uint8_t reg8;
|
||||
uint8_t *const pmcbase = pmc_mmio_regs();
|
||||
|
||||
reg8 = read8(pmcbase + GEN_PMCON_A);
|
||||
if (on)
|
||||
reg8 &= ~SLEEP_AFTER_POWER_FAIL;
|
||||
else
|
||||
reg8 |= SLEEP_AFTER_POWER_FAIL;
|
||||
write8(pmcbase + GEN_PMCON_A, reg8);
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
#include <string.h>
|
||||
|
||||
static void soc_memory_init_params(FSP_M_CONFIG *m_cfg,
|
||||
const struct soc_intel_alderlake_dev_config *config)
|
||||
const struct soc_intel_alderlake_config *config)
|
||||
{
|
||||
unsigned int i;
|
||||
uint32_t mask = 0;
|
||||
|
@ -159,7 +159,7 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg,
|
|||
|
||||
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
|
||||
{
|
||||
const struct soc_intel_alderlake_dev_config *config;
|
||||
const struct soc_intel_alderlake_config *config;
|
||||
FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
|
||||
|
||||
config = config_of_soc();
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <device/pci_def.h>
|
||||
#include <intelblocks/cse.h>
|
||||
#include <intelblocks/smihandler.h>
|
||||
#include <soc/soc_chip.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pm.h>
|
||||
|
||||
/*
|
||||
* Specific SOC SMI handler during ramstage finalize phase
|
||||
*
|
||||
* BIOS can't make CSME function disable as is due to POSTBOOT_SAI
|
||||
* restriction in place from ADP chipset. Hence create SMI Handler to
|
||||
* perform CSME function disabling logic during SMM mode.
|
||||
*/
|
||||
void smihandler_soc_at_finalize(void)
|
||||
{
|
||||
const struct soc_intel_alderlake_config *config;
|
||||
|
||||
config = config_of_soc();
|
||||
|
||||
if (!config->HeciEnabled && CONFIG(HECI_DISABLE_USING_SMM))
|
||||
heci_disable();
|
||||
}
|
||||
|
||||
const smi_handler_t southbridge_smi[SMI_STS_BITS] = {
|
||||
[SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep,
|
||||
[APM_STS_BIT] = smihandler_southbridge_apmc,
|
||||
[PM1_STS_BIT] = smihandler_southbridge_pm1,
|
||||
[GPE0_STS_BIT] = smihandler_southbridge_gpe0,
|
||||
[GPIO_STS_BIT] = smihandler_southbridge_gpi,
|
||||
[ESPI_SMI_STS_BIT] = smihandler_southbridge_espi,
|
||||
[MCSMI_STS_BIT] = smihandler_southbridge_mc,
|
||||
#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE)
|
||||
[TCO_STS_BIT] = smihandler_southbridge_tco,
|
||||
#endif
|
||||
[PERIODIC_STS_BIT] = smihandler_southbridge_periodic,
|
||||
[MONITOR_STS_BIT] = smihandler_southbridge_monitor,
|
||||
};
|
|
@ -0,0 +1,251 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <cpu/intel/common/common.h>
|
||||
#include <cpu/intel/em64t101_save_state.h>
|
||||
#include <cpu/intel/smm_reloc.h>
|
||||
#include <cpu/x86/mp.h>
|
||||
#include <cpu/x86/msr.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <smp/node.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/msr.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/soc_chip.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
|
||||
static void update_save_state(int cpu, uintptr_t curr_smbase,
|
||||
uintptr_t staggered_smbase,
|
||||
struct smm_relocation_params *relo_params)
|
||||
{
|
||||
u32 smbase;
|
||||
u32 iedbase;
|
||||
|
||||
/*
|
||||
* The relocated handler runs with all CPUs concurrently. Therefore
|
||||
* stagger the entry points adjusting SMBASE downwards by save state
|
||||
* size * CPU num.
|
||||
*/
|
||||
smbase = staggered_smbase;
|
||||
iedbase = relo_params->ied_base;
|
||||
|
||||
printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x\n",
|
||||
smbase, iedbase);
|
||||
|
||||
/*
|
||||
* All threads need to set IEDBASE and SMBASE to the relocated
|
||||
* handler region. However, the save state location depends on the
|
||||
* smm_save_state_in_msrs field in the relocation parameters. If
|
||||
* smm_save_state_in_msrs is non-zero then the CPUs are relocating
|
||||
* the SMM handler in parallel, and each CPUs save state area is
|
||||
* located in their respective MSR space. If smm_save_state_in_msrs
|
||||
* is zero then the SMM relocation is happening serially so the
|
||||
* save state is at the same default location for all CPUs.
|
||||
*/
|
||||
if (relo_params->smm_save_state_in_msrs) {
|
||||
msr_t smbase_msr;
|
||||
msr_t iedbase_msr;
|
||||
|
||||
smbase_msr.lo = smbase;
|
||||
smbase_msr.hi = 0;
|
||||
|
||||
/*
|
||||
* According the BWG the IEDBASE MSR is in bits 63:32. It's
|
||||
* not clear why it differs from the SMBASE MSR.
|
||||
*/
|
||||
iedbase_msr.lo = 0;
|
||||
iedbase_msr.hi = iedbase;
|
||||
|
||||
wrmsr(SMBASE_MSR, smbase_msr);
|
||||
wrmsr(IEDBASE_MSR, iedbase_msr);
|
||||
} else {
|
||||
em64t101_smm_state_save_area_t *save_state;
|
||||
|
||||
save_state = (void *)(curr_smbase + SMM_DEFAULT_SIZE -
|
||||
sizeof(*save_state));
|
||||
|
||||
save_state->smbase = smbase;
|
||||
save_state->iedbase = iedbase;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 1 if SMM MSR save state was set. */
|
||||
static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params)
|
||||
{
|
||||
msr_t smm_mca_cap;
|
||||
|
||||
smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR);
|
||||
if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) {
|
||||
msr_t smm_feature_control;
|
||||
|
||||
smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);
|
||||
smm_feature_control.hi = 0;
|
||||
smm_feature_control.lo |= SMM_CPU_SAVE_EN;
|
||||
wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);
|
||||
relo_params->smm_save_state_in_msrs = 1;
|
||||
}
|
||||
return relo_params->smm_save_state_in_msrs;
|
||||
}
|
||||
|
||||
/*
|
||||
* The relocation work is actually performed in SMM context, but the code
|
||||
* resides in the ramstage module. This occurs by trampolining from the default
|
||||
* SMRAM entry point to here.
|
||||
*/
|
||||
void smm_relocation_handler(int cpu, uintptr_t curr_smbase,
|
||||
uintptr_t staggered_smbase)
|
||||
{
|
||||
msr_t mtrr_cap;
|
||||
struct smm_relocation_params *relo_params = &smm_reloc_params;
|
||||
|
||||
printk(BIOS_DEBUG, "In relocation handler: CPU %d\n", cpu);
|
||||
|
||||
/*
|
||||
* Determine if the processor supports saving state in MSRs. If so,
|
||||
* enable it before the non-BSPs run so that SMM relocation can occur
|
||||
* in parallel in the non-BSP CPUs.
|
||||
*/
|
||||
if (cpu == 0) {
|
||||
/*
|
||||
* If smm_save_state_in_msrs is 1 then that means this is the
|
||||
* 2nd time through the relocation handler for the BSP.
|
||||
* Parallel SMM handler relocation is taking place. However,
|
||||
* it is desired to access other CPUs save state in the real
|
||||
* SMM handler. Therefore, disable the SMM save state in MSRs
|
||||
* feature.
|
||||
*/
|
||||
if (relo_params->smm_save_state_in_msrs) {
|
||||
msr_t smm_feature_control;
|
||||
|
||||
smm_feature_control = rdmsr(SMM_FEATURE_CONTROL_MSR);
|
||||
smm_feature_control.lo &= ~SMM_CPU_SAVE_EN;
|
||||
wrmsr(SMM_FEATURE_CONTROL_MSR, smm_feature_control);
|
||||
} else if (bsp_setup_msr_save_state(relo_params))
|
||||
/*
|
||||
* Just return from relocation handler if MSR save
|
||||
* state is enabled. In that case the BSP will come
|
||||
* back into the relocation handler to setup the new
|
||||
* SMBASE as well disabling SMM save state in MSRs.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make appropriate changes to the save state map. */
|
||||
update_save_state(cpu, curr_smbase, staggered_smbase, relo_params);
|
||||
|
||||
/*
|
||||
* The SMRR MSRs are core-level registers, so if two threads that share
|
||||
* a core try to both set the lock bit (in the same physical register),
|
||||
* a #GP will be raised on the second write to that register (which is
|
||||
* exactly what the lock is supposed to do), therefore secondary threads
|
||||
* should exit here.
|
||||
*/
|
||||
if (intel_ht_sibling())
|
||||
return;
|
||||
|
||||
/* Write SMRR MSRs based on indicated support. */
|
||||
mtrr_cap = rdmsr(MTRR_CAP_MSR);
|
||||
|
||||
/* Set Lock bit if supported */
|
||||
if (mtrr_cap.lo & SMRR_LOCK_SUPPORTED)
|
||||
relo_params->smrr_mask.lo |= SMRR_PHYS_MASK_LOCK;
|
||||
|
||||
/* Write SMRRs if supported */
|
||||
if (mtrr_cap.lo & SMRR_SUPPORTED)
|
||||
write_smrr(relo_params);
|
||||
}
|
||||
|
||||
static void fill_in_relocation_params(struct smm_relocation_params *params)
|
||||
{
|
||||
uintptr_t tseg_base;
|
||||
size_t tseg_size;
|
||||
/* All range registers are aligned to 4KiB */
|
||||
const u32 rmask = ~(4 * KiB - 1);
|
||||
|
||||
smm_region(&tseg_base, &tseg_size);
|
||||
|
||||
if (!IS_ALIGNED(tseg_base, tseg_size)) {
|
||||
printk(BIOS_WARNING,
|
||||
"TSEG base not aligned with TSEG SIZE! Not setting SMRR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
smm_subregion(SMM_SUBREGION_CHIPSET, ¶ms->ied_base, ¶ms->ied_size);
|
||||
|
||||
/* SMRR has 32-bits of valid address aligned to 4KiB. */
|
||||
params->smrr_base.lo = (tseg_base & rmask) | MTRR_TYPE_WRBACK;
|
||||
params->smrr_base.hi = 0;
|
||||
params->smrr_mask.lo = (~(tseg_size - 1) & rmask) | MTRR_PHYS_MASK_VALID;
|
||||
params->smrr_mask.hi = 0;
|
||||
}
|
||||
|
||||
static void setup_ied_area(struct smm_relocation_params *params)
|
||||
{
|
||||
char *ied_base;
|
||||
|
||||
struct ied_header ied = {
|
||||
.signature = "INTEL RSVD",
|
||||
.size = params->ied_size,
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
ied_base = (void *)params->ied_base;
|
||||
|
||||
printk(BIOS_DEBUG, "IED base = 0x%08x\n", (u32)params->ied_base);
|
||||
printk(BIOS_DEBUG, "IED size = 0x%08x\n", (u32)params->ied_size);
|
||||
|
||||
/* Place IED header at IEDBASE. */
|
||||
memcpy(ied_base, &ied, sizeof(ied));
|
||||
|
||||
/* Zero out 32KiB at IEDBASE + 1MiB */
|
||||
memset(ied_base + 1 * MiB, 0, 32 * KiB);
|
||||
}
|
||||
|
||||
void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize,
|
||||
size_t *smm_save_state_size)
|
||||
{
|
||||
printk(BIOS_DEBUG, "Setting up SMI for CPU\n");
|
||||
|
||||
fill_in_relocation_params(&smm_reloc_params);
|
||||
|
||||
smm_subregion(SMM_SUBREGION_HANDLER, perm_smbase, perm_smsize);
|
||||
|
||||
if (smm_reloc_params.ied_size)
|
||||
setup_ied_area(&smm_reloc_params);
|
||||
|
||||
*smm_save_state_size = sizeof(em64t101_smm_state_save_area_t);
|
||||
}
|
||||
|
||||
void smm_initialize(void)
|
||||
{
|
||||
/* Clear the SMM state in the southbridge. */
|
||||
smm_southbridge_clear_state();
|
||||
|
||||
/*
|
||||
* Run the relocation handler for on the BSP to check and set up
|
||||
* parallel SMM relocation.
|
||||
*/
|
||||
smm_initiate_relocation();
|
||||
|
||||
if (smm_reloc_params.smm_save_state_in_msrs)
|
||||
printk(BIOS_DEBUG, "Doing parallel SMM relocation.\n");
|
||||
}
|
||||
|
||||
void smm_relocate(void)
|
||||
{
|
||||
/*
|
||||
* If smm_save_state_in_msrs is non-zero then parallel SMM relocation
|
||||
* shall take place. Run the relocation handler a second time on the
|
||||
* BSP to do * the final move. For APs, a relocation handler always
|
||||
* needs to be run.
|
||||
*/
|
||||
if (smm_reloc_params.smm_save_state_in_msrs)
|
||||
smm_initiate_relocation_parallel();
|
||||
else if (!boot_cpu())
|
||||
smm_initiate_relocation();
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi_soundwire.h>
|
||||
#include <console/console.h>
|
||||
#include <device/mmio.h>
|
||||
#include <device/soundwire.h>
|
||||
#include <drivers/intel/soundwire/soundwire.h>
|
||||
#include <intelblocks/pmclib.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
static const struct soundwire_link link_xtal_38_4 = {
|
||||
.clock_stop_mode0_supported = 1,
|
||||
.clock_stop_mode1_supported = 1,
|
||||
.clock_frequencies_supported_count = 1,
|
||||
.clock_frequencies_supported = { 4800 * KHz },
|
||||
.default_frame_rate = 48 * KHz,
|
||||
.default_frame_row_size = 50,
|
||||
.default_frame_col_size = 4,
|
||||
.dynamic_frame_shape = 1,
|
||||
.command_error_threshold = 16,
|
||||
};
|
||||
|
||||
static const struct soundwire_link link_xtal_24 = {
|
||||
.clock_stop_mode0_supported = 1,
|
||||
.clock_stop_mode1_supported = 1,
|
||||
.clock_frequencies_supported_count = 1,
|
||||
.clock_frequencies_supported = { 6 * MHz },
|
||||
.default_frame_rate = 48 * KHz,
|
||||
.default_frame_row_size = 125,
|
||||
.default_frame_col_size = 2,
|
||||
.dynamic_frame_shape = 1,
|
||||
.command_error_threshold = 16,
|
||||
};
|
||||
|
||||
static struct intel_soundwire_controller intel_controller = {
|
||||
.acpi_address = 0x40000000,
|
||||
.sdw = {
|
||||
/* TODO: Verified Audio in nocodec mode, add codec support */
|
||||
.master_list_count = 0
|
||||
}
|
||||
};
|
||||
|
||||
int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller)
|
||||
{
|
||||
const struct soundwire_link *link;
|
||||
enum pch_pmc_xtal xtal = pmc_get_xtal_freq();
|
||||
size_t i;
|
||||
|
||||
/* Select link config based on XTAL frequency and set IP clock. */
|
||||
switch (xtal) {
|
||||
case XTAL_24_MHZ:
|
||||
link = &link_xtal_24;
|
||||
intel_controller.ip_clock = 24 * MHz;
|
||||
break;
|
||||
case XTAL_38_4_MHZ:
|
||||
link = &link_xtal_38_4;
|
||||
intel_controller.ip_clock = 38400 * KHz;
|
||||
break;
|
||||
case XTAL_19_2_MHZ:
|
||||
default:
|
||||
printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Fill link config in controller map based on selected XTAL. */
|
||||
for (i = 0; i < intel_controller.sdw.master_list_count; i++)
|
||||
memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link));
|
||||
|
||||
*controller = &intel_controller;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 7
|
||||
*/
|
||||
|
||||
#include <intelblocks/spi.h>
|
||||
#include <soc/pci_devs.h>
|
||||
|
||||
int spi_soc_devfn_to_bus(unsigned int devfn)
|
||||
{
|
||||
switch (devfn) {
|
||||
case PCH_DEVFN_SPI:
|
||||
return 0;
|
||||
case PCH_DEVFN_GSPI0:
|
||||
return 1;
|
||||
case PCH_DEVFN_GSPI1:
|
||||
return 2;
|
||||
case PCH_DEVFN_GSPI2:
|
||||
return 3;
|
||||
case PCH_DEVFN_GSPI3:
|
||||
return 4;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor SA Datasheet
|
||||
* Document number: 619503
|
||||
* Chapter number: 3
|
||||
*/
|
||||
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <intelblocks/systemagent.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/systemagent.h>
|
||||
|
||||
/*
|
||||
* SoC implementation
|
||||
*
|
||||
* Add all known fixed memory ranges for Host Controller/Memory
|
||||
* controller.
|
||||
*/
|
||||
void soc_add_fixed_mmio_resources(struct device *dev, int *index)
|
||||
{
|
||||
static const struct sa_mmio_descriptor soc_fixed_resources[] = {
|
||||
{ PCIEXBAR, CONFIG_MMCONF_BASE_ADDRESS, CONFIG_SA_PCIEX_LENGTH,
|
||||
"PCIEXBAR" },
|
||||
{ MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" },
|
||||
{ DMIBAR, DMI_BASE_ADDRESS, DMI_BASE_SIZE, "DMIBAR" },
|
||||
{ EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" },
|
||||
{ REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" },
|
||||
{ EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },
|
||||
};
|
||||
|
||||
sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources,
|
||||
ARRAY_SIZE(soc_fixed_resources));
|
||||
|
||||
/* Add Vt-d resources if VT-d is enabled */
|
||||
if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE))
|
||||
return;
|
||||
|
||||
sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources,
|
||||
ARRAY_SIZE(soc_vtd_resources));
|
||||
}
|
||||
|
||||
/*
|
||||
* SoC implementation
|
||||
*
|
||||
* Perform System Agent Initialization during Ramstage phase.
|
||||
*/
|
||||
void soc_systemagent_init(struct device *dev)
|
||||
{
|
||||
/* Enable Power Aware Interrupt Routing */
|
||||
enable_power_aware_intr();
|
||||
|
||||
/* Enable BIOS Reset CPL */
|
||||
enable_bios_reset_cpl();
|
||||
/* TODO: Add set_power_limits() */
|
||||
}
|
||||
|
||||
uint32_t soc_systemagent_max_chan_capacity_mib(u8 capid0_a_ddrsz)
|
||||
{
|
||||
switch (capid0_a_ddrsz) {
|
||||
case 1:
|
||||
return 8192;
|
||||
case 2:
|
||||
return 4096;
|
||||
case 3:
|
||||
return 2048;
|
||||
default:
|
||||
return 65536;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* This file is created based on Intel Alder Lake Processor PCH Datasheet
|
||||
* Document number: 621483
|
||||
* Chapter number: 9
|
||||
*/
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <intelblocks/gpio.h>
|
||||
#include <intelblocks/lpss.h>
|
||||
#include <intelblocks/pcr.h>
|
||||
#include <intelblocks/uart.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/pch.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/pcr_ids.h>
|
||||
|
||||
const struct uart_gpio_pad_config uart_gpio_pads[] = {
|
||||
{
|
||||
.console_index = 0,
|
||||
.gpios = {
|
||||
PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0 RX */
|
||||
PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0 TX */
|
||||
},
|
||||
},
|
||||
{
|
||||
.console_index = 1,
|
||||
.gpios = {
|
||||
PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* UART1 RX */
|
||||
PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1), /* UART1 TX */
|
||||
},
|
||||
},
|
||||
{
|
||||
.console_index = 2,
|
||||
.gpios = {
|
||||
PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* UART2 RX */
|
||||
PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* UART2 TX */
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const int uart_max_index = ARRAY_SIZE(uart_gpio_pads);
|
||||
|
||||
DEVTREE_CONST struct device *soc_uart_console_to_device(int uart_console)
|
||||
{
|
||||
/*
|
||||
* if index is valid, this function will return corresponding structure
|
||||
* for uart console else will return NULL.
|
||||
*/
|
||||
switch (uart_console) {
|
||||
case 0:
|
||||
return pcidev_path_on_root(PCH_DEVFN_UART0);
|
||||
case 1:
|
||||
return pcidev_path_on_root(PCH_DEVFN_UART1);
|
||||
case 2:
|
||||
return pcidev_path_on_root(PCH_DEVFN_UART2);
|
||||
default:
|
||||
printk(BIOS_ERR, "Invalid UART console index\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue