mb/hardkernel/odroid-h4: Add support for ODROID-H4 series

Add support for the ODROID-H4 family of boards. Tested on an ODROID-H4+
board, but all of them use the same PCB (with different components).

The four SATA ports on the mainboard are provided by an onboard ASMedia
ASM1064B PCIe-to-SATA bridge. Unlike other mainboards in the tree using
an ASMedia ASM1061 or ASM1062 PCIe-to-SATA bridge, the ODROID-H4+ comes
with a SPI flash chip for the ASM1064B and does not seem to have issues
regarding PCIe power management (e.g. ASPM) or unusable SATA AHCI mode.

The ODROID-H4 comes with a single 16 MiB SPI flash chip. The ODROID-H4+
and the ODROID-H4 Ultra feature Dual BIOS, consisting of another 16 MiB
SPI flash chip and a 3-pin header to select between them. The board can
be flashed internally or using a SOIC-8 clip, but the M.2 slot may need
to be empty for the clip to fit.

Working:

 - DDR5 SO-DIMM slot
 - All SATA ports on ASMedia ASM1064B PCIe-to-SATA controller
 - UART to emit spam
 - All video outputs (FSP GOP only lights up one output at a time)
 - All USB ports (on the Ethernet connectors and on EXT_HDR1)
 - M.2 M connector (PCIe only)
 - PCIe power management
 - Ethernet NICs
 - eMMC
 - HD audio codec and display audio
 - S3 suspend/resume
 - SeaBIOS <current version>
 - MrChromebox edk2 <current version>
 - Super I/O HWM on Linux (using out-of-tree it87 kernel module)
 - Booting Arch Linux from NVMe and SATA
 - Booting Windows 10 from NVMe

Not working:

 - PECI: undocumented protocol and undocumented Super I/O
 - Resuming on Windows 10 BSODs with `VIDEO_TDR_FAILURE`

Untested:

 - Fan curves: may need to lower the temperature limits a bit

Change-Id: I7e0d395ba3d15dfcf6d47a222b90499ca371e4eb
Signed-off-by: David Milosevic <David.Milosevic@9elements.com>
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/83979
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
David Milosevic 2024-08-19 14:59:40 +02:00 committed by Lean Sheng Tan
commit b29b66c5f5
13 changed files with 641 additions and 0 deletions

View file

@ -0,0 +1,17 @@
## SPDX-License-Identifier: GPL-2.0-only
if VENDOR_HARDKERNEL
choice
prompt "Mainboard model"
source "src/mainboard/hardkernel/*/Kconfig.name"
endchoice
source "src/mainboard/hardkernel/*/Kconfig"
config MAINBOARD_VENDOR
default "Hardkernel"
endif # VENDOR_HARDKERNEL

View file

@ -0,0 +1,4 @@
## SPDX-License-Identifier: GPL-2.0-only
config VENDOR_HARDKERNEL
bool "Hardkernel"

View file

@ -0,0 +1,41 @@
## SPDX-License-Identifier: GPL-2.0-only
if BOARD_HARDKERNEL_ODROID_H4
config BOARD_SPECIFIC_OPTIONS
def_bool y
select BOARD_ROMSIZE_KB_16384
select CRB_TPM
select DRIVERS_UART_8250IO
select FSP_TYPE_IOT
select HAVE_ACPI_RESUME
select HAVE_ACPI_TABLES
select HAVE_INTEL_PTT
select INTEL_GMA_HAVE_VBT
select SUPERIO_ITE_IT8613E
select SOC_INTEL_ALDERLAKE_PCH_N
select SOC_INTEL_COMMON_BLOCK_HDA_VERB
select USE_DDR5
config MAINBOARD_DIR
default "hardkernel/odroid-h4"
config MAINBOARD_PART_NUMBER
default "ODROID-H4"
config ODROID_H4_ENABLE_SAGV
bool "Enable SAGV"
default y
help
SAGV (System Agent GeyserVille) is Intel's implementation of
DVFS (Dynamic Voltage Frequency Scaling) that reduces energy
consumption of the SA and DRAM during low-load conditions by
automatically switching to lower voltages / frequencies when
the system load is low enough. When enabled, memory training
has to run multiple times (once per SAGV point), which slows
down booting (but only when the MRC cache is unusable).
If unsure, keep enabled. If reflashing often, disabling this
option can be useful to reduce memory training time.
endif #BOARD_HARDKERNEL_ODROID_H4

