summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-bsp
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-bsp')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0001-flash-use-readX-writeX-not-udelay.patch424
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0002-intel-layout-environment-addr.patch42
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0004-Make-sure-debug-uart-is-using-24MHz-clock-source.patch75
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-enable-passthrough-in-uboot.patch56
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0006-Add-Aspeed-g5-interrupt-support.patch389
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0007-Add-espi-support.patch330
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0008-add-sgio-support-for-port80-snoop-post-LEDs.patch160
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0009-Add-basic-GPIO-support.patch414
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0010-Update-Force-Firmware-Update-Jumper-to-use-new-gpio.patch98
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0011-Add-basic-timer-support-for-Aspeed-g5-in-U-Boot.patch160
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0012-Add-status-and-ID-LED-support.patch144
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0013-aspeed-Add-Pwm-Driver.patch132
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0014-Keep-interrupts-enabled-until-last-second.patch91
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0015-Rewrite-memmove-to-optimize-on-word-transfers.patch114
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch28
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch54
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch73
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0019-u-boot-full-platform-reset-espi-oob-ready.patch48
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch121
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Enable-PCIe-L1-support.patch38
-rwxr-xr-xmeta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0021-Config-host-uart-clock-source-using-environment-vari.patch108
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch620
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch35
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch52
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch339
-rw-r--r--meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend33
26 files changed, 4178 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0001-flash-use-readX-writeX-not-udelay.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0001-flash-use-readX-writeX-not-udelay.patch
new file mode 100644
index 000000000..73ab78a65
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0001-flash-use-readX-writeX-not-udelay.patch
@@ -0,0 +1,424 @@
+Index: u-boot/arch/arm/mach-aspeed/flash.c
+===================================================================
+--- u-boot.orig/arch/arm/mach-aspeed/flash.c
++++ u-boot/arch/arm/mach-aspeed/flash.c
+@@ -28,6 +28,7 @@
+ #include <common.h>
+ #include <asm/processor.h>
+ #include <asm/byteorder.h>
++#include <asm/io.h>
+ #include <environment.h>
+
+ #include <asm/arch/ast_scu.h>
+@@ -199,7 +200,7 @@ static void reset_flash (flash_info_t *
+ if (info->dualport)
+ ulCtrlData |= 0x08;
+ #endif
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ }
+
+@@ -228,28 +229,22 @@ static void enable_write (flash_info_t *
+
+ ulCtrlData = (info->tCK_Write << 8);
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x06);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x06, base);
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x05);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x05, base);
+ do {
+- jReg = *(volatile uchar *) (base);
++ jReg = readb(base);
+ } while (!(jReg & 0x02));
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ }
+
+@@ -280,30 +275,23 @@ static void write_status_register (flash
+
+ ulCtrlData = (info->tCK_Write << 8);
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x01);
+- udelay(10);
+- *(uchar *) (base) = (uchar) (data);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x01, base);
++ writeb(data, base);
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x05);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x05, base);
+ do {
+- jReg = *(volatile uchar *) (base);
++ jReg = readb(base);
+ } while (jReg & 0x01);
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+-
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+ }
+
+ static void enable4b (flash_info_t * info)
+@@ -330,13 +318,11 @@ static void enable4b (flash_info_t * inf
+
+ ulCtrlData = (info->tCK_Write << 8);
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0xb7);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0xb7, base);
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ } /* enable4b */
+
+@@ -366,29 +352,23 @@ static void enable4b_spansion (flash_inf
+ /* Enable 4B: BAR0 D[7] = 1 */
+ ulCtrlData = (info->tCK_Write << 8);
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x17);
+- udelay(10);
+- *(uchar *) (base) = (uchar) (0x80);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x17, base);
++ writeb(0x80, base);
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x16);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x16, base);
+ do {
+- jReg = *(volatile uchar *) (base);
++ jReg = readb(base);
+ } while (!(jReg & 0x80));
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ } /* enable4b_spansion */
+
+@@ -420,14 +400,11 @@ static void enable4b_numonyx (flash_info
+ /* Enable 4B: CMD:0xB7 */
+ ulCtrlData = (info->tCK_Write << 8);
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0xB7);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0xB7, base);
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ } /* enable4b_numonyx */
+
+@@ -463,63 +440,49 @@ static void flash_write_buffer (flash_in
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x02);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x02, base);
+ if (info->address32)
+ {
+- *(uchar *) (base) = (uchar) ((offset & 0xff000000) >> 24);
+- udelay(10);
++ writeb((uchar) ((offset & 0xff000000) >> 24), base);
+ }
+- *(uchar *) (base) = (uchar) ((offset & 0xff0000) >> 16);
+- udelay(10);
+- *(uchar *) (base) = (uchar) ((offset & 0x00ff00) >> 8);
+- udelay(10);
+- *(uchar *) (base) = (uchar) ((offset & 0x0000ff));
+- udelay(10);
++ writeb((uchar) ((offset & 0xff0000) >> 16), base);
++ writeb((uchar) ((offset & 0x00ff00) >> 8), base);
++ writeb((uchar) ((offset & 0x0000ff)), base);
+
+ for (j=0; j<len; j++)
+ {
+- *(uchar *) (base) = *(uchar *) (src++);
+- udelay(10);
++ writeb(*src++, base);
+ }
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x05);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x05, base);
+ do {
+- jReg = *(volatile uchar *) (base);
++ jReg = readb(base);
+ } while ((jReg & 0x01));
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ /* RFSR */
+ if (info->specificspi == SpecificSPI_N25Q512)
+ {
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x70);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x70, base);
+ do {
+- jReg = *(volatile uchar *) (base);
++ jReg = readb(base);
+ } while (!(jReg & 0x80));
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+ }
+ }
+
+@@ -603,57 +566,44 @@ int flash_erase (flash_info_t * info, in
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0xd8);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0xd8, base);
+ if (info->address32)
+ {
+- *(uchar *) (base) = (uchar) ((offset & 0xff000000) >> 24);
+- udelay(10);
++ writeb((uchar) ((offset & 0xff000000) >> 24), base);
+ }
+- *(uchar *) (base) = (uchar) ((offset & 0xff0000) >> 16);
+- udelay(10);
+- *(uchar *) (base) = (uchar) ((offset & 0x00ff00) >> 8);
+- udelay(10);
+- *(uchar *) (base) = (uchar) ((offset & 0x0000ff));
+- udelay(10);
++ writeb((uchar) ((offset & 0xff0000) >> 16), base);
++ writeb((uchar) ((offset & 0x00ff00) >> 8), base);
++ writeb((uchar) ((offset & 0x0000ff)), base);
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x05);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x05, base);
+ do {
+- jReg = *(volatile uchar *) (base);
++ jReg = readb(base);
+ } while ((jReg & 0x01));
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+
+ /* RFSR */
+ if (info->specificspi == SpecificSPI_N25Q512)
+ {
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (base) = (uchar) (0x70);
+- udelay(10);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x70, base);
+ do {
+- jReg = *(volatile uchar *) (base);
++ jReg = readb(base);
+ } while (!(jReg & 0x80));
+ ulCtrlData &= CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+ }
+
+ putc ('.');
+@@ -764,22 +714,16 @@ static ulong flash_get_size (ulong base,
+ }
+
+ /* Get Flash ID */
+- ulCtrlData = *(ulong *) (info->reg_base + CtrlOffset) & CMD_MASK;
++ ulCtrlData = readl(info->reg_base + CtrlOffset) & CMD_MASK;
+ ulCtrlData |= CE_LOW | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
+- *(uchar *) (vbase) = (uchar) (0x9F);
+- udelay(10);
+- ch[0] = *(volatile uchar *)(vbase);
+- udelay(10);
+- ch[1] = *(volatile uchar *)(vbase);
+- udelay(10);
+- ch[2] = *(volatile uchar *)(vbase);
+- udelay(10);
+- ulCtrlData = *(ulong *) (info->reg_base + CtrlOffset) & CMD_MASK;
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
++ writeb(0x9F, vbase);
++ ch[0] = readb(vbase);
++ ch[1] = readb(vbase);
++ ch[2] = readb(vbase);
++ ulCtrlData = readl(info->reg_base + CtrlOffset) & CMD_MASK;
+ ulCtrlData |= CE_HIGH | USERMODE;
+- *(ulong *) (info->reg_base + CtrlOffset) = ulCtrlData;
+- udelay(200);
++ writel(ulCtrlData, info->reg_base + CtrlOffset);
+ ulID = ((ulong)ch[0]) | ((ulong)ch[1] << 8) | ((ulong)ch[2] << 16) ;
+ info->flash_id = ulID;
+
+@@ -1294,13 +1238,13 @@ static ulong flash_get_size (ulong base,
+
+ if (info->address32) {
+ #ifndef AST_SOC_G5
+- reg = *((volatile ulong*) 0x1e6e2070); /* set H/W Trappings */
++ reg = readl(0x1e6e2070); /* set H/W Trappings */
+ reg |= 0x10;
+- *((volatile ulong*) 0x1e6e2070) = reg;
++ writel(reg, 0x1e6e2070);
+ #endif
+- reg = *((volatile ulong*) (info->reg_base + 0x4)); /* enable 32b control bit*/
++ reg = readl(info->reg_base + 0x4); /* enable 32b control bit*/
+ reg |= (0x01 << info->CE);
+- *((volatile ulong*) (info->reg_base + 0x4)) = reg;
++ writel(reg, info->reg_base + 0x4);
+
+ /* set flash chips to 32bits addressing mode */
+ if ((info->flash_id & 0xFF) == 0x01) /* Spansion */
+@@ -1322,7 +1266,7 @@ unsigned long flash_init (void)
+ unsigned long size = 0;
+ int i;
+
+- *((volatile ulong*) AST_FMC_BASE) |= 0x800f0000; /* enable Flash Write */
++ writel(readl(AST_FMC_BASE) | 0x800f0000, AST_FMC_BASE); /* enable Flash Write */
+
+ /* Init: FMC */
+ /* BANK 0 : FMC CS0 , 1: FMC CS1, */
+@@ -1352,7 +1296,7 @@ unsigned long flash_init (void)
+ #ifdef CONFIG_SPI0_CS
+ //pin switch by trap[13:12] -- [0:1] Enable SPI Master
+ ast_scu_spi_master(1); /* enable SPI master */
+- *((volatile ulong*) AST_FMC_SPI0_BASE) |= 0x10000; /* enable Flash Write */
++ writel(readl(AST_FMC_SPI0_BASE) | 0x10000, AST_FMC_SPI0_BASE); /* enable Flash Write */
+ flash_info[CONFIG_FMC_CS].sysspi = 1;
+ flash_info[CONFIG_FMC_CS].reg_base = AST_FMC_SPI0_BASE;
+ flash_info[CONFIG_FMC_CS].flash_id = FLASH_UNKNOWN;
+@@ -1403,21 +1347,24 @@ void memmove_dma(void * dest,const void
+ poll_time = 100; /* set 100 us as default */
+
+ /* force end of burst read */
+- *(volatile ulong *) (AST_FMC_BASE + CS0_CTRL) |= CE_HIGH;
+- *(volatile ulong *) (AST_FMC_BASE + CS0_CTRL) &= ~CE_HIGH;
+-
+- *(ulong *) (AST_FMC_BASE + REG_FLASH_DMA_CONTROL) = (ulong) (~FLASH_DMA_ENABLE);
+- *(ulong *) (AST_FMC_BASE + REG_FLASH_DMA_FLASH_BASE) = (ulong) (src);
+- *(ulong *) (AST_FMC_BASE + REG_FLASH_DMA_DRAM_BASE) = (ulong) (dest);
+- *(ulong *) (AST_FMC_BASE + REG_FLASH_DMA_LENGTH) = (ulong) (count_align);
+- *(ulong *) (AST_FMC_BASE + REG_FLASH_DMA_CONTROL) = (ulong) (FLASH_DMA_ENABLE);
++ data = readl(AST_FMC_BASE + CS0_CTRL);
++ writel(data | CE_HIGH, AST_FMC_BASE + CS0_CTRL);
++ writel(data & ~CE_HIGH, AST_FMC_BASE + CS0_CTRL);
++
++ writel(~FLASH_DMA_ENABLE, AST_FMC_BASE + REG_FLASH_DMA_CONTROL);
++ writel((ulong)src, AST_FMC_BASE + REG_FLASH_DMA_FLASH_BASE);
++ writel((ulong)dest, AST_FMC_BASE + REG_FLASH_DMA_DRAM_BASE);
++ writel(count_align, AST_FMC_BASE + REG_FLASH_DMA_LENGTH);
++ writel(FLASH_DMA_ENABLE, AST_FMC_BASE + REG_FLASH_DMA_CONTROL);
+
+ /* wait poll */
+ do {
+ udelay(poll_time);
+- data = *(ulong *) (AST_FMC_BASE + REG_FLASH_INTERRUPT_STATUS);
++ data = readl(AST_FMC_BASE + REG_FLASH_INTERRUPT_STATUS);
+ } while (!(data & FLASH_STATUS_DMA_READY));
+
+ /* clear status */
+- *(ulong *) (AST_FMC_BASE + REG_FLASH_INTERRUPT_STATUS) |= FLASH_STATUS_DMA_CLEAR;
++ data = readl(AST_FMC_BASE + REG_FLASH_INTERRUPT_STATUS);
++ writel(data | FLASH_STATUS_DMA_CLEAR,
++ AST_FMC_BASE + REG_FLASH_INTERRUPT_STATUS);
+ }
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0002-intel-layout-environment-addr.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0002-intel-layout-environment-addr.patch
new file mode 100644
index 000000000..86fa5b7d5
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0002-intel-layout-environment-addr.patch
@@ -0,0 +1,42 @@
+Index: u-boot/include/configs/ast-common.h
+===================================================================
+--- u-boot.orig/include/configs/ast-common.h
++++ u-boot/include/configs/ast-common.h
+@@ -103,10 +103,13 @@
+ #define CONFIG_SYS_MAX_FLASH_BANKS (CONFIG_FMC_CS)
+ #define CONFIG_SYS_MAX_FLASH_SECT (8192) /* max number of sectors on one chip */
+ #define CONFIG_ENV_IS_IN_FLASH 1
+-#define CONFIG_ENV_ADDR (AST_FMC_CS0_BASE + 0x60000)
++#define CONFIG_ENV_OFFSET 0x2400000 /* environment starts here */
++#define CONFIG_ENV_ADDR (AST_FMC_CS0_BASE + CONFIG_ENV_OFFSET)
++#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
+
+-#define CONFIG_ENV_OFFSET 0x60000 /* environment starts here */
+-#define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
++#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
++#define CONFIG_ENV_ADDR_REDUND (AST_FMC_CS0_BASE + CONFIG_ENV_OFFSET_REDUND)
++#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+
+ #define CONFIG_BOOTCOMMAND "bootm 20080000"
+ #define CONFIG_ENV_OVERWRITE
+Index: u-boot/common/board_r.c
+===================================================================
+--- u-boot.orig/common/board_r.c
++++ u-boot/common/board_r.c
+@@ -494,10 +494,14 @@ static int should_load_env(void)
+ static int initr_env(void)
+ {
+ /* initialize environment */
+- if (should_load_env())
++ if (should_load_env()) {
++ /* try again, in case the environment failed to load the first time */
++ if (!gd->env_valid)
++ env_init();
+ env_relocate();
+- else
++ } else {
+ set_default_env(NULL);
++ }
+ #ifdef CONFIG_OF_CONTROL
+ setenv_addr("fdtcontroladdr", gd->fdt_blob);
+ #endif
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0004-Make-sure-debug-uart-is-using-24MHz-clock-source.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0004-Make-sure-debug-uart-is-using-24MHz-clock-source.patch
new file mode 100644
index 000000000..8bc0a3ed3
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0004-Make-sure-debug-uart-is-using-24MHz-clock-source.patch
@@ -0,0 +1,75 @@
+From 2f0e14630abec2c9679d21901072648c7802f2c4 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Tue, 11 Sep 2018 16:24:06 +0800
+Subject: [PATCH] Make sure debug uart is using 24MHz clock source
+
+u-boot defines the uart5(debug console) as 24MHz,
+set the SCU14[28] to 0, to make sure the clock source is 24M
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ arch/arm/include/asm/arch-aspeed/ast_scu.h | 2 ++
+ arch/arm/include/asm/arch-aspeed/platform.h | 1 +
+ arch/arm/mach-aspeed/ast-scu.c | 6 ++++++
+ board/aspeed/ast-g5/ast-g5.c | 8 ++++++++
+ 4 files changed, 17 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h
+index d248416..98e6335 100644
+--- a/arch/arm/include/asm/arch-aspeed/ast_scu.h
++++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h
+@@ -45,4 +45,6 @@ extern void ast_scu_init_eth(u8 num);
+ extern void ast_scu_multi_func_eth(u8 num);
+ extern void ast_scu_multi_func_romcs(u8 num);
+
++void ast_config_uart5_clk(void);
++
+ #endif
+diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h
+index c9c7a81..a423052 100644
+--- a/arch/arm/include/asm/arch-aspeed/platform.h
++++ b/arch/arm/include/asm/arch-aspeed/platform.h
+@@ -27,6 +27,7 @@
+ #include <asm/arch/ast2400_platform.h>
+ #elif defined(AST_SOC_G5)
+ #include <asm/arch/ast_g5_platform.h>
++#define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */
+ #else
+ #err "No define for platform.h"
+ #endif
+diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
+index 0cc0d67..902263b 100644
+--- a/arch/arm/mach-aspeed/ast-scu.c
++++ b/arch/arm/mach-aspeed/ast-scu.c
+@@ -496,3 +496,9 @@ void ast_scu_get_who_init_dram(void)
+ break;
+ }
+ }
++
++void ast_config_uart5_clk(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) &
++ ~(1 << 28), AST_SCU_MISC2_CTRL);
++}
+diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
+index e67a4bf..5a1fade 100644
+--- a/board/aspeed/ast-g5/ast-g5.c
++++ b/board/aspeed/ast-g5/ast-g5.c
+@@ -16,6 +16,14 @@
+
+ DECLARE_GLOBAL_DATA_PTR;
+
++int board_early_init_f(void)
++{
++ /* make sure uart5 is using 24MHz clock */
++ ast_config_uart5_clk();
++
++ return 0;
++}
++
+ int board_init(void)
+ {
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-enable-passthrough-in-uboot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-enable-passthrough-in-uboot.patch
new file mode 100644
index 000000000..0385a5e31
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0005-enable-passthrough-in-uboot.patch
@@ -0,0 +1,56 @@
+From b344cf4462acb1f043ed903ccee713e24ce7226d Mon Sep 17 00:00:00 2001
+From: Kuiying Wang <kuiying.wang@intel.com>
+Date: Wed, 7 Nov 2018 13:57:57 +0800
+Subject: [PATCH 1/1] enable passthrough in uboot
+
+---
+ arch/arm/mach-aspeed/ast-scu.c | 22 ++++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5.c | 2 ++
+ 2 files changed, 24 insertions(+)
+
+diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
+index 902263b28b..c83931ed54 100644
+--- a/arch/arm/mach-aspeed/ast-scu.c
++++ b/arch/arm/mach-aspeed/ast-scu.c
+@@ -502,3 +502,25 @@ void ast_config_uart5_clk(void)
+ ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) &
+ ~(1 << 28), AST_SCU_MISC2_CTRL);
+ }
++
++
++void ast_enable_pass_through(void)
++{
++ //Enable GPIOE pin mode, SCU80[16:23] = 00 */
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL1) & (~0x00FF0000),
++ AST_SCU_FUN_PIN_CTRL1);
++
++ //Enable all pass through pins by setting SCU8C[15:12] = 0x3.
++ //Pass-through pins set:
++ //GPIOE0 -> GPIOE1
++ //GPIOE2 -> GPIOE3
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL4) | (0x3000),
++ AST_SCU_FUN_PIN_CTRL4);
++
++ //Disable HWStrap for GPIOE pass-through mode
++ //The write operation to SCU70(0x1e6e2070) only can set to '1'.
++ //To clear to '0', it must write '1' to 0x1e6e207c
++ if (ast_scu_read(AST_SCU_HW_STRAP1) & (0x1 << 22)){
++ ast_scu_write((0x1 << 22), AST_SCU_REVISION_ID);
++ }
++}
+diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
+index 5a1fadeedd..b492003f51 100644
+--- a/board/aspeed/ast-g5/ast-g5.c
++++ b/board/aspeed/ast-g5/ast-g5.c
+@@ -20,6 +20,8 @@ int board_early_init_f(void)
+ {
+ /* make sure uart5 is using 24MHz clock */
+ ast_config_uart5_clk();
++ /*enable pass through*/
++ ast_enable_pass_through();
+
+ return 0;
+ }
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0006-Add-Aspeed-g5-interrupt-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0006-Add-Aspeed-g5-interrupt-support.patch
new file mode 100644
index 000000000..dbaf7b362
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0006-Add-Aspeed-g5-interrupt-support.patch
@@ -0,0 +1,389 @@
+From f33755167ddcdebbf56bc875e4091990273c6997 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Wed, 14 Nov 2018 10:21:40 -0800
+Subject: [PATCH 1/7] Add Aspeed g5 interrupt support
+
+This adds a few new files to the board g5 directory. Several Intel
+features require interrupts running in U-Boot, so this adds basic
+interrupt registration and handling support.
+
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+Change-Id: Id7072f1408dcf364968b1b74f2192e50a22a82f0
+---
+ Kconfig | 13 ++
+ arch/arm/lib/interrupts.c | 11 ++
+ board/aspeed/ast-g5/Makefile | 4 +-
+ board/aspeed/ast-g5/ast-g5-irq.c | 176 ++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5-irq.h | 39 ++++++
+ board/aspeed/ast-g5/ast-g5.c | 3 +
+ board/aspeed/ast-g5/ast-g5.h | 7 ++
+ cmd/Kconfig | 5 +
+ configs/ast_g5_ncsi_2boot_defconfig | 1 +
+ configs/ast_g5_ncsi_defconfig | 1 +
+ configs/ast_g5_phy_defconfig | 1 +
+ 11 files changed, 260 insertions(+), 1 deletion(-)
+ create mode 100644 board/aspeed/ast-g5/ast-g5-irq.c
+ create mode 100644 board/aspeed/ast-g5/ast-g5-irq.h
+ create mode 100644 board/aspeed/ast-g5/ast-g5.h
+
+diff --git a/Kconfig b/Kconfig
+index 3ceff25032..d6439d01ca 100644
+--- a/Kconfig
++++ b/Kconfig
+@@ -115,6 +115,19 @@ if EXPERT
+ When disabling this, please check if malloc calls, maybe
+ should be replaced by calloc - if one expects zeroed memory.
+ endif
++
++config USE_IRQ
++ bool "Use interrupts"
++ default n
++
++config STACKSIZE_IRQ
++ int "Size for IRQ stack (only if USE_IRQ enabled)"
++ default 16384
++
++config STACKSIZE_FIQ
++ int "Size for FIQ stack (only if USE_IRQ enabled)"
++ default 16384
++
+ endmenu # General setup
+
+ menu "Boot images"
+diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
+index ed83043abb..a96b3aa070 100644
+--- a/arch/arm/lib/interrupts.c
++++ b/arch/arm/lib/interrupts.c
+@@ -94,6 +94,17 @@ int disable_interrupts (void)
+ : "memory");
+ return (old & 0x80) == 0;
+ }
++
++int global_interrupts_enabled(void)
++{
++ unsigned long old;
++ __asm__ __volatile__("mrs %0, cpsr\n"
++ : "=r" (old)
++ :
++ : "memory");
++ return (old & 0x80) == 0;
++}
++
+ #else
+ int interrupt_init (void)
+ {
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index d1d7f8525e..d41b11589f 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -1 +1,2 @@
+-obj-y = ast-g5.o
++obj-y += ast-g5.o
++obj-y += ast-g5-irq.o
+diff --git a/board/aspeed/ast-g5/ast-g5-irq.c b/board/aspeed/ast-g5/ast-g5-irq.c
+new file mode 100644
+index 0000000000..860f16cf05
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-irq.c
+@@ -0,0 +1,176 @@
++/*
++ * 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/arch/ast_scu.h>
++#include <asm/arch/ast-sdmc.h>
++#include <asm/io.h>
++
++#include "ast-g5.h"
++#include "ast-g5-irq.h"
++
++DECLARE_GLOBAL_DATA_PTR;
++
++#ifdef CONFIG_USE_IRQ
++
++#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)
++
++int arch_interrupt_init_early(void)
++{
++ writel(VIC_CLEAR_ALL, AST_VIC_BASE + VIC_ENABLE_CLEAR_L);
++ writel(VIC_CLEAR_ALL, AST_VIC_BASE + VIC_ENABLE_CLEAR_H);
++ return 0;
++}
++int arch_interrupt_init(void)
++{
++ return 0;
++}
++
++#define AST_IRQ_START_L 0
++#define AST_IRQ_END_L 31
++#define AST_IRQ_START_H 32
++#define AST_IRQ_END_H 63
++#define AST_IRQ_COUNT 64
++static interrupt_handler_t *handlers[AST_IRQ_COUNT] = {NULL};
++static unsigned long irq_total = 0;
++static unsigned long irq_counts[AST_IRQ_COUNT] = {0};
++
++int request_irq(int irq, interrupt_handler_t *handler)
++{
++ if (irq < AST_IRQ_START_L || irq > AST_IRQ_END_H) {
++ printf("irq %d out of range\n", irq);
++ return -1;
++ }
++ if (handlers[irq]) {
++ printf("irq %d already in use (%p)\n", irq, handlers[irq]);
++ return -1;
++ }
++ handlers[irq] = handler;
++ if (irq < AST_IRQ_START_H) {
++ writel((1 << irq), AST_VIC_BASE + VIC_ENABLE_L);
++ } else {
++ writel((1 << (irq - AST_IRQ_START_H)),
++ AST_VIC_BASE + VIC_ENABLE_H);
++ }
++ return 0;
++}
++
++int release_irq(int irq)
++{
++ if (irq < AST_IRQ_START_L || irq > AST_IRQ_END_H) {
++ return -1;
++ }
++ if (handlers[irq]) {
++ handlers[irq] = NULL;
++ if (irq < AST_IRQ_START_H) {
++ writel((1 << irq), AST_VIC_BASE + VIC_ENABLE_CLEAR_L);
++ } else {
++ writel((1 << (irq - AST_IRQ_START_H)),
++ AST_VIC_BASE + VIC_ENABLE_CLEAR_H);
++ }
++ }
++ return 0;
++}
++
++extern int global_interrupts_enabled(void);
++int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
++{
++ int i;
++ int enabled = global_interrupts_enabled();
++ unsigned long long irqs_enabled =
++ ((unsigned long long)readl(AST_VIC_BASE + VIC_ENABLE_H))
++ << AST_IRQ_START_H
++ | readl(AST_VIC_BASE + VIC_ENABLE_L);
++ printf("interrupts %sabled\n", (enabled ? "en" : "dis"));
++ for (i = AST_IRQ_START_L; i < AST_IRQ_COUNT; i++) {
++ printf("% 2i (% 3s): %lu\n", i,
++ ((irqs_enabled & 1) ? "on" : "off"), irq_counts[i]);
++ irqs_enabled >>= 1;
++ }
++ printf("total: %lu\n", irq_total);
++ return 0;
++}
++
++void do_irq(struct pt_regs *pt_regs)
++{
++ uint32_t irq = readl(AST_VIC_BASE + VIC_STATUS_L);
++ int i;
++ irq_total++;
++ if (irq) {
++ // handler irq0-31
++ for (i = AST_IRQ_START_L; i <= AST_IRQ_END_L; i++) {
++ if (irq & (1 << i)) {
++ irq_counts[i]++;
++ /* mask */
++ writel((1 << i),
++ AST_VIC_BASE + VIC_ENABLE_CLEAR_L);
++ if (handlers[i]) {
++ handlers[i](pt_regs);
++ /* clear */
++ writel((1 << i),
++ AST_VIC_BASE
++ + VIC_INTERRUPT_CLEAR_L);
++ /* unmask */
++ writel((1 << i),
++ AST_VIC_BASE + VIC_ENABLE_L);
++ } else {
++ printf("unexpected interrupt %i; masking\n",
++ i);
++ /* clear; do not unmask */
++ writel((1 << i),
++ AST_VIC_BASE
++ + VIC_INTERRUPT_CLEAR_L);
++ }
++ }
++ }
++ }
++ irq = readl(AST_VIC_BASE + VIC_STATUS_H);
++ if (irq) {
++ // handler irq32-63
++ for (i = AST_IRQ_START_H; i <= AST_IRQ_END_H; i++) {
++ if (irq & (1 << (i - AST_IRQ_START_H))) {
++ irq_counts[i]++;
++ /* mask */
++ writel((1 << (i - AST_IRQ_START_H)),
++ AST_VIC_BASE + VIC_ENABLE_CLEAR_H);
++ if (handlers[i]) {
++ handlers[i](pt_regs);
++ /* clear */
++ writel((1 << (i - AST_IRQ_START_H)),
++ AST_VIC_BASE
++ + VIC_INTERRUPT_CLEAR_H);
++ /* unmask */
++ writel((1 << (i - AST_IRQ_START_H)),
++ AST_VIC_BASE + VIC_ENABLE_H);
++ } else {
++ printf("unexpected interrupt %i; masking\n",
++ i);
++ /* clear; do not unmask */
++ writel((1 << (i - AST_IRQ_START_H)),
++ AST_VIC_BASE
++ + VIC_INTERRUPT_CLEAR_H);
++ }
++ }
++ }
++ }
++}
++#endif
+diff --git a/board/aspeed/ast-g5/ast-g5-irq.h b/board/aspeed/ast-g5/ast-g5-irq.h
+new file mode 100644
+index 0000000000..703eeabf13
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-irq.h
+@@ -0,0 +1,39 @@
++/*
++ * 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.
++ */
++
++#ifndef __AST_G5_IRQ_H__
++#define __AST_G5_IRQ_H__
++
++#include <common.h>
++
++#ifdef CONFIG_USE_IRQ
++
++int arch_interrupt_init_early(void);
++
++int request_irq(int irq, interrupt_handler_t *handler);
++
++int release_irq(int irq);
++
++#else /* CONFIG_USE_IRQ */
++
++int arch_interrupt_init_early(void) {
++ return 0;
++}
++
++int request_irq(int irq, interrupt_handler_t *handler) {
++ return -1;
++}
++
++int release_irq(int irq) {
++ return -1;
++}
++
++#endif /* CONFIG_USE_IRQ */
++
++#endif /* __AST_G5_IRQ_H__ */
+diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
+index b492003f51..2472aa3603 100644
+--- a/board/aspeed/ast-g5/ast-g5.c
++++ b/board/aspeed/ast-g5/ast-g5.c
+@@ -14,6 +14,8 @@
+ #include <asm/arch/ast-sdmc.h>
+ #include <asm/io.h>
+
++#include "ast-g5.h"
++
+ DECLARE_GLOBAL_DATA_PTR;
+
+ int board_early_init_f(void)
+@@ -22,6 +24,7 @@ int board_early_init_f(void)
+ ast_config_uart5_clk();
+ /*enable pass through*/
+ ast_enable_pass_through();
++ arch_interrupt_init_early();
+
+ return 0;
+ }
+diff --git a/board/aspeed/ast-g5/ast-g5.h b/board/aspeed/ast-g5/ast-g5.h
+new file mode 100644
+index 0000000000..9fd10eccb3
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5.h
+@@ -0,0 +1,7 @@
++#ifndef _AST_G5_H_
++#define _AST_G5_H_
++
++#include <common.h>
++#include "ast-g5-irq.h"
++
++#endif /* _AST_G5_H_ */
+diff --git a/cmd/Kconfig b/cmd/Kconfig
+index d69b817c82..33be2407d2 100644
+--- a/cmd/Kconfig
++++ b/cmd/Kconfig
+@@ -313,6 +313,11 @@ endmenu
+
+ menu "Device access commands"
+
++config CMD_IRQ
++ bool "interrupts - enable/disable interrupts"
++ depends on USE_IRQ
++ default y
++
+ config CMD_DM
+ bool "dm - Access to driver model information"
+ depends on DM
+diff --git a/configs/ast_g5_ncsi_2boot_defconfig b/configs/ast_g5_ncsi_2boot_defconfig
+index 2d28c86966..d5b7894a9e 100644
+--- a/configs/ast_g5_ncsi_2boot_defconfig
++++ b/configs/ast_g5_ncsi_2boot_defconfig
+@@ -33,3 +33,4 @@ CONFIG_CMD_CRC32=y
+ CONFIG_LOOPW=y
+ CONFIG_CMD_MEMTEST=y
+ CONFIG_CMD_MX_CYCLIC=y
++CONFIG_USE_IRQ=y
+diff --git a/configs/ast_g5_ncsi_defconfig b/configs/ast_g5_ncsi_defconfig
+index 74029ed514..9481e5fb6e 100644
+--- a/configs/ast_g5_ncsi_defconfig
++++ b/configs/ast_g5_ncsi_defconfig
+@@ -11,3 +11,4 @@ CONFIG_HUSH_PARSER=y
+ CONFIG_OF_LIBFDT=y
+ CONFIG_SPI_FLASH=y
+ CONFIG_SYS_NS16550=y
++CONFIG_USE_IRQ=y
+diff --git a/configs/ast_g5_phy_defconfig b/configs/ast_g5_phy_defconfig
+index 767f3af605..4aefcf49e8 100644
+--- a/configs/ast_g5_phy_defconfig
++++ b/configs/ast_g5_phy_defconfig
+@@ -12,3 +12,4 @@ CONFIG_HUSH_PARSER=y
+ CONFIG_OF_LIBFDT=y
+ CONFIG_SPI_FLASH=y
+ CONFIG_SYS_NS16550=y
++CONFIG_USE_IRQ=y
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0007-Add-espi-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0007-Add-espi-support.patch
new file mode 100644
index 000000000..18cc2f9c8
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0007-Add-espi-support.patch
@@ -0,0 +1,330 @@
+From 7ad0ea13337550f35c1e726f21d4751bf74078d6 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Wed, 14 Nov 2018 10:21:40 -0800
+Subject: [PATCH 2/7] Add espi support
+
+This adds basic eSPI support for U-Boot. The eSPI driver works best with
+interrupts because the timing of the initialization with the PCH is not
+trivial.
+
+The espi driver is currently just a bare-minimum driver allowing the
+host to boot. In the future it may be expanded to have further
+functions.
+
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+Change-Id: Id7072f1408dcf364968b1b74f2192e50a22a82f0
+---
+ arch/arm/include/asm/arch-aspeed/regs-scu.h | 2 +
+ board/aspeed/ast-g5/Makefile | 1 +
+ board/aspeed/ast-g5/ast-g5-espi.c | 231 ++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5-intel.c | 16 ++
+ board/aspeed/ast-g5/ast-g5.c | 3 +
+ 5 files changed, 253 insertions(+)
+ create mode 100644 board/aspeed/ast-g5/ast-g5-espi.c
+ create mode 100644 board/aspeed/ast-g5/ast-g5-intel.c
+
+diff --git a/arch/arm/include/asm/arch-aspeed/regs-scu.h b/arch/arm/include/asm/arch-aspeed/regs-scu.h
+index b714fa9234..10b983a966 100644
+--- a/arch/arm/include/asm/arch-aspeed/regs-scu.h
++++ b/arch/arm/include/asm/arch-aspeed/regs-scu.h
+@@ -552,6 +552,8 @@
+
+ #define CLK_25M_IN (0x1 << 23)
+
++#define SCU_HW_STRAP_FAST_RESET (1 << 27)
++#define SCU_HW_STRAP_ESPI_ENABLED (1 << 25)
+ #define SCU_HW_STRAP_2ND_BOOT_WDT (0x1 << 17)
+ #define SCU_HW_STRAP_SUPER_IO_CONFIG (0x1 << 16)
+ #define SCU_HW_STRAP_VGA_CLASS_CODE (0x1 << 15)
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index d41b11589f..58e0c648f4 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -1,2 +1,4 @@
+ obj-y += ast-g5.o
++obj-y += ast-g5-intel.o
++obj-y += ast-g5-espi.o
+ obj-y += ast-g5-irq.o
+diff --git a/board/aspeed/ast-g5/ast-g5-espi.c b/board/aspeed/ast-g5/ast-g5-espi.c
+new file mode 100644
+index 0000000000..79ef253b86
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-espi.c
+@@ -0,0 +1,231 @@
++/*
++ * 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>
++#include <asm/arch/regs-scu.h>
++#include <asm/arch/ast_scu.h>
++#include <asm/arch/aspeed.h>
++
++#include "ast-g5.h"
++
++#define DEBUG_ESPI_ENABLED 1
++#ifdef DEBUG_ESPI_ENABLED
++#define DBG_ESPI debug
++#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 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 (1 << 4)
++#define AST_ESPI_FLASH_SW_CHRDY (0x1 << 7)
++#define AST_ESPI_FLASH_SW_READ (0x1 << 10)
++
++/* ESPI00C bits (Interrupt Enable) */
++#define AST_ESPI_IEN_SYS_EV (1 << 8)
++#define AST_ESPI_IEN_GPIO_EV (1 << 9)
++
++/* ESPI008 bits ISR */
++#define AST_ESPI_VW_SYS_EVT (1 << 8)
++#define AST_ESPI_VW_SYS_EV1 (1 << 22)
++
++/* ESPI098 and ESPI11C bits */
++#define AST_ESPI_OOB_RST_WARN (1 << 6)
++#define AST_ESPI_HOST_RST_WARN (1 << 8)
++#define AST_ESPI_OOB_RST_ACK (1 << 16)
++#define AST_ESPI_SL_BT_DONE (1 << 20)
++#define AST_ESPI_SL_BT_STATUS (1 << 23)
++#define AST_ESPI_HOST_RST_ACK (1 << 27)
++
++/* ESPI104 bits */
++#define AST_ESPI_SUS_WARN (1 << 0)
++#define AST_ESPI_SUS_ACK (1 << 20)
++
++/* LPC chip ID */
++#define SCR0SIO 0x170
++#define IRQ_SRC_ESPI 23 /* IRQ 23 */
++
++static int espi_irq_handler(struct pt_regs *regs)
++{
++ uint32_t irq_status = readl(AST_ESPI_BASE + ESPI008);
++
++ DBG_ESPI("ISR irq_status : 0x%08X\n", 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 ev: %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);
++ }
++ }
++ if (sys_status & AST_ESPI_OOB_RST_WARN) {
++ DBG_ESPI("OOB_RST_WARN ev: %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);
++ }
++ }
++ 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 ev: %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);
++ }
++ }
++ writel(sys1_status, AST_ESPI_BASE + ESPI12C); // clear status
++ }
++ writel(irq_status, AST_ESPI_BASE + ESPI008); // clear irq_status
++ return 0;
++}
++
++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);
++ }
++
++ if (readl(AST_ESPI_BASE + ESPI104) & AST_ESPI_SUS_WARN) {
++ DBG_ESPI("Boot SUS WARN set %08x\n",
++ readl(AST_ESPI_BASE + ESPI104));
++ uint32_t v = readl(AST_ESPI_BASE + ESPI104) | AST_ESPI_SUS_ACK;
++ writel(v, AST_ESPI_BASE + ESPI104);
++ }
++}
++
++void espi_init(void)
++{
++ if (readl(AST_SCU_BASE + AST_SCU_HW_STRAP1)
++ & SCU_HW_STRAP_ESPI_ENABLED) {
++ uint32_t v;
++ DBG_ESPI("espi_init\n");
++
++ /* 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);
++
++ v = readl(AST_ESPI_BASE + ESPI000) | AST_ESPI_OOB_CHRDY;
++ writel(v, AST_ESPI_BASE + ESPI000);
++
++ 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_BASE + ESPI118);
++ writel(AST_ESPI_HOST_RST_WARN | AST_ESPI_OOB_RST_WARN,
++ 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_SYS_EV,
++ AST_ESPI_BASE + ESPI00C); // Enable only sys events
++
++ espi_handshake_ack();
++
++ request_irq(IRQ_SRC_ESPI, espi_irq_handler);
++ } else {
++ DBG_ESPI("No espi strap\n");
++ }
++}
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+new file mode 100644
+index 0000000000..e79235c8d0
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -0,0 +1,16 @@
++/*
++ * 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>
++
++extern void espi_init(void);
++void ast_g5_intel(void)
++{
++ espi_init();
++}
+diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
+index 2472aa3603..d41ef9cbd3 100644
+--- a/board/aspeed/ast-g5/ast-g5.c
++++ b/board/aspeed/ast-g5/ast-g5.c
+@@ -18,6 +18,8 @@
+
+ DECLARE_GLOBAL_DATA_PTR;
+
++extern void ast_g5_intel(void);
++
+ int board_early_init_f(void)
+ {
+ /* make sure uart5 is using 24MHz clock */
+@@ -34,6 +36,7 @@ int board_init(void)
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+ gd->flags = 0;
+
++ ast_g5_intel();
+ return 0;
+ }
+
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0008-add-sgio-support-for-port80-snoop-post-LEDs.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0008-add-sgio-support-for-port80-snoop-post-LEDs.patch
new file mode 100644
index 000000000..cb61bd545
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0008-add-sgio-support-for-port80-snoop-post-LEDs.patch
@@ -0,0 +1,160 @@
+From cf43453a75880cf53ea7bbf5859706f2a7cae292 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Wed, 14 Nov 2018 12:09:52 -0800
+Subject: [PATCH 3/7] add sgio support for port80 snoop post LEDs
+
+This ties together the port 80 snooping to the SGPIO output that
+ultimately drives the POST code LEDs.
+
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+Change-Id: Iaa1b91cd40f4b6323dba0598da373cb631459e66
+---
+ arch/arm/include/asm/arch-aspeed/ast_scu.h | 1 +
+ arch/arm/mach-aspeed/ast-scu.c | 8 ++
+ board/aspeed/ast-g5/ast-g5-intel.c | 96 ++++++++++++++++++++++
+ 3 files changed, 105 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h
+index 98e63351f1..c10e6a9d4b 100644
+--- a/arch/arm/include/asm/arch-aspeed/ast_scu.h
++++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h
+@@ -44,6 +44,7 @@ extern u32 ast_scu_get_vga_memsize(void);
+ extern void ast_scu_init_eth(u8 num);
+ extern void ast_scu_multi_func_eth(u8 num);
+ extern void ast_scu_multi_func_romcs(u8 num);
++extern void ast_scu_multi_func_sgpio(void);
+
+ void ast_config_uart5_clk(void);
+
+diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
+index c83931ed54..63e9c7c167 100644
+--- a/arch/arm/mach-aspeed/ast-scu.c
++++ b/arch/arm/mach-aspeed/ast-scu.c
+@@ -407,6 +407,14 @@ void ast_scu_multi_func_romcs(u8 num)
+ SCU_FUN_PIN_ROMCS(num), AST_SCU_FUN_PIN_CTRL3);
+ }
+
++void ast_scu_multi_func_sgpio(void)
++{
++ ast_scu_write(ast_scu_read(AST_SCU_FUN_PIN_CTRL2) |
++ SCU_FUN_PIN_SGPMI | SCU_FUN_PIN_SGPMO |
++ SCU_FUN_PIN_SGPMLD | SCU_FUN_PIN_SGPMCK,
++ AST_SCU_FUN_PIN_CTRL2);
++}
++
+ u32 ast_scu_revision_id(void)
+ {
+ int i;
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index e79235c8d0..fca4d91115 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -8,9 +8,105 @@
+ */
+
+ #include <common.h>
++#include <asm/io.h>
++#include <asm/arch/regs-scu.h>
++#include <asm/arch/ast_scu.h>
++#include <asm/arch/aspeed.h>
++
++#include "ast-g5.h"
++
++#define LPC_SNOOP_ADDR 0x80
++#define HICR5 0x080 /* Host Interface Control Register 5 */
++#define HICR6 0x084 /* Host Interface Control Register 6 */
++#define HICR7 0x088 /* Host Interface Control Register 7 */
++#define HICR8 0x08c /* Host Interface Control Register 8 */
++#define SNPWADR 0x090 /* LPC Snoop Address Register */
++#define SNPWDR 0x094 /* LPC Snoop Data Register */
++#define HICR9 0x098 /* Host Interface Control Register 9 */
++#define HICRA 0x09c /* Host Interface Control Register A */
++#define LHCR0 0x0a0 /* LPC Host Control Register 0 */
++#define LHCR1 0x0a4 /* LPC Host Control Register 1 */
++#define LHCR2 0x0a8 /* LPC Host Control Register 2 */
++#define LHCR3 0x0ac /* LPC Host Control Register 3 */
++#define LHCR4 0x0b0 /* LPC Host Control Register 4 */
++#define LHCR5 0x0b4 /* LPC Host Control Register 5 */
++#define LHCR6 0x0b8 /* LPC Host Control Register 6 */
++#define LHCR7 0x0bc /* LPC Host Control Register 7 */
++#define LHCR8 0x0c0 /* LPC Host Control Register 8 */
++#define PCCR6 0x0c4 /* Post Code Control Register 6 */
++#define LHCRA 0x0c8 /* LPC Host Control Register A */
++#define LHCRB 0x0cc /* LPC Host Control Register B */
++#define PCCR4 0x0d0 /* Post Code Control Register 4 */
++#define PCCR5 0x0d4 /* Post Code Control Register 5 */
++#define HICRB 0x100 /* Host Interface Control Register B */
++#define HICRC 0x104 /* Host Interface Control Register C */
++/* 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 SGPIO_CLK_DIV(N) ((N) << 16)
++#define SGPIO_BYTES(N) ((N) << 6)
++#define SGPIO_ENABLE 1
++#define GPIO254 0x254
++
++static void sgpio_init(void)
++{
++ uint32_t value;
++ /*
++ 33.4.2
++ LPC port80h direct to SGPIO
++ In AST2500 SGPIO, it supports output data from 80h. It always uses SGPIOA.
++ 1. Configure LPC snoop function.
++ (a) Set SNPWADR(0x1e789090)[15:0] to 0x80.
++ (b) Set HICR5(0x1e789080)[0] to 1 to enable snoop.
++ 2. Configure SGPIO
++ (a) Set GPIO254[9:6] to larger than or equal to 0x1.
++ (b) Set GPIO254[0] to 1 to enable SGPIO.
++ 3. Set SuperIO
++ (a) Set SIOR7 30h to 0x40.
++ */
++ /* make sure multi-pin stuff goes in our favor */
++ ast_scu_multi_func_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 | HICR5_ENINT_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);
++
++ /* set the gpio clock to pclk/(2*(5+1)) or ~2 MHz */
++ value = SGPIO_CLK_DIV(256) | SGPIO_BYTES(10) | SGPIO_ENABLE;
++ writel(value, AST_GPIO_BASE + GPIO254);
++}
+
+ extern void espi_init(void);
+ void ast_g5_intel(void)
+ {
+ espi_init();
++ sgpio_init();
+ }
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0009-Add-basic-GPIO-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0009-Add-basic-GPIO-support.patch
new file mode 100644
index 000000000..a49f196ac
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0009-Add-basic-GPIO-support.patch
@@ -0,0 +1,414 @@
+From 89728d8c255204c8d9ec46a1dc0d412b04708f22 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Fri, 16 Nov 2018 09:58:01 -0800
+Subject: [PATCH 4/7] Add basic GPIO support
+
+Add a table of well-known gpios (such as FP LEDs and FF UPD jumper) and
+initialize them at boot.
+
+Add a mechanism to get/set well known gpios from command line.
+
+Change-Id: I4136a5ccb048b3604f13b17ea0c18a4bc596c249
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+---
+ board/aspeed/ast-g5/Makefile | 1 +
+ board/aspeed/ast-g5/ast-g5-gpio.c | 195 +++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5-gpio.h | 102 +++++++++++++++
+ board/aspeed/ast-g5/ast-g5-intel.c | 42 +++++++
+ board/aspeed/ast-g5/ast-g5.h | 1 +
+ 5 files changed, 341 insertions(+)
+ create mode 100644 board/aspeed/ast-g5/ast-g5-gpio.c
+ create mode 100644 board/aspeed/ast-g5/ast-g5-gpio.h
+
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index 58e0c648f4..2970ae5741 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -2,3 +2,4 @@ obj-y += ast-g5.o
+ obj-y += ast-g5-intel.o
+ obj-y += ast-g5-espi.o
+ obj-y += ast-g5-irq.o
++obj-y += ast-g5-gpio.o
+diff --git a/board/aspeed/ast-g5/ast-g5-gpio.c b/board/aspeed/ast-g5/ast-g5-gpio.c
+new file mode 100644
+index 0000000000..d596c15914
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-gpio.c
+@@ -0,0 +1,195 @@
++/*
++ * 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>
++#include <asm/arch/regs-scu.h>
++#include <asm/arch/ast_scu.h>
++#include <asm/arch/aspeed.h>
++
++#include "ast-g5.h"
++#include "ast-g5-gpio.h"
++
++typedef struct _gpio_bases {
++ uint32_t u32ddr; /* data and direction registers */
++ uint32_t u32intcfg; /* interrupt config */
++ uint32_t u32debounce; /* debounce config */
++ uint32_t u32cmdsrc; /* command source config */
++} sGPIO_BASES;
++
++static const sGPIO_BASES GPIO_BASES[] = {
++ /* ABCD */
++ {AST_GPIO_BASE + 0x0000, AST_GPIO_BASE + 0x0008,
++ AST_GPIO_BASE + 0x0040, AST_GPIO_BASE + 0x0060},
++ /* EFGH */
++ {AST_GPIO_BASE + 0x0020, AST_GPIO_BASE + 0x0028,
++ AST_GPIO_BASE + 0x0048, AST_GPIO_BASE + 0x0068},
++ /* IJKL */
++ {AST_GPIO_BASE + 0x0070, AST_GPIO_BASE + 0x0098,
++ AST_GPIO_BASE + 0x00b0, AST_GPIO_BASE + 0x0090},
++ /* MNOP */
++ {AST_GPIO_BASE + 0x0078, AST_GPIO_BASE + 0x00e8,
++ AST_GPIO_BASE + 0x0100, AST_GPIO_BASE + 0x00e0},
++ /* QRST */
++ {AST_GPIO_BASE + 0x0080, AST_GPIO_BASE + 0x0118,
++ AST_GPIO_BASE + 0x0130, AST_GPIO_BASE + 0x0110},
++ /* UVWX */
++ {AST_GPIO_BASE + 0x0088, AST_GPIO_BASE + 0x0148,
++ AST_GPIO_BASE + 0x0160, AST_GPIO_BASE + 0x0140},
++ /* YZAB */
++ {AST_GPIO_BASE + 0x01e0, AST_GPIO_BASE + 0x0178,
++ AST_GPIO_BASE + 0x0190, AST_GPIO_BASE + 0x0170},
++ /* AC__ */
++ {AST_GPIO_BASE + 0x01e8, AST_GPIO_BASE + 0x01a8,
++ AST_GPIO_BASE + 0x01c0, AST_GPIO_BASE + 0x01a0},
++};
++
++static size_t gpio_max = 0;
++static const GPIOValue * gpio_table = NULL;
++
++void gpio_set_value(int n, int asserted)
++{
++ uint8_t port;
++ uint8_t pin;
++ uint32_t base;
++ uint8_t shift;
++ uint8_t assert;
++ uint32_t gpio_value;
++
++ if (n >= gpio_max || !gpio_table) {
++ return;
++ }
++ port = GPIO_PORT(gpio_table[n].u8PortPin);
++ assert = GPIO_PORT(gpio_table[n].u8Value);
++ pin = GPIO_PIN(gpio_table[n].u8PortPin);
++ base = GPIO_BASES[GPIO_GROUP(port)].u32ddr;
++ shift = GPIO_SHIFT(port, pin);
++
++ gpio_value = readl(base + GPIO_DATA_VALUE);
++ if ((assert &&asserted) || !(assert || asserted)) {
++ // set the bit
++ gpio_value |= (1 << shift);
++ } else {
++ // clear the bit
++ gpio_value &= ~(1 << shift);
++ }
++ writel(gpio_value, base + GPIO_DATA_VALUE);
++}
++
++int gpio_get_value(int n)
++{
++ uint8_t port;
++ uint8_t pin;
++ uint32_t base;
++ uint8_t shift;
++ uint8_t assert;
++ uint32_t gpio_value;
++
++ if (n >= gpio_max || !gpio_table) {
++ return -1;
++ }
++ port = GPIO_PORT(gpio_table[n].u8PortPin);
++ assert = GPIO_PORT(gpio_table[n].u8Value);
++ pin = GPIO_PIN(gpio_table[n].u8PortPin);
++ base = GPIO_BASES[GPIO_GROUP(port)].u32ddr;
++ shift = GPIO_SHIFT(port, pin);
++
++ gpio_value = readl(base + GPIO_DATA_VALUE);
++ gpio_value >>= shift;
++ gpio_value &= 1;
++ gpio_value ^= assert;
++ return !gpio_value;
++}
++
++void gpio_init(const GPIOValue* table, size_t count)
++{
++ uint32_t pclk, value;
++ int i;
++
++ gpio_table = table;
++ gpio_max = count;
++ /* set up the debounce timers (in units of PCLK cycles) */
++ pclk = ast_get_ahbclk();
++ /* GPIO_DEBOUNCE_120us */
++ writel((pclk / 1000000) * 120, AST_GPIO_BASE + GPIO_DEBOUNCE_TIMER_0);
++ /* GPIO_DEBOUNCE_8ms */
++ writel((pclk / 1000000) * 8000, AST_GPIO_BASE + GPIO_DEBOUNCE_TIMER_1);
++ /* GPIO_DEBOUNCE_16ms */
++ writel((pclk / 1000000) * 16000, AST_GPIO_BASE + GPIO_DEBOUNCE_TIMER_2);
++
++ for (i = 0; i < gpio_max; i++) {
++ uint8_t port;
++ uint8_t pin;
++ uint32_t base;
++ uint8_t shift;
++
++ port = GPIO_PORT(gpio_table[i].u8PortPin);
++ pin = GPIO_PIN(gpio_table[i].u8PortPin);
++ base = GPIO_BASES[GPIO_GROUP(port)].u32ddr;
++ shift = GPIO_SHIFT(port, pin);
++
++ /* set direction */
++ value = readl(base + GPIO_DIRECTION);
++ if (gpio_table[i].u8PinCFG & GPCFG_OUTPUT_EN)
++ value |= (1 << shift);
++ else
++ value &= ~(1 << shift);
++ writel(value, base + GPIO_DIRECTION);
++
++ /* set data value */
++ value = readl(base + GPIO_DATA_VALUE);
++ if (gpio_table[i].u8Value)
++ value |= (1 << shift);
++ else
++ value &= ~(1 << shift);
++ writel(value, base + GPIO_DATA_VALUE);
++
++ /* set debounce */
++ base = GPIO_BASES[GPIO_GROUP(port)].u32debounce;
++ value = readl(base + GPIO_DEBOUNCE_SEL_0);
++ if (gpio_table[i].u8Debounce & 0x01)
++ value |= (1 << shift);
++ else
++ value &= ~(1 << shift);
++ writel(value, base + GPIO_DEBOUNCE_SEL_0);
++ value = readl(base + GPIO_DEBOUNCE_SEL_1);
++ if (gpio_table[i].u8Debounce & 0x02)
++ value |= (1 << shift);
++ else
++ value &= ~(1 << shift);
++ writel(value, base + GPIO_DEBOUNCE_SEL_1);
++ }
++}
++
++int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
++{
++ int n;
++ if (argc < 3) {
++ return 1;
++ }
++ n = simple_strtoul(argv[2], NULL, 16);
++ if (argv[1][0] == 'g') {
++ printf("%d\n", gpio_get_value(n));
++ return 0;
++ }
++ if (argc < 4) {
++ return 1;
++ }
++ if (argv[1][0] == 's') {
++ int value;
++ value = simple_strtoul(argv[3], NULL, 16);
++ gpio_set_value(n, value);
++ return 0;
++ }
++
++ return 1;
++}
++U_BOOT_CMD(gpio, 4, 0, do_gpio,
++ "do stuff with gpios <set|get> [n] [value]",
++ "");
+diff --git a/board/aspeed/ast-g5/ast-g5-gpio.h b/board/aspeed/ast-g5/ast-g5-gpio.h
+new file mode 100644
+index 0000000000..a820c0fcad
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-gpio.h
+@@ -0,0 +1,102 @@
++#ifndef __HW_GPIO_H__
++#define __HW_GPIO_H__
++
++#define GPIO_PORT_A 0
++#define GPIO_PORT_B 1
++#define GPIO_PORT_C 2
++#define GPIO_PORT_D 3
++#define GPIO_PORT_E 4
++#define GPIO_PORT_F 5
++#define GPIO_PORT_G 6
++#define GPIO_PORT_H 7
++#define GPIO_PORT_I 8
++#define GPIO_PORT_J 9
++#define GPIO_PORT_K 10
++#define GPIO_PORT_L 11
++#define GPIO_PORT_M 12
++#define GPIO_PORT_N 13
++#define GPIO_PORT_O 14
++#define GPIO_PORT_P 15
++#define GPIO_PORT_Q 16
++#define GPIO_PORT_R 17
++#define GPIO_PORT_S 18
++#define GPIO_PORT_T 19
++#define GPIO_PORT_U 20
++#define GPIO_PORT_V 21
++#define GPIO_PORT_W 22
++#define GPIO_PORT_X 23
++#define GPIO_PORT_Y 24
++#define GPIO_PORT_Z 25
++#define GPIO_PORT_AA 26
++#define GPIO_PORT_AB 27
++#define GPIO_PORT_AC 28
++
++#define GPIO_PIN_0 0
++#define GPIO_PIN_1 1
++#define GPIO_PIN_2 2
++#define GPIO_PIN_3 3
++#define GPIO_PIN_4 4
++#define GPIO_PIN_5 5
++#define GPIO_PIN_6 6
++#define GPIO_PIN_7 7
++
++#define GPIO_DEBOUNCE_TIMER_0 0x50
++#define GPIO_DEBOUNCE_TIMER_1 0x54
++#define GPIO_DEBOUNCE_TIMER_2 0x58
++
++/* relative to u32ddr base */
++#define GPIO_DATA_VALUE 0x00
++#define GPIO_DIRECTION 0x04
++/* relative to u32intcfg base */
++#define GPIO_INT_ENABLE 0x00
++#define GPIO_INT_SENSE0 0x04
++#define GPIO_INT_SENSE1 0x18
++#define GPIO_INT_SENSE2 0x1c
++#define GPIO_INT_STATUS 0x20
++#define GPIO_RESET_TOL 0x24
++/* relative to u32debounce base */
++#define GPIO_DEBOUNCE_SEL_0 0
++#define GPIO_DEBOUNCE_SEL_1 4
++/* relative to u32cmdsrc base */
++#define GPIO_CMD_SRC_0 0
++#define GPIO_CMD_SRC_1 4
++
++#define PORT_PIN(PORT, PIN) (((PORT) << 3) | ((PIN)&0x07))
++#define GPIO_PIN(N) (N & 0x07)
++#define GPIO_PORT(N) (N >> 3)
++#define GPIO_SHIFT(PORT, PIN) ((PIN) + (((PORT) % 4) * 8))
++#define GPIO_GROUP(PORT) ((PORT) / 4)
++
++#define ID_LED_PORT_PIN PORT_PIN(GPIO_PORT_S, GPIO_PIN_6)
++#define GRN_LED_PORT_PIN PORT_PIN(GPIO_PORT_S, GPIO_PIN_4)
++#define AMB_LED_PORT_PIN PORT_PIN(GPIO_PORT_S, GPIO_PIN_5)
++#define FORCE_BMC_UPDATE_PORT_PIN PORT_PIN(GPIO_PORT_D, GPIO_PIN_0)
++#define TPM_EN_PULSE_PORT_PIN PORT_PIN(GPIO_PORT_D, GPIO_PIN_6)
++
++
++// GPIO Configuration Register bits
++#define GPCFG_EVENT_TO_SMI (1 << 7) // 1 == enabled
++#define GPCFG_EVENT_TO_IRQ (1 << 6) // 1 == enabled
++#define GPCFG_DEBOUNCE_EN (1 << 5) // 1 == input debounce, 0 == pulse output
++#define GPCFG_ACTIVE_HIGH (1 << 4) // 1 == Active high
++#define GPCFG_LEVEL_TRIG (1 << 3) // 1 == level (default), 0 == edge
++#define GPCFG_OUTPUT_EN (1 << 0) // 1 == Output enabled
++
++// GPIO Debounce and Blink Configuration Register bits
++#define GPIO_DEBOUNCE_NONE 0x00
++#define GPIO_DEBOUNCE_60US 0x01
++#define GPIO_DEBOUNCE_8MS 0x02
++#define GPIO_DEBOUNCE_16MS 0x03
++
++typedef struct {
++ uint8_t u8PortPin;
++ uint8_t u8PinCFG;
++ uint8_t u8Value;
++ uint8_t u8Debounce;
++} GPIOValue;
++
++void gpio_init(const GPIOValue* table, size_t count);
++void gpio_set_value(int n, int asserted);
++int gpio_get_value(int n);
++
++#endif /* __HW_GPIO_H__ */
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index fca4d91115..252a05dd73 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -14,6 +14,47 @@
+ #include <asm/arch/aspeed.h>
+
+ #include "ast-g5.h"
++#include "ast-g5-gpio.h"
++
++/* Names to match the GPIOs */
++enum gpio_names {
++ GPIO_ID_LED = 0,
++ GPIO_GREEN_LED,
++ GPIO_AMBER_LED,
++ GPIO_FF_UPD_JUMPER,
++ GPIO_ENABLE_TPM_PULSE,
++};
++
++#define GPIO_CFG_DEFAULT (GPCFG_ACTIVE_HIGH | GPCFG_LEVEL_TRIG)
++// Active High, Level, Output Disabled
++
++#define GPIO_CFG_FP_LED (GPCFG_OUTPUT_EN)
++// Active High, Pull-up, Level, Output Disabled
++
++// Format is:
++// GPIO PORT, GPIO PIN Number, GPIO PIN Configuration, GPIO PIN Value, GPIO
++// Debounce/Blink Setting
++static const GPIOValue gpio_table[] = {
++ /* ID LED pin S6 - low asserted, 0=on */
++ [GPIO_ID_LED] = {ID_LED_PORT_PIN, GPIO_CFG_FP_LED, 0,
++ GPIO_DEBOUNCE_NONE},
++
++ /* Green LED pin S4 - high asserted, 0=off */
++ [GPIO_GREEN_LED] = {GRN_LED_PORT_PIN, GPIO_CFG_FP_LED, 1,
++ GPIO_DEBOUNCE_NONE},
++
++ /* Amber LED pin S5 - high asserted, 0=off */
++ [GPIO_AMBER_LED] = {AMB_LED_PORT_PIN, GPIO_CFG_FP_LED, 1,
++ GPIO_DEBOUNCE_NONE},
++
++ /* Force Update Jumper -- pin D0 */
++ [GPIO_FF_UPD_JUMPER] = {FORCE_BMC_UPDATE_PORT_PIN, GPIO_CFG_DEFAULT, 0,
++ GPIO_DEBOUNCE_8MS},
++
++ /* Enable Pulse -- pin D6 */
++ [GPIO_ENABLE_TPM_PULSE] = {PORT_PIN(GPIO_PORT_D, GPIO_PIN_6),
++ GPIO_CFG_DEFAULT, 0, GPIO_DEBOUNCE_8MS},
++};
+
+ #define LPC_SNOOP_ADDR 0x80
+ #define HICR5 0x080 /* Host Interface Control Register 5 */
+@@ -107,6 +148,7 @@ static void sgpio_init(void)
+ extern void espi_init(void);
+ void ast_g5_intel(void)
+ {
++ gpio_init(gpio_table, ARRAY_SIZE(gpio_table));
+ espi_init();
+ sgpio_init();
+ }
+diff --git a/board/aspeed/ast-g5/ast-g5.h b/board/aspeed/ast-g5/ast-g5.h
+index 9fd10eccb3..908db1477b 100644
+--- a/board/aspeed/ast-g5/ast-g5.h
++++ b/board/aspeed/ast-g5/ast-g5.h
+@@ -3,5 +3,6 @@
+
+ #include <common.h>
+ #include "ast-g5-irq.h"
++#include "ast-g5-gpio.h"
+
+ #endif /* _AST_G5_H_ */
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0010-Update-Force-Firmware-Update-Jumper-to-use-new-gpio.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0010-Update-Force-Firmware-Update-Jumper-to-use-new-gpio.patch
new file mode 100644
index 000000000..c97e6d74f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0010-Update-Force-Firmware-Update-Jumper-to-use-new-gpio.patch
@@ -0,0 +1,98 @@
+From 1f710737f2fe8dea4bc5ebef1e6011de294764b4 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Fri, 16 Nov 2018 14:59:04 -0800
+Subject: [PATCH] Update Force Firmware Update Jumper to use new gpio API
+
+Add a function that allows easy reading of the FFUJ from other
+functions, such as autoboot.
+
+Change-Id: I8ead931e9dd828522095a0ef386875be652ec885
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+---
+ .../include/asm/arch-aspeed/ast-g5-intel.h | 19 +++++++++++++++++++
+ arch/arm/include/asm/arch-aspeed/platform.h | 1 +
+ board/aspeed/ast-g5/ast-g5-intel.c | 5 +++++
+ common/autoboot.c | 6 ++++++
+ 4 files changed, 31 insertions(+)
+ create mode 100644 arch/arm/include/asm/arch-aspeed/ast-g5-intel.h
+
+diff --git a/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h b/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h
+new file mode 100644
+index 0000000000..cd9a0994fa
+--- /dev/null
++++ b/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h
+@@ -0,0 +1,19 @@
++/*
++ * 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.
++ */
++
++#ifndef __AST_INTEL_G5_H__
++#define __AST_INTEL_G5_H__
++
++#define AST_G5_INTEL 1
++
++#ifndef __ASSEMBLY__
++int intel_force_firmware_jumper_enabled(void);
++#endif
++
++#endif /* __AST_INTEL_G5_H__ */
+diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h
+index 9f339e913a..3ea1c99089 100644
+--- a/arch/arm/include/asm/arch-aspeed/platform.h
++++ b/arch/arm/include/asm/arch-aspeed/platform.h
+@@ -27,6 +27,7 @@
+ #include <asm/arch/ast2400_platform.h>
+ #elif defined(AST_SOC_G5)
+ #include <asm/arch/ast_g5_platform.h>
++#include <asm/arch/ast-g5-intel.h>
+ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */
+ #else
+ #err "No define for platform.h"
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index 252a05dd73..58ad6a55b8 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -145,6 +145,11 @@ static void sgpio_init(void)
+ writel(value, AST_GPIO_BASE + GPIO254);
+ }
+
++int intel_force_firmware_jumper_enabled(void)
++{
++ return gpio_get_value(GPIO_FF_UPD_JUMPER);
++}
++
+ extern void espi_init(void);
+ void ast_g5_intel(void)
+ {
+diff --git a/common/autoboot.c b/common/autoboot.c
+index c52bad84a4..d66c0fa63a 100644
+--- a/common/autoboot.c
++++ b/common/autoboot.c
+@@ -14,6 +14,7 @@
+ #include <menu.h>
+ #include <post.h>
+ #include <u-boot/sha256.h>
++#include <asm/arch/platform.h>
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+@@ -259,6 +260,11 @@ static int abortboot(int bootdelay)
+ {
+ int abort = 0;
+
++# ifdef AST_G5_INTEL
++ if (intel_force_firmware_jumper_enabled())
++ return 1;
++# endif
++
+ if (bootdelay >= 0)
+ abort = __abortboot(bootdelay);
+
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0011-Add-basic-timer-support-for-Aspeed-g5-in-U-Boot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0011-Add-basic-timer-support-for-Aspeed-g5-in-U-Boot.patch
new file mode 100644
index 000000000..11a474b96
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0011-Add-basic-timer-support-for-Aspeed-g5-in-U-Boot.patch
@@ -0,0 +1,160 @@
+From 83d67b5b3cbffcefda5efdc0060b9e30f44c9aca Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Fri, 16 Nov 2018 14:44:49 -0800
+Subject: [PATCH 6/7] Add basic timer support for Aspeed g5 in U-Boot
+
+Timers will be used for timing events and making blinky LEDs. This just
+adds the API and infrastructure.
+
+Change-Id: I8ff03b26070b43a47fb970ddf6124d6c3f29b058
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+---
+ board/aspeed/ast-g5/Makefile | 1 +
+ board/aspeed/ast-g5/ast-g5-intel.c | 1 +
+ board/aspeed/ast-g5/ast-g5-timer.c | 66 ++++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5-timer.h | 27 ++++++++++++
+ board/aspeed/ast-g5/ast-g5.h | 1 +
+ 5 files changed, 96 insertions(+)
+ create mode 100644 board/aspeed/ast-g5/ast-g5-timer.c
+ create mode 100644 board/aspeed/ast-g5/ast-g5-timer.h
+
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index 2970ae5741..90224333c4 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -3,3 +3,4 @@ obj-y += ast-g5-intel.o
+ obj-y += ast-g5-espi.o
+ obj-y += ast-g5-irq.o
+ obj-y += ast-g5-gpio.o
++obj-y += ast-g5-timer.o
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index 58ad6a55b8..23bf4e4352 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -15,6 +15,7 @@
+
+ #include "ast-g5.h"
+ #include "ast-g5-gpio.h"
++#include "ast-g5-timer.h"
+
+ /* Names to match the GPIOs */
+ enum gpio_names {
+diff --git a/board/aspeed/ast-g5/ast-g5-timer.c b/board/aspeed/ast-g5/ast-g5-timer.c
+new file mode 100644
+index 0000000000..56157222d9
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-timer.c
+@@ -0,0 +1,66 @@
++/*
++ * 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>
++#include <asm/arch/regs-scu.h>
++#include <asm/arch/ast_scu.h>
++#include <asm/arch/aspeed.h>
++
++#include "ast-g5.h"
++#include "ast-g5-timer.h"
++#include "ast-g5-irq.h"
++
++static const int timer_irqs[] = {16, 17, 18, 35, 37, 37, 38, 39};
++/* 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_ENABLE_PULSE 8
++#define TIMER_CONTROL 0x30
++#define TIMER_RELOAD 0x04
++
++void timer_enable(int n, uint32_t freq, interrupt_handler_t *handler)
++{
++ if (n < 0 || n > 7) {
++ return;
++ }
++ uint32_t tctrl = readl(AST_TIMER_BASE + TIMER_CONTROL);
++ writel(tctrl & ~(0x0f << (n * 4)), AST_TIMER_BASE + TIMER_CONTROL);
++
++ // figure out best base for requested frequency
++ // (this will give 1MHz clock preference if period is within 1ms of
++ // requested)
++ uint32_t v = TIMER_1MHZ_CLK_COUNT / freq;
++ if (v > 1000 || v * freq == TIMER_1MHZ_CLK_COUNT) {
++ tctrl |= (TIMER_1MHZ_CLK_SEL << (n * 4));
++ } else {
++ uint32_t pclk = ast_get_ahbclk();
++ v = pclk / freq;
++ }
++ writel(v, AST_TIMER_BASE + timer_bases[n] + TIMER_RELOAD);
++ if (handler) {
++ request_irq(timer_irqs[n], handler);
++ tctrl |= (TIMER_ENABLE_IRQ << (n * 4));
++ }
++ tctrl |= (TIMER_ENABLE << (n * 4));
++ writel(tctrl, AST_TIMER_BASE + TIMER_CONTROL);
++}
++
++void timer_disable(int n)
++{
++ if (n < 0 || n > 7) {
++ return;
++ }
++ uint32_t tctrl = readl(AST_TIMER_BASE + TIMER_CONTROL);
++ writel(tctrl & ~(0x0f << (n * 4)), AST_TIMER_BASE + TIMER_CONTROL);
++}
+diff --git a/board/aspeed/ast-g5/ast-g5-timer.h b/board/aspeed/ast-g5/ast-g5-timer.h
+new file mode 100644
+index 0000000000..4b1ac28a9f
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-timer.h
+@@ -0,0 +1,27 @@
++/*
++ * 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.
++ */
++
++#ifndef __AST_G5_TIMER_H__
++#define __AST_G5_TIMER_H__
++
++#include <common.h>
++
++#define TIMER_1 0
++#define TIMER_2 1
++#define TIMER_3 2
++#define TIMER_4 3
++#define TIMER_5 4
++#define TIMER_6 5
++#define TIMER_7 6
++#define TIMER_8 7
++
++void timer_enable(int n, uint32_t freq, interrupt_handler_t handler);
++void timer_disable(int n);
++
++#endif /* __AST_G5_TIMER_H__ */
+diff --git a/board/aspeed/ast-g5/ast-g5.h b/board/aspeed/ast-g5/ast-g5.h
+index 908db1477b..28fe5eafcb 100644
+--- a/board/aspeed/ast-g5/ast-g5.h
++++ b/board/aspeed/ast-g5/ast-g5.h
+@@ -4,5 +4,6 @@
+ #include <common.h>
+ #include "ast-g5-irq.h"
+ #include "ast-g5-gpio.h"
++#include "ast-g5-timer.h"
+
+ #endif /* _AST_G5_H_ */
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0012-Add-status-and-ID-LED-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0012-Add-status-and-ID-LED-support.patch
new file mode 100644
index 000000000..5a2c2206f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0012-Add-status-and-ID-LED-support.patch
@@ -0,0 +1,144 @@
+From f0e3631ea3005640f988727f051106d83b5dfdaf Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Wed, 14 Nov 2018 12:16:53 -0800
+Subject: [PATCH 7/7] Add status and ID LED support
+
+Add status (amber and green) and ID (blue) LED support. In the
+bootloader phase, the LEDs should be blinking. When booting linux, they
+should turn to a fixed state.
+
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+Change-Id: Ic9595621b21000ef465ff57ed2047855296e2714
+---
+ board/aspeed/ast-g5/ast-g5-intel.c | 118 +++++++++++++++++++++++++++++
+ 1 file changed, 118 insertions(+)
+
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index 23bf4e4352..5ff2cbd0e2 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -146,6 +146,110 @@ static void sgpio_init(void)
+ writel(value, AST_GPIO_BASE + GPIO254);
+ }
+
++/* running the timer at 48 hertz will easily give a 24Hz blink */
++#define TICK_HZ 48
++#define BLINK_DELAY(HZ) ((int)((TICK_HZ / (HZ)) / 2) - 1)
++typedef enum {
++ /*
++ * Identifies the control request for the ID LED.
++ */
++ EIDLED_Initialize = 0,
++ EIDLED_Tick,
++ EIDLED_Toggle,
++ EIDLED_Off,
++ EIDLED_On,
++ EIDLED_Blink,
++ EIDLED_Blink_24HZ = EIDLED_Blink + BLINK_DELAY(24),
++ EIDLED_Blink_12HZ = EIDLED_Blink + BLINK_DELAY(12),
++ EIDLED_Blink_6HZ = EIDLED_Blink + BLINK_DELAY(6),
++ EIDLED_Blink_3HZ = EIDLED_Blink + BLINK_DELAY(3),
++ EIDLED_Blink_1HZ = EIDLED_Blink + BLINK_DELAY(1),
++ EIDLED_Blink_0_5HZ = EIDLED_Blink + BLINK_DELAY(0.5),
++} EIDLEDControl;
++
++struct led_info {
++ int gpio;
++ EIDLEDControl mode;
++ int count;
++ int state;
++};
++
++static struct led_info s_led_info[] = {
++ [GPIO_ID_LED] = {GPIO_ID_LED, EIDLED_Blink_3HZ, 1, 0},
++ [GPIO_GREEN_LED] = {GPIO_GREEN_LED, EIDLED_Off, 0, 0},
++ [GPIO_AMBER_LED] = {GPIO_AMBER_LED, EIDLED_Off, 0, 0},
++};
++
++extern void gpio_set_value(int n, int asserted);
++void id_led_control(int id, int action)
++{
++ if (id >= ARRAY_SIZE(s_led_info)) {
++ return;
++ }
++ /* don't bother with LEDs that are not initialized */
++ if (EIDLED_Initialize == s_led_info[id].mode) {
++ return;
++ }
++
++ /* check for a blinker action */
++ if (EIDLED_Tick == action) {
++ if (s_led_info[id].mode < EIDLED_Blink) {
++ return;
++ }
++ /* check countdown for blink */
++ if (s_led_info[id].count == 0) {
++ s_led_info[id].count =
++ s_led_info[id].mode - EIDLED_Blink;
++ s_led_info[id].state = !s_led_info[id].state;
++ } else {
++ s_led_info[id].count--;
++ return;
++ }
++ } else if (EIDLED_Toggle == action) {
++ s_led_info[id].state = !s_led_info[id].state;
++ s_led_info[id].mode =
++ s_led_info[id].state ? EIDLED_On : EIDLED_Off;
++ } else if (action > EIDLED_Toggle) {
++ s_led_info[id].mode = action;
++ if (EIDLED_Off == action) {
++ s_led_info[id].state = 0;
++ } else if (EIDLED_On == action) {
++ s_led_info[id].state = 1;
++ } else if (action >= EIDLED_Blink) {
++ s_led_info[id].count = action - EIDLED_Blink;
++ /* wait for the next tick */
++ return;
++ }
++ } else if (EIDLED_Initialize == action) {
++ if (s_led_info[id].mode >= EIDLED_Blink) {
++ s_led_info[id].count =
++ s_led_info[id].mode - EIDLED_Blink;
++ }
++ }
++ gpio_set_value(s_led_info[id].gpio, s_led_info[id].state);
++}
++
++static void timer8_irq_handler(void *regs)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(s_led_info); i++) {
++ id_led_control(i, EIDLED_Tick);
++ }
++}
++
++void timer8_init(void)
++{
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(s_led_info); i++) {
++ id_led_control(i, EIDLED_Initialize);
++ }
++
++ /* set up the timer to fire at TICK_HZ HZ */
++ timer_enable(TIMER_8, TICK_HZ, timer8_irq_handler);
++}
++
+ int intel_force_firmware_jumper_enabled(void)
+ {
+ return gpio_get_value(GPIO_FF_UPD_JUMPER);
+@@ -157,4 +269,10 @@ void ast_g5_intel(void)
+ gpio_init(gpio_table, ARRAY_SIZE(gpio_table));
+ espi_init();
+ sgpio_init();
++ timer8_init();
++ if (intel_force_firmware_jumper_enabled()) {
++ id_led_control(GPIO_AMBER_LED, EIDLED_On);
++ } else {
++ id_led_control(GPIO_GREEN_LED, EIDLED_On);
++ }
+ }
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0013-aspeed-Add-Pwm-Driver.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0013-aspeed-Add-Pwm-Driver.patch
new file mode 100644
index 000000000..d235aea62
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0013-aspeed-Add-Pwm-Driver.patch
@@ -0,0 +1,132 @@
+From 3134584998f624bb6c4ee11102b0bd9b7bb1cbba Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Fri, 16 Nov 2018 15:57:57 -0800
+Subject: [PATCH 1/1] aspeed: add Pwm Driver
+
+Change-Id: Ia8b80212f7c70aafcc6a71782936ec95cf9b7f38
+---
+ board/aspeed/ast-g5/ast-g5-intel.c | 105 +++++++++++++++++++++++++++++
+ 1 file changed, 105 insertions(+)
+
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index 5ff2cbd0e2..f810ded4e7 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -263,9 +263,114 @@ int intel_force_firmware_jumper_enabled(void)
+ return gpio_get_value(GPIO_FF_UPD_JUMPER);
+ }
+
++/* PWM offsets */
++
++#define PWM_BASE_ADDR 0x1E786000
++#define PWM_CONTROL 0x00
++#define PWM_CLOCK_SELECTION 0x04
++#define PWM_DUTY_CYCLE 0x08
++#define PWM_M0 0x10
++#define PWM_M1 0x14
++#define PWM_N0 0x18
++#define PWM_N1 0x1c
++#define PWM_CONTROL_EXT 0x40
++#define PWM_CLOCK_SEL_EXT 0x44
++#define PWM_O0 0x50
++#define PWM_O1 0x54
++#define PWM_CHANNEL_COUNT 8
++
++#define PWM_CLK_ENABLE BIT(0)
++#define PWM_DUTY(PCT) (((PCT) * 128) / 100)
++#define PWM_DUTY_VALUE PWM_DUTY(57)
++
++
++static inline uint32_t ast_scu_read(uint32_t reg)
++{
++ uint32_t val = readl(AST_SCU_BASE + reg);
++
++ debug("ast_scu_read : reg = 0x%08x, val = 0x%08x\n", reg, val);
++ return val;
++}
++
++static inline void ast_scu_write(uint32_t val, uint32_t reg)
++{
++ debug("ast_scu_write : reg = 0x%08x, val = 0x%08x\n", reg, val);
++
++ writel(SCU_PROTECT_UNLOCK, AST_SCU_BASE);
++ writel(val, AST_SCU_BASE + reg);
++#ifdef CONFIG_AST_SCU_LOCK
++ writel(0xaa, AST_SCU_BASE);
++#endif
++}
++
++static void pwm_init(void)
++{
++ uint32_t val;
++ uint32_t chan;
++
++ /* select pwm 0-7 */
++ val = ast_scu_read(AST_SCU_FUN_PIN_CTRL3);
++ val |= (SCU_FUN_PIN_VPIG7 | SCU_FUN_PIN_VPIG6 | SCU_FUN_PIN_VPIG5
++ | SCU_FUN_PIN_VPIG4 | SCU_FUN_PIN_VPIG3 | SCU_FUN_PIN_VPIG2
++ | SCU_FUN_PIN_VPIG1 | SCU_FUN_PIN_VPIG0);
++ ast_scu_write(val, AST_SCU_FUN_PIN_CTRL3);
++
++ /* disable video output mux */
++ val = ast_scu_read(AST_SCU_FUN_PIN_CTRL5);
++ val &= 0xffffffcf;
++ ast_scu_write(val, AST_SCU_FUN_PIN_CTRL5);
++ val = readl(AST_SCU_FUN_PIN_CTRL6);
++ val &= 0xfffffffc;
++ ast_scu_write(val, AST_SCU_FUN_PIN_CTRL6);
++
++ /* SCU reset of PWM module */
++ val = ast_scu_read(AST_SCU_RESET);
++ val |= SCU_RESET_PWM;
++ ast_scu_write(val, AST_SCU_RESET);
++ val &= ~SCU_RESET_PWM;
++ ast_scu_write(val, AST_SCU_RESET);
++
++ /* set M, N, and 0 clock regs to 0 */
++ writel(0, PWM_BASE_ADDR + PWM_M0);
++ writel(0, PWM_BASE_ADDR + PWM_N0);
++ writel(0, PWM_BASE_ADDR + PWM_O0);
++
++ /* disable fans and tachos, set M type control */
++ writel(0x1, PWM_BASE_ADDR + PWM_CONTROL);
++ writel(0x1, PWM_BASE_ADDR + PWM_CONTROL_EXT);
++
++ /* enable pwm channels */
++ for (chan = 0; chan < PWM_CHANNEL_COUNT; chan++) {
++ uint32_t base = chan < 4 ? PWM_BASE_ADDR : PWM_BASE_ADDR + 0x40;
++ uint8_t ch_duty_shift = 16 * (chan & 0x1);
++ uint8_t ch_pair = (chan & 0x3) / 2;
++
++ /* enable pwm for the channel */
++ val = readl(base);
++ val |= ((1 << (chan & 0x3)) << 8);
++ writel(val, base);
++
++ /* set duty cycle */
++ val = readl(base + PWM_DUTY_CYCLE + ch_pair * 4);
++ val &= ~(0xffff << ch_duty_shift);
++ val |= (((uint32_t)PWM_DUTY_VALUE) << 8) << ch_duty_shift;
++ writel(val, base + PWM_DUTY_CYCLE + ch_pair * 4);
++ }
++
++ /* set up clock type M: period = 127 units at 24MHz/8 (resulting ~23kHz period) */
++ writel(0x7f30, PWM_BASE_ADDR + PWM_CLOCK_SELECTION);
++
++ /* enable pwm-tacho */
++
++ val = readl(PWM_BASE_ADDR + PWM_CONTROL);
++ val |= PWM_CLK_ENABLE;
++ writel(val, PWM_BASE_ADDR + PWM_CONTROL);
++}
++
+ extern void espi_init(void);
+ void ast_g5_intel(void)
+ {
++ pwm_init();
+ gpio_init(gpio_table, ARRAY_SIZE(gpio_table));
+ espi_init();
+ sgpio_init();
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0014-Keep-interrupts-enabled-until-last-second.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0014-Keep-interrupts-enabled-until-last-second.patch
new file mode 100644
index 000000000..91665e064
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0014-Keep-interrupts-enabled-until-last-second.patch
@@ -0,0 +1,91 @@
+From 2078771e0ff84be710250b2e9b2e887f7238f9cc Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Sat, 17 Nov 2018 14:17:27 -0800
+Subject: [PATCH 2/3] Keep interrupts enabled until last second
+
+The U-Boot bootm command disabled interrupts almost first thing. This
+would prevent a person hitting the power button on the host immediatly
+after AC on because the BMC would fail to respond to the espi interrupts
+and the host would power off.
+
+Change-Id: I6c0fb5cca1be6c326da4c9a3d3dfbab89dac9928
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+---
+ board/aspeed/ast-g5/ast-g5-intel.c | 8 ++++++++
+ common/bootm.c | 7 -------
+ common/bootm_os.c | 1 +
+ 3 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index f810ded4e7..4d399be392 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -263,6 +263,14 @@ int intel_force_firmware_jumper_enabled(void)
+ return gpio_get_value(GPIO_FF_UPD_JUMPER);
+ }
+
++void arch_preboot_os(void)
++{
++ // last second before booting... set the LEDs
++ id_led_control(GPIO_ID_LED, EIDLED_On);
++ id_led_control(GPIO_GREEN_LED, EIDLED_On);
++ id_led_control(GPIO_AMBER_LED, EIDLED_Off);
++}
++
+ /* PWM offsets */
+
+ #define PWM_BASE_ADDR 0x1E786000
+diff --git a/common/bootm.c b/common/bootm.c
+index 2431019b3f..46909ecdbb 100644
+--- a/common/bootm.c
++++ b/common/bootm.c
+@@ -602,7 +602,6 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+ int states, bootm_headers_t *images, int boot_progress)
+ {
+ boot_os_fn *boot_fn;
+- ulong iflag = 0;
+ int ret = 0, need_boot_fn;
+
+ images->state |= states;
+@@ -626,7 +625,6 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+ if (!ret && (states & BOOTM_STATE_LOADOS)) {
+ ulong load_end;
+
+- iflag = bootm_disable_interrupts();
+ ret = bootm_load_os(images, &load_end, 0);
+ if (ret == 0)
+ lmb_reserve(&images->lmb, images->os.load,
+@@ -670,8 +668,6 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+ BOOTM_STATE_OS_BD_T | BOOTM_STATE_OS_PREP |
+ BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO);
+ if (boot_fn == NULL && need_boot_fn) {
+- if (iflag)
+- enable_interrupts();
+ printf("ERROR: booting os '%s' (%d) is not supported\n",
+ genimg_get_os_name(images->os.os), images->os.os);
+ bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
+@@ -711,9 +707,6 @@ int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+
+ /* Deal with any fallout */
+ err:
+- if (iflag)
+- enable_interrupts();
+-
+ if (ret == BOOTM_ERR_UNIMPLEMENTED)
+ bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
+ else if (ret == BOOTM_ERR_RESET)
+diff --git a/common/bootm_os.c b/common/bootm_os.c
+index 9ec84bd0db..b56eb39780 100644
+--- a/common/bootm_os.c
++++ b/common/bootm_os.c
+@@ -476,6 +476,7 @@ __weak void arch_preboot_os(void)
+ int boot_selected_os(int argc, char * const argv[], int state,
+ bootm_headers_t *images, boot_os_fn *boot_fn)
+ {
++ disable_interrupts();
+ arch_preboot_os();
+ boot_fn(state, argc, argv, images);
+
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0015-Rewrite-memmove-to-optimize-on-word-transfers.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0015-Rewrite-memmove-to-optimize-on-word-transfers.patch
new file mode 100644
index 000000000..475b8c3ff
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0015-Rewrite-memmove-to-optimize-on-word-transfers.patch
@@ -0,0 +1,114 @@
+From a71794fc928429e199c5ea48181e5edfbb0c4f39 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Mon, 19 Nov 2018 11:04:02 -0800
+Subject: [PATCH] Rewrite memmove to optimize on word transfers
+
+Reading from the flash at boot time was using byte-sized transfers,
+which ultimately turns into four word transfers over spi for every real
+word read. This change breaks memmove down into a header, body, and
+trailer, where the body is all done with word-sized transfers.
+
+Change-Id: Ie0a1f3261e507fb34a908571883d9bf04a1059ee
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+---
+ lib/string.c | 77 +++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 64 insertions(+), 13 deletions(-)
+
+diff --git a/lib/string.c b/lib/string.c
+index 67d5f6a421..0bf472f1f6 100644
+--- a/lib/string.c
++++ b/lib/string.c
+@@ -505,26 +505,77 @@ void * memcpy(void *dest, const void *src, size_t count)
+ *
+ * Unlike memcpy(), memmove() copes with overlapping areas.
+ */
+-void * memmove(void * dest,const void *src,size_t count)
++void *memmove(void *dest, const void *src, size_t count)
+ {
+- char *tmp, *s;
+-
+- if (src == dest)
++ unsigned char *bdst = (unsigned char *)dest;
++ const unsigned char *bsrc = (const unsigned char *)src;
++ unsigned long *ldst;
++ const unsigned long *lsrc;
++ size_t unaligned_header = 0, unaligned_trailer = 0;
++ size_t unaligned_src =
++ (sizeof(*ldst) - (size_t)src) & (sizeof(*ldst) - 1);
++ size_t unaligned_dst =
++ (sizeof(*ldst) - (size_t)dest) & (sizeof(*ldst) - 1);
++
++ if (src == dest || !count)
+ return dest;
+
++ if (unaligned_src || unaligned_dst) {
++ if (unaligned_dst != unaligned_src) {
++ unaligned_header = count;
++ } else {
++ unaligned_header = unaligned_src;
++ if (unaligned_header > count) {
++ unaligned_header = count;
++ }
++ }
++ count -= unaligned_header;
++ }
++ if (count & (sizeof(*ldst) - 1)) {
++ unaligned_trailer = count & (sizeof(*ldst) - 1);
++ count -= unaligned_trailer;
++ }
++
+ if (dest <= src) {
+- tmp = (char *) dest;
+- s = (char *) src;
+- while (count--)
+- *tmp++ = *s++;
++ /* possible un-aligned bytes */
++ while (unaligned_header--)
++ *bdst++ = *bsrc++;
++
++ /* aligned words */
++ ldst = (unsigned long *)bdst;
++ lsrc = (const unsigned long *)bsrc;
++ while (count >= sizeof(*ldst)) {
++ count -= sizeof(*ldst);
++ *ldst++ = *lsrc++;
+ }
+- else {
+- tmp = (char *) dest + count;
+- s = (char *) src + count;
+- while (count--)
+- *--tmp = *--s;
++
++ /* possibly un-aligned bytes */
++ bdst = (unsigned char *)ldst;
++ bsrc = (const unsigned char *)lsrc;
++ while (unaligned_trailer--)
++ *bdst++ = *bsrc++;
++ } else {
++ bdst += unaligned_header + count + unaligned_trailer;
++ bsrc += unaligned_header + count + unaligned_trailer;
++
++ /* possibly un-aligned bytes */
++ while (unaligned_trailer--)
++ *--bdst = *--bsrc;
++
++ /* aligned words */
++ ldst = (unsigned long *)bdst;
++ lsrc = (unsigned long *)bsrc;
++ while (count >= sizeof(*ldst)) {
++ count -= sizeof(*ldst);
++ *--ldst = *--lsrc;
+ }
+
++ /* possibly un-aligned bytes */
++ bdst = (unsigned char *)ldst;
++ bsrc = (const unsigned char *)lsrc;
++ while (unaligned_header--)
++ *--bdst = *--bsrc;
++ }
+ return dest;
+ }
+ #endif
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch
new file mode 100644
index 000000000..cc1e56fdb
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch
@@ -0,0 +1,28 @@
+From 8992df8f3a0f5fc16ec41ad6dd7a5a13e6f94d32 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@linux.intel.com>
+Date: Wed, 5 Dec 2018 16:13:15 -0800
+Subject: [PATCH] Add support for 128MB Macronix spi flash MX66L1G45G
+
+This will enable u-boot support for the Macronix MX66L1G45G part.
+
+Change-Id: I5edc69357a8b1607c5c44e53bed3eddf38fdc0be
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+---
+ drivers/mtd/spi/sf_params.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c
+index c577d9ed6c..d2a96efe48 100644
+--- a/drivers/mtd/spi/sf_params.c
++++ b/drivers/mtd/spi/sf_params.c
+@@ -50,6 +50,7 @@ const struct spi_flash_params spi_flash_params_table[] = {
+ {"MX25L12805", 0xc22018, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP},
+ {"MX25L25635F", 0xc22019, 0x0, 64 * 1024, 512, RD_FULL, WR_QPP},
+ {"MX25L51235F", 0xc2201a, 0x0, 64 * 1024, 1024, RD_FULL, WR_QPP},
++ {"MX66L1G45G", 0xc2201b, 0x0, 64 * 1024, 2048, RD_FULL, SECT_4K|WR_QPP},
+ {"MX25L12855E", 0xc22618, 0x0, 64 * 1024, 256, RD_FULL, WR_QPP},
+ #endif
+ #ifdef CONFIG_SPI_FLASH_SPANSION /* SPANSION */
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch
new file mode 100644
index 000000000..b26803c95
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0017-Enable-Macronix-and-Micron-SPI-support.patch
@@ -0,0 +1,54 @@
+From 8415002a2e77a41831b3064dae264f60996ac88a Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Thu, 6 Dec 2018 15:07:09 -0800
+Subject: [PATCH] Enable Macronix and Micron SPI support
+
+This commit enables Macronix and Micron SPI support.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ configs/ast_g5_ncsi_2boot_defconfig | 2 ++
+ configs/ast_g5_ncsi_defconfig | 2 ++
+ configs/ast_g5_phy_defconfig | 2 ++
+ 3 files changed, 6 insertions(+)
+
+diff --git a/configs/ast_g5_ncsi_2boot_defconfig b/configs/ast_g5_ncsi_2boot_defconfig
+index d5b7894a9e00..abceed817615 100644
+--- a/configs/ast_g5_ncsi_2boot_defconfig
++++ b/configs/ast_g5_ncsi_2boot_defconfig
+@@ -10,6 +10,8 @@ CONFIG_FIT_VERBOSE=y
+ CONFIG_HUSH_PARSER=y
+ CONFIG_OF_LIBFDT=y
+ CONFIG_SPI_FLASH=y
++CONFIG_SPI_FLASH_MACRONIX=y
++CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SYS_NS16550=y
+ CONFIG_FIRMWARE_2ND_BOOT=y
+ CONFIG_AUTOBOOT=y
+diff --git a/configs/ast_g5_ncsi_defconfig b/configs/ast_g5_ncsi_defconfig
+index 9481e5fb6e9d..3f504a325649 100644
+--- a/configs/ast_g5_ncsi_defconfig
++++ b/configs/ast_g5_ncsi_defconfig
+@@ -10,5 +10,7 @@ CONFIG_FIT_VERBOSE=y
+ CONFIG_HUSH_PARSER=y
+ CONFIG_OF_LIBFDT=y
+ CONFIG_SPI_FLASH=y
++CONFIG_SPI_FLASH_MACRONIX=y
++CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SYS_NS16550=y
+ CONFIG_USE_IRQ=y
+diff --git a/configs/ast_g5_phy_defconfig b/configs/ast_g5_phy_defconfig
+index 4aefcf49e880..8f0919043376 100644
+--- a/configs/ast_g5_phy_defconfig
++++ b/configs/ast_g5_phy_defconfig
+@@ -11,5 +11,7 @@ CONFIG_FIT_VERBOSE=y
+ CONFIG_HUSH_PARSER=y
+ CONFIG_OF_LIBFDT=y
+ CONFIG_SPI_FLASH=y
++CONFIG_SPI_FLASH_MACRONIX=y
++CONFIG_SPI_FLASH_STMICRO=y
+ CONFIG_SYS_NS16550=y
+ CONFIG_USE_IRQ=y
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch
new file mode 100644
index 000000000..2ed297a96
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch
@@ -0,0 +1,73 @@
+From 0039c15251a7fcf60154d59933a11d9e17b04d5c Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Thu, 6 Dec 2018 18:49:04 -0800
+Subject: [PATCH] Add support for Macronix and Micron 1Gbits SPI flash
+
+Quick fix to support Macronix and Micron 1Gbits SPI.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ arch/arm/mach-aspeed/flash.c | 33 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 32 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-aspeed/flash.c b/arch/arm/mach-aspeed/flash.c
+index dece4315d755..2a31b6503a22 100644
+--- a/arch/arm/mach-aspeed/flash.c
++++ b/arch/arm/mach-aspeed/flash.c
+@@ -79,6 +79,7 @@ flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* FLASH chips info */
+ #define MX25L12805D 0x1820C2
+ #define MX25L25635E 0x1920C2
+ #define MX66L51235F 0x1A20C2
++#define MX66L1G45G 0x1B20C2
+ #define SST25VF016B 0x4125bf
+ #define SST25VF064C 0x4b25bf
+ #define SST25VF040B 0x8d25bf
+@@ -978,6 +979,35 @@ static ulong flash_get_size (ulong base, flash_info_t *info)
+ #endif
+ break;
+
++ case MX66L1G45G:
++ erase_region_size = 0x10000;
++ info->readcmd = 0x0b;
++ info->dualport = 0;
++ info->dummybyte = 1;
++ info->buffersize = 256;
++ WriteClk = 50;
++ EraseClk = 20;
++ ReadClk = 50;
++#if 1
++ info->sector_count = 2048;
++ info->size = 0x4000000;
++ info->address32 = 1;
++#if defined(CONFIG_FLASH_SPIx2_Dummy)
++ info->readcmd = 0xbb;
++ info->dummybyte = 1;
++ info->dualport = 1;
++ info->iomode = IOMODEx2_dummy;
++#elif defined(CONFIG_FLASH_SPIx4_Dummy)
++ info->readcmd = 0xeb;
++ info->dummybyte = 3;
++ info->dualport = 0;
++ info->iomode = IOMODEx4_dummy;
++ info->quadport = 1;
++ info->dummydata = 0xaa;
++#endif
++#endif
++ break;
++
+ case MX25L12805D:
+ info->sector_count = 256;
+ info->size = 0x1000000;
+@@ -1093,7 +1123,8 @@ static ulong flash_get_size (ulong base, flash_info_t *info)
+ info->readcmd = 0x0b;
+ info->dualport = 0;
+ info->dummybyte = 1;
+- info->buffersize = 1;
++ info->buffersize = 256;
++ info->address32 = 1;
+ WriteClk = 50;
+ EraseClk = 25;
+ ReadClk = 50;
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0019-u-boot-full-platform-reset-espi-oob-ready.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0019-u-boot-full-platform-reset-espi-oob-ready.patch
new file mode 100644
index 000000000..1d2b02954
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0019-u-boot-full-platform-reset-espi-oob-ready.patch
@@ -0,0 +1,48 @@
+From bb490aa226dcf261d3d6865be37130765ecbe9f4 Mon Sep 17 00:00:00 2001
+From: Vernon Mauery <vernon.mauery@intel.com>
+Date: Mon, 17 Dec 2018 20:37:23 -0800
+Subject: [PATCH] u-boot: full platform reset + espi oob-ready
+
+If the platform is strapped for fast reset, have platform-g5.S do a full
+reset and then immediately set oob-ready so the espi master controller
+can initiate communication.
+
+Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
+---
+ arch/arm/mach-aspeed/platform_g5.S | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-aspeed/platform_g5.S b/arch/arm/mach-aspeed/platform_g5.S
+index 2ac1ca4721..66427b6f33 100644
+--- a/arch/arm/mach-aspeed/platform_g5.S
++++ b/arch/arm/mach-aspeed/platform_g5.S
+@@ -139,7 +139,7 @@
+ But if FW has other initial code executed before platform.S, then it should use WDT_SOC mode.
+ Use WDT_Full may clear the initial result of prior initial code.
+ ******************************************************************************/
+-//#define ASTMMC_INIT_RESET_MODE_FULL
++#define ASTMMC_INIT_RESET_MODE_FULL
+
+ /******************************************************************************
+ There is a compatibility issue for Hynix DDR4 SDRAM.
+@@ -563,6 +563,17 @@ wait_first_reset:
+ *******************************************/
+
+ bypass_first_reset:
++ /* Timing from ESPI master requires OOB channel ready bit be set early */
++ ldr r0, =0x1e6e2070 @ check strapping for eSPI mode
++ tst r0, #0x02000000 @ Test for bit 25 - eSPI Mode
++ beq espi_early_init_done @ if bit 25 clear, dont set OOB ready
++
++ ldr r0, =0x1e6ee000
++ ldr r1, [r0] @ ESPI000: ESPI Engine Control Reg
++ orr r1, r1, #0x00000010 @ Set OOB Channel Ready bit
++ str r1, [r0]
++espi_early_init_done:
++
+ /* Enable Timer separate clear mode */
+ ldr r0, =0x1e782038
+ mov r1, #0xAE
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch
new file mode 100644
index 000000000..2e541561a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Add-system-reset-status-support.patch
@@ -0,0 +1,121 @@
+From 06445210bfda7f9bbbb36133e6818575bd6a0cc1 Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Tue, 9 Apr 2019 14:42:05 +0800
+Subject: [PATCH] Add system reset status support
+
+Will display the reset reasons and other CPU information in u-boot,
+and save the reset reasons into kernel command line,
+for applications to query.
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ arch/arm/include/asm/arch-aspeed/platform.h | 2 ++
+ arch/arm/mach-aspeed/ast-scu.c | 4 ++++
+ board/aspeed/ast-g5/ast-g5-intel.c | 30 +++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5.c | 7 +++++++
+ 4 files changed, 43 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h
+index 3b06e52..4e4140d 100644
+--- a/arch/arm/include/asm/arch-aspeed/platform.h
++++ b/arch/arm/include/asm/arch-aspeed/platform.h
+@@ -29,6 +29,8 @@
+ #include <asm/arch/ast_g5_platform.h>
+ #include <asm/arch/ast-g5-intel.h>
+ #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */
++#define CONFIG_BOARD_LATE_INIT 1 /* Call board_late_init */
++#define CONFIG_DISPLAY_CPUINFO 1
+ #else
+ #err "No define for platform.h"
+ #endif
+diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c
+index 3a9ba05..976c59b 100644
+--- a/arch/arm/mach-aspeed/ast-scu.c
++++ b/arch/arm/mach-aspeed/ast-scu.c
+@@ -494,6 +494,9 @@ void ast_scu_sys_rest_info(void)
+ {
+ u32 rest = ast_scu_read(AST_SCU_SYS_CTRL);
+
++#ifdef AST_SOC_G5
++ printf("RST : 0x%02x\n", rest);
++#else
+ if (rest & SCU_SYS_EXT_RESET_FLAG) {
+ printf("RST : External\n");
+ ast_scu_write(SCU_SYS_EXT_RESET_FLAG, AST_SCU_SYS_CTRL);
+@@ -506,6 +509,7 @@ void ast_scu_sys_rest_info(void)
+ } else {
+ printf("RST : CLK en\n");
+ }
++#endif
+ }
+
+ u32 ast_scu_get_vga_memsize(void)
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index bcaf81e..1e8708a 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -303,6 +303,36 @@ static inline void ast_scu_write(uint32_t val, uint32_t reg)
+ #endif
+ }
+
++void ast_g5_intel_late_init(void)
++{
++ char *cmdline = NULL;
++ char *cmdline_new = NULL;
++ char buf[32];
++ u32 rest = 0;
++
++ /* save and clear reset status */
++ rest = ast_scu_read(AST_SCU_SYS_CTRL);
++ snprintf(buf, sizeof(buf), " resetreason=0x%x", rest);
++ ast_scu_write(0, AST_SCU_SYS_CTRL);
++
++ cmdline = getenv("bootargs");
++ if (!cmdline) {
++ printf("Get bootargs fail!\n");
++ return;
++ }
++
++ cmdline_new = malloc(strlen(cmdline) + strlen(buf) + 1);
++ if (!cmdline_new) {
++ printf("Cannot malloc memory!\n");
++ return;
++ }
++
++ /* append the reset status into kernel command line */
++ snprintf(cmdline_new, strlen(cmdline) + strlen(buf) + 1, "%s%s", cmdline, buf);
++ setenv("bootargs", cmdline_new);
++ free(cmdline_new);
++}
++
+ static void pwm_init(void)
+ {
+ uint32_t val;
+diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c
+index d41ef9c..0953677 100644
+--- a/board/aspeed/ast-g5/ast-g5.c
++++ b/board/aspeed/ast-g5/ast-g5.c
+@@ -19,6 +19,7 @@
+ DECLARE_GLOBAL_DATA_PTR;
+
+ extern void ast_g5_intel(void);
++extern void ast_g5_intel_late_init(void);
+
+ int board_early_init_f(void)
+ {
+@@ -40,6 +41,12 @@ int board_init(void)
+ return 0;
+ }
+
++int board_late_init(void)
++{
++ ast_g5_intel_late_init();
++ return 0;
++}
++
+ int dram_init(void)
+ {
+ u32 vga = ast_scu_get_vga_memsize();
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Enable-PCIe-L1-support.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Enable-PCIe-L1-support.patch
new file mode 100644
index 000000000..bdf3d2ddd
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0020-Enable-PCIe-L1-support.patch
@@ -0,0 +1,38 @@
+From 22c61ba094d8ebdbdcb44f848eef1f5d87a4be87 Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Tue, 8 Jan 2019 13:33:15 -0800
+Subject: [PATCH] Enable PCIe L1 support
+
+This commit enables PCIe L1 support using magic registers.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ arch/arm/mach-aspeed/platform_g5.S | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/arm/mach-aspeed/platform_g5.S b/arch/arm/mach-aspeed/platform_g5.S
+index 66427b6f33e7..b4043534b083 100644
+--- a/arch/arm/mach-aspeed/platform_g5.S
++++ b/arch/arm/mach-aspeed/platform_g5.S
+@@ -2432,6 +2432,18 @@ spi_cbr_end:
+ bic r1, r1, #0x00400000
+ str r1, [r0]
+
++ ldr r0, =0x1e6ed07c @ Enable PCIe L1 support
++ ldr r1, =0xa8
++ str r1, [r0]
++
++ ldr r0, =0x1e6ed068
++ ldr r1, =0xc81f0a
++ str r1, [r0]
++
++ ldr r0, =0x1e6ed07c
++ mov r1, #0
++ str r1, [r0]
++
+ /******************************************************************************
+ Configure MAC timing
+ ******************************************************************************/
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0021-Config-host-uart-clock-source-using-environment-vari.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0021-Config-host-uart-clock-source-using-environment-vari.patch
new file mode 100755
index 000000000..310d9359b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0021-Config-host-uart-clock-source-using-environment-vari.patch
@@ -0,0 +1,108 @@
+From c82ba33ea40e0007945cbc93da58f296fdeedeaf Mon Sep 17 00:00:00 2001
+From: Yong Li <yong.b.li@linux.intel.com>
+Date: Mon, 11 Feb 2019 15:19:56 +0800
+Subject: [PATCH] Config host uart clock source using environment variable
+
+In order to support high speed uart for host uarts,
+the uart clock needs to be switched between 24M and 192M.
+Config SCU4C based on environment variable hostserialcfg,
+this variable is set by IPMI OEM commands.
+
+Tested:
+Change the hostserialcfg variable to 0/1/2/3,
+using the below commands:
+
+ipmitool raw 0x32 0x90 1 0; reboot
+cat /sys/class/tty/ttyS*/uartclk, all should be 24MHz
+
+ipmitool raw 0x32 0x90 1 1; reboot
+cat /sys/class/tty/ttyS*/uartclk, ttyS0/2/3 should be 192MHz
+
+ipmitool raw 0x32 0x90 1 2; reboot
+cat /sys/class/tty/ttyS*/uartclk, ttyS1 should be 192MHz
+
+ipmitool raw 0x32 0x90 1 3; reboot
+cat /sys/class/tty/ttyS*/uartclk, ttyS0/12/3 should be 192MHz
+
+Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
+---
+ arch/arm/include/asm/arch-aspeed/regs-scu.h | 5 ++++
+ board/aspeed/ast-g5/ast-g5-intel.c | 39 +++++++++++++++++++++++++++++
+ 2 files changed, 44 insertions(+)
+
+diff --git a/arch/arm/include/asm/arch-aspeed/regs-scu.h b/arch/arm/include/asm/arch-aspeed/regs-scu.h
+index 10b983a..8a596ce 100644
+--- a/arch/arm/include/asm/arch-aspeed/regs-scu.h
++++ b/arch/arm/include/asm/arch-aspeed/regs-scu.h
+@@ -529,6 +529,11 @@
+ /* AST_SCU_MAC_CLK 0x48 - MAC interface clock delay setting register */
+
+ /* AST_SCU_MISC2_CTRL 0x4C - Misc. 2 Control register */
++#define SCU_UART5_HS_CLOCK (1 << 28)
++#define SCU_UART4_HS_CLOCK (1 << 27)
++#define SCU_UART3_HS_CLOCK (1 << 26)
++#define SCU_UART2_HS_CLOCK (1 << 25)
++#define SCU_UART1_HS_CLOCK (1 << 24)
+ #ifdef AST_SOC_G5
+ #define SCU_PCIE_MAPPING_HIGH (1 << 15)
+ #define SCU_MALI_DTY_MODE (1 << 8)
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index 1e8708a..f810a40 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -103,6 +103,9 @@ static const GPIOValue gpio_table[] = {
+ #define SGPIO_ENABLE 1
+ #define GPIO254 0x254
+
++#define HOST_SERIAL_A_HIGH_SPEED (1 << 0)
++#define HOST_SERIAL_B_HIGH_SPEED (1 << 1)
++
+ static void sgpio_init(void)
+ {
+ uint32_t value;
+@@ -310,6 +313,42 @@ void ast_g5_intel_late_init(void)
+ char buf[32];
+ u32 rest = 0;
+
++ /* By default host serail A and B use normal speed */
++ uint32_t host_serial_cfg = 0;
++ char *host_serial_cfg_txt = NULL;
++
++ /* Config the uart clock source based on environment configuration */
++ host_serial_cfg_txt = getenv("hostserialcfg");
++
++ if (host_serial_cfg_txt != NULL)
++ host_serial_cfg = simple_strtoul(host_serial_cfg_txt, NULL, 16);
++
++ if (host_serial_cfg > (HOST_SERIAL_A_HIGH_SPEED | HOST_SERIAL_B_HIGH_SPEED)) {
++ printf("Invalided hostserialcfg %x, use default!\n", host_serial_cfg);
++ host_serial_cfg = 0;
++ }
++
++ /* SOL implementation requires uart1/uart3/uart4 have the same clock
++ * source for data forwarding, config uart3 and uart4
++ */
++ if (host_serial_cfg & HOST_SERIAL_A_HIGH_SPEED) {
++ ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) |
++ SCU_UART1_HS_CLOCK | SCU_UART3_HS_CLOCK |
++ SCU_UART4_HS_CLOCK, AST_SCU_MISC2_CTRL);
++ } else {
++ ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) &
++ ~SCU_UART1_HS_CLOCK & ~SCU_UART3_HS_CLOCK &
++ ~SCU_UART4_HS_CLOCK, AST_SCU_MISC2_CTRL);
++ }
++
++ if (host_serial_cfg & HOST_SERIAL_B_HIGH_SPEED) {
++ ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) |
++ SCU_UART2_HS_CLOCK, AST_SCU_MISC2_CTRL);
++ } else {
++ ast_scu_write(ast_scu_read(AST_SCU_MISC2_CTRL) &
++ ~SCU_UART2_HS_CLOCK, AST_SCU_MISC2_CTRL);
++ }
++
+ /* save and clear reset status */
+ rest = ast_scu_read(AST_SCU_SYS_CTRL);
+ snprintf(buf, sizeof(buf), " resetreason=0x%x", rest);
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch
new file mode 100644
index 000000000..79028d2a1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-KCS-driver-support-in-uBoot.patch
@@ -0,0 +1,620 @@
+From 16209364c27a0cb7e2b7fdd445942f68e9180263 Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Wed, 13 Mar 2019 14:28:05 +0530
+Subject: [PATCH] KCS driver support in uBoot
+
+Added KCS support in uBoot. This will enable
+KCS channels and set the specified registers
+to do KCS communication in uBoot. It also
+consist of read and write KCS message transations
+work flow implementation( As specified in IPMI
+specification Section 9.15). It is enabled
+only when Force Firmware Update Jumper is ON.
+
+Tested By:
+Stopped booting in uBoot and sent IPMI commands
+via KCS interfaces using cmdtool.efi.
+ - Get Device ID:
+ Req: cmdtool.efi 20 18 1
+ Res: 00 23 00 12 03 02 BF 57 01 00 7B 00 00 00 00 00
+ - Get Self Test Results
+ Req: cmdtool.efi 20 18 4
+ Res: 00 56 00
+ - All other commands
+ Req: cmdtool.efi 20 18 2
+ Res: C1 (Invalid).
+
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ board/aspeed/ast-g5/Makefile | 1 +
+ board/aspeed/ast-g5/ast-g5-intel.c | 3 +
+ board/aspeed/ast-g5/ast-g5-kcs.c | 425 +++++++++++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ast-g5-kcs.h | 114 ++++++++++
+ 4 files changed, 543 insertions(+)
+ create mode 100644 board/aspeed/ast-g5/ast-g5-kcs.c
+ create mode 100644 board/aspeed/ast-g5/ast-g5-kcs.h
+
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index 9022433..05972b9 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -4,3 +4,4 @@ obj-y += ast-g5-espi.o
+ obj-y += ast-g5-irq.o
+ obj-y += ast-g5-gpio.o
+ obj-y += ast-g5-timer.o
++obj-y += ast-g5-kcs.o
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index f810a40..f9955c7 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -437,6 +437,7 @@ static void pwm_init(void)
+ }
+
+ extern void espi_init(void);
++extern void kcs_init(void);
+ void ast_g5_intel(void)
+ {
+ pwm_init();
+@@ -446,6 +447,8 @@ void ast_g5_intel(void)
+ timer8_init();
+ if (intel_force_firmware_jumper_enabled()) {
+ id_led_control(GPIO_AMBER_LED, EIDLED_On);
++ kcs_init();
++ /* TODO: need to stop the booting here. */
+ } else {
+ id_led_control(GPIO_GREEN_LED, EIDLED_On);
+ }
+diff --git a/board/aspeed/ast-g5/ast-g5-kcs.c b/board/aspeed/ast-g5/ast-g5-kcs.c
+new file mode 100644
+index 0000000..f983b4a
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-kcs.c
+@@ -0,0 +1,425 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2018-2019 Intel Corporation
++
++#include "ast-g5-kcs.h"
++
++#define DEBUG_KCS_ENABLED 0
++#ifdef DEBUG_KCS_ENABLED
++#define DBG_KCS printf
++#else
++#define DBG_KCS(...)
++#endif
++
++/* TODO: Move to IPMI file. */
++#define IPMI_CC_OK 0x00
++#define IPMI_CC_INVALID 0xC1
++#define IPMI_CC_UNSPECIFIED 0xFF
++
++#define KCS_CHANNEL_NO_3 3
++
++static const u16 enabled_kcs_channel[] = { KCS_CHANNEL_NO_3 };
++
++static const struct kcs_io_reg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = {
++ { .idr = LPC_IDR1, .odr = LPC_ODR1, .str = LPC_STR1 },
++ { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 },
++ { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 },
++ { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }
++};
++
++#define NO_OF_ENABLED_KCS_CHANNELS ARRAY_SIZE(enabled_kcs_channel)
++
++static struct kcs_packet m_kcs_pkt[NO_OF_ENABLED_KCS_CHANNELS];
++
++static u16 read_status(u16 channel_num)
++{
++ return readl(AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].str);
++}
++
++static void write_status(u16 channel_num, u16 value)
++{
++ writel(value, AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].str);
++}
++
++static u16 read_data(u16 channel_num)
++{
++ return readl(AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].idr);
++}
++
++static void write_data(u16 channel_num, u16 value)
++{
++ writel(value, AST_LPC_BASE + ast_kcs_bmc_ioregs[channel_num - 1].odr);
++}
++
++static void set_kcs_state(u16 channel_num, u16 state)
++{
++ u16 status = read_status(channel_num);
++
++ status &= ~KCS_STATE_MASK;
++ status |= KCS_STATE(state) & KCS_STATE_MASK;
++ write_status(channel_num, status);
++}
++
++static struct kcs_packet *get_kcs_packet(u16 channel_num)
++{
++ for (u16 idx = 0; idx < NO_OF_ENABLED_KCS_CHANNELS; idx++) {
++ if (channel_num == enabled_kcs_channel[idx])
++ return &m_kcs_pkt[idx];
++ }
++
++ /* very unlike code hits here. */
++ printf("ERROR: %s error. ChannelNo: %d\n", __func__, channel_num);
++ BUG();
++}
++
++static void kcs_force_abort(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++ printf("ERROR: KCS communication aborted (Channel:%d, Error:%d)\n",
++ channel_num, kcs_pkt->error);
++ set_kcs_state(channel_num, KCS_STATE_ERROR);
++ read_data(channel_num);
++ write_data(channel_num, ZERO_DATA);
++
++ kcs_pkt->phase = KCS_PHASE_ERROR;
++ kcs_pkt->read_req_done = false;
++ kcs_pkt->data_in_idx = 0;
++}
++
++static void init_kcs_packet(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++ kcs_pkt->channel = channel_num;
++ kcs_pkt->read_req_done = false;
++ kcs_pkt->phase = KCS_PHASE_IDLE;
++ kcs_pkt->error = KCS_NO_ERROR;
++ kcs_pkt->data_in_idx = 0;
++ kcs_pkt->data_out_idx = 0;
++ kcs_pkt->data_out_len = 0;
++}
++
++static void process_kcs_request(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++ if (!kcs_pkt->read_req_done)
++ return;
++
++ DBG_KCS("%s:- chan:%d\n", __func__, channel_num);
++
++#ifdef DEBUG_KCS_ENABLED
++ int i;
++
++ DBG_KCS("Request data(Len:%d): ", kcs_pkt->data_in_idx);
++ for (i = 0; i < kcs_pkt->data_in_idx; i++)
++ DBG_KCS(" 0x%02x", kcs_pkt->data_in[i]);
++ DBG_KCS("\n");
++#endif
++
++ /*
++ * TODO: Move it to IPMI Command Handler
++ * Below code is added for timebeing till
++ * we implement the IPMI command handler.
++ */
++ kcs_pkt->data_out[0] = kcs_pkt->data_in[0]; /* netfn */
++ kcs_pkt->data_out[1] = kcs_pkt->data_in[1]; /* cmd */
++ kcs_pkt->data_out[2] = IPMI_CC_OK; /* cc */
++
++ if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
++ (kcs_pkt->data_in[1] == 0x01)) {
++ /* Get Device ID */
++ u8 device_id[15] = { 0x23, 0x00, 0x12, 0x03, 0x02,
++ 0xBF, 0x57, 0x01, 0x00, 0x7B,
++ 0x00, 0x00, 0x00, 0x00, 0x00 };
++ for (i = 0; i < 15; i++)
++ kcs_pkt->data_out[i + 3] = device_id[i];
++ kcs_pkt->data_out_len = 18;
++ } else if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
++ (kcs_pkt->data_in[1] == 0x04)) {
++ /* Get Self Test Results */
++ kcs_pkt->data_out[3] = 0x56;
++ kcs_pkt->data_out[4] = 0x00;
++ kcs_pkt->data_out_len = 5;
++ } else {
++ kcs_pkt->data_out[2] =
++ IPMI_CC_INVALID; /* Invalid or not supported. */
++ kcs_pkt->data_out_len = 3;
++ }
++ /* END: TODO */
++
++#ifdef DEBUG_KCS_ENABLED
++ DBG_KCS("Response data(Len:%d): ", kcs_pkt->data_out_len);
++ for (i = 0; i < kcs_pkt->data_out_len; i++)
++ DBG_KCS(" 0x%02x", kcs_pkt->data_out[i]);
++ DBG_KCS("\n");
++#endif
++
++ kcs_pkt->phase = KCS_PHASE_READ;
++ write_data(channel_num, kcs_pkt->data_out[kcs_pkt->data_out_idx++]);
++ kcs_pkt->read_req_done = false;
++}
++
++static void read_kcs_data(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++ DBG_KCS("%s:- chan:%d, kcs_pkt->phase:%d\n", __func__, channel_num,
++ kcs_pkt->phase);
++
++ switch (kcs_pkt->phase) {
++ case KCS_PHASE_WRITE_START:
++ kcs_pkt->phase = KCS_PHASE_WRITE_DATA;
++ /* fall through */
++
++ case KCS_PHASE_WRITE_DATA:
++ if (kcs_pkt->data_in_idx >= MAX_KCS_PKT_SIZE) {
++ kcs_pkt->error = KCS_LENGTH_ERROR;
++ kcs_force_abort(channel_num);
++ return;
++ }
++ set_kcs_state(channel_num, KCS_STATE_WRITE);
++ write_data(channel_num, ZERO_DATA);
++ kcs_pkt->data_in[kcs_pkt->data_in_idx++] =
++ read_data(channel_num);
++ break;
++
++ case KCS_PHASE_WRITE_END:
++ if (kcs_pkt->data_in_idx >= MAX_KCS_PKT_SIZE) {
++ kcs_pkt->error = KCS_LENGTH_ERROR;
++ kcs_force_abort(channel_num);
++ return;
++ }
++ set_kcs_state(channel_num, KCS_STATE_READ);
++ kcs_pkt->data_in[kcs_pkt->data_in_idx++] =
++ read_data(channel_num);
++ kcs_pkt->phase = KCS_PHASE_READ_WAIT;
++ kcs_pkt->read_req_done = true;
++
++ process_kcs_request(channel_num);
++ break;
++
++ case KCS_PHASE_READ:
++ if (kcs_pkt->data_out_idx == kcs_pkt->data_out_len)
++ set_kcs_state(channel_num, KCS_STATE_IDLE);
++
++ u8 data = read_data(channel_num);
++ if (data != KCS_CTRL_CODE_READ) {
++ DBG_KCS("Invalid Read data. Phase:%d, Data:0x%02x\n",
++ kcs_pkt->phase, data);
++ set_kcs_state(channel_num, KCS_STATE_ERROR);
++ write_data(channel_num, ZERO_DATA);
++ break;
++ }
++
++ if (kcs_pkt->data_out_idx == kcs_pkt->data_out_len) {
++ write_data(channel_num, ZERO_DATA);
++ kcs_pkt->phase = KCS_PHASE_IDLE;
++ break;
++ }
++ write_data(channel_num,
++ kcs_pkt->data_out[kcs_pkt->data_out_idx++]);
++ break;
++
++ case KCS_PHASE_ABORT_1:
++ set_kcs_state(channel_num, KCS_STATE_READ);
++ read_data(channel_num);
++ write_data(channel_num, kcs_pkt->error);
++ kcs_pkt->phase = KCS_PHASE_ABORT_2;
++ break;
++
++ case KCS_PHASE_ABORT_2:
++ set_kcs_state(channel_num, KCS_STATE_IDLE);
++ read_data(channel_num);
++ write_data(channel_num, ZERO_DATA);
++ kcs_pkt->phase = KCS_PHASE_IDLE;
++ break;
++
++ default:
++ kcs_force_abort(channel_num);
++ }
++}
++
++static void read_kcs_cmd(u16 channel_num)
++{
++ struct kcs_packet *kcs_pkt = NULL;
++
++ kcs_pkt = get_kcs_packet(channel_num);
++
++ set_kcs_state(channel_num, KCS_STATE_WRITE);
++ write_data(channel_num, ZERO_DATA);
++
++ u16 cmd = read_data(channel_num);
++ DBG_KCS("%s:- chan:%d, cmd:0x%02x\n", __func__, channel_num, cmd);
++ switch (cmd) {
++ case KCS_CTRL_CODE_WRITE_START:
++ init_kcs_packet(channel_num);
++ kcs_pkt->phase = KCS_PHASE_WRITE_START;
++ break;
++
++ case KCS_CTRL_CODE_WRITE_END:
++ if (kcs_pkt->error != KCS_NO_ERROR) {
++ kcs_force_abort(channel_num);
++ return;
++ }
++
++ kcs_pkt->phase = KCS_PHASE_WRITE_END;
++ break;
++
++ case KCS_CTRL_CODE_GET_STATUS_ABORT:
++ kcs_pkt->phase = KCS_PHASE_ABORT_1;
++ kcs_pkt->error = KCS_ABORT_BY_CMD;
++ break;
++
++ default:
++ kcs_pkt->error = KCS_ILLEGAL_CTRL_CMD;
++ kcs_force_abort(channel_num);
++ }
++}
++
++static u16 kcs_irq_handler(struct pt_regs *regs)
++{
++ for (u16 idx = 0; idx < NO_OF_ENABLED_KCS_CHANNELS; idx++) {
++ u16 channel_num = enabled_kcs_channel[idx];
++ /* Look-up the interrupted KCS channel */
++ u16 status = read_status(channel_num);
++ if (status & BIT_STATUS_IBF) {
++ if (status & BIT_STATUS_COD)
++ read_kcs_cmd(channel_num);
++ else
++ read_kcs_data(channel_num);
++ }
++ }
++
++ return 0;
++}
++
++static void set_kcs_channel_addr(u16 channel_num)
++{
++ u32 val;
++
++ switch (channel_num) {
++ case 1:
++ val = readl(AST_LPC_BASE + LPC_HICR4) & ~BIT_LADR12AS;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ val = (KCS_CHANNEL1_ADDR >> 8);
++ writel(val, AST_LPC_BASE + LPC_LADR12H);
++ val = (KCS_CHANNEL1_ADDR & 0xFF);
++ writel(val, AST_LPC_BASE + LPC_LADR12L);
++ break;
++
++ case 2:
++ val = readl(AST_LPC_BASE + LPC_HICR4) | BIT_LADR12AS;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ val = (KCS_CHANNEL2_ADDR >> 8);
++ writel(val, AST_LPC_BASE + LPC_LADR12H);
++ val = (KCS_CHANNEL2_ADDR & 0xFF);
++ writel(val, AST_LPC_BASE + LPC_LADR12L);
++ break;
++
++ case 3:
++ val = (KCS_CHANNEL3_ADDR >> 8);
++ writel(val, AST_LPC_BASE + LPC_LADR3H);
++ val = (KCS_CHANNEL3_ADDR & 0xFF);
++ writel(val, AST_LPC_BASE + LPC_LADR3L);
++ break;
++
++ case 4:
++ val = (((KCS_CHANNEL4_ADDR + 1) << 16) | KCS_CHANNEL4_ADDR);
++ writel(val, AST_LPC_BASE + LPC_LADR4);
++ break;
++
++ default:
++ DBG_KCS("Invalid channel (%d) specified\n", channel_num);
++ break;
++ }
++}
++
++static void enable_kcs_channel(u16 channel_num, u16 enable)
++{
++ u32 val;
++
++ switch (channel_num) {
++ case 1:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICR2) | BIT_IBFIE1;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ val = readl(AST_LPC_BASE + LPC_HICR0) | BIT_LPC1E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICR0) & ~BIT_LPC1E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR2) & ~BIT_IBFIE1;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ }
++ break;
++
++ case 2:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICR2) | BIT_IBFIE2;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ val = readl(AST_LPC_BASE + LPC_HICR0) | BIT_LPC2E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICR0) & ~BIT_LPC2E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR2) & ~BIT_IBFIE2;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ }
++ break;
++
++ case 3:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICR2) | BIT_IBFIE3;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ val = readl(AST_LPC_BASE + LPC_HICR0) | BIT_LPC3E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR4) | BIT_KCSENBL;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICR0) & ~BIT_LPC3E;
++ writel(val, AST_LPC_BASE + LPC_HICR0);
++ val = readl(AST_LPC_BASE + LPC_HICR4) & ~BIT_KCSENBL;
++ writel(val, AST_LPC_BASE + LPC_HICR4);
++ val = readl(AST_LPC_BASE + LPC_HICR2) & ~BIT_IBFIE3;
++ writel(val, AST_LPC_BASE + LPC_HICR2);
++ }
++ break;
++
++ case 4:
++ if (enable) {
++ val = readl(AST_LPC_BASE + LPC_HICRB) | BIT_IBFIE4 |
++ BIT_LPC4E;
++ writel(val, AST_LPC_BASE + LPC_HICRB);
++ } else {
++ val = readl(AST_LPC_BASE + LPC_HICRB) &
++ ~(BIT_IBFIE4 | BIT_LPC4E);
++ writel(val, AST_LPC_BASE + LPC_HICRB);
++ }
++ break;
++
++ default:
++ DBG_KCS("Invalid channel (%d) specified\n", channel_num);
++ }
++}
++
++void kcs_init(void)
++{
++ /* Initialize the KCS channels. */
++ for (u16 idx = 0; idx < NO_OF_ENABLED_KCS_CHANNELS; idx++) {
++ u16 channel_num = enabled_kcs_channel[idx];
++ DBG_KCS("%s Channel: %d\n", __func__, channel_num);
++ set_kcs_channel_addr(channel_num);
++ enable_kcs_channel(channel_num, 1);
++
++ /* Set KCS channel state to idle */
++ set_kcs_state(channel_num, KCS_STATE_IDLE);
++ }
++
++ /* KCS interrupt */
++ request_irq(IRQ_SRC_LPC, kcs_irq_handler);
++}
+diff --git a/board/aspeed/ast-g5/ast-g5-kcs.h b/board/aspeed/ast-g5/ast-g5-kcs.h
+new file mode 100644
+index 0000000..52b5097
+--- /dev/null
++++ b/board/aspeed/ast-g5/ast-g5-kcs.h
+@@ -0,0 +1,114 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (c) 2018-2019 Intel Corporation */
++
++#include <asm/io.h>
++#include <common.h>
++
++#include "ast-g5.h"
++
++#define KCS_CHANNEL_MAX 4
++#define IRQ_SRC_LPC 8 /* IRQ 8 */
++#define MAX_KCS_PKT_SIZE (64 * 1024)
++/* KCS channel addresses */
++#define KCS_CHANNEL1_ADDR 0xCA0
++#define KCS_CHANNEL2_ADDR 0xCA8
++#define KCS_CHANNEL3_ADDR 0xCA2
++#define KCS_CHANNEL4_ADDR 0xCB2
++
++#define ZERO_DATA 0x00
++
++/* Aspeed KCS control registers */
++#define LPC_HICR0 0x00 /* Host Interface Control Register 0 */
++#define LPC_HICR1 0x04 /* Host Interface Control Register 1 */
++#define LPC_HICR2 0x08 /* Host Interface Control Register 2 */
++#define LPC_HICR3 0x0C /* Host Interface Control Register 3 */
++#define LPC_HICR4 0x10 /* Host Interface Control Register 4 */
++#define LPC_LADR3H 0x14 /* LPC channel #3 Address Register H */
++#define LPC_LADR3L 0x18 /* LPC channel #3 Address Register H */
++#define LPC_LADR12H 0x1C /* LPC channel #1#2 Address Register H */
++#define LPC_LADR12L 0x20 /* LPC channel #1#2 Address Register L */
++#define LPC_IDR1 0x24 /* Input Data Register 1 */
++#define LPC_IDR2 0x28 /* Input Data Register 2 */
++#define LPC_IDR3 0x2C /* Input Data Register 3 */
++#define LPC_ODR1 0x30 /* Output Data Register 1 */
++#define LPC_ODR2 0x34 /* Output Data Register 2 */
++#define LPC_ODR3 0x38 /* Output Data Register 3 */
++#define LPC_STR1 0x3C /* Status Register 1 */
++#define LPC_STR2 0x40 /* Status Register 2 */
++#define LPC_STR3 0x44 /* Status Register 3 */
++
++/* LPC Bits */
++#define BIT_LADR12AS BIT(7) /* Channel Address selection */
++#define BIT_IBFIE1 BIT(1) /* Enable IDR1 Recv completion interrupt */
++#define BIT_IBFIE2 BIT(2) /* Enable IDR2 Recv completion interrupt */
++#define BIT_IBFIE3 BIT(3) /* Enable IBF13 interrupt */
++#define BIT_LPC1E BIT(5) /* Enable LPC channel #1 */
++#define BIT_LPC2E BIT(6) /* Enable LPC channel #2 */
++#define BIT_LPC3E BIT(7) /* Enable LPC channel #2 */
++#define BIT_KCSENBL BIT(2) /* Enable KCS interface in Channel #3 */
++
++/* mapped to lpc-host@80 IO space */
++#define LPC_HICRB 0x080
++#define BIT_IBFIE4 BIT(1)
++#define BIT_LPC4E BIT(0)
++#define LPC_LADR4 0x090
++#define LPC_IDR4 0x094 /* Input Data Register 4 */
++#define LPC_ODR4 0x098 /* Output Data Register 4 */
++#define LPC_STR4 0x09c /* Status Data Register 4 */
++
++#define BIT_STATUS_OBF BIT(0) /* Output Data Register full #1/#2/#3 */
++#define BIT_STATUS_IBF BIT(1) /* Input Data Register full #1/#2/#3 */
++#define BIT_STATUS_COD BIT(3) /* Command/Data - (1=command,0=data) */
++
++#define KCS_STATE_MASK 0xC0 /* BIT[6:7] of status register */
++#define KCS_STATE(state) ((state) << 6)
++
++/* IPMI2.0(section 9.7) - KCS interface State Bits */
++#define KCS_STATE_IDLE 0x00
++#define KCS_STATE_READ 0x01
++#define KCS_STATE_WRITE 0x02
++#define KCS_STATE_ERROR 0x03
++
++/* IPMI2.0(section 9.10) - KCS interface control codes */
++#define KCS_CTRL_CODE_GET_STATUS_ABORT 0x60
++#define KCS_CTRL_CODE_WRITE_START 0x61
++#define KCS_CTRL_CODE_WRITE_END 0x62
++#define KCS_CTRL_CODE_READ 0x68
++
++struct kcs_io_reg {
++ u32 idr;
++ u32 odr;
++ u32 str;
++};
++
++enum kcs_phase {
++ KCS_PHASE_IDLE = 0,
++ KCS_PHASE_WRITE_START = 1,
++ KCS_PHASE_WRITE_DATA = 2,
++ KCS_PHASE_WRITE_END = 3,
++ KCS_PHASE_READ_WAIT = 4,
++ KCS_PHASE_READ = 5,
++ KCS_PHASE_ABORT_1 = 6,
++ KCS_PHASE_ABORT_2 = 7,
++ KCS_PHASE_ERROR = 8
++};
++
++enum kcs_error {
++ KCS_NO_ERROR = 0x00,
++ KCS_ABORT_BY_CMD = 0x01,
++ KCS_ILLEGAL_CTRL_CMD = 0x02,
++ KCS_LENGTH_ERROR = 0x06,
++ KCS_UNSPECIFIED_ERROR = 0xFF,
++};
++
++struct kcs_packet {
++ enum kcs_phase phase;
++ enum kcs_error error;
++ u16 channel;
++ bool read_req_done;
++ u16 data_in_idx;
++ u8 data_in[MAX_KCS_PKT_SIZE];
++ u16 data_out_len;
++ u16 data_out_idx;
++ u8 data_out[MAX_KCS_PKT_SIZE];
++};
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch
new file mode 100644
index 000000000..746063a56
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0022-u-boot-env-change-for-PFR-image.patch
@@ -0,0 +1,35 @@
+From 6651a2663ee3e9f02c6ed8377097456528a2ee1a Mon Sep 17 00:00:00 2001
+From: Vikram Bodireddy <vikram.bodireddy@intel.com>
+Date: Tue, 26 Mar 2019 20:34:51 +0530
+Subject: [PATCH] u-boot env change for PFR image
+
+Signed-off-by: Vikram Bodireddy <vikram.bodireddy@intel.com>
+---
+ include/configs/ast-common.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/configs/ast-common.h b/include/configs/ast-common.h
+index b7d7192..dd89d91 100644
+--- a/include/configs/ast-common.h
++++ b/include/configs/ast-common.h
+@@ -103,7 +103,7 @@
+ #define CONFIG_SYS_MAX_FLASH_BANKS (CONFIG_FMC_CS)
+ #define CONFIG_SYS_MAX_FLASH_SECT (8192) /* max number of sectors on one chip */
+ #define CONFIG_ENV_IS_IN_FLASH 1
+-#define CONFIG_ENV_OFFSET 0x2400000 /* environment starts here */
++#define CONFIG_ENV_OFFSET 0xa0000 /* environment starts here */
+ #define CONFIG_ENV_ADDR (AST_FMC_CS0_BASE + CONFIG_ENV_OFFSET)
+ #define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
+
+@@ -111,7 +111,7 @@
+ #define CONFIG_ENV_ADDR_REDUND (AST_FMC_CS0_BASE + CONFIG_ENV_OFFSET_REDUND)
+ #define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+
+-#define CONFIG_BOOTCOMMAND "bootm 20080000"
++#define CONFIG_BOOTCOMMAND "bootm 21100000"
+ #define CONFIG_ENV_OVERWRITE
+
+ #define ASPEED_ENV_SETTINGS \
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch
new file mode 100644
index 000000000..5e8cd103d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0023-Add-TPM-enable-pulse-triggering.patch
@@ -0,0 +1,52 @@
+From f762526077a7af02fc93bacc74fb9d49481d664f Mon Sep 17 00:00:00 2001
+From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+Date: Fri, 29 Mar 2019 12:30:20 -0700
+Subject: [PATCH] Add TPM enable pulse triggering
+
+This commit adds onboard TPM enable pulse triggering.
+
+Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
+---
+ board/aspeed/ast-g5/ast-g5-intel.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c
+index f9955c70d2f2..d9ba4a47a413 100644
+--- a/board/aspeed/ast-g5/ast-g5-intel.c
++++ b/board/aspeed/ast-g5/ast-g5-intel.c
+@@ -53,8 +53,8 @@ static const GPIOValue gpio_table[] = {
+ GPIO_DEBOUNCE_8MS},
+
+ /* Enable Pulse -- pin D6 */
+- [GPIO_ENABLE_TPM_PULSE] = {PORT_PIN(GPIO_PORT_D, GPIO_PIN_6),
+- GPIO_CFG_DEFAULT, 0, GPIO_DEBOUNCE_8MS},
++ [GPIO_ENABLE_TPM_PULSE] = {TPM_EN_PULSE_PORT_PIN, GPCFG_OUTPUT_EN, 0,
++ GPIO_DEBOUNCE_NONE},
+ };
+
+ #define LPC_SNOOP_ADDR 0x80
+@@ -232,6 +232,13 @@ void id_led_control(int id, int action)
+ gpio_set_value(s_led_info[id].gpio, s_led_info[id].state);
+ }
+
++static void enable_onboard_tpm(void)
++{
++ gpio_set_value(GPIO_ENABLE_TPM_PULSE, 1);
++ mdelay(50);
++ gpio_set_value(GPIO_ENABLE_TPM_PULSE, 0);
++}
++
+ static void timer8_irq_handler(void *regs)
+ {
+ int i;
+@@ -445,6 +452,7 @@ void ast_g5_intel(void)
+ espi_init();
+ sgpio_init();
+ timer8_init();
++ enable_onboard_tpm();
+ if (intel_force_firmware_jumper_enabled()) {
+ id_led_control(GPIO_AMBER_LED, EIDLED_On);
+ kcs_init();
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch
new file mode 100644
index 000000000..47cb56062
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0024-IPMI-command-handler-implementation-in-uboot.patch
@@ -0,0 +1,339 @@
+From d770ea7a30742339b0692858847838dd2a738aeb Mon Sep 17 00:00:00 2001
+From: AppaRao Puli <apparao.puli@linux.intel.com>
+Date: Fri, 5 Apr 2019 17:53:21 +0530
+Subject: [PATCH] IPMI command handler implementation in uboot
+
+IPMI command handler implemtation in uBoot.
+Implemented IPMI commands:
+ 1) Get Device ID
+ 2) Get Self Test Result
+
+Tested By:
+Ran the above IPMI command Via KCS channel
+and got proper response.
+- Get Device ID
+ Req: cmdtool.efi 20 18 1
+ Res: 0x00 0x23 0x00 0x82 0x03 0x02 0x00 0x57 0x01 0x00 0x7b 0x00 0x00 0x00 0x00 0x00
+- Get Self Test Results
+ Req: cmdtool.efi 20 18 4
+ Res: 00 56 00
+
+Change-Id: I18b205bc45c34f7c4ef16adc29fa5bd494624ceb
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+---
+ board/aspeed/ast-g5/Makefile | 1 +
+ board/aspeed/ast-g5/ast-g5-kcs.c | 78 +++++++++++++-----------
+ board/aspeed/ast-g5/ipmi-handler.c | 118 +++++++++++++++++++++++++++++++++++++
+ board/aspeed/ast-g5/ipmi-handler.h | 40 +++++++++++++
+ 4 files changed, 202 insertions(+), 35 deletions(-)
+ create mode 100644 board/aspeed/ast-g5/ipmi-handler.c
+ create mode 100644 board/aspeed/ast-g5/ipmi-handler.h
+
+diff --git a/board/aspeed/ast-g5/Makefile b/board/aspeed/ast-g5/Makefile
+index 05972b9..f28fcfe 100644
+--- a/board/aspeed/ast-g5/Makefile
++++ b/board/aspeed/ast-g5/Makefile
+@@ -5,3 +5,4 @@ obj-y += ast-g5-irq.o
+ obj-y += ast-g5-gpio.o
+ obj-y += ast-g5-timer.o
+ obj-y += ast-g5-kcs.o
++obj-y += ipmi-handler.o
+diff --git a/board/aspeed/ast-g5/ast-g5-kcs.c b/board/aspeed/ast-g5/ast-g5-kcs.c
+index f983b4a..05b1cc2 100644
+--- a/board/aspeed/ast-g5/ast-g5-kcs.c
++++ b/board/aspeed/ast-g5/ast-g5-kcs.c
+@@ -1,7 +1,7 @@
+ // SPDX-License-Identifier: GPL-2.0
+ // Copyright (c) 2018-2019 Intel Corporation
+
+-#include "ast-g5-kcs.h"
++#include "ipmi-handler.h"
+
+ #define DEBUG_KCS_ENABLED 0
+ #ifdef DEBUG_KCS_ENABLED
+@@ -10,11 +10,6 @@
+ #define DBG_KCS(...)
+ #endif
+
+-/* TODO: Move to IPMI file. */
+-#define IPMI_CC_OK 0x00
+-#define IPMI_CC_INVALID 0xC1
+-#define IPMI_CC_UNSPECIFIED 0xFF
+-
+ #define KCS_CHANNEL_NO_3 3
+
+ static const u16 enabled_kcs_channel[] = { KCS_CHANNEL_NO_3 };
+@@ -104,13 +99,13 @@ static void init_kcs_packet(u16 channel_num)
+ static void process_kcs_request(u16 channel_num)
+ {
+ struct kcs_packet *kcs_pkt = NULL;
++ struct ipmi_cmd_data ipmi_data;
+
+ kcs_pkt = get_kcs_packet(channel_num);
+ if (!kcs_pkt->read_req_done)
+ return;
+
+ DBG_KCS("%s:- chan:%d\n", __func__, channel_num);
+-
+ #ifdef DEBUG_KCS_ENABLED
+ int i;
+
+@@ -119,37 +114,49 @@ static void process_kcs_request(u16 channel_num)
+ DBG_KCS(" 0x%02x", kcs_pkt->data_in[i]);
+ DBG_KCS("\n");
+ #endif
++ u8 req_lun = kcs_pkt->data_in[0] & 0x03; /* LUN[1:0] */
++ ipmi_data.net_fun = (kcs_pkt->data_in[0] >> 2); /* netfn[7:2] */
++ ipmi_data.cmd = kcs_pkt->data_in[1]; /* cmd */
++ /* We support only BMC LUN 00h */
++ if (req_lun != LUN_BMC) {
++ kcs_pkt->data_out[0] =
++ GET_RESP_NETFN_LUN(req_lun, ipmi_data.net_fun);
++ kcs_pkt->data_out[1] = ipmi_data.cmd; /* cmd */
++ kcs_pkt->data_out[2] = IPMI_CC_INVALID_CMD_LUN; /* CC code */
++ kcs_pkt->data_out_len = 3;
++ goto done;
++ }
+
+- /*
+- * TODO: Move it to IPMI Command Handler
+- * Below code is added for timebeing till
+- * we implement the IPMI command handler.
+- */
+- kcs_pkt->data_out[0] = kcs_pkt->data_in[0]; /* netfn */
+- kcs_pkt->data_out[1] = kcs_pkt->data_in[1]; /* cmd */
+- kcs_pkt->data_out[2] = IPMI_CC_OK; /* cc */
+-
+- if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
+- (kcs_pkt->data_in[1] == 0x01)) {
+- /* Get Device ID */
+- u8 device_id[15] = { 0x23, 0x00, 0x12, 0x03, 0x02,
+- 0xBF, 0x57, 0x01, 0x00, 0x7B,
+- 0x00, 0x00, 0x00, 0x00, 0x00 };
+- for (i = 0; i < 15; i++)
+- kcs_pkt->data_out[i + 3] = device_id[i];
+- kcs_pkt->data_out_len = 18;
+- } else if (((kcs_pkt->data_in[0] >> 2) == 0x06) &&
+- (kcs_pkt->data_in[1] == 0x04)) {
+- /* Get Self Test Results */
+- kcs_pkt->data_out[3] = 0x56;
+- kcs_pkt->data_out[4] = 0x00;
+- kcs_pkt->data_out_len = 5;
+- } else {
+- kcs_pkt->data_out[2] =
+- IPMI_CC_INVALID; /* Invalid or not supported. */
++ /* Boundary check */
++ if ((kcs_pkt->data_in_idx - 2) > sizeof(ipmi_data.req_data)) {
++ kcs_pkt->data_out[0] =
++ GET_RESP_NETFN_LUN(req_lun, ipmi_data.net_fun);
++ kcs_pkt->data_out[1] = ipmi_data.cmd; /* cmd */
++ kcs_pkt->data_out[2] = IPMI_CC_OUT_OF_SPACE; /* CC code */
+ kcs_pkt->data_out_len = 3;
++ goto done;
+ }
+- /* END: TODO */
++ /* Fill in IPMI request data */
++ ipmi_data.req_len = kcs_pkt->data_in_idx - 2;
++ for (i = 0; i < kcs_pkt->data_in_idx - 2; i++)
++ ipmi_data.req_data[i] = kcs_pkt->data_in[i + 2];
++
++ /* Call IPMI command handler */
++ ipmi_cmd_handler(&ipmi_data);
++
++ /* Get IPMI response and fill KCS out data */
++ /* First 2 bytes in KCS response are netFn, Cmd */
++ kcs_pkt->data_out[0] = GET_RESP_NETFN_LUN(req_lun, ipmi_data.net_fun);
++ kcs_pkt->data_out[1] = ipmi_data.cmd;
++ if ((ipmi_data.res_len + 2) > sizeof(kcs_pkt->data_out)) {
++ kcs_pkt->data_out[2] = IPMI_CC_UNSPECIFIED; /* CC code */
++ kcs_pkt->data_out_len = 3;
++ goto done;
++ }
++ for (i = 0; i < ipmi_data.res_len; i++)
++ kcs_pkt->data_out[i + 2] = ipmi_data.res_data[i];
++
++ kcs_pkt->data_out_len = ipmi_data.res_len + 2;
+
+ #ifdef DEBUG_KCS_ENABLED
+ DBG_KCS("Response data(Len:%d): ", kcs_pkt->data_out_len);
+@@ -158,6 +165,7 @@ static void process_kcs_request(u16 channel_num)
+ DBG_KCS("\n");
+ #endif
+
++done:
+ kcs_pkt->phase = KCS_PHASE_READ;
+ write_data(channel_num, kcs_pkt->data_out[kcs_pkt->data_out_idx++]);
+ kcs_pkt->read_req_done = false;
+diff --git a/board/aspeed/ast-g5/ipmi-handler.c b/board/aspeed/ast-g5/ipmi-handler.c
+new file mode 100644
+index 0000000..9cccee9
+--- /dev/null
++++ b/board/aspeed/ast-g5/ipmi-handler.c
+@@ -0,0 +1,118 @@
++
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2018-2019 Intel Corporation
++
++#include "ipmi-handler.h"
++
++/* IPMI network function codes */
++#define NETFN_APP 0x06
++
++/* IPMI command codes */
++#define CMD_GET_DEV_ID 0x01
++#define CMD_GET_SELF_TEST_RESULTS 0x04
++
++typedef u16 (*fun_handler)(u8 *req, u16 req_len, u8 *res);
++
++struct get_dev_id {
++ u8 completion_code;
++ u8 dev_id;
++ u8 dev_rev;
++ u8 fw_rev1;
++ u8 fw_rev2;
++ u8 ipmi_ver;
++ u8 dev_support;
++ u8 mfg_id[3];
++ u8 product_id[2];
++ u8 aux_fw_rev[4];
++};
++struct self_test_res {
++ u8 completion_code;
++ u8 res_byte[2];
++};
++
++struct ipmi_cmd_table {
++ u8 net_fun;
++ u8 cmd;
++ fun_handler process_cmd;
++};
++
++static u16 get_device_id(u8 *req, u16 req_len, u8 *res)
++{
++ /* Get Device ID */
++ bool operation = 1; /* Firmware operation */
++ u8 intel_mfg_id[3] = { 0x57, 0x01, 0x00 };
++ u8 platform_id[2] = { 0x7B, 0x00 };
++ u8 aux_fw_rev[4] = { 0x00, 0x00, 0x00, 0x00 };
++ struct get_dev_id *result = (struct get_dev_id *)res;
++
++ if (req_len != 0) {
++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH;
++ return sizeof(result->completion_code);
++ }
++
++ result->completion_code = IPMI_CC_OK;
++ result->dev_id = 0x23;
++ result->dev_rev = 0x00; /* Not provides dev SDR */
++
++ result->ipmi_ver = 0x02; /* IPMI 2.0 */
++ result->dev_support = 0x00; /* No dev support in this mode */
++ memcpy(result->mfg_id, intel_mfg_id, sizeof(result->mfg_id));
++ memcpy(result->aux_fw_rev, aux_fw_rev, sizeof(result->aux_fw_rev));
++
++ /* TODO: Get Firmware version from flash(PFM Header) */
++ result->fw_rev1 = ((operation << 7) | (0x02 & 0x7F));
++ result->fw_rev2 = 0x03;
++ /* TODO: Read Platform ID from GPIO */
++ memcpy(result->product_id, platform_id, sizeof(result->product_id));
++
++ return sizeof(struct get_dev_id);
++}
++
++static u16 get_self_test_result(u8 *req, u16 req_len, u8 *res)
++{
++ /* Get Self Test Results */
++ struct self_test_res *result = (struct self_test_res *)res;
++
++ if (req_len != 0) {
++ result->completion_code = IPMI_CC_INVALID_DATA_LENGTH;
++ return sizeof(result->completion_code);
++ }
++
++ result->completion_code = IPMI_CC_OK;
++ result->res_byte[0] = 0x56; /* Self test function not implemented. */
++ result->res_byte[1] = 0x00;
++
++ return sizeof(struct self_test_res);
++}
++
++const struct ipmi_cmd_table cmd_info[] = {
++ { NETFN_APP, CMD_GET_DEV_ID, get_device_id },
++ { NETFN_APP, CMD_GET_SELF_TEST_RESULTS, get_self_test_result }
++};
++
++#define CMD_TABLE_SIZE ARRAY_SIZE(cmd_info)
++
++void ipmi_cmd_handler(struct ipmi_cmd_data *ipmi_data)
++{
++ int i = 0;
++ for (i = 0; i < CMD_TABLE_SIZE; i++) {
++ if ((cmd_info[i].net_fun == ipmi_data->net_fun) &&
++ (cmd_info[i].cmd == ipmi_data->cmd)) {
++ break;
++ }
++ }
++
++ if (i == CMD_TABLE_SIZE) {
++ /* Invalid or not supported. */
++ ipmi_data->res_data[0] = IPMI_CC_INVALID_CMD;
++ ipmi_data->res_len = 1;
++ return;
++ }
++
++ /* Call the appropriate function handler */
++ ipmi_data->res_len =
++ cmd_info[i].process_cmd(ipmi_data->req_data, ipmi_data->req_len,
++ &ipmi_data->res_data[0]);
++
++ return;
++}
+diff --git a/board/aspeed/ast-g5/ipmi-handler.h b/board/aspeed/ast-g5/ipmi-handler.h
+new file mode 100644
+index 0000000..9d46d9b
+--- /dev/null
++++ b/board/aspeed/ast-g5/ipmi-handler.h
+@@ -0,0 +1,40 @@
++
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (c) 2018-2019 Intel Corporation */
++
++#include "ast-g5-kcs.h"
++
++/* IPMI completion codes */
++#define IPMI_CC_OK 0x00
++#define IPMI_CC_NODE_BUSY 0xC0
++#define IPMI_CC_INVALID_CMD 0xC1
++#define IPMI_CC_INVALID_CMD_LUN 0xC2
++#define IPMI_CC_OUT_OF_SPACE 0xC4
++#define IPMI_CC_INVALID_DATA_LENGTH 0xC7
++#define IPMI_CC_INVALID_DATA_FIELD 0xCC
++#define IPMI_CC_UNSPECIFIED 0xFF
++
++/* BMC IPMB LUNs */
++#define LUN_BMC 0x00
++#define LUN_OEM1 0x01
++#define LUN_SMS 0x02
++#define LUN_OEM2 0x01
++
++
++#define MAX_IPMI_REQ_DATA_SIZE MAX_KCS_PKT_SIZE
++#define MAX_IPMI_RES_DATA_SIZE 64
++
++/* Response netFn[7:2], Lun[1:0] */
++#define GET_RESP_NETFN_LUN(lun, netfn) \
++ ((lun & 0x03) | (((netfn + 1) << 2) & 0xFD))
++
++struct ipmi_cmd_data {
++ u8 net_fun;
++ u8 cmd;
++ u16 req_len;
++ u16 res_len;
++ u8 req_data[MAX_IPMI_REQ_DATA_SIZE];
++ u8 res_data[MAX_IPMI_RES_DATA_SIZE];
++};
++
++void ipmi_cmd_handler(struct ipmi_cmd_data *ipmi_data);
+--
+2.7.4
+
diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend
new file mode 100644
index 000000000..8eb06b622
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend
@@ -0,0 +1,33 @@
+FILESEXTRAPATHS_append_wolfpass:= "${THISDIR}/files:"
+
+# the meta-phosphor layer adds this patch, which conflicts
+# with the intel layout for environment
+SRC_URI_remove_wolfpass = " file://0001-configs-ast-Add-redundnant-env.patch"
+
+SRC_URI_append_wolfpass = " \
+ file://0001-flash-use-readX-writeX-not-udelay.patch \
+ file://0002-intel-layout-environment-addr.patch \
+ file://0004-Make-sure-debug-uart-is-using-24MHz-clock-source.patch \
+ file://0005-enable-passthrough-in-uboot.patch \
+ file://0006-Add-Aspeed-g5-interrupt-support.patch \
+ file://0007-Add-espi-support.patch \
+ file://0008-add-sgio-support-for-port80-snoop-post-LEDs.patch \
+ file://0009-Add-basic-GPIO-support.patch \
+ file://0010-Update-Force-Firmware-Update-Jumper-to-use-new-gpio.patch \
+ file://0011-Add-basic-timer-support-for-Aspeed-g5-in-U-Boot.patch \
+ file://0012-Add-status-and-ID-LED-support.patch \
+ file://0013-aspeed-Add-Pwm-Driver.patch \
+ file://0014-Keep-interrupts-enabled-until-last-second.patch \
+ file://0015-Rewrite-memmove-to-optimize-on-word-transfers.patch \
+ file://0016-Add-support-for-128MB-Macronix-spi-flash-MX66L1G45G.patch \
+ file://0017-Enable-Macronix-and-Micron-SPI-support.patch \
+ file://0018-Add-support-for-Macronix-and-Micron-1Gbits-SPI-flash.patch \
+ file://0019-u-boot-full-platform-reset-espi-oob-ready.patch \
+ file://0020-Enable-PCIe-L1-support.patch \
+ file://0020-Add-system-reset-status-support.patch \
+ file://0021-Config-host-uart-clock-source-using-environment-vari.patch \
+ file://0022-KCS-driver-support-in-uBoot.patch \
+ file://0023-Add-TPM-enable-pulse-triggering.patch \
+ file://0024-IPMI-command-handler-implementation-in-uboot.patch \
+ "
+SRC_URI_append_wolfpass += "${@bb.utils.contains('IMAGE_TYPE', 'pfr', 'file://0022-u-boot-env-change-for-PFR-image.patch', '', d)}"