soc/intel/mtl: Do initial Meteor Lake SoC commit till romstage

List of changes:
1. Add required SoC programming till romstage
2. Include only required headers into include/soc
3. Fill required FSP-M UPD to call FSP-M API

BUG=b:224325352
TEST=Build 'util/abuild/abuild -p none -t google/rex -a -c max'.

Signed-off-by: Ravi Sarawadi <ravishankar.sarawadi@intel.com>
Change-Id: I3d5c6ceb7f97429ff903e7577186e8d8843c1f14
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63363
Reviewed-by: Subrata Banik <subratabanik@google.com>
Reviewed-by: Tarun Tuli <taruntuli@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Ravi Sarawadi 2022-04-10 23:36:52 -07:00 committed by Subrata Banik
parent b0c68656aa
commit 8069b5d3f2
19 changed files with 1716 additions and 8 deletions

View file

@ -8,13 +8,22 @@ config CPU_SPECIFIC_OPTIONS
select ARCH_X86
select BOOT_DEVICE_SUPPORTS_WRITES
select INTEL_DESCRIPTOR_MODE_CAPABLE
select CACHE_MRC_SETTINGS
select CPU_INTEL_COMMON
select FSP_M_XIP
select IDT_IN_EVERY_STAGE
select INTEL_CAR_NEM
select INTEL_GMA_ADD_VBT if RUN_FSP_GOP
select IOAPIC
select MICROCODE_BLOB_UNDISCLOSED
select MRC_SETTINGS_PROTECT
select SOC_INTEL_COMMON
select SOC_INTEL_COMMON_BLOCK
select SOC_INTEL_COMMON_BLOCK_CAR
select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG
select SOC_INTEL_COMMON_BLOCK_CPU
select SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2
select SOC_INTEL_COMMON_BLOCK_MEMINIT
select SOC_INTEL_COMMON_BLOCK_SA
select SOC_INTEL_COMMON_PCH_BASE
select SOC_INTEL_COMMON_RESET
@ -97,14 +106,6 @@ config SOC_INTEL_UART_DEV_MAX
int
default 3
config SOC_INTEL_USB2_DEV_MAX
int
default 10
config SOC_INTEL_USB3_DEV_MAX
int
default 2
config CONSOLE_UART_BASE_ADDRESS
hex
default 0xfe03e000
@ -121,6 +122,13 @@ config SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL
hex
default 0x7fff
config VBOOT
select VBOOT_MUST_REQUEST_DISPLAY
select VBOOT_STARTS_IN_BOOTBLOCK
select VBOOT_VBNV_CMOS
select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH
select VBOOT_X86_SHA256_ACCELERATION
config CBFS_SIZE
hex
default 0x200000
@ -129,4 +137,41 @@ config PRERAM_CBMEM_CONSOLE_SIZE
hex
default 0x2000
config FSP_HEADER_PATH
string "Location of FSP headers"
default "src/vendorcode/intel/fsp/fsp2_0/meteorlake/"
config FSP_FD_PATH
string
depends on FSP_USE_REPO
default "3rdparty/fsp/MeteorLakeFspBinPkg/Fsp.fd"
config SOC_INTEL_METEORLAKE_DEBUG_CONSENT
int "Debug Consent for MTL"
# USB DBC is more common for developers so make this default to 3 if
# SOC_INTEL_DEBUG_CONSENT=y
default 3 if SOC_INTEL_DEBUG_CONSENT
default 0
help
This is to control debug interface on SOC.
Setting non-zero value will allow to use DBC or DCI to debug SOC.
PlatformDebugConsent in FspmUpd.h has the details.
Desired platform debug type are
0:Disabled, 1:Enabled (DCI OOB+[DbC]), 2:Enabled (DCI OOB),
3:Enabled (USB3 DbC), 4:Enabled (XDP/MIPI60), 5:Enabled (USB2 DbC),
6:Enable (2-wire DCI OOB), 7:Manual
config DATA_BUS_WIDTH
int
default 128
config DIMMS_PER_CHANNEL
int
default 2
config MRC_CHANNEL_WIDTH
int
default 16
endif

View file

@ -1,9 +1,19 @@
ifeq ($(CONFIG_SOC_INTEL_METEORLAKE),y)
subdirs-y += romstage
subdirs-y += ../../../cpu/intel/microcode
subdirs-y += ../../../cpu/intel/turbo
bootblock-y += bootblock/bootblock.c
bootblock-y += bootblock/ioe_die.c
bootblock-y += bootblock/report_platform.c
bootblock-y += bootblock/soc_die.c
bootblock-y += espi.c
bootblock-y += p2sb.c
romstage-y += espi.c
romstage-y += meminit.c
romstage-y += reset.c
CPPFLAGS_common += -I$(src)/soc/intel/meteorlake
CPPFLAGS_common += -I$(src)/soc/intel/meteorlake/include

View file