View file

@ -0,0 +1,4 @@
## SPDX-License-Identifier: GPL-2.0-only
config BOARD_HARDKERNEL_ODROID_H4
bool "ODROID-H4 / H4+ / H4 Ultra"

View file

@ -0,0 +1,7 @@
## SPDX-License-Identifier: GPL-2.0-only
bootblock-y += bootblock.c
romstage-y += romstage_fsp_params.c
ramstage-y += mainboard.c

View file

@ -0,0 +1,9 @@
Vendor name: Hardkernel
Board name: Odroid H4
Board URL: https://wiki.odroid.com/odroid-h4/start
Category: mini
ROM package: SOIC-8
ROM protocol: SPI
ROM socketed: n
Flashrom support: y
Release year: 2024

View file

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <bootblock_common.h>
#include <superio/ite/common/ite.h>
#include <superio/ite/it8613e/it8613e.h>
#define GPIO_DEV PNP_DEV(0x2e, IT8613E_GPIO)
#define UART_DEV PNP_DEV(0x2e, IT8613E_SP1)
void bootblock_mainboard_early_init(void)
{
/* Set up Super I/O GPIOs, values are dumped from vendor firmware */
ite_reg_write(GPIO_DEV, 0x26, 0xfb);
ite_reg_write(GPIO_DEV, 0x29, 0x01);
ite_reg_write(GPIO_DEV, 0x2c, 0x41);
ite_reg_write(GPIO_DEV, 0x2d, 0x02);
ite_reg_write(GPIO_DEV, 0xbc, 0xc0);
ite_reg_write(GPIO_DEV, 0xbd, 0x03);
ite_reg_write(GPIO_DEV, 0xc1, 0x0a);
ite_reg_write(GPIO_DEV, 0xc8, 0x00);
ite_reg_write(GPIO_DEV, 0xc9, 0x0a);
ite_reg_write(GPIO_DEV, 0xda, 0xb0);
ite_reg_write(GPIO_DEV, 0xdb, 0x44);
ite_delay_pwrgd3(GPIO_DEV);
ite_enable_serial(UART_DEV, CONFIG_TTYS0_BASE);
}
void bootblock_mainboard_init(void)
{
}

Binary file not shown.

View file

