From b29b66c5f5935e0dfab18cca10b69101b75ce508 Mon Sep 17 00:00:00 2001 From: David Milosevic Date: Mon, 19 Aug 2024 14:59:40 +0200 Subject: [PATCH] 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 - MrChromebox edk2 - 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 Signed-off-by: Angel Pons Reviewed-on: https://review.coreboot.org/c/coreboot/+/83979 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/mainboard/hardkernel/Kconfig | 17 ++ src/mainboard/hardkernel/Kconfig.name | 4 + src/mainboard/hardkernel/odroid-h4/Kconfig | 41 ++++ .../hardkernel/odroid-h4/Kconfig.name | 4 + .../hardkernel/odroid-h4/Makefile.mk | 7 + .../hardkernel/odroid-h4/board_info.txt | 9 + .../hardkernel/odroid-h4/bootblock.c | 32 +++ src/mainboard/hardkernel/odroid-h4/data.vbt | Bin 0 -> 9216 bytes .../hardkernel/odroid-h4/devicetree.cb | 211 +++++++++++++++++ src/mainboard/hardkernel/odroid-h4/dsdt.asl | 26 +++ src/mainboard/hardkernel/odroid-h4/hda_verb.c | 46 ++++ .../hardkernel/odroid-h4/mainboard.c | 219 ++++++++++++++++++ .../odroid-h4/romstage_fsp_params.c | 25 ++ 13 files changed, 641 insertions(+) create mode 100644 src/mainboard/hardkernel/Kconfig create mode 100644 src/mainboard/hardkernel/Kconfig.name create mode 100644 src/mainboard/hardkernel/odroid-h4/Kconfig create mode 100644 src/mainboard/hardkernel/odroid-h4/Kconfig.name create mode 100644 src/mainboard/hardkernel/odroid-h4/Makefile.mk create mode 100644 src/mainboard/hardkernel/odroid-h4/board_info.txt create mode 100644 src/mainboard/hardkernel/odroid-h4/bootblock.c create mode 100644 src/mainboard/hardkernel/odroid-h4/data.vbt create mode 100644 src/mainboard/hardkernel/odroid-h4/devicetree.cb create mode 100644 src/mainboard/hardkernel/odroid-h4/dsdt.asl create mode 100644 src/mainboard/hardkernel/odroid-h4/hda_verb.c create mode 100644 src/mainboard/hardkernel/odroid-h4/mainboard.c create mode 100644 src/mainboard/hardkernel/odroid-h4/romstage_fsp_params.c diff --git a/src/mainboard/hardkernel/Kconfig b/src/mainboard/hardkernel/Kconfig new file mode 100644 index 0000000000..eff82b2e65 --- /dev/null +++ b/src/mainboard/hardkernel/Kconfig @@ -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 diff --git a/src/mainboard/hardkernel/Kconfig.name b/src/mainboard/hardkernel/Kconfig.name new file mode 100644 index 0000000000..ff0f70dc2e --- /dev/null +++ b/src/mainboard/hardkernel/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config VENDOR_HARDKERNEL + bool "Hardkernel" diff --git a/src/mainboard/hardkernel/odroid-h4/Kconfig b/src/mainboard/hardkernel/odroid-h4/Kconfig new file mode 100644 index 0000000000..3e03116db7 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/Kconfig @@ -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 diff --git a/src/mainboard/hardkernel/odroid-h4/Kconfig.name b/src/mainboard/hardkernel/odroid-h4/Kconfig.name new file mode 100644 index 0000000000..b7a26bc508 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_HARDKERNEL_ODROID_H4 + bool "ODROID-H4 / H4+ / H4 Ultra" diff --git a/src/mainboard/hardkernel/odroid-h4/Makefile.mk b/src/mainboard/hardkernel/odroid-h4/Makefile.mk new file mode 100644 index 0000000000..2e6759f093 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/Makefile.mk @@ -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 diff --git a/src/mainboard/hardkernel/odroid-h4/board_info.txt b/src/mainboard/hardkernel/odroid-h4/board_info.txt new file mode 100644 index 0000000000..e0c5888b97 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/board_info.txt @@ -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 diff --git a/src/mainboard/hardkernel/odroid-h4/bootblock.c b/src/mainboard/hardkernel/odroid-h4/bootblock.c new file mode 100644 index 0000000000..31db135281 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/bootblock.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +#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) +{ +} diff --git a/src/mainboard/hardkernel/odroid-h4/data.vbt b/src/mainboard/hardkernel/odroid-h4/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..a3c168fce30b250c78c77e3ae01e94c52e0f69a3 GIT binary patch literal 9216 zcmeHMUrbw782`?_ZRu)}PHb*_)g7cg`*C%7#?ubj*Iuckj99 z`_Aut-|w8Bd+xml$GS#&pueYgxIb{Bw;{wKG15q_ZpHC_=?V^wjQ0da1LIx&L)|C% zZ?uQ5SN(pAD8|@6ceAE72hY#Nr@X^;d|-NFaw^``6Tk5K-1H0&bq9Ii?AiEKeD=&- zJjO@HUJ7u5SM2J#I5`#LgBQB9 zyLx)NhXz8y{=jH(Xpj#L^Pb>HU}U6spsW8B4-F3;3w8xZdwYsqIVp5c&s>_FeD$?C z?(MGQKJ?Qdab?K7dwO=Jkq4%x_^|M~z=z`(;yl_UuTA$PmT zLryZFHmDBeP*JBq8I%|lR)UpaC0Geo7@*>yyw4Qa4++0}1%0ZxPNE^t)N^!}D@E32 z61Y5L;pp*tlsq1)sS^E35gjJcB^QOX=yXH6b*9~bCSn6x+D(K&K(^dYr`?J-VvFXu z$*$1pTWPo5M0T`Jl9AJ?=t0ExVcM;f$RXX#95)#z+`dk`iB^y#&E#|{I235tHoH-- zn`pbe+<6;5X@VFrAwgnpO!6?!@4B$ zZ>0Eu^J8Iqu2Eepa?x7RZMInYc$OYO-4<2Zd9;N?p}N4pLo(p4CPi(@0TBzEkZfiB znB7p;nX&t6dAD-Ty73Q-C~kSa%{(~UOAb*gbz_%d^7R8AXSCXCUD0RyvIGH`*KYNJDlkR4S1O*j_uf|6kPU6g8+c>hWMZDnw@C5hZtj zUuZmZ=6rl=@XWdR6L2Atdeo9iz0k}Y$5+V_S$=fK)Fx3B6bn@1+n!$Ng;~SVfGQ-RB`*U1nEfGvq?n#gTNa#MvEEQ8AU6PjdcF?bBkQU ztsq+4u}ObiQrVKQ?f3WUJ>P5`XO5^q$QW1?<~V0iox7U{C;x!CTsiJ7}ZRk z_u)Zt-0LSF+~wmW&V`<{+!fgV=V#b$X8jgR|9UAqGPxy(l=kb^4j|XI!>^7GyBuk>^rtM2iqZ#;UXoqK6ND?Y+ z^LEZWuvOSRIX3f0VOwVrT7s=M$F?@FknYeF9Vja{Uykk00HZPcGV3D~u~foly-_sK z-w$hyOhQ6Jf)CPWZ711HOSri>?mxu1fzs~jfLn6EvVJNw4SkrP2`|E zR;irAu*HNo)XHxwUXrjMEEc>Z@JNqn)V*kx<)y4g#8Qsj8>rpZkQ3+CckxBqiSOX} Zk)sr`$anve&p#W#C&32V3i5wt;15I>bqW9g literal 0 HcmV?d00001 diff --git a/src/mainboard/hardkernel/odroid-h4/devicetree.cb b/src/mainboard/hardkernel/odroid-h4/devicetree.cb new file mode 100644 index 0000000000..48f35fd421 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/devicetree.cb @@ -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 diff --git a/src/mainboard/hardkernel/odroid-h4/dsdt.asl b/src/mainboard/hardkernel/odroid-h4/dsdt.asl new file mode 100644 index 0000000000..584f330cbb --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/dsdt.asl @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20110725 +) +{ + #include + #include + #include + #include + + Device (\_SB.PCI0) { + #include + #include + #include + } + + #include +} diff --git a/src/mainboard/hardkernel/odroid-h4/hda_verb.c b/src/mainboard/hardkernel/odroid-h4/hda_verb.c new file mode 100644 index 0000000000..0ac706c851 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/hda_verb.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +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; diff --git a/src/mainboard/hardkernel/odroid-h4/mainboard.c b/src/mainboard/hardkernel/odroid-h4/mainboard.c new file mode 100644 index 0000000000..d8cfc8814d --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/mainboard.c @@ -0,0 +1,219 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include + +/* + * 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, +}; diff --git a/src/mainboard/hardkernel/odroid-h4/romstage_fsp_params.c b/src/mainboard/hardkernel/odroid-h4/romstage_fsp_params.c new file mode 100644 index 0000000000..549a4bdc34 --- /dev/null +++ b/src/mainboard/hardkernel/odroid-h4/romstage_fsp_params.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +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); +}