@ -0,0 +1,331 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_CHIP_H_
#define _SOC_CHIP_H_
#include <drivers/i2c/designware/dw_i2c.h>
#include <intelblocks/cfg.h>
#include <intelblocks/gpio.h>
#include <intelblocks/gspi.h>
#include <intelblocks/power_limit.h>
#include <intelblocks/pcie_rp.h>
#include <intelblocks/tcss.h>
#include <soc/gpe.h>
#include <soc/pci_devs.h>
#include <soc/pmc.h>
#include <soc/serialio.h>
#include <soc/usb.h>
#include <stdint.h>
/* Types of different SKUs */
enum soc_intel_meteorlake_power_limits {
MTL_P_POWER_LIMITS_1,
MTL_P_POWER_LIMITS_2,
MTL_P_POWER_LIMITS_3,
MTL_POWER_LIMITS_COUNT
};
/* Types of display ports */
enum ddi_ports {
DDI_PORT_A,
DDI_PORT_B,
DDI_PORT_C,
DDI_PORT_1,
DDI_PORT_2,
DDI_PORT_3,
DDI_PORT_4,
DDI_PORT_COUNT,
};
enum ddi_port_flags {
DDI_ENABLE_DDC = 1 << 0,
DDI_ENABLE_HPD = 1 << 1,
};
/* Bit values for use in LpmStateEnableMask. */
enum lpm_state_mask {
LPM_S0i2_0 = BIT(0),
LPM_S0i2_1 = BIT(1),
LPM_S0i2_2 = BIT(2),
LPM_S0i3_0 = BIT(3),
LPM_S0i3_1 = BIT(4),
LPM_S0i3_2 = BIT(5),
LPM_S0i3_3 = BIT(6),
LPM_S0i3_4 = BIT(7),
LPM_S0iX_ALL = LPM_S0i2_0 | LPM_S0i2_1 | LPM_S0i2_2
| LPM_S0i3_0 | LPM_S0i3_1 | LPM_S0i3_2 | LPM_S0i3_3 | LPM_S0i3_4,
};
struct soc_intel_meteorlake_config {
/* Common struct containing soc config data required by common code */
struct soc_intel_common_config common_soc_config;
/* Common struct containing power limits configuration information */
struct soc_power_limits_config power_limits_config[MTL_POWER_LIMITS_COUNT];
/* Gpio group routed to each dword of the GPE0 block. Values are
* of the form PMC_GPP_[A:U] or GPD. */
uint8_t pmc_gpe0_dw0; /* GPE0_31_0 STS/EN */
uint8_t pmc_gpe0_dw1; /* GPE0_63_32 STS/EN */
uint8_t pmc_gpe0_dw2; /* GPE0_95_64 STS/EN */
/* Generic IO decode ranges */
uint32_t gen1_dec;
uint32_t gen2_dec;
uint32_t gen3_dec;
uint32_t gen4_dec;
/* Enable S0iX support */
int s0ix_enable;
/* Support for TCSS xhci, xdci, TBT PCIe root ports and DMA controllers */
uint8_t tcss_d3_hot_disable;
/* Support for TBT PCIe root ports and DMA controllers with D3Hot->D3Cold */
uint8_t tcss_d3_cold_disable;
/* Enable DPTF support */
int dptf_enable;
/* Deep SX enable for both AC and DC */
int deep_s3_enable_ac;
int deep_s3_enable_dc;
int deep_s5_enable_ac;
int deep_s5_enable_dc;
/* Deep Sx Configuration
* DSX_EN_WAKE_PIN - Enable WAKE# pin
* DSX_EN_LAN_WAKE_PIN - Enable LAN_WAKE# pin
* DSX_DIS_AC_PRESENT_PD - Disable pull-down on AC_PRESENT pin */
uint32_t deep_sx_config;
/* TCC activation offset */
uint32_t tcc_offset;
/* System Agent dynamic frequency support. Only effects ULX/ULT CPUs.
* When enabled memory will be training at two different frequencies.
* 0:Disabled, 1:FixedPoint0, 2:FixedPoint1, 3:FixedPoint2,
* 4:FixedPoint3, 5:Enabled */
enum {
SaGv_Disabled,
SaGv_FixedPoint0,
SaGv_FixedPoint1,
SaGv_FixedPoint2,
SaGv_FixedPoint3,
SaGv_Enabled,
} SaGv;
/* Rank Margin Tool. 1:Enable, 0:Disable */
uint8_t RMT;
/* USB related */
struct usb2_port_config usb2_ports[CONFIG_SOC_INTEL_USB2_DEV_MAX];
struct usb3_port_config usb3_ports[CONFIG_SOC_INTEL_USB3_DEV_MAX];
/* Wake Enable Bitmap for USB2 ports */
uint16_t usb2_wake_enable_bitmap;
/* Wake Enable Bitmap for USB3 ports */
uint16_t usb3_wake_enable_bitmap;
/* Program OC pins for TCSS */
struct tcss_port_config tcss_ports[MAX_TYPE_C_PORTS];
uint8_t tbt_pcie_port_disable[4];
/* SATA related */
uint8_t sata_mode;
uint8_t sata_salp_support;
uint8_t sata_ports_enable[8];
uint8_t sata_ports_dev_slp[8];
/*
* Enable(0)/Disable(1) SATA Power Optimizer on PCH side.
* Default 0. Setting this to 1 disables the SATA Power Optimizer.
*/
uint8_t sata_pwr_optimize_disable;
/*
* SATA Port Enable Dito Config.
* Enable DEVSLP Idle Timeout settings (DmVal, DitoVal).
*/
uint8_t sata_ports_enable_dito_config[8];
/* SataPortsDmVal is the DITO multiplier. Default is 15. */
uint8_t sata_ports_dm_val[8];
/* SataPortsDitoVal is the DEVSLP Idle Timeout, default is 625ms */
uint16_t sata_ports_dito_val[8];
/* Audio related */
uint8_t pch_hda_dsp_enable;
/* iDisp-Link T-Mode 0: 2T, 2: 4T, 3: 8T, 4: 16T */
enum {
HDA_TMODE_2T = 0,
HDA_TMODE_4T = 2,
HDA_TMODE_8T = 3,
HDA_TMODE_16T = 4,
} pch_hda_idisp_link_tmode;
/* iDisp-Link Freq 4: 96MHz, 3: 48MHz. */
enum {
HDA_LINKFREQ_48MHZ = 3,
HDA_LINKFREQ_96MHZ = 4,
} pch_hda_idisp_link_frequency;
bool pch_hda_idisp_codec_enable;
struct pcie_rp_config pcie_rp[CONFIG_MAX_ROOT_PORTS];
uint8_t pcie_clk_config_flag[CONFIG_MAX_PCIE_CLOCK_SRC];
/* Gfx related */
enum {
IGD_SM_0MB = 0x00,
IGD_SM_32MB = 0x01,
IGD_SM_64MB = 0x02,
IGD_SM_96MB = 0x03,
IGD_SM_128MB = 0x04,
IGD_SM_160MB = 0x05,
IGD_SM_4MB = 0xF0,
IGD_SM_8MB = 0xF1,
IGD_SM_12MB = 0xF2,
IGD_SM_16MB = 0xF3,
IGD_SM_20MB = 0xF4,
IGD_SM_24MB = 0xF5,
IGD_SM_28MB = 0xF6,
IGD_SM_36MB = 0xF8,
IGD_SM_40MB = 0xF9,
IGD_SM_44MB = 0xFA,
IGD_SM_48MB = 0xFB,
IGD_SM_52MB = 0xFC,
IGD_SM_56MB = 0xFD,
IGD_SM_60MB = 0xFE,
} igd_dvmt50_pre_alloc;
uint8_t skip_ext_gfx_scan;
/* Enable/Disable EIST. 1b:Enabled, 0b:Disabled */
uint8_t eist_enable;
uint8_t PmTimerDisabled;
/*
* SerialIO device mode selection:
* PchSerialIoDisabled,
* PchSerialIoPci,
* PchSerialIoHidden,
* PchSerialIoLegacyUart,
* PchSerialIoSkipInit
*/
uint8_t serial_io_i2c_mode[CONFIG_SOC_INTEL_I2C_DEV_MAX];
uint8_t serial_io_gspi_mode[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX];
uint8_t serial_io_uart_mode[CONFIG_SOC_INTEL_UART_DEV_MAX];
/*
* GSPIn Default Chip Select Mode:
* 0:Hardware Mode,
* 1:Software Mode
*/
uint8_t serial_io_gspi_cs_mode[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX];
/*
* GSPIn Default Chip Select State:
* 0: Low,
* 1: High
*/
uint8_t serial_io_gspi_cs_state[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX];
/* CNVi BT Core Enable/Disable */
bool cnvi_bt_core;
/* CNVi BT Audio Offload: Enable/Disable BT Audio Offload. */
bool cnvi_bt_audio_offload;
/*
* These GPIOs will be programmed by the IOM to handle biasing of the
* Type-C aux (SBU) signals when certain alternate modes are used.
* `pad_auxn_dc` should be assigned to the GPIO pad providing negative
* bias (name usually contains `AUXN_DC` or `AUX_N`); similarly,
* `pad_auxp_dc` should be assigned to the GPIO providing positive bias
* (name often contains `AUXP_DC` or `_AUX_P`).
*/
struct typec_aux_bias_pads typec_aux_bias_pads[MAX_TYPE_C_PORTS];
/*
* SOC Aux orientation override:
* This is a bitfield that corresponds to up to 4 TCSS ports on MTL.
* Even numbered bits (0, 2, 4, 6) control the retimer being handled by SOC.
* Odd numbered bits (1, 3, 5, 7) control the orientation of the physical aux lines
* on the motherboard.
*/
uint16_t tcss_aux_ori;
/* Connect Topology Command timeout value */
uint16_t itbt_connect_topology_timeout_in_ms;
/*
* Override GPIO PM configuration:
* 0: Use FSP default GPIO PM program,
* 1: coreboot to override GPIO PM program
*/
uint8_t gpio_override_pm;
/*
* GPIO PM configuration: 0 to disable, 1 to enable power gating
* Bit 6-7: Reserved
* Bit 5: MISCCFG_GPSIDEDPCGEN
* Bit 4: MISCCFG_GPRCOMPCDLCGEN
* Bit 3: MISCCFG_GPRTCDLCGEN
* Bit 2: MISCCFG_GSXLCGEN
* Bit 1: MISCCFG_GPDPCGEN
* Bit 0: MISCCFG_GPDLCGEN
*/
uint8_t gpio_pm[TOTAL_GPIO_COMM];
/* DP config */
/*
* Port config
* 0:Disabled, 1:eDP, 2:MIPI DSI
*/
uint8_t ddi_port_A_config;
uint8_t ddi_port_B_config;
/* Enable(1)/Disable(0) HPD/DDC */
uint8_t ddi_ports_config[DDI_PORT_COUNT];
/* Hybrid storage mode enable (1) / disable (0)
* This mode makes FSP detect Optane and NVME and set PCIe lane mode
* accordingly */
uint8_t hybrid_storage_mode;
/*
* Override CPU flex ratio value:
* CPU ratio value controls the maximum processor non-turbo ratio.
* Valid Range 0 to 63.
*
* In general descriptor provides option to set default cpu flex ratio.
* Default cpu flex ratio is 0 ensures booting with non-turbo max frequency.
* That's the reason FSP skips cpu_ratio override if cpu_ratio is 0.
*
* Only override CPU flex ratio if don't want to boot with non-turbo max.
*/
uint8_t cpu_ratio_override;
/*
* Enable(0)/Disable(1) DMI Power Optimizer on PCH side.
* Default 0. Setting this to 1 disables the DMI Power Optimizer.
*/
uint8_t dmi_pwr_optimize_disable;
/*
* Enable(1)/Disable(0) CPU Replacement check.
* Default 0. Setting this to 1 to check CPU replacement.
*/
uint8_t cpu_replacement_check;
/* ISA Serial Base selection. */
enum {
ISA_SERIAL_BASE_ADDR_3F8,
ISA_SERIAL_BASE_ADDR_2F8,
} isa_serial_uart_base;
/*
* Assign clock source port for GbE. 0: Disable, N-1: port number
* Default 0.
*/
uint8_t lan_clk;
};
typedef struct soc_intel_meteorlake_config config_t;
#endif