@ -0,0 +1,211 @@
## SPDX-License-Identifier: GPL-2.0-only
chip soc/intel/alderlake
register "pmc_gpe0_dw0" = "PMC_GPP_A"
register "pmc_gpe0_dw1" = "PMC_GPP_R"
register "pmc_gpe0_dw2" = "PMC_GPD"
register "sagv" = "CONFIG(ODROID_H4_ENABLE_SAGV) ? SaGv_Enabled : SaGv_Disabled"
register "enable_c6dram" = "true"
register "tcc_offset" = "10" # TCC of 90C
device domain 0 on
device ref igpu on
register "ddi_portA_config" = "1"
register "ddi_portB_config" = "1"
register "ddi_ports_config" = "{
[DDI_PORT_A] = DDI_ENABLE_HPD | DDI_ENABLE_DDC,
[DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC,
[DDI_PORT_1] = DDI_ENABLE_HPD | DDI_ENABLE_DDC,
}"
end
device ref xhci on
## Yes, the numbering of the three USB2 ports routed to the EXT_HEAD1
## pin header does not correlate with the numbering of the USB2 ports
## on the ADL-N SoC. But schematics and lsusb agree with the mapping.
##
## For onboard USB Type-A ports, tune PHYs for short trace lengths as
## the ODROID-H4 is a tiny board (and exact trace length is unknown).
##
## The USB2 ports on the EXT_HEAD1 pin header are meant to be cabled.
## So, have these ports use medium trace length PHY settings instead.
register "usb2_ports" = "{
#define ODROID_H4_USB2_PORT_REAR { \
.enable = 1, \
.ocpin = OC_SKIP, \
.tx_bias = USB2_BIAS_0MV, \
.tx_emp_enable = USB2_PRE_EMP_ON | USB2_DE_EMP_ON, \
.pre_emp_bias = USB2_BIAS_16P9MV, \
.pre_emp_bit = USB2_FULL_BIT_PRE_EMP, \
}
[0] = ODROID_H4_USB2_PORT_REAR, // USB3_LAN1 Bottom
[1] = ODROID_H4_USB2_PORT_REAR, // USB3_LAN1 Top
[2] = USB2_PORT_MID(OC_SKIP), // EXT_HEAD1 P7
[3] = USB2_PORT_MID(OC_SKIP), // EXT_HEAD1 P5
[4] = ODROID_H4_USB2_PORT_REAR, // USBLAN1 Top
[5] = USB2_PORT_MID(OC_SKIP), // EXT_HEAD1 P6
[6] = ODROID_H4_USB2_PORT_REAR, // USBLAN1 Bottom
}"
register "usb3_ports" = "{
[0] = USB3_PORT_DEFAULT(OC_SKIP), // USB3_LAN1 Bottom
[1] = USB3_PORT_DEFAULT(OC_SKIP), // USB3_LAN1 Top
}"
chip drivers/usb/acpi
device ref xhci_root_hub on
chip drivers/usb/acpi
register "desc" = ""USB3 Type-A (Bottom Right)""
register "type" = "UPC_TYPE_USB3_A"
device ref usb2_port1 on end
device ref usb3_port1 on end
end
chip drivers/usb/acpi
register "desc" = ""USB3 Type-A (Top Right)""
register "type" = "UPC_TYPE_USB3_A"
device ref usb2_port2 on end
device ref usb3_port2 on end
end
chip drivers/usb/acpi
register "desc" = ""USB2 P7 (EXT_HEAD1)""
register "type" = "UPC_TYPE_PROPRIETARY"
device ref usb2_port3 on end
end
chip drivers/usb/acpi
register "desc" = ""USB2 P5 (EXT_HEAD1)""
register "type" = "UPC_TYPE_PROPRIETARY"
device ref usb2_port4 on end
end
chip drivers/usb/acpi
register "desc" = ""USB2 Type-A (Top Left)""
register "type" = "UPC_TYPE_A"
device ref usb2_port5 on end
end
chip drivers/usb/acpi
register "desc" = ""USB2 P6 (EXT_HEAD1)""
register "type" = "UPC_TYPE_PROPRIETARY"
device ref usb2_port6 on end
end
chip drivers/usb/acpi
register "desc" = ""USB2 Type-A (Bottom Left)""
register "type" = "UPC_TYPE_A"
device ref usb2_port7 on end
end
end
end
end
device ref i2c0 on
register "serial_io_i2c_mode[PchSerialIoIndexI2C0]" = "PchSerialIoPci"
register "common_soc_config.i2c[0]" = "{
.speed = I2C_SPEED_FAST,
.rise_time_ns = 80,
.fall_time_ns = 110,
}"
end
device ref i2c1 on
register "serial_io_i2c_mode[PchSerialIoIndexI2C1]" = "PchSerialIoPci"
register "common_soc_config.i2c[1]" = "{
.speed = I2C_SPEED_FAST,
.rise_time_ns = 80,
.fall_time_ns = 110,
}"
end
device ref emmc on
register "emmc_enable_hs400_mode" = "true"
end
device ref pcie_rp3 on # LAN1
register "pch_pcie_rp[PCH_RP(3)]" = "{
.clk_src = 1,
.clk_req = 1,
.flags = PCIE_RP_LTR | PCIE_RP_AER,
}"
end
device ref pcie_rp4 on # LAN2
register "pch_pcie_rp[PCH_RP(4)]" = "{
.clk_src = 2,
.clk_req = 2,
.flags = PCIE_RP_LTR | PCIE_RP_AER,
}"
end
device ref pcie_rp7 on # ASM1064B SATA
register "pch_pcie_rp[PCH_RP(7)]" = "{
.clk_src = 3,
.clk_req = 3, // Use hardwired CLKREQ# to allow clock gating
.flags = PCIE_RP_LTR | PCIE_RP_AER,
}"
end
device ref pcie_rp9 on # M.2 M (x4)
register "pch_pcie_rp[PCH_RP(9)]" = "{
.clk_src = 0,
.clk_req = 0,
.flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT,
}"
smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther"
"M.2/M 2280 (M2_SSD1)" "SlotDataBusWidth4X"
end
device ref pch_espi on
register "gen1_dec" = "0x00fc0201"
register "gen2_dec" = "0x007c0a01"
register "gen3_dec" = "0x000c03e1"
register "gen4_dec" = "0x001c02e1"
chip superio/ite/it8613e
register "ec.vin_mask" = "VIN0 | VIN1 | VIN2 | VIN4 | VIN5"
# TODO: figure out how to make PECI work
register "TMPIN1.mode" = "THERMAL_DIODE"
#register "TMPIN1.mode" = "THERMAL_PECI"
#register "TMPIN1.offset" = "0x56"
register "FAN2" = "{
.mode = FAN_SMART_AUTOMATIC,
.smart = {
.tmpin = 1,
.tmp_off = 20,
.tmp_start = 35,
.tmp_full = 70,
.tmp_delta = 1,
.pwm_start = 20,
.slope = 3,
.smoothing = 0,
},
}"
device pnp 2e.1 on # COM 1
io 0x60 = 0x3f8
irq 0x70 = 4
irq 0xf0 = 0x01
end
device pnp 2e.4 on # Environment Controller
io 0x60 = 0xa30
io 0x62 = 0xa20
irq 0x70 = 0x00
irq 0xf0 = 0x80
irq 0xfc = 0xa0
end
device pnp 2e.5 off end # Keyboard
device pnp 2e.6 off end # Mouse
device pnp 2e.7 on # GPIO
io 0x60 = 0xa10
io 0x62 = 0xa00
end
device pnp 2e.a off end # CIR
end
end
device ref hda on
register "pch_hda_dsp_enable" = "true"
register "pch_hda_sdi_enable[0]" = "true"
register "pch_hda_audio_link_hda_enable" = "true"
register "pch_hda_idisp_codec_enable" = "true"
register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ"
register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T"
end
device ref smbus on end
chip drivers/crb
device mmio 0xfed40000 on end
end
end
end

