diff options
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.patch | 1358 |
1 files changed, 1358 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..7accd788c --- /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,1358 @@ +From a40cea99245e624e8fb2e39e26c7e76f1aee67fe 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: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Signed-off-by: Kuiying Wang <kuiying.wang@intel.com> +--- + arch/arm/dts/Makefile | 3 +- + arch/arm/dts/ast2600-intel.dts | 197 ++++++++++++++++ + arch/arm/lib/interrupts.c | 5 + + arch/arm/mach-aspeed/ast2600/Kconfig | 8 + + board/aspeed/ast2600_intel/Kconfig | 13 ++ + board/aspeed/ast2600_intel/Makefile | 4 + + board/aspeed/ast2600_intel/ast-espi.c | 298 ++++++++++++++++++++++++ + 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 | 185 +++++++++++++++ + cmd/Kconfig | 2 +- + common/autoboot.c | 10 + + 13 files changed, 1189 insertions(+), 2 deletions(-) + create mode 100644 arch/arm/dts/ast2600-intel.dts + create mode 100644 board/aspeed/ast2600_intel/Kconfig + create mode 100644 board/aspeed/ast2600_intel/Makefile + 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 + create mode 100644 board/aspeed/ast2600_intel/intel.c + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index e4dae2937968..da8903123999 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -683,7 +683,8 @@ dtb-$(CONFIG_ARCH_ASPEED) += \ + ast2600-fpga.dtb \ + ast2600-rainier.dtb \ + ast2600-slt.dtb \ +- ast2600-tacoma.dtb ++ ast2600-tacoma.dtb \ ++ ast2600-intel.dtb + + dtb-$(CONFIG_ARCH_STI) += stih410-b2260.dtb + +diff --git a/arch/arm/dts/ast2600-intel.dts b/arch/arm/dts/ast2600-intel.dts +new file mode 100644 +index 000000000000..9a15e204f83b +--- /dev/null ++++ b/arch/arm/dts/ast2600-intel.dts +@@ -0,0 +1,197 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++// Copyright (c) 2019-2020 Intel Corporation ++/dts-v1/; ++ ++#include "ast2600-u-boot.dtsi" ++ ++/ { ++ memory { ++ device_type = "memory"; ++ reg = <0x80000000 0x40000000>; ++ }; ++ ++ chosen { ++ stdout-path = &uart5; ++ }; ++ ++ aliases { ++ spi0 = &fmc; ++ ethernet1 = &mac1; ++ }; ++ ++ cpus { ++ cpu@0 { ++ clock-frequency = <800000000>; ++ }; ++ cpu@1 { ++ clock-frequency = <800000000>; ++ }; ++ }; ++ ++ 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 { ++ u-boot,dm-pre-reloc; ++ status = "okay"; ++}; ++ ++&sdrammc { ++ clock-frequency = <400000000>; ++}; ++ ++&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"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ethphy1: ethernet-phy@1 { ++ reg = <0>; ++ }; ++ ++ ethphy2: ethernet-phy@2 { ++ reg = <0>; ++ }; ++ ++ ethphy3: ethernet-phy@3 { ++ reg = <0>; ++ }; ++ ++ ethphy4: ethernet-phy@4 { ++ reg = <0>; ++ }; ++}; ++ ++&mac1 { ++ status = "okay"; ++ phy-mode = "rgmii"; ++ phy-handle = <ðphy2>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mac2link_default &pinctrl_mdio2_default>; ++}; ++ ++&fmc { ++ status = "okay"; ++#if 0 ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_fmcquad_default>; ++#endif ++ flash@0 { ++ compatible = "spi-flash", "sst,w25q256"; ++ status = "okay"; ++ spi-max-frequency = <40000000>; ++ spi-tx-bus-width = <2>; ++ spi-rx-bus-width = <2>; ++ }; ++}; ++ ++&emmc_slot0 { ++ status = "okay"; ++ bus-width = <4>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_emmc_default>; ++}; ++ ++&i2c4 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c5_default>; ++}; ++ ++&i2c5 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c6_default>; ++}; ++ ++&i2c6 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c7_default>; ++}; ++ ++&i2c7 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c8_default>; ++}; ++ ++&i2c8 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c9_default>; ++}; ++ ++&i2c9 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c10_default>; ++}; ++ ++&i2c12 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c13_default>; ++}; ++ ++&i2c13 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c14_default>; ++}; +\ No newline at end of file +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 dd991e87c795..7ccbb0b5e0ea 100644 +--- a/arch/arm/mach-aspeed/ast2600/Kconfig ++++ b/arch/arm/mach-aspeed/ast2600/Kconfig +@@ -51,6 +51,13 @@ config TARGET_SLT_AST2600 + help + SLT-AST2600 is Aspeed SLT board for AST2600 chip. + ++config TARGET_AST2600_INTEL ++ bool "AST2600-INTEL" ++ depends on ASPEED_AST2600 ++ help ++ AST2600-INTEL is an Intel server board with the AST2600 ++ as the BMC. ++ + endchoice + + source "board/aspeed/evb_ast2600a0/Kconfig" +@@ -59,5 +66,6 @@ source "board/aspeed/ncsi_ast2600a0/Kconfig" + source "board/aspeed/ncsi_ast2600a1/Kconfig" + source "board/aspeed/fpga_ast2600/Kconfig" + source "board/aspeed/slt_ast2600/Kconfig" ++source "board/aspeed/ast2600_intel/Kconfig" + + endif +diff --git a/board/aspeed/ast2600_intel/Kconfig b/board/aspeed/ast2600_intel/Kconfig +new file mode 100644 +index 000000000000..b841dab60c76 +--- /dev/null ++++ b/board/aspeed/ast2600_intel/Kconfig +@@ -0,0 +1,13 @@ ++if TARGET_AST2600_INTEL ++ ++config SYS_BOARD ++ default "ast2600_intel" ++ ++config SYS_VENDOR ++ default "aspeed" ++ ++config SYS_CONFIG_NAME ++ string "board configuration name" ++ default "ast2600_intel" ++ ++endif +diff --git a/board/aspeed/ast2600_intel/Makefile b/board/aspeed/ast2600_intel/Makefile +new file mode 100644 +index 000000000000..37d2f0064f38 +--- /dev/null ++++ b/board/aspeed/ast2600_intel/Makefile +@@ -0,0 +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..1852dd3d86e2 +--- /dev/null ++++ b/board/aspeed/ast2600_intel/ast-espi.c +@@ -0,0 +1,298 @@ ++/* ++ * 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 <asm/io.h> ++ ++#define AST_LPC_BASE 0x1e6e9000 ++#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 +new file mode 100644 +index 000000000000..03363b80b4f5 +--- /dev/null ++++ b/board/aspeed/ast2600_intel/intel.c +@@ -0,0 +1,185 @@ ++/* Intel customizations of Das U-Boot */ ++#include <common.h> ++#include <asm/gpio.h> ++#include <asm/io.h> ++ ++/* 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) ++{ ++ 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 */ ++ ++static void port80h_snoop_init(void) ++{ ++ uint32_t value; ++ /* enable port80h snoop and sgpio */ ++ /* set lpc snoop #0 to port 0x80 */ ++ value = readl(AST_LPC_BASE + SNPWADR) & 0xffff0000; ++ writel(value | LPC_SNOOP_ADDR, AST_LPC_BASE + SNPWADR); ++ ++ /* clear interrupt status */ ++ 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 */ ++ 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 */ ++ value = readl(AST_LPC_BASE + HICRB) | HICRB_EN80HSGIO; ++ 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) ++ ++ uint32_t value; ++ /* set the sgpio clock to pclk/(2*(5+1)) or ~2 MHz */ ++ value = SGPIO_CLK_DIV(256) | 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); ++} ++ ++void espi_init(void); ++int arch_interrupt_init_early(void); ++ ++static void timer_handler(void *regs) ++{ ++ printf("+"); ++} ++ ++void timer_enable(int n, uint32_t freq, interrupt_handler_t *handler); ++int board_early_init_f(void) ++{ ++ /* 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; ++} ++ ++int board_early_init_r(void) ++{ ++ debug("board_early_init_r\n"); ++ /* timer_enable(0, 1, timer_handler); */ ++ ++ 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 d5aa204290bd..89f6668b788e 100644 +--- a/cmd/Kconfig ++++ b/cmd/Kconfig +@@ -1876,7 +1876,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); + +-- +2.7.4 + |