View file

@ -0,0 +1,175 @@
chip soc/intel/meteorlake
device cpu_cluster 0 on end
#FIXME: update values for MTL and enable override in systemagent.c
register "power_limits_config[MTL_P_POWER_LIMITS_2]" = "{
.tdp_pl1_override = 15,
.tdp_pl2_override = 55,
}"
register "power_limits_config[MTL_P_POWER_LIMITS_1]" = "{
.tdp_pl1_override = 45,
.tdp_pl2_override = 115,
}"
# NOTE: if any variant wants to override this value, use the same format
# as register "common_soc_config.pch_thermal_trip" = "value", instead of
# putting it under register "common_soc_config" in overridetree.cb file.
#FIXME: update value for MTL
register "common_soc_config.pch_thermal_trip" = "100"
device domain 0 on
device pci 00.0 alias system_agent on end
device pci 01.0 alias pcie_rp12 off end
device pci 02.0 alias igpu off end
device pci 04.0 alias dtt off end
device pci 05.0 alias ipu off end
device pci 06.0 alias pcie_rp9 off end
device pci 06.1 alias pcie_rp10 off end
device pci 06.2 alias pcie_rp11 off end
device pci 07.0 alias tbt_pcie_rp0 off
chip soc/intel/common/block/usb4
use tcss_dma0 as usb4_port
device generic 0 on end
end
end
device pci 07.1 alias tbt_pcie_rp1 off
chip soc/intel/common/block/usb4
use tcss_dma0 as usb4_port
device generic 1 on end
end
end
device pci 07.2 alias tbt_pcie_rp2 off
chip soc/intel/common/block/usb4
use tcss_dma1 as usb4_port
device generic 0 on end
end
end
device pci 07.3 alias tbt_pcie_rp3 off
chip soc/intel/common/block/usb4
use tcss_dma1 as usb4_port
device generic 1 on end
end
end
device pci 08.0 alias gna off end
device pci 0a.0 alias crashlog on end
device pci 0b.0 alias vpu off end
device pci 0d.0 alias tcss_xhci off
chip drivers/usb/acpi
register "type" = "UPC_TYPE_HUB"
device usb 0.0 alias tcss_root_hub off
chip drivers/usb/acpi
device usb 3.0 alias tcss_usb3_port1 off end
end
chip drivers/usb/acpi
device usb 3.1 alias tcss_usb3_port2 off end
end
chip drivers/usb/acpi
device usb 3.2 alias tcss_usb3_port3 off end
end
chip drivers/usb/acpi
device usb 3.3 alias tcss_usb3_port4 off end
end
end
end
end
device pci 0d.1 alias tcss_xdci off end
device pci 0d.2 alias tcss_dma0 off end
device pci 0d.3 alias tcss_dma1 off end
device pci 0e.0 alias vmd off end
device pci 10.0 alias thc0 off end
device pci 10.1 alias thc1 off end
device pci 12.0 alias ish off end
device pci 12.7 alias ufs off end
device pci 13.0 alias ioe_p2sb hidden end
device pci 13.1 alias ieh2 off end
device pci 13.2 alias pmc2 hidden end
device pci 13.3 alias shared_sram2 off end
device pci 14.0 alias xhci off
chip drivers/usb/acpi
register "type" = "UPC_TYPE_HUB"
device usb 0.0 alias xhci_root_hub off
chip drivers/usb/acpi
device usb 2.0 alias usb2_port1 off end
end
chip drivers/usb/acpi
device usb 2.1 alias usb2_port2 off end
end
chip drivers/usb/acpi
device usb 2.2 alias usb2_port3 off end
end
chip drivers/usb/acpi
device usb 2.3 alias usb2_port4 off end
end
chip drivers/usb/acpi
device usb 2.4 alias usb2_port5 off end
end
chip drivers/usb/acpi
device usb 2.5 alias usb2_port6 off end
end
chip drivers/usb/acpi
device usb 2.6 alias usb2_port7 off end
end
chip drivers/usb/acpi
device usb 2.7 alias usb2_port8 off end
end
chip drivers/usb/acpi
device usb 2.8 alias usb2_port9 off end
end
chip drivers/usb/acpi
device usb 2.9 alias usb2_port10 off end
end
chip drivers/usb/acpi
device usb 3.0 alias usb3_port1 off end
end
chip drivers/usb/acpi
device usb 3.1 alias usb3_port2 off end
end
end
end
end
device pci 14.1 alias usb_otg off end
device pci 14.2 alias shared_sram off end
device pci 14.3 alias cnvi_wifi off end
device pci 14.5 alias ieh off end
device pci 15.0 alias i2c0 off end
device pci 15.1 alias i2c1 off end
device pci 15.2 alias i2c2 off end
device pci 15.3 alias i2c3 off end
device pci 15.4 alias i3c off end
device pci 16.0 alias heci1 on end
device pci 16.1 alias heci2 off end
device pci 16.4 alias heci3 off end
device pci 16.5 alias heci4 off end
device pci 17.0 alias sata off end
device pci 18.0 alias eheci1 off end
device pci 18.1 alias eheci2 off end
device pci 18.2 alias eheci3 off end
device pci 19.0 alias i2c4 off end
device pci 19.1 alias i2c5 off end
device pci 19.2 alias uart2 off end
device pci 1c.0 alias pcie_rp1 off end
device pci 1c.1 alias pcie_rp2 off end
device pci 1c.2 alias pcie_rp3 off end
device pci 1c.3 alias pcie_rp4 off end
device pci 1c.4 alias pcie_rp5 off end
device pci 1c.5 alias pcie_rp6 off end
device pci 1c.6 alias pcie_rp7 off end
device pci 1c.7 alias pcie_rp8 off end
device pci 1e.0 alias uart0 off end
device pci 1e.1 alias uart1 off end
device pci 1e.2 alias gspi0 off end
device pci 1e.3 alias gspi1 off end
device pci 1e.4 alias tsn_gbe1 off end
device pci 1e.5 alias tsn_gbe2 off end
device pci 1f.0 alias soc_espi on end
device pci 1f.1 alias p2sb off end
device pci 1f.2 alias pmc hidden end
device pci 1f.3 alias hda off end
device pci 1f.4 alias smbus off end
device pci 1f.5 alias fast_spi on end
device pci 1f.6 alias gbe off end
device pci 1f.7 alias npk off end
end
end

View file

@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#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>
void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES])
{
const config_t *config = config_of_soc();
gen_io_dec[0] = config->gen1_dec;
gen_io_dec[1] = config->gen2_dec;
gen_io_dec[2] = config->gen3_dec;
gen_io_dec[3] = config->gen4_dec;
}
#if ENV_RAMSTAGE
void lpc_soc_init(struct device *dev)
{
/* Legacy initialization */
isa_dma_init();
pch_misc_init();
/* Enable CLKRUN_EN for power gating ESPI */
lpc_enable_pci_clk_cntl();
/* Set ESPI Serial IRQ mode */
if (CONFIG(SERIRQ_CONTINUOUS_MODE))
lpc_set_serirq_mode(SERIRQ_CONTINUOUS);
else
lpc_set_serirq_mode(SERIRQ_QUIET);
/* Interrupt configuration */
pch_enable_ioapic();
pch_pirq_init();
setup_i8259();
i8259_configure_irq_trigger(9, 1);
}
#endif

View file

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_GPE_H_
#define _SOC_GPE_H_
#include <intelpch/gpe.h>
#endif /* _SOC_GPE_H_ */