View file

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <acpi/acpi.h>
DefinitionBlock(
"dsdt.aml",
"DSDT",
ACPI_DSDT_REV_2,
OEM_ID,
ACPI_TABLE_CREATOR,
0x20110725
)
{
#include <acpi/dsdt_top.asl>
#include <soc/intel/common/block/acpi/acpi/platform.asl>
#include <soc/intel/common/block/acpi/acpi/globalnvs.asl>
#include <cpu/intel/common/acpi/cpu.asl>
Device (\_SB.PCI0) {
#include <soc/intel/common/block/acpi/acpi/northbridge.asl>
#include <soc/intel/alderlake/acpi/southbridge.asl>
#include <soc/intel/alderlake/acpi/tcss.asl>
}
#include <southbridge/intel/common/acpi/sleepstates.asl>
}

View file

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <device/azalia_device.h>
const u32 cim_verb_data[] = {
0x10ec0897, /* Vendor ID: Realtek ALC897 */
0x10ec0897, /* Subsystem ID */
16, /* Number of entries */
AZALIA_SUBVENDOR(0, 0x10ec0897),
AZALIA_PIN_CFG(0, 0x11, 0x40000000),
AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x14, 0x01214010),
AZALIA_PIN_CFG(0, 0x15, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x16, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x17, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x18, 0x01a19030),
AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x1c, AZALIA_PIN_CFG_NC(0)),
AZALIA_PIN_CFG(0, 0x1d, 0x40210201),
AZALIA_PIN_CFG(0, 0x1e, 0x01441120),
AZALIA_PIN_CFG(0, 0x1f, AZALIA_PIN_CFG_NC(0)),
0x8086281c, /* Vendor ID: Intel Alder Lake */
0x80860101, /* Subsystem ID */
11, /* Number of entries */
AZALIA_VERB_12B(2, 0x02, 0x781, 3),
AZALIA_VERB_12B(2, 0x00, 0xf00, 0),
AZALIA_VERB_12B(2, 0x00, 0xf00, 0),
AZALIA_VERB_12B(2, 0x00, 0xf00, 0),
AZALIA_SUBVENDOR(2, 0x80860101),
AZALIA_PIN_CFG(2, 0x04, 0x18560010),
AZALIA_PIN_CFG(2, 0x06, 0x18560010),
AZALIA_PIN_CFG(2, 0x08, 0x18560010),
AZALIA_PIN_CFG(2, 0x0a, 0x18560010),
AZALIA_PIN_CFG(2, 0x0b, 0x18560010),
AZALIA_PIN_CFG(2, 0x0c, 0x18560010),
AZALIA_PIN_CFG(2, 0x0d, 0x18560010),
AZALIA_PIN_CFG(2, 0x0e, 0x18560010),
AZALIA_PIN_CFG(2, 0x0f, 0x18560010),
};
const u32 pc_beep_verbs[] = {};
AZALIA_ARRAY_SIZES;

