summaryrefslogtreecommitdiff
path: root/src/mainboard/amd/mayan
diff options
context:
space:
mode:
authorRitul Guru <ritul.bits@gmail.com>2022-11-25 11:31:26 +0530
committerMartin L Roth <gaumless@gmail.com>2022-11-27 17:18:13 +0000
commitf123ffe78c2a519fdf0a32bcbfd1ec36733bb13a (patch)
treec55736e1ec014b52d32af70b2112915f0558638a /src/mainboard/amd/mayan
parent21e0da31282f584a1a830c6621e0673f1d0f1b76 (diff)
mb/amd/mayan: Add framework for morgana crb mayan
mayan is the reference board for the morgana SoC. It needs to be updated to match the actual board design as well. amd/mayan is started as a copy of amd/birman. Change-Id: Id6801e6c6e706ae3878ce9e2c3d6452964235148 Signed-off-by: Ritul Guru <ritul.bits@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/70010 Reviewed-by: Felix Held <felix-coreboot@felixheld.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/mainboard/amd/mayan')
-rw-r--r--src/mainboard/amd/mayan/Kconfig110
-rw-r--r--src/mainboard/amd/mayan/Kconfig.name5
-rw-r--r--src/mainboard/amd/mayan/Makefile.inc42
-rw-r--r--src/mainboard/amd/mayan/board.fmd8
-rw-r--r--src/mainboard/amd/mayan/board_info.txt1
-rw-r--r--src/mainboard/amd/mayan/bootblock.c18
-rw-r--r--src/mainboard/amd/mayan/chromeos.c21
-rw-r--r--src/mainboard/amd/mayan/chromeos.fmd34
-rw-r--r--src/mainboard/amd/mayan/devicetree_morgana.cb226
-rw-r--r--src/mainboard/amd/mayan/dsdt.asl16
-rw-r--r--src/mainboard/amd/mayan/early_gpio.c16
-rw-r--r--src/mainboard/amd/mayan/ec.c67
-rw-r--r--src/mainboard/amd/mayan/ec.h8
-rw-r--r--src/mainboard/amd/mayan/gpio.c20
-rw-r--r--src/mainboard/amd/mayan/gpio.h9
-rw-r--r--src/mainboard/amd/mayan/mainboard.c67
-rw-r--r--src/mainboard/amd/mayan/port_descriptors.c130
17 files changed, 798 insertions, 0 deletions
diff --git a/src/mainboard/amd/mayan/Kconfig b/src/mainboard/amd/mayan/Kconfig
new file mode 100644
index 0000000000..8a54481681
--- /dev/null
+++ b/src/mainboard/amd/mayan/Kconfig
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+if BOARD_AMD_MAYAN_MORGANA
+
+config BOARD_SPECIFIC_OPTIONS
+ def_bool y
+ select BOARD_ROMSIZE_KB_16384 # Mayan actually has a 32MiB ROM
+ select EC_ACPI
+ select SOC_AMD_COMMON_BLOCK_USE_ESPI
+ select AMD_SOC_CONSOLE_UART
+ select MAINBOARD_HAS_CHROMEOS
+ select PCIEXP_ASPM
+ select PCIEXP_CLK_PM
+ select PCIEXP_COMMON_CLOCK
+ select PCIEXP_L1_SUB_STATE
+ select SOC_AMD_COMMON_BLOCK_ESPI_RETAIN_PORT80_EN
+
+config FMDFILE
+ default "src/mainboard/amd/mayan/chromeos.fmd" if CHROMEOS
+ default "src/mainboard/amd/mayan/board.fmd"
+
+config MAINBOARD_DIR
+ default "amd/mayan"
+
+config MAINBOARD_PART_NUMBER
+ default "Mayan_Morgana"
+
+config DEVICETREE
+ default "devicetree_morgana.cb"
+
+config AMD_FWM_POSITION_INDEX
+ int
+ default 3 if CHROMEOS
+ help
+ TODO: might need to be adapted for better placement of files in cbfs
+
+config MAYAN_HAVE_MCHP_FW
+ bool "Have Microchip EC firmware?"
+ default n
+
+config MAYAN_MCHP_SIG_FILE
+ string "Microchip EC signature file"
+ depends on MAYAN_HAVE_MCHP_FW
+ default "3rdparty/blobs/mainboard/amd/mayan/EC_mayan_sig.bin"
+ help
+ The EC sig blob is the first 4kBytes of the firmware image.
+ The first 4 bytes form a pointer (with CRC) to where the EC firmware
+ is located
+
+config MAYAN_MCHP_FW_FILE
+ string "Microchip EC firmware file"
+ depends on MAYAN_HAVE_MCHP_FW
+ default "3rdparty/blobs/mainboard/amd/mayan/EC_mayan.bin"
+ help
+ The EC firmware blob is at the MAYAN_MCHP_FW_OFFSET offset of the
+ firmware image.
+
+config MAYAN_MCHP_FW_OFFSET
+ hex
+ depends on MAYAN_HAVE_MCHP_FW
+ default 0xB80000
+ help
+ The EC firmware blob defaults to the 4MByte offset of the firmware
+ image. If this offset needs to change, a new signature block must be
+ generated with the updated offset.
+
+config VBOOT
+ select VBOOT_NO_BOARD_SUPPORT
+ select VBOOT_SEPARATE_VERSTAGE
+ select VBOOT_STARTS_IN_BOOTBLOCK
+
+config VBOOT_VBNV_OFFSET
+ hex
+ default 0x2A
+
+config RO_REGION_ONLY
+ string
+ depends on VBOOT_SLOTS_RW_AB || VBOOT_SLOTS_RW_A
+ # Add the EFS and EC to the RO region only
+ # This is a mayan-specific override of soc/amd/morgana/Kconfig
+ default "apu/amdfw apu/ecfw"
+
+config CHROMEOS
+ # Use default libpayload config
+ select LP_DEFCONFIG_OVERRIDE if PAYLOAD_DEPTHCHARGE
+ # We don't have recovery buttons, so we can't manually enable devmode.
+ select GBB_FLAG_FORCE_DEV_SWITCH_ON
+
+if !EM100 # EM100 defaults in soc/amd/common/blocks/spi/Kconfig
+config EFS_SPI_READ_MODE
+ default 3 # Quad IO (1-1-4)
+
+config EFS_SPI_SPEED
+ default 0 # 66MHz
+
+config EFS_SPI_MICRON_FLAG
+ default 0
+
+config NORMAL_READ_SPI_SPEED
+ default 1 # 33MHz
+
+config ALT_SPI_SPEED
+ default 1 # 33MHz
+
+config TPM_SPI_SPEED
+ default 1 # 33MHz
+
+endif # !EM100
+
+endif # BOARD_AMD_MAYAN_MORGANA
diff --git a/src/mainboard/amd/mayan/Kconfig.name b/src/mainboard/amd/mayan/Kconfig.name
new file mode 100644
index 0000000000..1d60d67882
--- /dev/null
+++ b/src/mainboard/amd/mayan/Kconfig.name
@@ -0,0 +1,5 @@
+comment "Mayan"
+
+config BOARD_AMD_MAYAN_MORGANA
+ bool "-> Mayan for Morgana SoC"
+ select SOC_AMD_MORGANA
diff --git a/src/mainboard/amd/mayan/Makefile.inc b/src/mainboard/amd/mayan/Makefile.inc
new file mode 100644
index 0000000000..fdf00ea21a
--- /dev/null
+++ b/src/mainboard/amd/mayan/Makefile.inc
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+bootblock-y += bootblock.c
+bootblock-y += early_gpio.c
+bootblock-y += ec.c
+
+romstage-y += port_descriptors.c
+
+ramstage-y += chromeos.c
+ramstage-y += gpio.c
+
+ifneq ($(wildcard $(MAINBOARD_BLOBS_DIR)/APCB_Updatable.bin),)
+APCB_SOURCES = $(MAINBOARD_BLOBS_DIR)/APCB_Updatable.bin
+APCB_SOURCES_RECOVERY = $(MAINBOARD_BLOBS_DIR)/APCB_DefaultRecovery.bin
+else
+$(info APCB sources not found. Skipping APCB. The resulting image won't boot.)
+endif
+
+ifeq ($(CONFIG_MAYAN_HAVE_MCHP_FW),y)
+$(call add_intermediate, add_mchp_fw)
+ $(CBFSTOOL) $(obj)/coreboot.pre write -r EC -f $(CONFIG_MAYAN_MCHP_SIG_FILE) --fill-upward
+
+# calculate the absolute position from the config offset
+MAYAN_EC_POSITION=$(call int-add, \
+ $(call int-subtract, 0xffffffff \
+ $(CONFIG_ROM_SIZE)) $(CONFIG_MAYAN_MCHP_FW_OFFSET) 1)
+
+cbfs-files-y += apu/ecfw
+apu/ecfw-file := $(CONFIG_MAYAN_MCHP_FW_FILE)
+apu/ecfw-position := $(MAYAN_EC_POSITION)
+apu/ecfw-type := raw
+
+else
+files_added:: warn_no_mchp
+endif # CONFIG_MAYAN_HAVE_MCHP_FW
+
+PHONY+=warn_no_mchp
+warn_no_mchp:
+ printf "\n\t** WARNING **\n"
+ printf "coreboot has been built without the EC FW.\n"
+ printf "Do not flash this image. Your Mayan's power button\n"
+ printf "will not respond when you press it.\n\n"
diff --git a/src/mainboard/amd/mayan/board.fmd b/src/mainboard/amd/mayan/board.fmd
new file mode 100644
index 0000000000..6c6ad92a28
--- /dev/null
+++ b/src/mainboard/amd/mayan/board.fmd
@@ -0,0 +1,8 @@
+FLASH@0xFF000000 16M {
+ BIOS {
+ EC 4K
+ RW_MRC_CACHE 120K
+ FMAP 4K
+ COREBOOT(CBFS)
+ }
+}
diff --git a/src/mainboard/amd/mayan/board_info.txt b/src/mainboard/amd/mayan/board_info.txt
new file mode 100644
index 0000000000..b351b8e696
--- /dev/null
+++ b/src/mainboard/amd/mayan/board_info.txt
@@ -0,0 +1 @@
+Category: eval
diff --git a/src/mainboard/amd/mayan/bootblock.c b/src/mainboard/amd/mayan/bootblock.c
new file mode 100644
index 0000000000..4c01cc14b3
--- /dev/null
+++ b/src/mainboard/amd/mayan/bootblock.c
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <bootblock_common.h>
+#include <soc/espi.h>
+#include "ec.h"
+#include "gpio.h"
+
+void bootblock_mainboard_early_init(void)
+{
+ mainboard_program_early_gpios();
+
+ espi_switch_to_spi1_pads();
+}
+
+void bootblock_mainboard_init(void)
+{
+ mayan_ec_init();
+}
diff --git a/src/mainboard/amd/mayan/chromeos.c b/src/mainboard/amd/mayan/chromeos.c
new file mode 100644
index 0000000000..3119303ba1
--- /dev/null
+++ b/src/mainboard/amd/mayan/chromeos.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <bootmode.h>
+#include <boot/coreboot_tables.h>
+#include <gpio.h>
+#include <types.h>
+#include <vendorcode/google/chromeos/chromeos.h>
+
+void fill_lb_gpios(struct lb_gpios *gpios)
+{
+ struct lb_gpio chromeos_gpios[] = {};
+ lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios));
+}
+
+int get_write_protect_state(void)
+{
+ /* Mayan doesn't have a write protect pin */
+ return 0;
+}
+
+DECLARE_NO_CROS_GPIOS();
diff --git a/src/mainboard/amd/mayan/chromeos.fmd b/src/mainboard/amd/mayan/chromeos.fmd
new file mode 100644
index 0000000000..c28070ad11
--- /dev/null
+++ b/src/mainboard/amd/mayan/chromeos.fmd
@@ -0,0 +1,34 @@
+FLASH@0xFF000000 16M {
+ SI_BIOS {
+ EC 4K
+ RW_MRC_CACHE(PRESERVE) 120K
+ RW_SECTION_A 4M {
+ VBLOCK_A 8K
+ FW_MAIN_A(CBFS)
+ RW_FWID_A 256
+ }
+ RW_SECTION_B 4M {
+ VBLOCK_B 8K
+ FW_MAIN_B(CBFS)
+ RW_FWID_B 256
+ }
+ RW_ELOG(PRESERVE) 4K
+ RW_SHARED 16K {
+ SHARED_DATA 8K
+ VBLOCK_DEV 8K
+ }
+ RW_VPD(PRESERVE) 8K
+ RW_NVRAM(PRESERVE) 20K
+ SMMSTORE(PRESERVE) 64K
+ RW_LEGACY(CBFS)
+ WP_RO@10M 6M {
+ RO_VPD(PRESERVE) 16K
+ RO_SECTION {
+ FMAP 2K
+ RO_FRID 64
+ GBB@4K 448K
+ COREBOOT(CBFS)
+ }
+ }
+ }
+}
diff --git a/src/mainboard/amd/mayan/devicetree_morgana.cb b/src/mainboard/amd/mayan/devicetree_morgana.cb
new file mode 100644
index 0000000000..cfcacfa013
--- /dev/null
+++ b/src/mainboard/amd/mayan/devicetree_morgana.cb
@@ -0,0 +1,226 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# TODO: Update for mayan
+
+chip soc/amd/morgana
+ register "common_config.espi_config" = "{
+ .std_io_decode_bitmap = ESPI_DECODE_IO_0x80_EN | ESPI_DECODE_IO_0X2E_0X2F_EN | ESPI_DECODE_IO_0X60_0X64_EN,
+ .generic_io_range[0] = {
+ .base = 0x3f8,
+ .size = 8,
+ },
+ .generic_io_range[1] = {
+ .base = 0x600,
+ .size = 256,
+ },
+ .io_mode = ESPI_IO_MODE_QUAD,
+ .op_freq_mhz = ESPI_OP_FREQ_16_MHZ,
+ .crc_check_enable = 1,
+ .alert_pin = ESPI_ALERT_PIN_PUSH_PULL,
+ .periph_ch_en = 1,
+ .vw_ch_en = 1,
+ .oob_ch_en = 1,
+ .flash_ch_en = 0,
+ }"
+
+ register "i2c_scl_reset" = "GPIO_I2C0_SCL | GPIO_I2C1_SCL |
+ GPIO_I2C2_SCL | GPIO_I2C3_SCL"
+
+ register "i2c[0].early_init" = "1"
+ register "i2c[1].early_init" = "1"
+ register "i2c[2].early_init" = "1"
+ register "i2c[3].early_init" = "1"
+
+ # I2C Pad Control RX Select Configuration
+ register "i2c_pad[0].rx_level" = "I2C_PAD_RX_1_8V"
+ register "i2c_pad[1].rx_level" = "I2C_PAD_RX_1_8V"
+ register "i2c_pad[2].rx_level" = "I2C_PAD_RX_1_8V"
+ register "i2c_pad[3].rx_level" = "I2C_PAD_RX_1_8V"
+
+ register "s0ix_enable" = "true"
+
+ register "pspp_policy" = "DXIO_PSPP_DISABLED" # TODO: reenable when PSPP works
+
+ register "usb_phy_custom" = "1"
+ register "usb_phy" = "{
+ .Usb2PhyPort[0] = {
+ .compdistune = 0x3,
+ .pllbtune = 0x1,
+ .pllitune = 0x0,
+ .pllptune = 0xe,
+ .sqrxtune = 0x3,
+ .txfslstune = 0x3,
+ .txpreempamptune = 0x2,
+ .txpreemppulsetune = 0x0,
+ .txrisetune = 0x1,
+ .txvreftune = 0x3,
+ .txhsxvtune = 0x3,
+ .txrestune = 0x2,
+ },
+ .Usb2PhyPort[1] = {
+ .compdistune = 0x3,
+ .pllbtune = 0x1,
+ .pllitune = 0x0,
+ .pllptune = 0xe,
+ .sqrxtune = 0x3,
+ .txfslstune = 0x3,
+ .txpreempamptune = 0x2,
+ .txpreemppulsetune = 0x0,
+ .txrisetune = 0x1,
+ .txvreftune = 0x3,
+ .txhsxvtune = 0x3,
+ .txrestune = 0x2,
+ },
+ .Usb2PhyPort[2] = {
+ .compdistune = 0x3,
+ .pllbtune = 0x1,
+ .pllitune = 0x0,
+ .pllptune = 0xe,
+ .sqrxtune = 0x3,
+ .txfslstune = 0x3,
+ .txpreempamptune = 0x2,
+ .txpreemppulsetune = 0x0,
+ .txrisetune = 0x1,
+ .txvreftune = 0x3,
+ .txhsxvtune = 0x3,
+ .txrestune = 0x2,
+ },
+ .Usb2PhyPort[3] = {
+ .compdistune = 0x3,
+ .pllbtune = 0x1,
+ .pllitune = 0x0,
+ .pllptune = 0xe,
+ .sqrxtune = 0x3,
+ .txfslstune = 0x3,
+ .txpreempamptune = 0x2,
+ .txpreemppulsetune = 0x0,
+ .txrisetune = 0x1,
+ .txvreftune = 0x3,
+ .txhsxvtune = 0x3,
+ .txrestune = 0x2,
+ },
+ .Usb2PhyPort[4] = {
+ .compdistune = 0x3,
+ .pllbtune = 0x1,
+ .pllitune = 0x0,
+ .pllptune = 0xe,
+ .sqrxtune = 0x3,
+ .txfslstune = 0x3,
+ .txpreempamptune = 0x2,
+ .txpreemppulsetune = 0x0,
+ .txrisetune = 0x1,
+ .txvreftune = 0x3,
+ .txhsxvtune = 0x3,
+ .txrestune = 0x2,
+ },
+ .Usb2PhyPort[5] = {
+ .compdistune = 0x3,
+ .pllbtune = 0x1,
+ .pllitune = 0x0,
+ .pllptune = 0xe,
+ .sqrxtune = 0x3,
+ .txfslstune = 0x3,
+ .txpreempamptune = 0x2,
+ .txpreemppulsetune = 0x0,
+ .txrisetune = 0x1,
+ .txvreftune = 0x3,
+ .txhsxvtune = 0x3,
+ .txrestune = 0x2,
+ },
+ .Usb3PhyPort[0] = {
+ .tx_term_ctrl = 0x2,
+ .rx_term_ctrl = 0x2,
+ .tx_vboost_lvl_en = 0x0,
+ .tx_vboost_lvl = 0x5,
+ },
+ .Usb3PhyPort[1] = {
+ .tx_term_ctrl = 0x2,
+ .rx_term_ctrl = 0x2,
+ .tx_vboost_lvl_en = 0x0,
+ .tx_vboost_lvl = 0x5,
+ },
+ .Usb3PhyPort[2] = {
+ .tx_term_ctrl = 0x2,
+ .rx_term_ctrl = 0x2,
+ .tx_vboost_lvl_en = 0x0,
+ .tx_vboost_lvl = 0x5,
+ },
+ .ComboPhyStaticConfig[0] = USB_COMBO_PHY_MODE_USB_C,
+ .ComboPhyStaticConfig[1] = USB_COMBO_PHY_MODE_USB_C,
+ .BatteryChargerEnable = 0,
+ .PhyP3CpmP4Support = 0,
+ }"
+
+ register "gpp_clk_config[0]" = "GPP_CLK_REQ"
+ register "gpp_clk_config[1]" = "GPP_CLK_REQ"
+ register "gpp_clk_config[2]" = "GPP_CLK_OFF"
+ register "gpp_clk_config[3]" = "GPP_CLK_REQ"
+
+ device domain 0 on
+ device ref iommu on end
+ device ref gpp_bridge_0 on end # GBE
+ device ref gpp_bridge_1 on end # WIFI
+ device ref gpp_bridge_2 on end # NVMe SSD
+ device ref gpp_bridge_a on # Internal GPP Bridge 0 to Bus A
+ device ref gfx on end # Internal GPU (GFX)
+ device ref gfx_hda on end # Display HD Audio Controller (GFXAZ)
+ device ref crypto on end # Crypto Coprocessor
+ device ref xhci_0 on # USB 3.1 (USB0)
+ chip drivers/usb/acpi
+ device ref xhci_0_root_hub on
+ chip drivers/usb/acpi
+ device ref usb3_port0 on end
+ end
+ chip drivers/usb/acpi
+ device ref usb2_port0 on end
+ end
+ chip drivers/usb/acpi
+ device ref usb2_port1 on end
+ end
+ end
+ end
+ end
+ device ref xhci_1 on # USB 3.1 (USB1)
+ chip drivers/usb/acpi
+ device ref xhci_1_root_hub on
+ chip drivers/usb/acpi
+ device ref usb3_port2 on end
+ end
+ chip drivers/usb/acpi
+ device ref usb3_port3 on end
+ end
+ chip drivers/usb/acpi
+ device ref usb2_port2 on end
+ end
+ chip drivers/usb/acpi
+ device ref usb2_port3 on end
+ end
+ chip drivers/usb/acpi
+ device ref usb2_port4 on end
+ end
+ end
+ end
+ end
+ device ref acp on end # Audio Processor (ACP)
+ end
+ device ref gpp_bridge_c on # Internal GPP Bridge 2 to Bus C
+ device ref xhci_2 on
+ chip drivers/usb/acpi
+ register "type" = "UPC_TYPE_HUB"
+ device usb 0.0 alias xhci_2_root_hub on
+ chip drivers/usb/acpi
+ device usb 2.0 alias usb2_port5 on end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ device ref i2c_0 on end
+ device ref i2c_1 on end
+ device ref i2c_2 on end
+ device ref i2c_3 on end
+ device ref uart_0 on end # UART0
+
+end
diff --git a/src/mainboard/amd/mayan/dsdt.asl b/src/mainboard/amd/mayan/dsdt.asl
new file mode 100644
index 0000000000..7b8982a645
--- /dev/null
+++ b/src/mainboard/amd/mayan/dsdt.asl
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpi.h>
+DefinitionBlock (
+ "dsdt.aml",
+ "DSDT",
+ ACPI_DSDT_REV_2,
+ OEM_ID,
+ ACPI_TABLE_CREATOR,
+ 0x00010001 /* OEM Revision */
+ )
+{
+ #include <acpi/dsdt_top.asl>
+
+ #include <soc.asl>
+}
diff --git a/src/mainboard/amd/mayan/early_gpio.c b/src/mainboard/amd/mayan/early_gpio.c
new file mode 100644
index 0000000000..cf7166c8e4
--- /dev/null
+++ b/src/mainboard/amd/mayan/early_gpio.c
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <soc/gpio.h>
+#include "gpio.h"
+
+/* TODO: Update for mayan */
+
+/* GPIO pins used by coreboot should be initialized in bootblock */
+
+static const struct soc_amd_gpio gpio_set_stage_reset[] = {
+};
+
+void mainboard_program_early_gpios(void)
+{
+ gpio_configure_pads(gpio_set_stage_reset, ARRAY_SIZE(gpio_set_stage_reset));
+}
diff --git a/src/mainboard/amd/mayan/ec.c b/src/mainboard/amd/mayan/ec.c
new file mode 100644
index 0000000000..1b1d09bc72
--- /dev/null
+++ b/src/mainboard/amd/mayan/ec.c
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* TODO: Update for mayan */
+
+#include <ec/acpi/ec.h>
+#include "ec.h"
+
+#define MAYAN_EC_CMD 0x666
+#define MAYAN_EC_DATA 0x662
+
+#define EC_GPIO_3_ADDR 0xA3
+#define EC_GPIO_LOM_RESET_AUX BIT(1)
+
+#define EC_GPIO_7_ADDR 0xA7
+#define EC_GPIO_DT_PWREN BIT(2)
+#define EC_GPIO_WWAN_MODULE_RST BIT(5)
+
+#define EC_GPIO_8_ADDR 0xA8
+#define EC_GPIO_SMBUS0_EN BIT(0)
+
+#define EC_GPIO_A_ADDR 0xAA
+#define EC_GPIO_WWAN_PWREN BIT(3)
+#define EC_GPIO_M2_SSD0_PWREN BIT(6)
+#define EC_GPIO_LOM_PWREN BIT(7)
+
+#define EC_GPIO_C_ADDR 0xAC
+#define EC_GPIO_DT_N_WLAN_SW BIT(1)
+#define EC_GPIO_MP2_SEL BIT(2)
+#define EC_GPIO_WWAN_N_LOM_SW BIT(3)
+
+#define EC_SW02_ADDR 0xB7
+#define EC_SW02_MS BIT(7)
+
+static void configure_ec_gpio(void)
+{
+ uint8_t tmp;
+
+ tmp = ec_read(EC_GPIO_3_ADDR);
+ tmp |= EC_GPIO_LOM_RESET_AUX;
+ ec_write(EC_GPIO_3_ADDR, tmp);
+
+ tmp = ec_read(EC_GPIO_7_ADDR);
+ tmp |= EC_GPIO_WWAN_MODULE_RST | EC_GPIO_DT_PWREN;
+ ec_write(EC_GPIO_7_ADDR, tmp);
+
+ tmp = ec_read(EC_GPIO_8_ADDR);
+ tmp |= EC_GPIO_SMBUS0_EN;
+ ec_write(EC_GPIO_8_ADDR, tmp);
+
+ tmp = ec_read(EC_GPIO_A_ADDR);
+ tmp |= EC_GPIO_M2_SSD0_PWREN | EC_GPIO_LOM_PWREN | EC_GPIO_WWAN_PWREN;
+ ec_write(EC_GPIO_A_ADDR, tmp);
+
+ tmp = ec_read(EC_GPIO_C_ADDR);
+ tmp |= EC_GPIO_WWAN_N_LOM_SW | EC_GPIO_MP2_SEL | EC_GPIO_DT_N_WLAN_SW;
+ ec_write(EC_GPIO_C_ADDR, tmp);
+
+ tmp = ec_read(EC_SW02_ADDR);
+ tmp |= EC_SW02_MS;
+ ec_write(EC_SW02_ADDR, tmp);
+}
+
+void mayan_ec_init(void)
+{
+ ec_set_ports(MAYAN_EC_CMD, MAYAN_EC_DATA);
+ configure_ec_gpio();
+}
diff --git a/src/mainboard/amd/mayan/ec.h b/src/mainboard/amd/mayan/ec.h
new file mode 100644
index 0000000000..b74b236474
--- /dev/null
+++ b/src/mainboard/amd/mayan/ec.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef MAYAN_EC_H
+#define MAYAN_EC_H
+
+void mayan_ec_init(void);
+
+#endif /* MAYAN_EC_H */
diff --git a/src/mainboard/amd/mayan/gpio.c b/src/mainboard/amd/mayan/gpio.c
new file mode 100644
index 0000000000..62f6447723
--- /dev/null
+++ b/src/mainboard/amd/mayan/gpio.c
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <soc/gpio.h>
+#include "gpio.h"
+
+/* TODO: Update for mayan */
+
+/*
+ * As a rule of thumb, GPIO pins used by coreboot should be initialized at
+ * bootblock while GPIO pins used only by the OS should be initialized at
+ * ramstage.
+ */
+static const struct soc_amd_gpio gpio_set_stage_ram[] = {
+
+};
+
+void mainboard_program_gpios(void)
+{
+ gpio_configure_pads(gpio_set_stage_ram, ARRAY_SIZE(gpio_set_stage_ram));
+}
diff --git a/src/mainboard/amd/mayan/gpio.h b/src/mainboard/amd/mayan/gpio.h
new file mode 100644
index 0000000000..04c98c50df
--- /dev/null
+++ b/src/mainboard/amd/mayan/gpio.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef MAINBOARD_GPIO_H
+#define MAINBOARD_GPIO_H
+
+void mainboard_program_early_gpios(void); /* bootblock GPIO configuration */
+void mainboard_program_gpios(void); /* ramstage GPIO configuration */
+
+#endif /* MAINBOARD_GPIO_H */
diff --git a/src/mainboard/amd/mayan/mainboard.c b/src/mainboard/amd/mayan/mainboard.c
new file mode 100644
index 0000000000..0f42fc9712
--- /dev/null
+++ b/src/mainboard/amd/mayan/mainboard.c
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/amd_pci_util.h>
+#include <commonlib/helpers.h>
+#include <device/device.h>
+#include <soc/acpi.h>
+#include <types.h>
+#include "gpio.h"
+
+/* TODO: Update for mayan */
+
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+ accessed via I/O ports 0xc00/0xc01. */
+
+/*
+ * This controls the device -> IRQ routing.
+ *
+ * Hardcoded IRQs:
+ * 0: timer < soc/amd/common/acpi/lpc.asl
+ * 1: i8042 - Keyboard
+ * 2: cascade
+ * 8: rtc0 <- soc/amd/common/acpi/lpc.asl
+ * 9: acpi <- soc/amd/common/acpi/lpc.asl
+ */
+static const struct fch_irq_routing fch_irq_map[] = {
+ { PIRQ_A, 12, PIRQ_NC },
+ { PIRQ_B, 14, PIRQ_NC },
+ { PIRQ_C, 15, PIRQ_NC },
+ { PIRQ_D, 12, PIRQ_NC },
+ { PIRQ_E, 14, PIRQ_NC },
+ { PIRQ_F, 15, PIRQ_NC },
+ { PIRQ_G, 12, PIRQ_NC },
+ { PIRQ_H, 14, PIRQ_NC },
+
+ { PIRQ_SCI, ACPI_SCI_IRQ, ACPI_SCI_IRQ },
+ { PIRQ_SD, PIRQ_NC, PIRQ_NC },
+ { PIRQ_SDIO, PIRQ_NC, PIRQ_NC },
+ { PIRQ_EMMC, PIRQ_NC, PIRQ_NC },
+ { PIRQ_GPIO, 11, 11 },
+ { PIRQ_I2C0, 10, 10 },
+ { PIRQ_I2C1, 7, 7 },
+ { PIRQ_I2C2, 6, 6 },
+ { PIRQ_I2C3, 5, 5 },
+ { PIRQ_UART0, 4, 4 },
+ { PIRQ_UART1, 3, 3 },
+
+ /* The MISC registers are not interrupt numbers */
+ { PIRQ_MISC, 0xfa, 0x00 },
+ { PIRQ_MISC0, 0x91, 0x00 },
+ { PIRQ_HPET_L, 0x00, 0x00 },
+ { PIRQ_HPET_H, 0x00, 0x00 },
+};
+
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+{
+ *length = ARRAY_SIZE(fch_irq_map);
+ return fch_irq_map;
+}
+
+static void mainboard_init(void *chip_info)
+{
+ mainboard_program_gpios();
+}
+
+struct chip_operations mainboard_ops = {
+ .init = mainboard_init,
+};
diff --git a/src/mainboard/amd/mayan/port_descriptors.c b/src/mainboard/amd/mayan/port_descriptors.c
new file mode 100644
index 0000000000..151ad141ad
--- /dev/null
+++ b/src/mainboard/amd/mayan/port_descriptors.c
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <device/i2c_simple.h>
+#include <soc/gpio.h>
+#include <soc/platform_descriptors.h>
+#include <types.h>
+
+/* TODO: Update for mayan */
+
+static const fsp_dxio_descriptor mayan_dxio_descriptors[] = {
+ {
+ .engine_type = PCIE_ENGINE,
+ .port_present = true,
+ .start_logical_lane = 0,
+ .end_logical_lane = 0,
+ .device_number = 2,
+ .function_number = 1,
+ .link_speed_capability = GEN3,
+ .turn_off_unused_lanes = true,
+ .link_aspm = 2,
+ .link_hotplug = 3,
+ .clk_req = CLK_REQ3,
+ },
+ {
+ .engine_type = PCIE_ENGINE,
+ .port_present = true,
+ .start_logical_lane = 1,
+ .end_logical_lane = 1,
+ .device_number = 2,
+ .function_number = 2,
+ .link_speed_capability = GEN3,
+ .turn_off_unused_lanes = true,
+ .link_aspm = 2,
+ .link_hotplug = 3,
+ .clk_req = CLK_REQ1,
+ },
+ {
+ .engine_type = PCIE_ENGINE,
+ .port_present = true,
+ .start_logical_lane = 2,
+ .end_logical_lane = 3,
+ .device_number = 2,
+ .function_number = 3,
+ .link_speed_capability = GEN3,
+ .turn_off_unused_lanes = true,
+ .link_aspm = 2,
+ .link_hotplug = 3,
+ .gpio_group_id = GPIO_27,
+ .clk_req = CLK_REQ0,
+ },
+};
+
+static fsp_ddi_descriptor mayan_ddi_descriptors[] = {
+ { /* DDI0 - eDP */
+ .connector_type = DDI_EDP,
+ .aux_index = DDI_AUX1,
+ .hdp_index = DDI_HDP1
+ },
+ { /* DDI1 - HDMI/DP */
+ .connector_type = DDI_HDMI,
+ .aux_index = DDI_AUX2,
+ .hdp_index = DDI_HDP2
+ },
+ { /* DDI2 - DP (type C) */
+ .connector_type = DDI_DP,
+ .aux_index = DDI_AUX3,
+ .hdp_index = DDI_HDP3,
+ },
+ { /* DDI3 - DP (type C) */
+ .connector_type = DDI_DP,
+ .aux_index = DDI_AUX4,
+ .hdp_index = DDI_HDP4,
+ },
+ { /* DDI4 - unused */
+ .connector_type = DDI_UNUSED_TYPE,
+ .aux_index = DDI_AUX5,
+ .hdp_index = DDI_HDP5,
+ }
+};
+
+static uint8_t get_ddi1_type(void)
+{
+ const uint8_t eeprom_i2c_bus = 2;
+ const uint8_t eeprom_i2c_address = 0x55;
+ const uint16_t eeprom_connector_type_offset = 2;
+ uint8_t eeprom_connector_type_data[2];
+ uint16_t connector_type;
+
+ if (i2c_2ba_read_bytes(eeprom_i2c_bus, eeprom_i2c_address,
+ eeprom_connector_type_offset, eeprom_connector_type_data,
+ sizeof(eeprom_connector_type_data))) {
+ printk(BIOS_NOTICE,
+ "Display connector type couldn't be determined. Disabling DDI1.\n");
+ return DDI_UNUSED_TYPE;
+ }
+
+ connector_type = eeprom_connector_type_data[1] | eeprom_connector_type_data[0] << 8;
+
+ switch (connector_type) {
+ case 0xc:
+ printk(BIOS_DEBUG, "Configuring DDI1 as HDMI.\n");
+ return DDI_HDMI;
+ break;
+ case 0x13:
+ printk(BIOS_DEBUG, "Configuring DDI1 as DP.\n");
+ return DDI_DP;
+ break;
+ case 0x14:
+ printk(BIOS_DEBUG, "Configuring DDI1 as eDP.\n");
+ return DDI_EDP;
+ break;
+ default:
+ printk(BIOS_WARNING, "Unexpected display connector type %x. Disabling DDI1.\n",
+ connector_type);
+ return DDI_UNUSED_TYPE;
+ }
+}
+
+void mainboard_get_dxio_ddi_descriptors(
+ const fsp_dxio_descriptor **dxio_descs, size_t *dxio_num,
+ const fsp_ddi_descriptor **ddi_descs, size_t *ddi_num)
+{
+ mayan_ddi_descriptors[1].connector_type = get_ddi1_type();
+
+ *dxio_descs = mayan_dxio_descriptors;
+ *dxio_num = ARRAY_SIZE(mayan_dxio_descriptors);
+ *ddi_descs = mayan_ddi_descriptors;
+ *ddi_num = ARRAY_SIZE(mayan_ddi_descriptors);
+}