View file

@ -0,0 +1,115 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_METEORLAKE_MEMINIT_H_
#define _SOC_METEORLAKE_MEMINIT_H_
#include <stddef.h>
#include <stdint.h>
#include <types.h>
#include <fsp/soc_binding.h>
#include <intelblocks/meminit.h>
enum mem_type {
MEM_TYPE_DDR5,
MEM_TYPE_LP5X,
};
struct mem_ddr_config {
/* Dqs Pins Interleaved Setting. Enable/Disable Control */
bool dq_pins_interleaved;
};
struct lpx_dq {
uint8_t dq0[BITS_PER_BYTE];
uint8_t dq1[BITS_PER_BYTE];
};
struct lpx_dqs {
uint8_t dqs0;
uint8_t dqs1;
};
struct lpx_dq_map {
struct lpx_dq ddr0;
struct lpx_dq ddr1;
struct lpx_dq ddr2;
struct lpx_dq ddr3;
struct lpx_dq ddr4;
struct lpx_dq ddr5;
struct lpx_dq ddr6;
struct lpx_dq ddr7;
};
struct lpx_dqs_map {
struct lpx_dqs ddr0;
struct lpx_dqs ddr1;
struct lpx_dqs ddr2;
struct lpx_dqs ddr3;
struct lpx_dqs ddr4;
struct lpx_dqs ddr5;
struct lpx_dqs ddr6;
struct lpx_dqs ddr7;
};
struct mem_lp5x_config {
uint8_t ccc_config;
};
struct rcomp {
/*
* Rcomp resistor value. This values represents the resistance in
* ohms of the rcomp resistor attached to the DDR_COMP pin on the SoC.
*
* Note: If mainboard users don't want to override rcomp related settings
* then associated rcomp UPDs will have its default value.
*/
uint16_t resistor;
/* Rcomp target values. */
uint16_t targets[5];
};
struct mb_cfg {
enum mem_type type;
struct rcomp rcomp;
union {
/*
* DQ CPU<>DRAM map:
* Index of the array represents DQ# on the CPU and the value represents DQ# on
* the DRAM part.
*/
uint8_t dq_map[CONFIG_DATA_BUS_WIDTH];
struct lpx_dq_map lpx_dq_map;
};
union {
/*
* DQS CPU<>DRAM map:
* Index of the array represents DQS# on the CPU and the value represents DQS#
* on the DRAM part.
*/
uint8_t dqs_map[CONFIG_DATA_BUS_WIDTH/BITS_PER_BYTE];
struct lpx_dqs_map lpx_dqs_map;
};
union {
struct mem_lp5x_config lp5x_config;
struct mem_ddr_config ddr_config;
};
/* Early Command Training Enable/Disable Control */
bool ect;
/* Board type */
uint8_t UserBd;
/* Command Mirror */
uint8_t CmdMirror;
/* Enable/Disable TxDqDqs Retraining for Lp4/Lp5/DDR */
uint8_t LpDdrDqDqsReTraining;
};
void memcfg_init(FSPM_UPD *memupd, const struct mb_cfg *mb_cfg,
const struct mem_spd *spd_info, bool half_populated);
#endif /* _SOC_METEORLAKE_MEMINIT_H_ */

View file

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_MSR_H_
#define _SOC_MSR_H_
#include <intelblocks/msr.h>
#define MSR_BIOS_DONE 0x151
#define ENABLE_IA_UNTRUSTED (1 << 0)
#endif

View file

@ -0,0 +1,144 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_METEORLAKE_PMC_H_
#define _SOC_METEORLAKE_PMC_H_
#include <device/device.h>
extern struct device_operations pmc_ops;
/* PCI Configuration Space (D31:F2): PMC */
#define PWRMBASE 0x10
#define ABASE 0x20
/* Memory mapped IO registers in PMC */
#define GEN_PMCON_A 0x1020
#define DC_PP_DIS (1 << 30)
#define DSX_PP_DIS (1 << 29)
#define AG3_PP_EN (1 << 28)
#define SX_PP_EN (1 << 27)
#define ALLOW_ICLK_PLL_SD_INC0 (1 << 26)
#define GBL_RST_STS (1 << 24)
#define DISB (1 << 23)
#define ALLOW_OPI_PLL_SD_INC0 (1 << 22)
#define MEM_SR (1 << 21)
#define ALLOW_SPXB_CG_INC0 (1 << 20)
#define ALLOW_L1LOW_C0 (1 << 19)
#define MS4V (1 << 18)
#define ALLOW_L1LOW_OPI_ON (1 << 17)
#define SUS_PWR_FLR (1 << 16)
#define PME_B0_S5_DIS (1 << 15)
#define PWR_FLR (1 << 14)
#define ALLOW_L1LOW_BCLKREQ_ON (1 << 13)
#define DIS_SLP_X_STRCH_SUS_UP (1 << 12)
#define SLP_S3_MIN_ASST_WDTH_MASK (3 << 10)
#define SLP_S3_MIN_ASST_WDTH_60USEC (0 << 10)
#define SLP_S3_MIN_ASST_WDTH_1MS (1 << 10)
#define SLP_S3_MIN_ASST_WDTH_50MS (2 << 10)
#define SLP_S3_MIN_ASST_WDTH_2S (3 << 10)
#define HOST_RST_STS (1 << 9)
#define ESPI_SMI_LOCK (1 << 8)
#define S4MAW_MASK (3 << 4)
#define S4MAW_1S (1 << 4)
#define S4MAW_2S (2 << 4)
#define S4MAW_3S (3 << 4)
#define S4MAW_4S (0 << 4)
#define S4ASE (1 << 3)
#define PER_SMI_SEL_MASK (3 << 1)
#define SMI_RATE_64S (0 << 1)
#define SMI_RATE_32S (1 << 1)
#define SMI_RATE_16S (2 << 1)
#define SMI_RATE_8S (3 << 1)
#define SLEEP_AFTER_POWER_FAIL (1 << 0)
#define GEN_PMCON_B 0x1024
#define SLP_STR_POL_LOCK (1 << 18)
#define ACPI_BASE_LOCK (1 << 17)
#define PM_DATA_BAR_DIS (1 << 16)
#define WOL_EN_OVRD (1 << 13)
#define BIOS_PCI_EXP_EN (1 << 10)
#define PWRBTN_LVL (1 << 9)
#define SMI_LOCK (1 << 4)
#define RTC_BATTERY_DEAD (1 << 2)
#define ETR 0x1048
#define CF9_LOCK (1 << 31)
#define CF9_GLB_RST (1 << 20)
#define SSML 0x104C
#define SSML_SSL_DS (0 << 0)
#define SSML_SSL_EN (1 << 0)
#define SSMC 0x1050
#define SSMC_SSMS (1 << 0)
#define SSMD 0x1054
#define SSMD_SSD_MASK (0xffff << 0)
#define PRSTS 0x1810
#define S3_PWRGATE_POL 0x1828
#define S3DC_GATE_SUS (1 << 1)
#define S3AC_GATE_SUS (1 << 0)
#define S4_PWRGATE_POL 0x182c
#define S4DC_GATE_SUS (1 << 1)
#define S4AC_GATE_SUS (1 << 0)
#define S5_PWRGATE_POL 0x1830
#define S5DC_GATE_SUS (1 << 15)
#define S5AC_GATE_SUS (1 << 14)
#define DSX_CFG 0x1834
#define REQ_CNV_NOWAKE_DSX (1 << 4)
#define REQ_BATLOW_DSX (1 << 3)
#define DSX_EN_WAKE_PIN (1 << 2)
#define DSX_DIS_AC_PRESENT_PD (1 << 1)
#define DSX_EN_LAN_WAKE_PIN (1 << 0)
#define DSX_CFG_MASK (0x1f << 0)
#define PMSYNC_TPR_CFG 0x18C4
#define PCH2CPU_TPR_CFG_LOCK (1 << 31)
#define PCH2CPU_TT_EN (1 << 26)
#define PCH_PWRM_ACPI_TMR_CTL 0x18FC
#define ACPI_TIM_DIS (1 << 1)
#define GPIO_GPE_CFG 0x1920
#define GPE0_DWX_MASK 0xf
#define GPE0_DW_SHIFT(x) (4*(x))
#define PMC_GPP_V 0x0
#define PMC_GPP_C 0x1
#define PMC_GPP_A 0x2
#define PMC_GPP_E 0x3
#define PMC_GPP_H 0x4
#define PMC_GPP_F 0x5
#define PMC_GPP_S 0x6
#define PMC_GPP_B 0x7
#define PMC_GPP_D 0x8
#define GBLRST_CAUSE0 0x1924
#define GBLRST_CAUSE0_THERMTRIP (1 << 5)
#define GBLRST_CAUSE1 0x1928
#define HPR_CAUSE0 0x192C
#define HPR_CAUSE0_MI_HRPD (1 << 10)
#define HPR_CAUSE0_MI_HRPC (1 << 9)
#define HPR_CAUSE0_MI_HR (1 << 8)
#define CPPMVRIC 0x1B1C
#define XTALSDQDIS (1 << 22)
#define IRQ_REG ACTL
#define SCI_IRQ_ADJUST 0
#define ACTL 0x1BD8
#define PWRM_EN (1 << 8)
#define ACPI_EN (1 << 7)
#define SCI_IRQ_SEL (7 << 0)
#define SCIS_IRQ9 0
#define SCIS_IRQ10 1
#define SCIS_IRQ11 2
#define SCIS_IRQ20 4
#define SCIS_IRQ21 5
#define SCIS_IRQ22 6
#define SCIS_IRQ23 7
#endif

