summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0001-Add-ast2600-intel-as-a-new-board.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0001-Add-ast2600-intel-as-a-new-board.patch')
-rw-r--r--meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0001-Add-ast2600-intel-as-a-new-board.patch1605
1 files changed, 1605 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0001-Add-ast2600-intel-as-a-new-board.patch b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0001-Add-ast2600-intel-as-a-new-board.patch
new file mode 100644
index 000000000..a2981f822
--- /dev/null
+++ b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/files/0001-Add-ast2600-intel-as-a-new-board.patch
@@ -0,0 +1,1605 @@
+From 9c65cf5fa3cdbbdf1ac7f8269502ec6564703319 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@intel.com>
+Date: Thu, 24 Oct 2019 14:06:33 -0700
+Subject: [PATCH] Add ast2600-intel as a new board
+
+Signed-off-by: Vernon Mauery <vernon.mauery@intel.com>
+Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Signed-off-by: AKSHAY RAVEENDRAN K <akshay.raveendran.k@intel.com>
+---
+ arch/arm/dts/ast2600-intel.dts | 202 ++++---------
+ arch/arm/lib/interrupts.c | 5 +
+ arch/arm/mach-aspeed/ast2600/Kconfig | 4 +-
+ board/aspeed/ast2600_intel/Makefile | 3 +
+ board/aspeed/ast2600_intel/ast-espi.c | 292 ++++++++++++++++++
+ board/aspeed/ast2600_intel/ast-irq.c | 399 +++++++++++++++++++++++++
+ board/aspeed/ast2600_intel/ast-irq.h | 8 +
+ board/aspeed/ast2600_intel/ast-timer.c | 59 ++++
+ board/aspeed/ast2600_intel/intel.c | 347 ++++++++++-----------
+ cmd/Kconfig | 2 +-
+ common/autoboot.c | 10 +
+ configs/ast2600_openbmc_defconfig | 2 +-
+ 12 files changed, 999 insertions(+), 334 deletions(-)
+ create mode 100644 board/aspeed/ast2600_intel/ast-espi.c
+ create mode 100644 board/aspeed/ast2600_intel/ast-irq.c
+ create mode 100644 board/aspeed/ast2600_intel/ast-irq.h
+ create mode 100644 board/aspeed/ast2600_intel/ast-timer.c
+
+diff --git a/arch/arm/dts/ast2600-intel.dts b/arch/arm/dts/ast2600-intel.dts
+index c76547cd6352..e6197831cf02 100644
+--- a/arch/arm/dts/ast2600-intel.dts
++++ b/arch/arm/dts/ast2600-intel.dts
+@@ -1,10 +1,11 @@
+ // SPDX-License-Identifier: GPL-2.0+
++// Copyright (c) 2019-2021 Intel Corporation
+ /dts-v1/;
+
+ #include "ast2600-u-boot.dtsi"
+
+ / {
+- model = "AST2600 Intel EGS server board";
++ model = "Intel server board with AST2600 as the BMC";
+ compatible = "aspeed,ast2600-intel", "aspeed,ast2600";
+
+ memory {
+@@ -37,6 +38,42 @@
+ clock-frequency = <1200000000>;
+ };
+ };
++
++ system-leds {
++ compatible = "gpio-leds";
++ green-led {
++ label = "green";
++ gpios = <&gpio0 50 GPIO_ACTIVE_LOW>;
++ default-state = "blink";
++ };
++ amber-led {
++ label = "amber";
++ gpios = <&gpio0 51 GPIO_ACTIVE_LOW>;
++ default-state = "off";
++ };
++ id-led {
++ label = "id";
++ gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
++ default-state = "blink";
++ };
++ hb-led {
++ label = "hb";
++ gpios = <&gpio0 25 GPIO_ACTIVE_LOW>;
++ linux,default-trigger = "heartbeat";
++ };
++ };
++};
++
++&gpio0 {
++ status = "okay";
++};
++
++&uart1 {
++ status = "okay";
++};
++
++&uart2 {
++ status = "okay";
+ };
+
+ &uart5 {
+@@ -49,22 +86,24 @@
+ };
+
+ &wdt1 {
++ u-boot,dm-pre-reloc;
+ status = "okay";
+ };
+
+ &wdt2 {
++ u-boot,dm-pre-reloc;
+ status = "okay";
+ };
+
+ &wdt3 {
++ u-boot,dm-pre-reloc;
+ status = "okay";
+ };
+
+ &mdio {
+ status = "okay";
+ pinctrl-names = "default";
+- pinctrl-0 = < &pinctrl_mdio1_default &pinctrl_mdio2_default
+- &pinctrl_mdio3_default &pinctrl_mdio4_default>;
++ pinctrl-0 = <&pinctrl_mdio2_default>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethphy0: ethernet-phy@0 {
+@@ -84,14 +123,6 @@
+ };
+ };
+
+-&mac0 {
+- status = "okay";
+- phy-mode = "rgmii";
+- phy-handle = <&ethphy0>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_rgmii1_default>;
+-};
+-
+ &mac1 {
+ status = "okay";
+ phy-mode = "rgmii";
+@@ -100,146 +131,30 @@
+ pinctrl-0 = <&pinctrl_rgmii2_default>;
+ };
+
+-&mac2 {
+- status = "okay";
+- phy-mode = "rgmii";
+- phy-handle = <&ethphy2>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_rgmii3_default>;
+-};
+-
+-&mac3 {
+- status = "okay";
+- phy-mode = "rgmii";
+- phy-handle = <&ethphy3>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_rgmii4_default>;
+-};
+-
+ &fmc {
+ status = "okay";
+-
++#if 0
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fmcquad_default>;
+-
+- flash@0 {
+- compatible = "spi-flash", "sst,w25q256";
+- status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
+- };
+-
+- flash@1 {
+- compatible = "spi-flash", "sst,w25q256";
+- status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
+- };
+-
+- flash@2 {
+- compatible = "spi-flash", "sst,w25q256";
+- status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
+- };
+-};
+-
+-&spi1 {
+- status = "okay";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_spi1_default &pinctrl_spi1abr_default
+- &pinctrl_spi1cs1_default &pinctrl_spi1wp_default
+- &pinctrl_spi1wp_default &pinctrl_spi1quad_default>;
+-
+- flash@0 {
+- compatible = "spi-flash", "sst,w25q256";
+- status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
+- };
+-
+- flash@1 {
+- compatible = "spi-flash", "sst,w25q256";
+- status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
+- };
+-};
+-
+-&spi2 {
+- status = "okay";
+-
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_spi2_default &pinctrl_spi2cs1_default
+- &pinctrl_spi2cs2_default &pinctrl_spi2quad_default>;
+-
++#endif
+ flash@0 {
+ compatible = "spi-flash", "sst,w25q256";
+ status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
+- };
+-
+- flash@1 {
+- compatible = "spi-flash", "sst,w25q256";
+- status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
+- };
+-
+- flash@2 {
+- compatible = "spi-flash", "sst,w25q256";
+- status = "okay";
+- spi-max-frequency = <50000000>;
+- spi-tx-bus-width = <4>;
+- spi-rx-bus-width = <4>;
++ spi-max-frequency = <40000000>;
++ spi-tx-bus-width = <2>;
++ spi-rx-bus-width = <2>;
+ };
+ };
+
+ &emmc {
+- u-boot,dm-pre-reloc;
+ timing-phase = <0x700ff>;
+ };
+
+ &emmc_slot0 {
+- u-boot,dm-pre-reloc;
+ status = "okay";
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_emmc_default>;
+- sdhci-drive-type = <1>;
+-};
+-
+-&sdhci {
+- timing-phase = <0xc6ffff>;
+-};
+-
+-&sdhci_slot0 {
+- status = "okay";
+- bus-width = <4>;
+- pwr-gpios = <&gpio0 ASPEED_GPIO(V, 0) GPIO_ACTIVE_HIGH>;
+- pwr-sw-gpios = <&gpio0 ASPEED_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_sd1_default>;
+- sdhci-drive-type = <1>;
+-};
+-
+-&sdhci_slot1 {
+- status = "okay";
+- bus-width = <4>;
+- pwr-gpios = <&gpio0 ASPEED_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+- pwr-sw-gpios = <&gpio0 ASPEED_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+- pinctrl-names = "default";
+- pinctrl-0 = <&pinctrl_sd2_default>;
+- sdhci-drive-type = <1>;
+ };
+
+ &i2c4 {
+@@ -277,29 +192,32 @@
+ pinctrl-0 = <&pinctrl_i2c9_default>;
+ };
+
+-&pcie_bridge1 {
++&i2c9 {
+ status = "okay";
+-};
+
+-&h2x {
+- status = "okay";
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_i2c10_default>;
+ };
+
+-#if 0
+-&fsim0 {
++&i2c12 {
+ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_i2c13_default>;
+ };
+
+-&fsim1 {
++&i2c13 {
+ status = "okay";
++
++ pinctrl-names = "default";
++ pinctrl-0 = <&pinctrl_i2c14_default>;
+ };
+-#endif
+
+-&ehci1 {
++&pcie_bridge1 {
+ status = "okay";
+ };
+
+-&display_port {
++&h2x {
+ status = "okay";
+ };
+
+diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
+index ee775ce5d264..8c985532afb4 100644
+--- a/arch/arm/lib/interrupts.c
++++ b/arch/arm/lib/interrupts.c
+@@ -25,6 +25,7 @@
+
+ DECLARE_GLOBAL_DATA_PTR;
+
++int interrupt_init (void) __attribute__((weak));
+ int interrupt_init (void)
+ {
+ /*
+@@ -35,10 +36,13 @@ int interrupt_init (void)
+ return 0;
+ }
+
++void enable_interrupts (void) __attribute__((weak));
+ void enable_interrupts (void)
+ {
+ return;
+ }
++
++int disable_interrupts (void) __attribute__((weak));
+ int disable_interrupts (void)
+ {
+ return 0;
+@@ -189,6 +193,7 @@ void do_fiq (struct pt_regs *pt_regs)
+ bad_mode ();
+ }
+
++void do_irq (struct pt_regs *pt_regs) __attribute__((weak));
+ void do_irq (struct pt_regs *pt_regs)
+ {
+ efi_restore_gd();
+diff --git a/arch/arm/mach-aspeed/ast2600/Kconfig b/arch/arm/mach-aspeed/ast2600/Kconfig
+index fcdc425de59d..0900d22366d3 100644
+--- a/arch/arm/mach-aspeed/ast2600/Kconfig
++++ b/arch/arm/mach-aspeed/ast2600/Kconfig
+@@ -35,8 +35,8 @@ config TARGET_AST2600_INTEL
+ bool "AST2600-INTEL"
+ depends on ASPEED_AST2600
+ help
+- AST2600-INTEL is an Intel Eagle Stream CRB with
+- AST2600 as the BMC.
++ AST2600-INTEL is an Intel server board with the AST2600
++ as the BMC.
+
+ endchoice
+
+diff --git a/board/aspeed/ast2600_intel/Makefile b/board/aspeed/ast2600_intel/Makefile
+index 1f9fcc73c719..37d2f0064f38 100644
+--- a/board/aspeed/ast2600_intel/Makefile
++++ b/board/aspeed/ast2600_intel/Makefile
+@@ -1 +1,4 @@
+ obj-y += intel.o
++obj-y += ast-espi.o
++obj-y += ast-irq.o
++obj-y += ast-timer.o
+diff --git a/board/aspeed/ast2600_intel/ast-espi.c b/board/aspeed/ast2600_intel/ast-espi.c
+new file mode 100644
+index 000000000000..0fdbf089a450
+--- /dev/null
++++ b/board/aspeed/ast2600_intel/ast-espi.c
+@@ -0,0 +1,292 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2018-2020, Intel Corporation.
++
++#include <common.h>
++#include <asm/io.h>
++
++#define AST_LPC_BASE 0x1e789000
++#define AST_ESPI_BASE 0x1e6ee000
++#define AST_SCU_BASE 0x1e6e2000
++#define AST_SCU_HW_STRAP2 0x510
++#define SCU_HW_STRAP_ESPI_ENABLED 0x40
++
++#define USE_HW_HANDSHAKE 0
++#define DEBUG_ESPI_ENABLED 0
++#if DEBUG_ESPI_ENABLED
++#define DBG_ESPI printf
++#else
++#define DBG_ESPI(...)
++#endif
++
++/* eSPI controller registers */
++#define ESPI000 0x000 /* Engine Control. */
++#define ESPI004 0x004 /* Engine Status. */
++#define ESPI008 0x008 /* Interrupt Status. */
++#define ESPI00C 0x00C /* Interrupt Enable. */
++#define ESPI010 0x010 /* DMA Addr of Peripheral Channel Posted Rx pkt */
++#define ESPI014 0x014 /* Control of Peripheral Channel Posted Rx pkt. */
++#define ESPI018 0x018 /* Data port of Peripheral Channel Posted Rx pkt. */
++#define ESPI020 0x020 /* DMA Addr of Peripheral Channel Posted Tx pkt. */
++#define ESPI024 0x024 /* Control of Peripheral Channel Posted Tx pkt. */
++#define ESPI028 0x028 /* Data port of Peripheral Channel Posted Tx pkt. */
++#define ESPI030 0x030 /* DMA Addr of Peripheral Channel Non-Posted Tx pkt. */
++#define ESPI034 0x034 /* Control of Peripheral Channel Non-Posted Tx pkt. */
++#define ESPI038 0x038 /* Data port of Peripheral Channel Non-Posted Tx pkt. */
++#define ESPI040 0x040 /* DMA Addr of OOB Channel Rx pkt. */
++#define ESPI044 0x044 /* Control of OOB Channel Rx pkt. */
++#define ESPI048 0x048 /* Data port of OOB Channel Rx pkt. */
++#define ESPI050 0x050 /* DMA Addr of OOB Channel Tx pkt. */
++#define ESPI054 0x054 /* Control of OOB Channel Tx pkt. */
++#define ESPI058 0x058 /* Data port of OOB Channel Tx pkt. */
++#define ESPI060 0x060 /* DMA Addr of Flash Channel Rx pkt. */
++#define ESPI064 0x064 /* Control of Flash Channel Rx pkt. */
++#define ESPI068 0x068 /* Data port of Flash Channel Rx pkt. */
++#define ESPI070 0x070 /* DMA Addr of Flash Channel Tx pkt. */
++#define ESPI074 0x074 /* Control of Flash Channel Tx pkt. */
++#define ESPI078 0x078 /* Data port of Flash Channel Tx pkt. */
++#define ESPI080 0x080 /* Engine Control 2. */
++#define ESPI084 0x084 /* Mapping Src Addr of Peripheral Channel Rx pkt. */
++#define ESPI088 0x088 /* Mapping Tgt Addr of Peripheral Channel Rx pkt. */
++#define ESPI08C 0x08C /* Mapping Addr Mask of Peripheral Channel Rx pkt. */
++#define ESPI090 0x090 /* Mapping Target Addr and Mask of Flash Channel. */
++#define ESPI094 0x094 /* Interrupt enable of System Event from Master. */
++#define ESPI098 0x098 /* System Event from and to Master. */
++#define ESPI09C 0x09C /* GPIO through Virtual Wire Channel. */
++#define ESPI0A0 0x0A0 /* General Capabilities and Configurations. */
++#define ESPI0A4 0x0A4 /* Channel 0 Capabilities and Configurations. */
++#define ESPI0A8 0x0A8 /* Channel 1 Capabilities and Configurations. */
++#define ESPI0AC 0x0AC /* Channel 2 Capabilities and Configurations. */
++#define ESPI0B0 0x0B0 /* Channel 3 Capabilities and Configurations. */
++#define ESPI0B4 0x0B4 /* GPIO Direction of Virtual Wire Channel. */
++#define ESPI0B8 0x0B8 /* GPIO Selection of Virtual Wire Channel. */
++#define ESPI0BC 0x0BC /* GPIO Reset Selection of Virtual Wire Channel. */
++#define ESPI100 0x100 /* Interrupt enable of System Event 1 from Master. */
++#define ESPI104 0x104 /* System Event 1 from and to Master. */
++#define ESPI110 0x110 /* Interrupt type 0 of System Event from Master. */
++#define ESPI114 0x114 /* Interrupt type 1 of System Event from Master. */
++#define ESPI118 0x118 /* Interrupt type 2 of System Event from Master. */
++#define ESPI11C 0x11C /* Interrupt status of System Event from Master. */
++#define ESPI120 0x120 /* Interrupt type 0 of System Event 1 from Master. */
++#define ESPI124 0x124 /* Interrupt type 1 of System Event 1 from Master. */
++#define ESPI128 0x128 /* Interrupt type 2 of System Event 1 from Master. */
++#define ESPI12C 0x12C /* Interrupt status of System Event 1 from Master. */
++#define ESPICFG004 0x004 /* Device Identification. */
++#define ESPICFG008 0x008 /* General Capabilities and Configurations. */
++#define ESPICFG010 0x010 /* Channel 0 Capabilities and Configurations. */
++#define ESPICFG020 0x020 /* Channel 1 Capabilities and Configurations. */
++#define ESPICFG030 0x030 /* Channel 2 Capabilities and Configurations. */
++#define ESPICFG040 0x040 /* Channel 3 Capabilities and Configurations. */
++#define ESPICFG044 0x044 /* Channel 3 Capabilities and Configurations 2. */
++#define ESPICFG800 0x800 /* GPIO Direction of Virtual Wire Channel. */
++#define ESPICFG804 0x804 /* GPIO Selection of Virtual Wire Channel. */
++#define ESPICFG808 0x808 /* GPIO Reset Selection of Virtual Wire Channel. */
++#define ESPICFG810 0x810 /* Mapping Src Addr of Peripheral Channel Rx pkt */
++#define ESPICFG814 0x814 /* Mapping Tgt Addr of Peripheral Channel Rx pkt */
++#define ESPICFG818 0x818 /* Mapping Addr Mask of Peripheral Channel Rx pkt */
++
++/* ESPI000 bits */
++#define AST_ESPI_OOB_CHRDY BIT(4)
++#define AST_ESPI_FLASH_SW_CHRDY BIT(7)
++#define AST_ESPI_FLASH_SW_READ BIT(10)
++
++/* ESPI00C bits (Interrupt Enable) */
++#define AST_ESPI_IEN_HW_RST BIT(31)
++#define AST_ESPI_IEN_SYS1_EV BIT(22)
++#define AST_ESPI_IEN_SYS_EV BIT(8)
++#define AST_ESPI_IEN_GPIO_EV BIT(9)
++
++/* ESPI008 bits ISR */
++#define AST_ESPI_VW_SYS_EVT BIT(8)
++#define AST_ESPI_VW_GPIO_EVT BIT(9)
++#define AST_ESPI_VW_SYS_EV1 BIT(22)
++#define AST_ESPI_HW_RST BIT(31)
++
++/* ESPI080 bits */
++#define AST_ESPI_AUTO_ACK_HOST_RST_WARN BIT(2)
++#define AST_ESPI_AUTO_ACK_OOB_RST_WARN BIT(1)
++#define AST_ESPI_AUTO_ACK_SUS_WARN BIT(0)
++
++/* ESPI098 and ESPI11C bits */
++#define AST_ESPI_OOB_RST_WARN BIT(6)
++#define AST_ESPI_HOST_RST_WARN BIT(8)
++#define AST_ESPI_PLTRSTN BIT(5)
++#define AST_ESPI_OOB_RST_ACK BIT(16)
++#define AST_ESPI_SL_BT_DONE BIT(20)
++#define AST_ESPI_SL_BT_STATUS BIT(23)
++#define AST_ESPI_HOST_RST_ACK BIT(27)
++
++/* ESPI104 bits */
++#define AST_ESPI_SUS_WARN BIT(0)
++#define AST_ESPI_SUS_ACK BIT(20)
++
++/* LPC chip ID */
++#define SCR0SIO 0x170
++#define IRQ_SRC_ESPI 74 /* IRQ 74 */
++
++static void espi_handshake_ack(void)
++{
++ /* IRQ only serviced if strapped, so no strap check */
++ if (!(readl(AST_ESPI_BASE + ESPI098) & AST_ESPI_SL_BT_STATUS)) {
++ DBG_ESPI("Setting espi slave boot done\n");
++ uint32_t v = readl(AST_ESPI_BASE + ESPI098) |
++ AST_ESPI_SL_BT_STATUS | AST_ESPI_SL_BT_DONE;
++ writel(v, AST_ESPI_BASE + ESPI098);
++ }
++
++ uint32_t sys1_event = readl(AST_ESPI_BASE + ESPI104);
++ if (sys1_event & AST_ESPI_SUS_WARN &&
++ !(sys1_event & AST_ESPI_SUS_ACK)) {
++ DBG_ESPI("Boot SUS_WARN, evt: 0x%08x\n", sys1_event);
++ writel(sys1_event | AST_ESPI_SUS_ACK, AST_ESPI_BASE + ESPI104);
++ DBG_ESPI("SUS_WARN sent ack\n");
++ }
++}
++
++int espi_irq_handler(struct pt_regs *regs)
++{
++ uint32_t irq_status = readl(AST_ESPI_BASE + ESPI008);
++
++ DBG_ESPI("espi_irq_handler, ESPI008=0X%x, ESPI00c=0X%x,\
++ ESPI100=0X%x, ESPI11c=0X%x, ESPI094=0X%x,\
++ ESPI12c=0X%x, irq_status=0x%x\n",
++ readl(AST_ESPI_BASE + ESPI008),
++ readl(AST_ESPI_BASE + ESPI00C),
++ readl(AST_ESPI_BASE + ESPI100),
++ readl(AST_ESPI_BASE + ESPI11C),
++ readl(AST_ESPI_BASE + ESPI094),
++ readl(AST_ESPI_BASE + ESPI12C), irq_status);
++
++ if (irq_status & AST_ESPI_VW_SYS_EVT) {
++ uint32_t sys_status = readl(AST_ESPI_BASE + ESPI11C);
++ uint32_t sys_event = readl(AST_ESPI_BASE + ESPI098);
++
++ DBG_ESPI("sys_status : 0x%08X\n", sys_status);
++ if (sys_status & AST_ESPI_HOST_RST_WARN) {
++ DBG_ESPI("HOST_RST_WARN evt: 0x%08X\n", sys_event);
++ if (sys_event & AST_ESPI_HOST_RST_WARN) {
++ uint32_t v = readl(AST_ESPI_BASE + ESPI098) |
++ AST_ESPI_HOST_RST_ACK;
++ writel(v, AST_ESPI_BASE + ESPI098);
++ DBG_ESPI("HOST_RST_WARN sent ack\n");
++ }
++ }
++ if (sys_status & AST_ESPI_OOB_RST_WARN) {
++ DBG_ESPI("OOB_RST_WARN evt: 0x%08X\n", sys_event);
++ if (sys_event & AST_ESPI_OOB_RST_WARN) {
++ uint32_t v = readl(AST_ESPI_BASE + ESPI098) |
++ AST_ESPI_OOB_RST_ACK;
++ writel(v, AST_ESPI_BASE + ESPI098);
++ DBG_ESPI("OOB_RST_WARN sent ack\n");
++ }
++ }
++ if (sys_status & AST_ESPI_PLTRSTN) {
++ DBG_ESPI("PLTRSTN: %c, evt: 0x%08X\n",
++ (sys_event & AST_ESPI_PLTRSTN) ? '1' : '0',
++ sys_event);
++ }
++ writel(sys_status, AST_ESPI_BASE + ESPI11C); /* clear status */
++ }
++
++ if (irq_status & AST_ESPI_VW_SYS_EV1) {
++ uint32_t sys1_status = readl(AST_ESPI_BASE + ESPI12C);
++ uint32_t sys1_event = readl(AST_ESPI_BASE + ESPI104);
++
++ DBG_ESPI("sys1_status : 0x%08X\n", sys1_status);
++ if (sys1_status & AST_ESPI_SUS_WARN) {
++ DBG_ESPI("SUS WARN evt: 0x%08X\n", sys1_event);
++ if (sys1_event & AST_ESPI_SUS_WARN) {
++ uint32_t v = readl(AST_ESPI_BASE + ESPI104) |
++ AST_ESPI_SUS_ACK;
++ writel(v, AST_ESPI_BASE + ESPI104);
++ DBG_ESPI("SUS_WARN sent ack\n");
++ }
++ }
++ writel(sys1_status, AST_ESPI_BASE + ESPI12C); /* clear status */
++ }
++
++ if (irq_status & AST_ESPI_HW_RST) {
++ uint32_t v = readl(AST_ESPI_BASE + ESPI000) & 0x00ffffffff;
++ writel(v, AST_ESPI_BASE + ESPI000);
++ v |= 0xff000000;
++ writel(v, AST_ESPI_BASE + ESPI000);
++
++ DBG_ESPI("HW_RESET\n");
++
++ espi_handshake_ack();
++ }
++
++ writel(irq_status, AST_ESPI_BASE + ESPI008); /* clear irq_status */
++
++ DBG_ESPI("end espi_irq_handler, ESPI008=0X%x, ESPI00c=0X%x,\
++ ESPI100=0X%x, ESPI11c=0X%x, ESPI094=0X%x,\
++ ESPI12c=0X%x, irq_status=0X%x\n",
++ readl(AST_ESPI_BASE + ESPI008),
++ readl(AST_ESPI_BASE + ESPI00C),
++ readl(AST_ESPI_BASE + ESPI100),
++ readl(AST_ESPI_BASE + ESPI11C),
++ readl(AST_ESPI_BASE + ESPI094),
++ readl(AST_ESPI_BASE + ESPI12C), irq_status);
++ return 0;
++}
++
++void espi_init(void)
++{
++ if (~readl(AST_SCU_BASE + AST_SCU_HW_STRAP2) &
++ SCU_HW_STRAP_ESPI_ENABLED) {
++ uint32_t v;
++
++ DBG_ESPI("espi init\n");
++
++ writel(0xff000000, AST_SCU_BASE + 0x454); /* driving strength */
++
++ /* Block flash access from Host */
++ v = readl(AST_ESPI_BASE + ESPI000) & ~AST_ESPI_FLASH_SW_CHRDY;
++ v |= AST_ESPI_FLASH_SW_READ | AST_ESPI_OOB_CHRDY;
++ writel(v, AST_ESPI_BASE + ESPI000);
++
++ /*
++ * Set SIO register 0x28 to 0xa8 as a faked ASPEED ChipID for
++ * BIOS using in eSPI mode.
++ */
++ v = readl(AST_LPC_BASE + SCR0SIO) & ~0x000000ff;
++ writel(v, AST_LPC_BASE + SCR0SIO);
++ v = readl(AST_LPC_BASE + SCR0SIO) | 0xa8;
++ writel(v, AST_LPC_BASE + SCR0SIO);
++
++#if USE_HW_HANDSHAKE
++ v = readl(AST_ESPI_BASE + ESPI098) |
++ AST_ESPI_SL_BT_STATUS | AST_ESPI_SL_BT_DONE;
++ writel(v, AST_ESPI_BASE + ESPI098);
++
++ return;
++#endif
++
++ v = readl(AST_ESPI_BASE + ESPI080);
++ v &= ~(AST_ESPI_AUTO_ACK_HOST_RST_WARN |
++ AST_ESPI_AUTO_ACK_OOB_RST_WARN |
++ AST_ESPI_AUTO_ACK_SUS_WARN);
++ writel(v, AST_ESPI_BASE + ESPI080); /* Disable auto H/W ack */
++
++ writel(0, AST_ESPI_BASE + ESPI110);
++ writel(0, AST_ESPI_BASE + ESPI114);
++ writel(AST_ESPI_HOST_RST_WARN | AST_ESPI_OOB_RST_WARN |
++ AST_ESPI_PLTRSTN, AST_ESPI_BASE + ESPI118);
++ writel(AST_ESPI_HOST_RST_WARN | AST_ESPI_OOB_RST_WARN |
++ AST_ESPI_PLTRSTN, AST_ESPI_BASE + ESPI094);
++
++ writel(AST_ESPI_SUS_WARN,
++ AST_ESPI_BASE + ESPI120); /* int type 0 susp warn */
++ writel(0, AST_ESPI_BASE + ESPI124);
++ writel(0, AST_ESPI_BASE + ESPI128);
++ writel(AST_ESPI_SUS_WARN,
++ AST_ESPI_BASE +
++ ESPI100); /* Enable sysev1 ints for susp warn */
++
++ writel(AST_ESPI_IEN_HW_RST | AST_ESPI_IEN_SYS1_EV |
++ AST_ESPI_IEN_SYS_EV, AST_ESPI_BASE + ESPI00C);
++
++ irq_install_handler(IRQ_SRC_ESPI, espi_irq_handler, NULL);
++ } else {
++ DBG_ESPI("No espi strap\n");
++ }
++}
+diff --git a/board/aspeed/ast2600_intel/ast-irq.c b/board/aspeed/ast2600_intel/ast-irq.c
+new file mode 100644
+index 000000000000..f817f8cd7c81
+--- /dev/null
++++ b/board/aspeed/ast2600_intel/ast-irq.c
+@@ -0,0 +1,399 @@
++/*
++ * Copyright 2018 Intel Corporation
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#include <common.h>
++#include <netdev.h>
++#include <asm/io.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#define GIC_DISTRIBUTOR_OFFSET 0x1000
++#define GIC_CPU_OFFSET 0x2000
++#define GIC_INTERFACE_OFFSET 0x4000
++#define GIC_VIRT_OFFSET 0x6000
++
++#define VIC_STATUS_L 0x80
++#define VIC_STATUS_H 0x84
++#define VIC_IRQ_SELECTION_L 0x98
++#define VIC_IRQ_SELECTION_H 0x9C
++#define VIC_ENABLE_L 0xA0
++#define VIC_ENABLE_H 0xA4
++#define VIC_ENABLE_CLEAR_L 0xA8
++#define VIC_ENABLE_CLEAR_H 0xAC
++#define VIC_INTERRUPT_CLEAR_L 0xD8
++#define VIC_INTERRUPT_CLEAR_H 0xDC
++
++#define VIC_CLEAR_ALL (~0)
++
++/* GIC_DISTRIBUTOR_OFFSET register offsets */
++#define GICD_CTLR 0x000
++#define GICD_TYPER 0x004
++#define GICD_IIDR 0x008
++#define GICD_IGROUPRn 0x080
++#define GICD_ISENABLERn 0x100
++#define GICD_ICENABLERn 0x180
++#define GICD_ISPENDRn 0x200
++#define GICD_ICPENDRn 0x280
++#define GICD_ISACTIVERn 0x300
++#define GICD_ICACTIVERn 0x380
++#define GICD_IPRIORITYRn 0x400
++#define GICD_ITARGETSRn 0x800
++#define GICD_ICFGRn 0xc00
++#define GICD_PPISR 0xd00
++#define GICD_SPISRn 0xd04
++#define GICD_SGIR 0xf00
++#define GICD_CPENDINGIRn 0xf10
++#define GICD_SPENDINGIRn 0xf10
++#define GICD_PIDR4 0xfd0
++#define GICD_PIDR5 0xfd4
++#define GICD_PIDR6 0xfd8
++#define GICD_PIDR7 0xfdc
++#define GICD_PIDR0 0xfe0
++#define GICD_PIDR1 0xfe4
++#define GICD_PIDR2 0xfe8
++#define GICD_PIDR3 0xfec
++#define GICD_CIDR0 0xff0
++#define GICD_CIDR1 0xff4
++#define GICD_CIDR2 0xff8
++#define GICD_CIDR3 0xffc
++
++#define GIC_DISTRIBUTOR_IMPLEMENTER_MAGIC 0x0100143b
++
++/* GIC_CPU_OFFSET register offsets */
++#define GICC_CTLR 0x0000
++#define GICC_PMRn 0x0004
++#define GICC_BPR 0x0008
++#define GICC_IAR 0x000c
++#define GICC_EOIR 0x0010
++#define GICC_RPR 0x0014
++#define GICC_HPPIR 0x0018
++#define GICC_ABPR 0x001c
++#define GICC_AIAR 0x0020
++#define GICC_AEOIR 0x0024
++#define GICC_AHPPIR 0x0028
++#define GICC_APR0 0x00d0
++#define GICC_NSAPR0 0x00e0
++#define GICC_IIDR 0x00fc
++#define GICC_DIR 0x1000
++
++#define GIC_CPU_IMPLEMENTER_MAGIC 0x0102143b
++
++/* GIC_INTERFACE_OFFSET register offsets */
++#define GICH_HCR 0x000
++#define GICH_VTR 0x004
++#define GICH_VMCR 0x008
++#define GICH_MISR 0x010
++#define GICH_EISR0 0x020
++#define GICH_ELSR0 0x020
++#define GICH_APR0 0x0f0
++#define GICH_LR0 0x100
++#define GICH_LR1 0x104
++#define GICH_LR2 0x108
++#define GICH_LR3 0x10c
++
++/* GIC_VIRT_OFFSET register offsets */
++#define GICV_CTLR 0x0000
++#define GICV_PMR 0x0004
++#define GICV_BPR 0x0008
++#define GICV_IAR 0x000c
++#define GICV_EOIR 0x0010
++#define GICV_RPR 0x0014
++#define GICV_HPPIR 0x0018
++#define GICV_ABPR 0x001c
++#define GICV_AIAR 0x0020
++#define GICV_AEOIR 0x0024
++#define GICV_AHPPIR 0x0028
++#define GICV_APR0 0x00d0
++#define GICV_NSAPR0 0x00e0
++#define GICV_IIDR 0x00fc
++#define GICV_DIR 0x1000
++
++#define GIC_VIRT_CPU_IMPLEMENTER_MAGIC 0x0102143b
++
++#define GICD_CTLR_ENABLE 0x03
++
++#define GICD_INT_DEF_PRI 0xa0
++#define GICD_INT_DEF_PRI_X4 (\
++ (GICD_INT_DEF_PRI << 24) |\
++ (GICD_INT_DEF_PRI << 16) |\
++ (GICD_INT_DEF_PRI << 8) |\
++ GICD_INT_DEF_PRI)
++
++#define GICD_INT_ACTLOW_LVLTRIG 0
++#define GICD_INT_EN_CLR_X32 0xffffffff
++#define GICD_INT_EN_CLR_PPI 0xffff0000
++#define GICD_INT_EN_SET_SGI 0x0000ffff
++
++#define gicd_readl(OFFSET) readl(gbase + GIC_DISTRIBUTOR_OFFSET + (OFFSET))
++#define gicd_writel(VALUE, OFFSET) \
++ writel((VALUE), gbase + GIC_DISTRIBUTOR_OFFSET + (OFFSET))
++#define gicc_readl(OFFSET) readl(gbase + GIC_CPU_OFFSET + (OFFSET))
++#define gich_readl(OFFSET) readl(gbase + GIC_INTERFACE_OFFSET + (OFFSET))
++#define gicv_readl(OFFSET) readl(gbase + GIC_VIRT_OFFSET + (OFFSET))
++
++static size_t max_irq = 0;
++
++#define ITLINES_MASK 0x1f
++#define ITLINES_SHIFT 5
++
++#define GIC_MAX_IRQ 1020
++static interrupt_handler_t *handlers[GIC_MAX_IRQ] = {NULL};
++static unsigned long irq_total = 0;
++static unsigned long irq_counts[GIC_MAX_IRQ] = {0};
++static uint32_t gbase = 0;
++
++/* TODO: This, hard-coded, or from dts? */
++static inline uint32_t gic_base(void)
++{
++ uint32_t base;
++ /* read the base address of the private peripheral space */
++ __asm__ __volatile__("mrc p15, 4, %r0, c15, c0, 0\n\t" : "=r"(base) : );
++ return base;
++}
++
++static void enable_gic(void)
++{
++ uint32_t gicd_ctlr;
++
++ /* add GIC offset ref table 1-3 for interrupt distributor address */
++ gicd_ctlr = gicd_readl(GICD_CTLR);
++ gicd_writel(gicd_ctlr | GICD_CTLR_ENABLE, GICD_CTLR);
++}
++
++static void disable_gic(void)
++{
++ uint32_t gicd_ctlr;
++
++ /* add GIC offset ref table 1-3 for interrupt distributor address */
++ gicd_ctlr = gicd_readl(GICD_CTLR);
++ gicd_writel(gicd_ctlr & ~GICD_CTLR_ENABLE, GICD_CTLR);
++}
++
++static void enable_irq_id(unsigned int id)
++{
++ uint32_t grp = id >> ITLINES_SHIFT;
++ uint32_t grp_bit = 1 << (id & ITLINES_MASK);
++ gicd_writel(grp_bit, GICD_ISENABLERn + grp * sizeof(uint32_t));
++}
++
++static void disable_irq_id(unsigned int id)
++{
++ uint32_t grp = id >> ITLINES_SHIFT;
++ uint32_t grp_bit = 1 << (id & ITLINES_MASK);
++ gicd_writel(grp_bit, GICD_ICENABLERn + grp * sizeof(uint32_t));
++}
++
++static int gic_probe(void)
++{
++ int i;
++ gbase = gic_base();
++ enable_gic();
++
++ if (gicd_readl(GICD_IIDR) != GIC_DISTRIBUTOR_IMPLEMENTER_MAGIC &&
++ gicc_readl(GICC_IIDR) != GIC_CPU_IMPLEMENTER_MAGIC &&
++ gicv_readl(GICV_IIDR) != GIC_VIRT_CPU_IMPLEMENTER_MAGIC)
++ {
++ return 0;
++ }
++ /* GIC supports up to 1020 lines */
++ max_irq = ((gicd_readl(GICD_TYPER) & ITLINES_MASK) + 1) << ITLINES_SHIFT;
++ if (max_irq > GIC_MAX_IRQ)
++ max_irq = GIC_MAX_IRQ;
++ /* set all lines to be level triggered N-N */
++ for (i = 32; i < max_irq; i += 16)
++ gicd_writel(0, GICD_ICFGRn + i / 4);
++
++ /* Set priority on all interrupts. */
++ for (i = 0; i < max_irq; i += 4)
++ gicd_writel(GICD_INT_DEF_PRI_X4, GICD_IPRIORITYRn + i);
++
++ /* Deactivate and disable all SPIs. */
++ for (i = 32; i < max_irq; i += 32) {
++ gicd_writel(GICD_INT_EN_CLR_X32, GICD_ICACTIVERn + i / 8);
++ gicd_writel(GICD_INT_EN_CLR_X32, GICD_ICENABLERn + i / 8);
++ }
++ gicd_writel(GICD_INT_EN_CLR_X32, GICD_ICACTIVERn);
++ gicd_writel(GICD_INT_EN_CLR_PPI, GICD_ICENABLERn);
++ gicd_writel(GICD_INT_EN_SET_SGI, GICD_ISENABLERn);
++
++ return 0;
++}
++
++void irq_free_handler (int irq);
++static void gic_shutdown(void)
++{
++ int i;
++ for (i = 0; i < max_irq; i++)
++ {
++ irq_free_handler(i);
++ }
++ disable_gic();
++}
++
++int arch_interrupt_init_early(void)
++{
++ return 0;
++}
++
++int arch_interrupt_init(void)
++{
++ int i;
++ for (i = 0; i < GIC_MAX_IRQ; i++)
++ {
++ handlers[i] = NULL;
++ irq_counts[i] = 0;
++ }
++ return gic_probe();
++}
++
++int arch_interrupt_fini(void)
++{
++ gic_shutdown();
++ return 0;
++}
++
++int interrupt_init (void)
++{
++ /*
++ * setup up stacks if necessary
++ */
++ IRQ_STACK_START_IN = gd->irq_sp + 8;
++
++ printf("%s()\n", __FUNCTION__);
++ return arch_interrupt_init();
++
++ return 0;
++}
++
++int global_interrupts_enabled (void)
++{
++ unsigned long cpsr;
++ __asm__ __volatile__("mrs %0, cpsr\n"
++ : "=r" (cpsr)
++ :
++ : "memory");
++
++ return (cpsr & 0x80) == 0;
++}
++
++void enable_interrupts (void)
++{
++ unsigned long cpsr;
++ __asm__ __volatile__("mrs %0, cpsr\n"
++ "bic %0, %0, #0x80\n"
++ "msr cpsr_c, %0"
++ : "=r" (cpsr)
++ :
++ : "memory");
++
++ return;
++}
++
++int disable_interrupts (void)
++{
++ unsigned long cpsr, temp;
++ __asm__ __volatile__("mrs %0, cpsr\n"
++ "orr %1, %0, #0xc0\n"
++ "msr cpsr_c, %1"
++ : "=r" (cpsr), "=r" (temp)
++ :
++ : "memory");
++ return (cpsr & 0x80) == 0;
++}
++
++void irq_install_handler(int irq, interrupt_handler_t *handler, void *ctx)
++{
++ if (irq > max_irq) {
++ printf("irq %d out of range\n", irq);
++ return;
++ }
++ if (handlers[irq]) {
++ printf("irq %d already in use (%p)\n", irq, handlers[irq]);
++ return;
++ }
++ printf("registering handler for irq %d\n", irq);
++ handlers[irq] = handler;
++ enable_irq_id(irq);
++}
++
++void irq_free_handler (int irq)
++{
++ if (irq >= max_irq) {
++ printf("irq %d out of range\n", irq);
++ return;
++ }
++ if (handlers[irq]) {
++ handlers[irq] = NULL;
++ disable_irq_id(irq);
++ }
++}
++
++int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
++{
++ int i;
++ int enabled = global_interrupts_enabled();
++ printf("GIC base = 0x%x\n", gbase);
++ printf("interrupts %sabled\n", (enabled ? "en" : "dis"));
++ uint32_t grp_en = 0;
++ for (i = 0; i < max_irq; i++) {
++ if ((i & ITLINES_MASK) == 0)
++ grp_en = gicd_readl(GICD_ISENABLERn +
++ (i >> ITLINES_SHIFT) * sizeof(uint32_t));
++ int irq_enabled = grp_en & (1 << (i & ITLINES_MASK));
++ if (!irq_enabled)
++ continue;
++ printf("% 2i (% 3s): %lu\n", i,
++ (irq_enabled ? "on" : "off"), irq_counts[i]);
++ }
++ printf("total: %lu\n", irq_total);
++ return 0;
++}
++
++void do_irq(struct pt_regs *pt_regs)
++{
++ int i;
++ if (!gbase) {
++ static int printed_msg = 0;
++ if (!printed_msg)
++ {
++ printed_msg = 1;
++ printf("interrupt before configured!\n");
++ }
++ return;
++ }
++ irq_total++;
++ uint32_t grp_pend = 0;
++ for (i = 0; i < max_irq; i++) {
++ /* limit reads of the pending register to once in 32 */
++ if ((i & ITLINES_MASK) == 0)
++ grp_pend = gicd_readl(GICD_ISPENDRn +
++ (i >> ITLINES_SHIFT) * sizeof(uint32_t));
++ uint32_t pending = grp_pend & (1 << (i & ITLINES_MASK));
++ if (pending) {
++ irq_counts[i]++;
++ /* mask via GICD_ICENABLERn */
++ gicd_writel(pending, GICD_ICENABLERn +
++ (i >> ITLINES_SHIFT) * sizeof(uint32_t));
++ if (handlers[i]) {
++ handlers[i](pt_regs);
++ /* unmask via GICD_ISENABLERn */
++ gicd_writel(pending, GICD_ISENABLERn +
++ (i >> ITLINES_SHIFT) * sizeof(uint32_t));
++ /* clear pending via GICD_ICPENDRn */
++ gicd_writel(pending, GICD_ICPENDRn +
++ (i >> ITLINES_SHIFT) * sizeof(uint32_t));
++ } else {
++ printf("unexpected interrupt %i; masking\n", i);
++ /* clear pending via GICD_ICPENDRn */
++ gicd_writel(pending, GICD_ISPENDRn +
++ (i >> ITLINES_SHIFT) * sizeof(uint32_t));
++ }
++ }
++ }
++}
+diff --git a/board/aspeed/ast2600_intel/ast-irq.h b/board/aspeed/ast2600_intel/ast-irq.h
+new file mode 100644
+index 000000000000..9957f2baa7ff
+--- /dev/null
++++ b/board/aspeed/ast2600_intel/ast-irq.h
+@@ -0,0 +1,8 @@
++#ifndef _AST_IRQ_H_
++#define _AST_IRQ_H_
++
++int request_irq(int irq, interrupt_handler_t *handler);
++int release_irq(int irq);
++int arch_interrupt_init_early(void);
++
++#endif
+diff --git a/board/aspeed/ast2600_intel/ast-timer.c b/board/aspeed/ast2600_intel/ast-timer.c
+new file mode 100644
+index 000000000000..cf8c69aba5d3
+--- /dev/null
++++ b/board/aspeed/ast2600_intel/ast-timer.c
+@@ -0,0 +1,59 @@
++/*
++ * Copyright 2019 Intel Corporation
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#include <common.h>
++#include <asm/io.h>
++
++static const int timer_irqs[] = {48, 49, 50, 51, 52, 53, 54, 55};
++#define AST_TIMER_BASE 0x1e782000
++/* offsets from AST_TIMER_BASE for each timer */
++static const uint32_t timer_bases[] = {0, 0x10, 0x20, 0x40,
++ 0x50, 0x60, 0x70, 0x80};
++#define TIMER_1MHZ_CLK_COUNT 1000000u
++#define TIMER_ENABLE 1
++#define TIMER_1MHZ_CLK_SEL 2
++#define TIMER_ENABLE_IRQ 4
++#define TIMER_RESET_BY_WDT 8
++#define TIMER_CONTROL 0x30
++#define TIMER_RELOAD 0x04
++#define TIMER_CONTROL_CLEAR 0x3c
++
++void timer_disable(int n)
++{
++ if (n < 0 || n > 7) {
++ return;
++ }
++ uint32_t tctrl = 0xf << (n * 4);
++ writel(tctrl, AST_TIMER_BASE + TIMER_CONTROL_CLEAR);
++}
++
++void timer_enable(int n, uint32_t freq, interrupt_handler_t *handler)
++{
++ if (n < 0 || n > 7) {
++ return;
++ }
++ if (!freq)
++ return;
++
++ timer_disable(n);
++
++ uint32_t v = TIMER_1MHZ_CLK_COUNT / freq;
++ writel(v, AST_TIMER_BASE + timer_bases[n] + TIMER_RELOAD);
++
++ uint32_t tctrl = (
++ TIMER_ENABLE |
++ TIMER_1MHZ_CLK_SEL |
++ TIMER_RESET_BY_WDT) << (n * 4);
++
++ if (handler) {
++ irq_install_handler(timer_irqs[n], handler, NULL);
++ tctrl |= (TIMER_ENABLE_IRQ << (n * 4));
++ }
++ writel(tctrl, AST_TIMER_BASE + TIMER_CONTROL);
++}
+diff --git a/board/aspeed/ast2600_intel/intel.c b/board/aspeed/ast2600_intel/intel.c
+index be6dc49a3bc7..fc0e41a47712 100644
+--- a/board/aspeed/ast2600_intel/intel.c
++++ b/board/aspeed/ast2600_intel/intel.c
+@@ -1,222 +1,193 @@
+-// SPDX-License-Identifier: GPL-2.0+
+-/*
+- * Copyright (C) ASPEED Technology Inc.
+- */
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2019-2021, Intel Corporation.
++
++/* Intel customizations of Das U-Boot */
+ #include <common.h>
++#include <asm/gpio.h>
+ #include <asm/io.h>
+
+-/* SCU registers */
+-#define SCU_BASE 0x1e6e2000
+-#define SCU_PINMUX4 (SCU_BASE + 0x410)
+-#define SCU_PINMUX4_RGMII3TXD1 BIT(19)
+-#define SCU_PINMUX5 (SCU_BASE + 0x414)
+-#define SCU_PINMUX5_SGPMI BIT(27)
+-#define SCU_PINMUX5_SGPMO BIT(26)
+-#define SCU_PINMUX5_SGPMLD BIT(25)
+-#define SCU_PINMUX5_SGPMCK BIT(24)
+-#define SCU_GPIO_PD0 (SCU_BASE + 0x610)
+-#define SCU_GPIO_PD0_B6 BIT(14)
+-#define SCU_PINMUX27 (SCU_BASE + 0x69c)
+-#define SCU_PINMUX27_HBLED_EN BIT(31)
+-
+-/* eSPI registers */
+-#define ESPI_BASE 0x1e6ee000
+-#define ESPI_CTRL (ESPI_BASE + 0x0)
+-#define ESPI_INT_EN (ESPI_BASE + 0xc)
+-#define ESPI_CTRL2 (ESPI_BASE + 0x80)
+-#define ESPI_SYSEVT_INT_EN (ESPI_BASE + 0x94)
+-#define ESPI_SYSEVT1_INT_EN (ESPI_BASE + 0x100)
+-#define ESPI_SYSEVT_INT_T0 (ESPI_BASE + 0x110)
+-#define ESPI_SYSEVT_INT_T1 (ESPI_BASE + 0x114)
+-#define ESPI_SYSEVT1_INT_T0 (ESPI_BASE + 0x120)
+-
+-/* LPC registers */
+-#define LPC_BASE 0x1e789000
+-#define LPC_HICR5 (LPC_BASE + 0x80)
+-#define LPC_HICR5_SIO80HGPIO_EN BIT(31)
+-#define LPC_HICR5_80HGPIO_EN BIT(30)
+-#define LPC_HICR5_80HGPIO_SEL_MASK GENMASK(28, 24)
+-#define LPC_HICR5_80HGPIO_SEL_SHIFT 24
+-#define LPC_HICR5_SNP0_INT_EN BIT(1)
+-#define LPC_HICR5_SNP0_EN BIT(0)
+-#define LPC_HICR6 (LPC_BASE + 0x84)
+-#define LPC_HICR6_STS_SNP1 BIT(1)
+-#define LPC_HICR6_STS_SNP0 BIT(0)
+-#define LPC_SNPWADR (LPC_BASE + 0x90)
+-#define LPC_SNPWADR_SNP0_MASK GENMASK(15, 0)
+-#define LPC_SNPWADR_SNP0_SHIFT 0
+-#define LPC_HICRB (LPC_BASE + 0x100)
+-#define LPC_HICRB_80HSGPIO_EN BIT(13)
+-
+-/* GPIO/SGPIO registers */
+-#define GPIO_BASE 0x1e780000
+-#define GPIO_ABCD_VAL (GPIO_BASE + 0x0)
+-#define GPIO_ABCD_VAL_D4 BIT(28)
+-#define GPIO_ABCD_VAL_C5 BIT(21)
+-#define GPIO_ABCD_VAL_C3 BIT(19)
+-#define GPIO_ABCD_DIR (GPIO_BASE + 0x4)
+-#define GPIO_ABCD_DIR_D4 BIT(28)
+-#define GPIO_ABCD_DIR_C5 BIT(21)
+-#define GPIO_ABCD_DIR_C3 BIT(19)
+-#define GPIO_EFGH_DIR (GPIO_BASE + 0x24)
+-#define GPIO_EFGH_DIR_G6 BIT(22)
+-#define SGPIO_M1_CONF (GPIO_BASE + 0x554)
+-#define SGPIO_M1_CONF_CLKDIV_MASK GENMASK(31, 16)
+-#define SGPIO_M1_CONF_CLKDIV_SHIFT 16
+-#define SGPIO_M1_PINS_MASK GENMASK(10, 6)
+-#define SGPIO_M1_PINS_SHIFT 6
+-#define SPGIO_M1_EN BIT(0)
+-
+-#define LPC_HICR5_UNKVAL_MASK 0x1FFF0000 /* bits with unknown values on reset */
+-
+-static void snoop_init(void)
++/* use GPIOC0 on intel boards */
++#define FFUJ_GPIO "gpio@1e78000016"
++
++int read_ffuj(void)
++{
++ struct gpio_desc desc;
++ int ret;
++
++ ret = dm_gpio_lookup_name(FFUJ_GPIO, &desc);
++ if (ret)
++ return ret;
++ ret = dm_gpio_request(&desc, "ffuj");
++ if (ret)
++ return ret;
++ ret = dm_gpio_set_dir_flags(&desc, GPIOD_ACTIVE_LOW);
++ if (ret)
++ return ret;
++ ret = dm_gpio_get_value(&desc);
++ dm_gpio_free(desc.dev, &desc);
++ return ret;
++}
++
++/* gpio_abort is a weak symbol in common/autoboot.c */
++int gpio_abort(void)
++{
++ int value;
++ /* check ffuj to abort the autoboot */
++ value = read_ffuj();
++ printf("FFUJ: %d\n", value);
++ return value <= 0 ? 0 : 1;
++}
++
++#define SCU_BASE 0x1E6E2000
++int misc_init_r(void)
++{
++ /* This is called near the end of the _r init sequence */
++
++ return 0;
++}
++
++#define SCU_418 0x418 /* Multi-function Pin Control #6 */
++#define SCU_418_PBIO_MASK GENMASK(6, 5)
++#define SCU_4bc 0x4bc /* Multi-function Pin Control #20 */
++#define SCU_4bc_PASSTHRU0_MASK GENMASK(25, 24)
++#define SCU_4bc_PASSTHRU1_MASK GENMASK(27, 26)
++#define SCU_4bc_PASSTHRU2_MASK GENMASK(29, 28)
++
++static void gpio_passthru_init(void)
+ {
+- u32 val;
++ writel(readl(SCU_BASE | SCU_4bc) |
++ SCU_4bc_PASSTHRU0_MASK | SCU_4bc_PASSTHRU1_MASK,
++ SCU_BASE | SCU_4bc);
++ writel(readl(SCU_BASE | SCU_418) | SCU_418_PBIO_MASK,
++ SCU_BASE | SCU_418);
++}
+
++#define AST_LPC_BASE 0x1e789000
++#define LPC_SNOOP_ADDR 0x80
++#define HICR5 0x080 /* Host Interface Control Register 5 */
++#define HICR6 0x084 /* Host Interface Control Register 6 */
++#define SNPWADR 0x090 /* LPC Snoop Address Register */
++#define HICRB 0x100 /* Host Interface Control Register B */
++
++/* HICR5 Bits */
++#define HICR5_EN_SIOGIO (1 << 31) /* Enable SIOGIO */
++#define HICR5_EN80HGIO (1 << 30) /* Enable 80hGIO */
++#define HICR5_SEL80HGIO (0x1f << 24) /* Select 80hGIO */
++#define SET_SEL80HGIO(x) ((x & 0x1f) << 24) /* Select 80hGIO Offset */
++#define HICR5_UNKVAL_MASK 0x1FFF0000 /* Bits with unknown values on reset */
++#define HICR5_ENINT_SNP0W (1 << 1) /* Enable Snooping address 0 */
++#define HICR5_EN_SNP0W (1 << 0) /* Enable Snooping address 0 */
++
++/* HRCR6 Bits */
++#define HICR6_STR_SNP0W (1 << 0) /* Interrupt Status Snoop address 0 */
++#define HICR6_STR_SNP1W (1 << 1) /* Interrupt Status Snoop address 1 */
++
++/* HICRB Bits */
++#define HICRB_EN80HSGIO (1 << 13) /* Enable 80hSGIO */
++#define HICRB_ENSNP0D (1 << 14) /* Enable ACCEPT response for snoop #0 */
++
++static void port80h_snoop_init(void)
++{
++ uint32_t value;
++ /* enable port80h snoop and sgpio */
+ /* set lpc snoop #0 to port 0x80 */
+- val = readl(LPC_SNPWADR) & 0xffff0000;
+- val |= ((0x80 << LPC_SNPWADR_SNP0_SHIFT) &
+- LPC_SNPWADR_SNP0_MASK);
+- writel(val, LPC_SNPWADR);
++ value = readl(AST_LPC_BASE + SNPWADR) & 0xffff0000;
++ writel(value | LPC_SNOOP_ADDR, AST_LPC_BASE + SNPWADR);
+
+ /* clear interrupt status */
+- val = readl(LPC_HICR6);
+- val |= (LPC_HICR6_STS_SNP0 |
+- LPC_HICR6_STS_SNP1);
+- writel(val, LPC_HICR6);
++ value = readl(AST_LPC_BASE + HICR6);
++ value |= HICR6_STR_SNP0W | HICR6_STR_SNP1W;
++ writel(value, AST_LPC_BASE + HICR6);
+
+ /* enable lpc snoop #0 and SIOGIO */
+- val = readl(LPC_HICR5);
+- val |= (LPC_HICR5_SIO80HGPIO_EN |
+- LPC_HICR5_SNP0_EN);
+- writel(val, LPC_HICR5);
++ value = readl(AST_LPC_BASE + HICR5) & ~(HICR5_UNKVAL_MASK);
++ value |= HICR5_EN_SIOGIO | HICR5_EN_SNP0W;
++ writel(value, AST_LPC_BASE + HICR5);
+
+ /* enable port80h snoop on SGPIO */
+- val = readl(LPC_HICRB);
+- val |= LPC_HICRB_80HSGPIO_EN;
+- writel(val, LPC_HICRB);
++ value = readl(AST_LPC_BASE + HICRB) | HICRB_EN80HSGIO | HICRB_ENSNP0D;
++ writel(value, AST_LPC_BASE + HICRB);
+ }
+
++#define AST_GPIO_BASE 0x1e780000
++
+ static void sgpio_init(void)
+ {
+ #define SGPIO_CLK_DIV(N) ((N) << 16)
+ #define SGPIO_BYTES(N) ((N) << 6)
+ #define SGPIO_ENABLE 1
++#define GPIO554 0x554
++#define SCU_414 0x414 /* Multi-function Pin Control #5 */
+ #define SCU_414_SGPM_MASK GENMASK(27, 24)
+
+- /* set the sgpio clock to pclk/(2*(5+1)) or ~2 MHz */
+- u32 val;
+-
+- val = ((256 << SGPIO_M1_CONF_CLKDIV_SHIFT) & SGPIO_M1_CONF_CLKDIV_MASK) |
+- ((10 << SGPIO_M1_PINS_SHIFT) & SGPIO_M1_PINS_MASK) |
+- SPGIO_M1_EN;
+- writel(val, SGPIO_M1_CONF);
++ uint32_t value;
++ /* set the sgpio clock to 2MHz */
++ value = SGPIO_CLK_DIV(24) | SGPIO_BYTES(10) | SGPIO_ENABLE;
++ writel(value, AST_GPIO_BASE + GPIO554);
++ writel(readl(SCU_BASE | SCU_414) | SCU_414_SGPM_MASK,
++ SCU_BASE | SCU_414);
++}
+
+- val = readl(SCU_PINMUX5);
+- val |= (SCU_PINMUX5_SGPMI |
+- SCU_PINMUX5_SGPMO |
+- SCU_PINMUX5_SGPMLD |
+- SCU_PINMUX5_SGPMCK);
+- writel(val, SCU_PINMUX5);
++static void timer_handler(void *regs)
++{
++ printf("+");
+ }
+
+-static void gpio_init(void)
++extern int arch_interrupt_init_early(void);
++int board_early_init_f(void)
+ {
+- /* Default setting of Y23 pad in AST2600 A1 is HBLED so disable it. */
+- writel(readl(SCU_PINMUX27) & ~SCU_PINMUX27_HBLED_EN,
+- SCU_PINMUX27);
+-
+- /*
+- * Set GPIOC3 as an output with value high explicitly since it doesn't
+- * have an external pull up. It uses direct register access because
+- * it's called from board_early_init_f().
+- */
+- writel(readl(SCU_PINMUX4) & ~SCU_PINMUX4_RGMII3TXD1,
+- SCU_PINMUX4);
+- writel(readl(GPIO_ABCD_DIR) | GPIO_ABCD_DIR_C3,
+- GPIO_ABCD_DIR);
+- writel(readl(GPIO_ABCD_VAL) | GPIO_ABCD_VAL_C3,
+- GPIO_ABCD_VAL);
+-
+- writel(readl(SCU_GPIO_PD0) | SCU_GPIO_PD0_B6, SCU_GPIO_PD0);
+-
+- /*
+- * GPIO C5 has a connection between BMC(3.3v) and CPU(1.0v) so if we
+- * set it as an logic high output, it will be clipped by a protection
+- * circuit in the CPU and eventually the signal will be detected as
+- * logic low. So we leave this GPIO as an input so that the signal
+- * can be pulled up by a CPU internal resister. The signal will be
+- * 1.0v logic high resultingy.
+- */
+- writel(readl(GPIO_ABCD_DIR) & ~GPIO_ABCD_DIR_C5,
+- GPIO_ABCD_DIR);
+-
+- /*
+- * Set GPIOD4 as an output with value low explicitly to set the
+- * default SPD mux path to CPU and DIMMs.
+- */
+- writel(readl(GPIO_ABCD_DIR) | GPIO_ABCD_DIR_D4,
+- GPIO_ABCD_DIR);
+- writel(readl(GPIO_ABCD_VAL) & ~GPIO_ABCD_VAL_D4,
+- GPIO_ABCD_VAL);
+-
+- /* GPIO G6 is also an open-drain output so set it as an input. */
+- writel(readl(GPIO_EFGH_DIR) & ~GPIO_EFGH_DIR_G6,
+- GPIO_EFGH_DIR);
++ /* This is called before relocation; beware! */
++ /* initialize running timer? timer_init is next in the list but
++ * I am not sure if it actually does anything... */
++ arch_interrupt_init_early();
++
++ gpio_passthru_init();
++
++ port80h_snoop_init();
++
++ sgpio_init();
++
++ /* TODO: is it too late to enforce HW security registers? */
++ return 0;
+ }
+
+-static void espi_init(void)
++extern void timer_enable(int n, uint32_t freq, interrupt_handler_t *handler);
++int board_early_init_r(void)
+ {
+- u32 reg;
+-
+- /*
+- * Aspeed STRONGLY NOT recommend to use eSPI early init.
+- *
+- * This eSPI early init sequence merely set OOB_FREE. It
+- * is NOT able to actually handle OOB requests from PCH.
+- *
+- * During the power on stage, PCH keep waiting OOB_FREE
+- * to continue its booting. In general, OOB_FREE is set
+- * when BMC firmware is ready. That is, the eSPI kernel
+- * driver is mounted and ready to serve eSPI. However,
+- * it means that PCH must wait until BMC kernel ready.
+- *
+- * For customers that request PCH booting as soon as
+- * possible. You may use this early init to set OOB_FREE
+- * to prevent PCH from blocking by OOB_FREE before BMC
+- * kernel ready.
+- *
+- * If you are not sure what you are doing, DO NOT use it.
+- */
+- reg = readl(ESPI_CTRL);
+- reg |= 0xef;
+- writel(reg, ESPI_CTRL);
+-
+- writel(0x0, ESPI_SYSEVT_INT_T0);
+- writel(0x0, ESPI_SYSEVT_INT_T1);
+-
+- reg = readl(ESPI_INT_EN);
+- reg |= 0x80000000;
+- writel(reg, ESPI_INT_EN);
+-
+- writel(0xffffffff, ESPI_SYSEVT_INT_EN);
+- writel(0x1, ESPI_SYSEVT1_INT_EN);
+- writel(0x1, ESPI_SYSEVT1_INT_T0);
+-
+- reg = readl(ESPI_CTRL2);
+- reg |= 0x50;
+- writel(reg, ESPI_CTRL2);
+-
+- reg = readl(ESPI_CTRL);
+- reg |= 0x10;
+- writel(reg, ESPI_CTRL);
++ debug("board_early_init_r\n");
++ /* timer_enable(0, 1, timer_handler); */
++
++ return 0;
+ }
+
+-int board_early_init_f(void)
++extern void espi_init(void);
++int board_late_init(void)
+ {
+- snoop_init();
+- gpio_init();
+- sgpio_init();
+ espi_init();
++
+ return 0;
+ }
++
++/* aspeed/board.c defines these functions
++int arch_early_init_r(void)
++{
++ return 0;
++}
++*/
++
++/*
++void board_init(void)
++{
++}
++*/
++
++#ifdef CONFIG_WATCHDOG
++/* watchdog stuff */
++void watchdog_init(void)
++{
++}
++
++void watchdog_reset(void)
++{
++}
++#endif
+diff --git a/cmd/Kconfig b/cmd/Kconfig
+index 1d2aa3a179a7..7599dd052df2 100644
+--- a/cmd/Kconfig
++++ b/cmd/Kconfig
+@@ -1888,7 +1888,7 @@ config CMD_DIAG
+
+ config CMD_IRQ
+ bool "irq - Show information about interrupts"
+- depends on !ARM && !MIPS && !SH
++ depends on !MIPS && !SH
+ help
+ This enables two commands:
+
+diff --git a/common/autoboot.c b/common/autoboot.c
+index 94133eaeda78..5e69000b848b 100644
+--- a/common/autoboot.c
++++ b/common/autoboot.c
+@@ -255,10 +255,20 @@ static int __abortboot(int bootdelay)
+ }
+ # endif /* CONFIG_AUTOBOOT_KEYED */
+
++int gpio_abort(void) __attribute__((weak));
++int gpio_abort(void)
++{
++ return 0;
++}
++
+ static int abortboot(int bootdelay)
+ {
+ int abort = 0;
+
++ abort = gpio_abort();
++ if (abort)
++ return abort;
++
+ if (bootdelay >= 0)
+ abort = __abortboot(bootdelay);
+
+diff --git a/configs/ast2600_openbmc_defconfig b/configs/ast2600_openbmc_defconfig
+index 179e3b005768..90735feec921 100644
+--- a/configs/ast2600_openbmc_defconfig
++++ b/configs/ast2600_openbmc_defconfig
+@@ -35,7 +35,7 @@ CONFIG_FIT=y
+ CONFIG_USE_BOOTARGS=y
+ CONFIG_BOOTARGS="console=ttyS4,115200n8 root=/dev/ram rw"
+ CONFIG_USE_BOOTCOMMAND=y
+-CONFIG_BOOTCOMMAND="bootm 20100000"
++CONFIG_BOOTCOMMAND="bootm 20080000"
+ CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y
+ CONFIG_DISPLAY_BOARDINFO_LATE=y
+ CONFIG_ARCH_EARLY_INIT_R=y
+--
+2.17.1
+