View file

@ -0,0 +1,219 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <gpio.h>
#include <soc/gpio.h>
#include <soc/ramstage.h>
/*
* Pad configuration was derived from schematics, revision 0.1
* - https://wiki.odroid.com/odroid-h4/hardware#odroid-h4_schematics
*/
static const struct pad_config gpio_table[] = {
/* ------- GPIO Group GPP_A ------- */
PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* ESPI_IO0 */
PAD_CFG_NF(GPP_A1, NONE, DEEP, NF1), /* ESPI_IO1 */
PAD_CFG_NF(GPP_A2, NONE, DEEP, NF1), /* ESPI_IO2 */
PAD_CFG_NF(GPP_A3, NONE, DEEP, NF1), /* ESPI_IO3 */
PAD_CFG_NF(GPP_A4, NONE, DEEP, NF1), /* ESPI_CS# */
PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* ESPI_ALERT# */
PAD_NC(GPP_A6, NONE),
PAD_NC(GPP_A7, NONE),
PAD_CFG_GPO(GPP_A8, 1, PLTRST), /* LAN_DISABLE# */
PAD_CFG_NF(GPP_A9, NONE, DEEP, NF1), /* ESPI_CLK */
PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), /* ESPI_RESET# */
PAD_NC(GPP_A11, NONE),
PAD_CFG_NF(GPP_A12, NONE, DEEP, NF1), /* M.2_SSD_PEDET_R */
PAD_NC(GPP_A13, NONE),
PAD_NC(GPP_A14, NONE),
PAD_NC(GPP_A15, NONE),
PAD_NC(GPP_A16, NONE),
PAD_NC(GPP_A17, NONE),
PAD_CFG_NF(GPP_A18, NONE, DEEP, NF1), /* DDI1_HPD */
PAD_CFG_NF(GPP_A19, NONE, DEEP, NF1), /* TCP0_HPD */
PAD_NC(GPP_A20, NONE),
PAD_NC(GPP_A21, NONE),
PAD_NC(GPP_A22, NONE),
PAD_NC(GPP_A23, NONE),
/* ------- GPIO Group GPP_B ------- */
PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), /* CORE_VID0 */
PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), /* CORE_VID1 */
PAD_CFG_NF(GPP_B2, NONE, PLTRST, NF1), /* VRALERT# */
PAD_NC(GPP_B3, NONE),
PAD_NC(GPP_B4, NONE),
PAD_NC(GPP_B5, NONE),
PAD_NC(GPP_B6, NONE),
PAD_NC(GPP_B7, NONE),
PAD_CFG_GPI(GPP_B8, NONE, DEEP), /* EMMC_DET#_L */
PAD_CFG_NF(GPP_B11, NONE, DEEP, NF1), /* PMCALERT# */
PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), /* SLP_S0# */
PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* PM_PLTRST_N */
PAD_CFG_NF(GPP_B14, NONE, PLTRST, NF4), /* PCH_SATA_LED# */
PAD_NC(GPP_B15, NONE),
PAD_NC(GPP_B16, NONE),
PAD_NC(GPP_B17, NONE),
PAD_NC(GPP_B18, NONE),
PAD_NC(GPP_B23, NONE),
/* ------- GPIO Group GPP_C ------- */
PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */
PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */
PAD_CFG_NF(GPP_C2, NONE, DEEP, NF1), /* SMB_ALERT# */
PAD_NC(GPP_C3, NONE),
PAD_NC(GPP_C4, NONE),
PAD_NC(GPP_C5, NONE),
PAD_NC(GPP_C6, NONE),
PAD_NC(GPP_C7, NONE),
/* ------- GPIO Group GPP_D ------- */
PAD_NC(GPP_D0, NONE),
PAD_NC(GPP_D1, NONE),
PAD_NC(GPP_D2, NONE),
PAD_NC(GPP_D3, NONE),
PAD_NC(GPP_D4, NONE),
PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* PCIE_CLKREQ0_N */
PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* PCIE_CLKREQ1_N */
PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* PCIE_CLKREQ2_N */
PAD_CFG_NF(GPP_D8, NONE, DEEP, NF1), /* CLKREQ3# but always asserted */
PAD_NC(GPP_D9, NONE),
PAD_NC(GPP_D10, NONE),
PAD_NC(GPP_D11, NONE),
PAD_NC(GPP_D11, NONE),
PAD_NC(GPP_D13, NONE),
PAD_NC(GPP_D14, NONE),
PAD_NC(GPP_D15, NONE),
PAD_NC(GPP_D16, NONE),
PAD_NC(GPP_D17, NONE),
PAD_NC(GPP_D18, NONE),
PAD_NC(GPP_D19, NONE),
/* ------- GPIO Group GPP_E ------- */
PAD_NC(GPP_E0, NONE),
PAD_NC(GPP_E1, NONE),
PAD_NC(GPP_E2, NONE),
PAD_NC(GPP_E3, NONE),
PAD_NC(GPP_E4, NONE),
PAD_NC(GPP_E5, NONE),
PAD_NC(GPP_E6, NONE),
PAD_NC(GPP_E7, NONE),
PAD_NC(GPP_E8, NONE),
PAD_NC(GPP_E9, NONE),
PAD_NC(GPP_E10, NONE),
PAD_NC(GPP_E11, NONE),
PAD_NC(GPP_E12, NONE),
PAD_NC(GPP_E13, NONE),
PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDI0_HPD */
PAD_NC(GPP_E15, NONE),
PAD_NC(GPP_E16, NONE), /* Unknown, goes to M.2 pin 67 (NC) */
PAD_NC(GPP_E17, NONE),
PAD_CFG_NF(GPP_E18, NONE, DEEP, NF1), /* TCP0_DDCCLK */
PAD_CFG_NF(GPP_E19, NONE, DEEP, NF1), /* TCP0_DDCDATA */
PAD_NC(GPP_E20, NONE),
PAD_NC(GPP_E21, NONE),
PAD_CFG_NF(GPP_E22, NONE, DEEP, NF1), /* DDI0_DDCCLK */
PAD_CFG_NF(GPP_E23, NONE, DEEP, NF1), /* DDI0_DDCDATA */
/* ------- GPIO Group GPP_F ------- */
PAD_NC(GPP_F0, NONE),
PAD_NC(GPP_F1, NONE),
PAD_NC(GPP_F2, NONE),
PAD_NC(GPP_F3, NONE),
PAD_NC(GPP_F4, NONE),
PAD_NC(GPP_F5, NONE),
PAD_NC(GPP_F6, NONE),
PAD_NC(GPP_F7, NONE),
PAD_NC(GPP_F10, NONE),
PAD_NC(GPP_F11, NONE),
PAD_NC(GPP_F12, NONE),
PAD_NC(GPP_F13, NONE),
PAD_NC(GPP_F14, NONE),
PAD_NC(GPP_F15, NONE),
PAD_NC(GPP_F16, NONE),
PAD_NC(GPP_F17, NONE),
PAD_NC(GPP_F18, NONE),
PAD_NC(GPP_F22, NONE),
PAD_NC(GPP_F23, NONE),
/* ------- GPIO Group GPP_H ------- */
PAD_NC(GPP_H0, NONE),
PAD_NC(GPP_H1, NONE),
PAD_NC(GPP_H2, NONE),
PAD_NC(GPP_H3, NONE),
PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), /* I2C_0_SDA */
PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), /* I2C_0_SCL */
PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1), /* I2C_1_SDA */
PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1), /* I2C_1_SCL */
PAD_NC(GPP_H8, NONE),
PAD_NC(GPP_H9, NONE),
PAD_NC(GPP_H10, NONE),
PAD_NC(GPP_H11, NONE),
PAD_NC(GPP_H12, NONE),
PAD_NC(GPP_H13, NONE),
PAD_CFG_NF(GPP_H15, NONE, DEEP, NF1), /* DDI1_DDCCLK */
PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), /* DDI1_DDCDATA */
PAD_NC(GPP_H18, NONE),
PAD_NC(GPP_H19, NONE),
PAD_NC(GPP_H20, NONE),
PAD_NC(GPP_H21, NONE),
PAD_NC(GPP_H22, NONE),
PAD_NC(GPP_H23, NONE),
/* ------- GPIO Group GPP_I ------- */
PAD_NC(GPP_I5, NONE),
PAD_CFG_NF(GPP_I7, NONE, DEEP, NF1), /* EMMC_CMD */
PAD_CFG_NF(GPP_I8, NONE, DEEP, NF1), /* EMMC_DATA_0 */
PAD_CFG_NF(GPP_I9, NONE, DEEP, NF1), /* EMMC_DATA_1 */
PAD_CFG_NF(GPP_I10, NONE, DEEP, NF1), /* EMMC_DATA_2 */
PAD_CFG_NF(GPP_I11, NONE, DEEP, NF1), /* EMMC_DATA_3 */
PAD_CFG_NF(GPP_I12, NONE, DEEP, NF1), /* EMMC_DATA_4 */
PAD_CFG_NF(GPP_I13, NONE, DEEP, NF1), /* EMMC_DATA_5 */
PAD_CFG_NF(GPP_I14, NONE, DEEP, NF1), /* EMMC_DATA_6 */
PAD_CFG_NF(GPP_I15, NONE, DEEP, NF1), /* EMMC_DATA_7 */
PAD_CFG_NF(GPP_I16, NONE, DEEP, NF1), /* EMMC_RCLK */
PAD_CFG_NF(GPP_I17, NONE, DEEP, NF1), /* EMMC_CLK */
PAD_CFG_NF(GPP_I18, NONE, DEEP, NF1), /* EMMC_RESET# */
/* ------- GPIO Group GPP_R ------- */
PAD_CFG_NF(GPP_R0, NONE, DEEP, NF1), /* HDA_BCLK_R */
PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), /* HDA_SYNC_R */
PAD_CFG_NF(GPP_R2, NONE, DEEP, NF1), /* HDA_SDO_R */
PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), /* HDA_SDI_R */
PAD_CFG_NF(GPP_R4, NATIVE, DEEP, NF1), /* HDA_RST_N */
PAD_NC(GPP_R5, NONE),
PAD_NC(GPP_R6, NONE),
PAD_NC(GPP_R7, NONE),
/* ------- GPIO Group GPP_S ------- */
PAD_NC(GPP_S0, NONE),
PAD_NC(GPP_S1, NONE),
PAD_NC(GPP_S2, NONE),
PAD_NC(GPP_S3, NONE),
PAD_NC(GPP_S4, NONE),
PAD_NC(GPP_S5, NONE),
PAD_NC(GPP_S6, NONE),
PAD_NC(GPP_S7, NONE),
/* ------- GPIO Group GPP_GPD ------- */
PAD_CFG_NF(GPD0, NONE, PWROK, NF1), /* BATLOW# */
PAD_CFG_NF(GPD1, NONE, PWROK, NF1), /* ACPRESENT */
PAD_NC(GPD2, NONE),
PAD_CFG_NF(GPD3, NONE, PWROK, NF1), /* PM_PWRBTN# */
PAD_CFG_NF(GPD4, NONE, PWROK, NF1), /* SLP_S3# */
PAD_CFG_NF(GPD5, NONE, PWROK, NF1), /* SLP_S4# */
PAD_CFG_NF(GPD6, NONE, PWROK, NF1), /* SLP_A# */
PAD_NC(GPD7, NONE),
PAD_CFG_NF(GPD8, NONE, PWROK, NF1), /* SUSCLK */
PAD_CFG_NF(GPD9, NONE, PWROK, NF1), /* SLP_WLAN# */
PAD_CFG_NF(GPD10, NONE, PWROK, NF1), /* SLP_S5# */
PAD_NC(GPD11, NONE),
};
static void mainboard_init(void *chip_info)
{
gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table));
}
struct chip_operations mainboard_ops = {
.init = mainboard_init,
};

View file

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <fsp/api.h>
#include <soc/romstage.h>
#include <soc/meminit.h>
static const struct mb_cfg ddr5_mem_config = {
.type = MEM_TYPE_DDR5,
/* According to DOC #573387 rcomp values no longer have to be provided */
/* DDR DIMM configuration does not need to set DQ/DQS maps */
.ect = true, /* Early Command Training */
.UserBd = BOARD_TYPE_MOBILE,
.LpDdrDqDqsReTraining = 1
};
static const struct mem_spd dimm_module_spd_info = {
.topo = MEM_TOPO_DIMM_MODULE,
.smbus[0] = { .addr_dimm[0] = 0x52, },
};
void mainboard_memory_init_params(FSPM_UPD *memupd)
{
const bool half_populated = true;
memcfg_init(memupd, &ddr5_mem_config, &dimm_module_spd_info, half_populated);
}