View file

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_ROMSTAGE_H_
#define _SOC_ROMSTAGE_H_
#include <fsp/api.h>
#include <stddef.h>
#include <soc/soc_chip.h>
void mainboard_update_premem_soc_chip_config(struct soc_intel_meteorlake_config *config);
void mainboard_memory_init_params(FSPM_UPD *memupd);
void systemagent_early_init(void);
/* Board type */
enum board_type {
BOARD_TYPE_MOBILE = 0,
BOARD_TYPE_DESKTOP = 1,
BOARD_TYPE_ULT_ULX = 5,
BOARD_TYPE_SERVER = 7
};
#endif /* _SOC_ROMSTAGE_H_ */

View file

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _SOC_METEORLAKE_SOC_CHIP_H_
#define _SOC_METEORLAKE_SOC_CHIP_H_
#include "../../chip.h"
#endif /* _SOC_METEORLAKE_SOC_CHIP_H_ */

View file

@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SOC_METEORLAKE_SYSTEMAGENT_H
#define SOC_METEORLAKE_SYSTEMAGENT_H
#include <intelblocks/systemagent.h>
/* Device 0:0.0 PCI configuration space */
#define EPBAR 0x40
#define DMIBAR 0x68
#define CAPID0_A 0xe4
#define VTD_DISABLE (1 << 23)
/* MCHBAR offsets */
#define EDRAMBAR 0x5408
#define GFXVTBAR 0x5410
#define REGBAR 0x5420
#define MCH_DDR_POWER_LIMIT_LO 0x58e0
#define MCH_DDR_POWER_LIMIT_HI 0x58e4
#define MCH_PKG_POWER_LIMIT_LO 0x59a0
#define MCH_PKG_POWER_LIMIT_HI 0x59a4
#define BIOS_RESET_CPL 0x5da8
#define IMRBASE 0x6a40
#define IMRLIMIT 0x6a48
#define IPUVTBAR 0x7880
#define TBTxBAR(x) (0x7888 + (x) * 8)
#define MAX_TBT_PCIE_PORT 4
#define VTBAR_ENABLED 0x01
#define VTBAR_MASK 0x7ffffff000ull
static const struct sa_mmio_descriptor soc_vtd_resources[] = {
{ GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" },
};
#define V_P2SB_CFG_IBDF_BUS 0
#define V_P2SB_CFG_IBDF_DEV 30
#define V_P2SB_CFG_IBDF_FUNC 7
#define V_P2SB_CFG_HBDF_BUS 0
#define V_P2SB_CFG_HBDF_DEV 30
#define V_P2SB_CFG_HBDF_FUNC 6
#endif

View file

@ -0,0 +1,227 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <console/console.h>
#include <fsp/util.h>
#include <soc/meminit.h>
#include <string.h>
#define LPX_PHYSICAL_CH_WIDTH 16
#define LPX_CHANNELS CHANNEL_COUNT(LPX_PHYSICAL_CH_WIDTH)
#define DDR5_PHYSICAL_CH_WIDTH 32
#define DDR5_CHANNELS CHANNEL_COUNT(DDR5_PHYSICAL_CH_WIDTH)
static void set_rcomp_config(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *mb_cfg)
{
if (mb_cfg->rcomp.resistor != 0)
mem_cfg->RcompResistor = mb_cfg->rcomp.resistor;
for (size_t i = 0; i < ARRAY_SIZE(mem_cfg->RcompTarget); i++) {
if (mb_cfg->rcomp.targets[i] != 0)
mem_cfg->RcompTarget[i] = mb_cfg->rcomp.targets[i];
}
}
static void meminit_lp5x(FSP_M_CONFIG *mem_cfg, const struct mem_lp5x_config *lp5x_config)
{
mem_cfg->DqPinsInterleaved = 0;
}
static void meminit_ddr(FSP_M_CONFIG *mem_cfg, const struct mem_ddr_config *ddr_config)
{
mem_cfg->DqPinsInterleaved = ddr_config->dq_pins_interleaved;
}
static const struct soc_mem_cfg soc_mem_cfg[] = {
[MEM_TYPE_DDR5] = {
.num_phys_channels = DDR5_CHANNELS,
.phys_to_mrc_map = {
[0] = 0,
[1] = 1,
[2] = 4,
[3] = 5,
},
.md_phy_masks = {
/*
* Physical channels 0 and 1 are populated in case of
* half-populated configurations.
*/
.half_channel = BIT(0) | BIT(1),
/* In mixed topologies, channels 2 and 3 are always memory-down. */
.mixed_topo = BIT(2) | BIT(3),
},
},
[MEM_TYPE_LP5X] = {
.num_phys_channels = LPX_CHANNELS,
.phys_to_mrc_map = {
[0] = 0,
[1] = 1,
[2] = 2,
[3] = 3,
[4] = 4,
[5] = 5,
[6] = 6,
[7] = 7,
},
.md_phy_masks = {
/*
* Physical channels 0, 1, 2 and 3 are populated in case of
* half-populated configurations.
*/
.half_channel = BIT(0) | BIT(1) | BIT(2) | BIT(3),
/* LP5x does not support mixed topologies. */
},
},
};
static void mem_init_spd_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_data *data)
{
uint32_t *spd_upds[MRC_CHANNELS][CONFIG_DIMMS_PER_CHANNEL] = {
[0] = { &mem_cfg->MemorySpdPtr000, &mem_cfg->MemorySpdPtr001, },
[1] = { &mem_cfg->MemorySpdPtr010, &mem_cfg->MemorySpdPtr011, },
[2] = { &mem_cfg->MemorySpdPtr020, &mem_cfg->MemorySpdPtr021, },
[3] = { &mem_cfg->MemorySpdPtr030, &mem_cfg->MemorySpdPtr031, },
[4] = { &mem_cfg->MemorySpdPtr100, &mem_cfg->MemorySpdPtr101, },
[5] = { &mem_cfg->MemorySpdPtr110, &mem_cfg->MemorySpdPtr111, },
[6] = { &mem_cfg->MemorySpdPtr120, &mem_cfg->MemorySpdPtr121, },
[7] = { &mem_cfg->MemorySpdPtr130, &mem_cfg->MemorySpdPtr131, },
};
uint8_t *disable_channel_upds[MRC_CHANNELS] = {
&mem_cfg->DisableMc0Ch0,
&mem_cfg->DisableMc0Ch1,
&mem_cfg->DisableMc0Ch2,
&mem_cfg->DisableMc0Ch3,
&mem_cfg->DisableMc1Ch0,
&mem_cfg->DisableMc1Ch1,
&mem_cfg->DisableMc1Ch2,
&mem_cfg->DisableMc1Ch3,
};
size_t ch, dimm;
mem_cfg->MemorySpdDataLen = data->spd_len;
for (ch = 0; ch < MRC_CHANNELS; ch++) {
uint8_t *disable_channel_ptr = disable_channel_upds[ch];
bool enable_channel = 0;
for (dimm = 0; dimm < CONFIG_DIMMS_PER_CHANNEL; dimm++) {
uint32_t *spd_ptr = spd_upds[ch][dimm];
*spd_ptr = data->spd[ch][dimm];
if (*spd_ptr)
enable_channel = 1;
}
*disable_channel_ptr = !enable_channel;
}
}
static void mem_init_dq_dqs_upds(void *upds[MRC_CHANNELS], const void *map, size_t upd_size,
const struct mem_channel_data *data, bool auto_detect)
{
size_t i;
for (i = 0; i < MRC_CHANNELS; i++, map += upd_size) {
if (auto_detect ||
!channel_is_populated(i, MRC_CHANNELS, data->ch_population_flags))
memset(upds[i], 0, upd_size);
else
memcpy(upds[i], map, upd_size);
}
}
static void mem_init_dq_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_data *data,
const struct mb_cfg *mb_cfg, bool auto_detect)
{
void *dq_upds[MRC_CHANNELS] = {
&mem_cfg->DqMapCpu2DramMc0Ch0,
&mem_cfg->DqMapCpu2DramMc0Ch1,
&mem_cfg->DqMapCpu2DramMc0Ch2,
&mem_cfg->DqMapCpu2DramMc0Ch3,
&mem_cfg->DqMapCpu2DramMc1Ch0,
&mem_cfg->DqMapCpu2DramMc1Ch1,
&mem_cfg->DqMapCpu2DramMc1Ch2,
&mem_cfg->DqMapCpu2DramMc1Ch3,
};
const size_t upd_size = sizeof(mem_cfg->DqMapCpu2DramMc0Ch0);
_Static_assert(sizeof(mem_cfg->DqMapCpu2DramMc0Ch0) == CONFIG_MRC_CHANNEL_WIDTH,
"Incorrect DQ UPD size!");
mem_init_dq_dqs_upds(dq_upds, mb_cfg->dq_map, upd_size, data, auto_detect);
}
static void mem_init_dqs_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_data *data,
const struct mb_cfg *mb_cfg, bool auto_detect)
{
void *dqs_upds[MRC_CHANNELS] = {
&mem_cfg->DqsMapCpu2DramMc0Ch0,
&mem_cfg->DqsMapCpu2DramMc0Ch1,
&mem_cfg->DqsMapCpu2DramMc0Ch2,
&mem_cfg->DqsMapCpu2DramMc0Ch3,
&mem_cfg->DqsMapCpu2DramMc1Ch0,
&mem_cfg->DqsMapCpu2DramMc1Ch1,
&mem_cfg->DqsMapCpu2DramMc1Ch2,
&mem_cfg->DqsMapCpu2DramMc1Ch3,
};
const size_t upd_size = sizeof(mem_cfg->DqsMapCpu2DramMc0Ch0);
_Static_assert(sizeof(mem_cfg->DqsMapCpu2DramMc0Ch0) == CONFIG_MRC_CHANNEL_WIDTH / 8,
"Incorrect DQS UPD size!");
mem_init_dq_dqs_upds(dqs_upds, mb_cfg->dqs_map, upd_size, data, auto_detect);
}
#define DDR5_CH_DIMM_OFFSET(ch, dimm) ((ch) * CONFIG_DIMMS_PER_CHANNEL + (dimm))
static void ddr5_fill_dimm_module_info(FSP_M_CONFIG *mem_cfg, const struct mb_cfg *mb_cfg,
const struct mem_spd *spd_info)
{
for (size_t ch = 0; ch < soc_mem_cfg[MEM_TYPE_DDR5].num_phys_channels; ch++) {
for (size_t dimm = 0; dimm < CONFIG_DIMMS_PER_CHANNEL; dimm++) {
size_t mrc_ch = soc_mem_cfg[MEM_TYPE_DDR5].phys_to_mrc_map[ch];
mem_cfg->SpdAddressTable[DDR5_CH_DIMM_OFFSET(mrc_ch, dimm)] =
spd_info->smbus[ch].addr_dimm[dimm] << 1;
}
}
mem_init_dq_upds(mem_cfg, NULL, mb_cfg, true);
mem_init_dqs_upds(mem_cfg, NULL, mb_cfg, true);
}
void memcfg_init(FSPM_UPD *memupd, const struct mb_cfg *mb_cfg,
const struct mem_spd *spd_info, bool half_populated)
{
struct mem_channel_data data;
bool dq_dqs_auto_detect = false;
FSP_M_CONFIG *mem_cfg = &memupd->FspmConfig;
mem_cfg->UserBd = mb_cfg->UserBd;
set_rcomp_config(mem_cfg, mb_cfg);
switch (mb_cfg->type) {
case MEM_TYPE_DDR5:
meminit_ddr(mem_cfg, &mb_cfg->ddr_config);
dq_dqs_auto_detect = true;
/*
* TODO: Drop this workaround once SMBus driver in coreboot is updated to
* support DDR5 EEPROM reading.
*/
if (spd_info->topo == MEM_TOPO_DIMM_MODULE) {
ddr5_fill_dimm_module_info(mem_cfg, mb_cfg, spd_info);
return;
}
break;
case MEM_TYPE_LP5X:
meminit_lp5x(mem_cfg, &mb_cfg->lp5x_config);
break;
default:
die("Unsupported memory type(%d)\n", mb_cfg->type);
}
mem_populate_channel_data(memupd, &soc_mem_cfg[mb_cfg->type], spd_info,
half_populated, &data);
mem_init_spd_upds(mem_cfg, &data);
mem_init_dq_upds(mem_cfg, &data, mb_cfg, dq_dqs_auto_detect);
mem_init_dqs_upds(mem_cfg, &data, mb_cfg, dq_dqs_auto_detect);
}

View file

@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <console/console.h>
#include <intelblocks/p2sb.h>
void p2sb_soc_get_sb_mask(uint32_t *ep_mask, size_t count)
{
uint32_t mask;
if (count != P2SB_EP_MASK_MAX_REG) {
printk(BIOS_ERR, "Unable to program EPMASK registers\n");
return;
}
/* Remove the host accessing right to PSF register range.
* Set p2sb PCI offset EPMASK5 [29, 28, 27, 26] to disable Sideband
* access for PCI Root Bridge.
*/
mask = (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26);
ep_mask[P2SB_EP_MASK_5_REG] = mask;
/*
* Set p2sb PCI offset EPMASK7 [31, 30] to disable Sideband
* access for Broadcast and Multicast.
*/
mask = (1 << 31) | (1 << 30);
ep_mask[P2SB_EP_MASK_7_REG] = mask;
}

View file

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <cf9_reset.h>
#include <intelblocks/cse.h>
#include <intelblocks/pmclib.h>
#include <soc/intel/common/reset.h>
void do_global_reset(void)
{
/* Ask CSE to do the global reset */
if (cse_request_global_reset())
return;
/* global reset if CSE fail to reset */
pmc_global_reset_enable(1);
do_full_reset();
}

View file

@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
romstage-y += fsp_params.c
romstage-y += ../../../../cpu/intel/car/romstage.c
romstage-y += romstage.c
romstage-y += systemagent.c

View file

@ -0,0 +1,297 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h>
#include <console/console.h>
#include <cpu/x86/msr.h>
#include <device/device.h>
#include <fsp/util.h>
#include <intelblocks/cpulib.h>
#include <intelblocks/pcie_rp.h>
#include <soc/gpio_soc_defs.h>
#include <soc/iomap.h>
#include <soc/msr.h>
#include <soc/pci_devs.h>
#include <soc/pcie.h>
#include <soc/romstage.h>
#include <soc/soc_chip.h>
#include <soc/soc_info.h>
#include <string.h>
#define FSP_CLK_NOTUSED 0xFF
#define FSP_CLK_LAN 0x70
#define FSP_CLK_FREE_RUNNING 0x80
static void pcie_rp_init(FSP_M_CONFIG *m_cfg, uint32_t en_mask,
const struct pcie_rp_config *cfg, size_t cfg_count)
{
size_t i;
for (i = 0; i < cfg_count; i++) {
if (!(en_mask & BIT(i)))
continue;
if (cfg[i].flags & PCIE_RP_CLK_SRC_UNUSED)
continue;
/* flags 0 means, RP config is not specify from devicetree */
if (cfg[i].flags == 0)
continue;
if (!(cfg[i].flags & PCIE_RP_CLK_REQ_UNUSED))
m_cfg->PcieClkSrcClkReq[cfg[i].clk_src] = cfg[i].clk_req;
m_cfg->PcieClkSrcUsage[cfg[i].clk_src] = i;
}
}
static void fill_fspm_pcie_rp_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
/* Disable all PCIe clock sources by default. And set RP irrelevant clock. */
unsigned int i;
uint8_t max_clock = get_max_pcie_clock();
for (i = 0; i < max_clock; i++) {
if (config->pcie_clk_config_flag[i] & PCIE_CLK_FREE_RUNNING)
m_cfg->PcieClkSrcUsage[i] = FSP_CLK_FREE_RUNNING;
else if (config->pcie_clk_config_flag[i] & PCIE_CLK_LAN)
m_cfg->PcieClkSrcUsage[i] = FSP_CLK_LAN;
else
m_cfg->PcieClkSrcUsage[i] = FSP_CLK_NOTUSED;
m_cfg->PcieClkSrcClkReq[i] = FSP_CLK_NOTUSED;
}
/* PCIE ports */
m_cfg->PcieRpEnableMask = pcie_rp_enable_mask(get_pcie_rp_table());
pcie_rp_init(m_cfg, m_cfg->PcieRpEnableMask, config->pcie_rp,
get_max_pcie_port());
}
static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
unsigned int i;
const struct ddi_port_upds {
uint8_t *ddc;
uint8_t *hpd;
} ddi_port_upds[] = {
[DDI_PORT_A] = {&m_cfg->DdiPortADdc, &m_cfg->DdiPortAHpd},
[DDI_PORT_B] = {&m_cfg->DdiPortBDdc, &m_cfg->DdiPortBHpd},
[DDI_PORT_C] = {&m_cfg->DdiPortCDdc, &m_cfg->DdiPortCHpd},
[DDI_PORT_1] = {&m_cfg->DdiPort1Ddc, &m_cfg->DdiPort1Hpd},
[DDI_PORT_2] = {&m_cfg->DdiPort2Ddc, &m_cfg->DdiPort2Hpd},
[DDI_PORT_3] = {&m_cfg->DdiPort3Ddc, &m_cfg->DdiPort3Hpd},
[DDI_PORT_4] = {&m_cfg->DdiPort4Ddc, &m_cfg->DdiPort4Hpd},
};
m_cfg->InternalGfx = !CONFIG(SOC_INTEL_DISABLE_IGD) && is_devfn_enabled(PCI_DEVFN_IGD);
if (m_cfg->InternalGfx) {
/* IGD is enabled, set IGD stolen size to 64MB. */
m_cfg->IgdDvmt50PreAlloc = IGD_SM_64MB;
/* DP port config */
m_cfg->DdiPortAConfig = config->ddi_port_A_config;
m_cfg->DdiPortBConfig = config->ddi_port_B_config;
for (i = 0; i < ARRAY_SIZE(ddi_port_upds); i++) {
*ddi_port_upds[i].ddc = !!(config->ddi_ports_config[i] &
DDI_ENABLE_DDC);
*ddi_port_upds[i].hpd = !!(config->ddi_ports_config[i] &
DDI_ENABLE_HPD);
}
} else {
/* IGD is disabled, skip IGD init in FSP. */
m_cfg->IgdDvmt50PreAlloc = 0;
/* DP port config */
m_cfg->DdiPortAConfig = 0;
m_cfg->DdiPortBConfig = 0;
for (i = 0; i < ARRAY_SIZE(ddi_port_upds); i++) {
*ddi_port_upds[i].ddc = 0;
*ddi_port_upds[i].hpd = 0;
}
}
}
static void fill_fspm_mrc_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
m_cfg->SaGv = config->SaGv;
m_cfg->RMT = config->RMT;
}
static void fill_fspm_cpu_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
m_cfg->TsegSize = CONFIG_SMM_TSEG_SIZE;
/* CpuRatio Settings */
if (config->cpu_ratio_override)
m_cfg->CpuRatio = config->cpu_ratio_override;
else
/* Set CpuRatio to match existing MSR value */
m_cfg->CpuRatio = (rdmsr(MSR_FLEX_RATIO).lo >> 8) & 0xff;
m_cfg->PrmrrSize = get_valid_prmrr_size();
/* Enable Hyper Threading */
m_cfg->HyperThreading = 1;
}
static void fill_fspm_security_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
/* Disable BIOS Guard */
m_cfg->BiosGuard = 0;
m_cfg->TmeEnable = CONFIG(INTEL_TME);
}
static void fill_fspm_uart_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
if (CONFIG(DRIVERS_UART_8250IO))
m_cfg->PcdIsaSerialUartBase = ISA_SERIAL_BASE_ADDR_3F8;
m_cfg->SerialIoUartDebugMode = PchSerialIoSkipInit;
m_cfg->SerialIoUartDebugControllerNumber = CONFIG_UART_FOR_CONSOLE;
}
static void fill_fspm_ipu_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
/* Image clock: disable all clocks for bypassing FSP pin mux */
memset(m_cfg->ImguClkOutEn, 0, sizeof(m_cfg->ImguClkOutEn));
/* IPU */
m_cfg->SaIpuEnable = is_devfn_enabled(PCI_DEVFN_IPU);
}
static void fill_fspm_smbus_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
m_cfg->SmbusEnable = is_devfn_enabled(PCI_DEVFN_SMBUS);
}
static void fill_fspm_misc_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
/* Disable Lock PCU Thermal Management registers */
m_cfg->LockPTMregs = 0;
/* Skip CPU replacement check */
m_cfg->SkipCpuReplacementCheck = !config->cpu_replacement_check;
/* Skip GPIO configuration from FSP */
m_cfg->GpioOverride = 0x1;
}
static void fill_fspm_audio_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
/* Audio: HDAUDIO_LINK_MODE I2S/SNDW */
m_cfg->PchHdaEnable = is_devfn_enabled(PCI_DEVFN_HDA);
m_cfg->PchHdaDspEnable = config->pch_hda_dsp_enable;
m_cfg->PchHdaIDispLinkTmode = config->pch_hda_idisp_link_tmode;
m_cfg->PchHdaIDispLinkFrequency = config->pch_hda_idisp_link_frequency;
m_cfg->PchHdaIDispCodecDisconnect = !config->pch_hda_idisp_codec_enable;
/*
* All the PchHdaAudioLink{Hda|Dmic|Ssp|Sndw}Enable UPDs are used by FSP only to
* configure GPIO pads for audio. Mainboard is expected to perform all GPIO
* configuration in coreboot and hence these UPDs are set to 0 to skip FSP GPIO
* configuration for audio pads.
*/
m_cfg->PchHdaAudioLinkHdaEnable = 0;
memset(m_cfg->PchHdaAudioLinkDmicEnable, 0, sizeof(m_cfg->PchHdaAudioLinkDmicEnable));
memset(m_cfg->PchHdaAudioLinkSspEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSspEnable));
memset(m_cfg->PchHdaAudioLinkSndwEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSndwEnable));
}
static void fill_fspm_ish_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
m_cfg->PchIshEnable = is_devfn_enabled(PCI_DEVFN_ISH);
}
static void fill_fspm_tcss_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
int i, max_port;
/* Tcss USB */
m_cfg->TcssXhciEn = is_devfn_enabled(PCI_DEVFN_TCSS_XHCI);
m_cfg->TcssXdciEn = is_devfn_enabled(PCI_DEVFN_TCSS_XDCI);
/* TCSS DMA */
m_cfg->TcssDma0En = is_devfn_enabled(PCI_DEVFN_TCSS_DMA0);
m_cfg->TcssDma1En = 0;
/* Enable TCSS port */
max_port = get_max_tcss_port();
m_cfg->UsbTcPortEnPreMem = 0;
for (i = 0; i < max_port; i++)
if (config->tcss_ports[i].enable)
m_cfg->UsbTcPortEnPreMem |= BIT(i);
}
static void fill_fspm_usb4_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
memset(&m_cfg->TcssItbtPcie0En, 0, sizeof(m_cfg->TcssItbtPcie0En)*4);
m_cfg->TcssItbtPcie0En = !(config->tbt_pcie_port_disable[0]);
m_cfg->TcssItbtPcie1En = !(config->tbt_pcie_port_disable[1]);
}
static void fill_fspm_vtd_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
m_cfg->VtdDisable = 0;
m_cfg->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS;
m_cfg->VtdBaseAddress[1] = VTVC0_BASE_ADDRESS;
/* Change VmxEnable UPD value according to ENABLE_VMX Kconfig */
m_cfg->VmxEnable = CONFIG(ENABLE_VMX);
}
static void fill_fspm_trace_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
/* Set debug probe type */
m_cfg->PlatformDebugConsent = CONFIG_SOC_INTEL_METEORLAKE_DEBUG_CONSENT;
/* CrashLog config */
if (CONFIG(SOC_INTEL_CRASHLOG)) {
m_cfg->CpuCrashLogDevice = 1;
m_cfg->CpuCrashLogEnable = 1;
}
}
static void soc_memory_init_params(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config)
{
const void (*const fill_fspm_params[])(FSP_M_CONFIG *m_cfg,
const struct soc_intel_meteorlake_config *config) = {
fill_fspm_igd_params,
fill_fspm_mrc_params,
fill_fspm_cpu_params,
fill_fspm_security_params,
fill_fspm_uart_params,
fill_fspm_ipu_params,
fill_fspm_smbus_params,
fill_fspm_misc_params,
fill_fspm_audio_params,
fill_fspm_pcie_rp_params,
fill_fspm_ish_params,
fill_fspm_tcss_params,
fill_fspm_usb4_params,
fill_fspm_vtd_params,
fill_fspm_trace_params,
};
for (size_t i = 0; i < ARRAY_SIZE(fill_fspm_params); i++)
fill_fspm_params[i](m_cfg, config);
}
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
{
const struct soc_intel_meteorlake_config *config;
FSP_M_CONFIG *m_cfg = &mupd->FspmConfig;
config = config_of_soc();
soc_memory_init_params(m_cfg, config);
mainboard_memory_init_params(mupd);
}
__weak void mainboard_memory_init_params(FSPM_UPD *memupd)
{
printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
}

View file

@ -0,0 +1,139 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/romstage.h>
#include <cbmem.h>
#include <console/console.h>
#include <fsp/util.h>
#include <intelblocks/cfg.h>
#include <intelblocks/cse.h>
#include <intelblocks/pmclib.h>
#include <intelblocks/smbus.h>
#include <memory_info.h>
#include <soc/intel/common/smbios.h>
#include <soc/iomap.h>
#include <soc/pm.h>
#include <soc/romstage.h>
#include <soc/soc_chip.h>
#include <string.h>
#define FSP_SMBIOS_MEMORY_INFO_GUID \
{ \
0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \
0x8d, 0x09, 0x11, 0xcf, 0x8b, 0x9f, 0x03, 0x23 \
}
/* Save the DIMM information for SMBIOS table 17 */
static void save_dimm_info(void)
{
int node, channel, dimm, dimm_max, index;
size_t hob_size;
const CONTROLLER_INFO *ctrlr_info;
const CHANNEL_INFO *channel_info;
const DIMM_INFO *src_dimm;
struct dimm_info *dest_dimm;
struct memory_info *mem_info;
const MEMORY_INFO_DATA_HOB *meminfo_hob;
const uint8_t smbios_memory_info_guid[sizeof(EFI_GUID)] = FSP_SMBIOS_MEMORY_INFO_GUID;
const uint8_t *serial_num;
const char *dram_part_num = NULL;
size_t dram_part_num_len = 0;
/* Locate the memory info HOB, presence validated by raminit */
meminfo_hob = fsp_find_extension_hob_by_guid(
smbios_memory_info_guid,
&hob_size);
if (meminfo_hob == NULL || hob_size == 0) {
printk(BIOS_ERR, "SMBIOS MEMORY_INFO_DATA_HOB not found\n");
return;
}
/*
* Allocate CBMEM area for DIMM information used to populate SMBIOS
* table 17
*/
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
if (mem_info == NULL) {
printk(BIOS_ERR, "CBMEM entry for DIMM info missing\n");
return;
}
memset(mem_info, 0, sizeof(*mem_info));
/* Allow mainboard to override DRAM part number. */
dram_part_num = mainboard_get_dram_part_num();
if (dram_part_num)
dram_part_num_len = strlen(dram_part_num);
/* Save available DIMM information */
index = 0;
dimm_max = ARRAY_SIZE(mem_info->dimm);
for (node = 0; node < MAX_NODE; node++) {
ctrlr_info = &meminfo_hob->Controller[node];
for (channel = 0; channel < MAX_CH && index < dimm_max; channel++) {
channel_info = &ctrlr_info->ChannelInfo[channel];
if (channel_info->Status != CHANNEL_PRESENT)
continue;
for (dimm = 0; dimm < MAX_DIMM && index < dimm_max; dimm++) {
src_dimm = &channel_info->DimmInfo[dimm];
dest_dimm = &mem_info->dimm[index];
if (src_dimm->Status != DIMM_PRESENT)
continue;
/* If there is no DRAM part number overridden by
* mainboard then use original one. */
if (!dram_part_num) {
dram_part_num_len = sizeof(src_dimm->ModulePartNum);
dram_part_num = (const char *)
&src_dimm->ModulePartNum[0];
}
uint8_t memProfNum = meminfo_hob->MemoryProfile;
serial_num = src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL;
/* Populate the DIMM information */
dimm_info_fill(dest_dimm,
src_dimm->DimmCapacity,
meminfo_hob->MemoryType,
meminfo_hob->ConfiguredMemoryClockSpeed,
src_dimm->RankInDimm,
channel_info->ChannelId,
src_dimm->DimmId,
dram_part_num,
dram_part_num_len,
serial_num,
meminfo_hob->DataWidth,
meminfo_hob->VddVoltage[memProfNum],
meminfo_hob->EccSupport,
src_dimm->MfgId,
src_dimm->SpdModuleType);
index++;
}
}
}
mem_info->dimm_cnt = index;
printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
}
void mainboard_romstage_entry(void)
{
bool s3wake;
struct chipset_power_state *ps = pmc_get_power_state();
/* Program MCHBAR, DMIBAR, GDXBAR and EDRAMBAR */
systemagent_early_init();
/* Program SMBus base address and enable it */
smbus_common_init();
/* Initialize HECI interface */
cse_init(HECI1_BASE_ADDRESS);
s3wake = pmc_fill_power_state(ps) == ACPI_S3;
if (!s3wake) {
if (CONFIG(SOC_INTEL_CSE_LITE_SKU))
cse_fw_sync();
}
fsp_memory_init(s3wake);
pmc_set_disb();
if (!s3wake)
save_dimm_info();
}

View file

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <intelblocks/systemagent.h>
#include <soc/iomap.h>
#include <soc/romstage.h>
#include <soc/systemagent.h>
void systemagent_early_init(void)
{
static const struct sa_mmio_descriptor soc_fixed_pci_resources[] = {
{ MCHBAR, MCH_BASE_ADDRESS, MCH_BASE_SIZE, "MCHBAR" },
{ DMIBAR, DMI_BASE_ADDRESS, DMI_BASE_SIZE, "DMIBAR" },
{ EPBAR, EP_BASE_ADDRESS, EP_BASE_SIZE, "EPBAR" },
};
static const struct sa_mmio_descriptor soc_fixed_mch_resources[] = {
{ REGBAR, REG_BASE_ADDRESS, REG_BASE_SIZE, "REGBAR" },
{ EDRAMBAR, EDRAM_BASE_ADDRESS, EDRAM_BASE_SIZE, "EDRAMBAR" },
};
/* Set Fixed MMIO address into PCI configuration space */
sa_set_pci_bar(soc_fixed_pci_resources,
ARRAY_SIZE(soc_fixed_pci_resources));
/* Set Fixed MMIO address into MCH base address */
sa_set_mch_bar(soc_fixed_mch_resources,
ARRAY_SIZE(soc_fixed_mch_resources));
/* Enable PAM registers */
enable_pam_region();
}