--- xfsbl_config.h
+++ xfsbl_config.h
@@ -77,7 +77,7 @@
 #endif
 
 #ifndef FSBL_DEBUG_VAL
-#define FSBL_DEBUG_VAL              (0U)
+#define FSBL_DEBUG_VAL              (1U)
 #endif
 
 #ifndef FSBL_DEBUG_INFO_VAL
@@ -140,11 +140,11 @@
  *       header is not authenticated" is excluded
  */
 #ifndef FSBL_NAND_EXCLUDE_VAL
-#define FSBL_NAND_EXCLUDE_VAL			(0U)
+#define FSBL_NAND_EXCLUDE_VAL			(1U)
 #endif
 
 #ifndef FSBL_QSPI_EXCLUDE_VAL
-#define FSBL_QSPI_EXCLUDE_VAL			(0U)
+#define FSBL_QSPI_EXCLUDE_VAL			(1U)
 #endif
 
 #ifndef FSBL_SD_EXCLUDE_VAL
 
--- xfsbl_ddr_init.c
+++ xfsbl_ddr_init.c
@@ -1,3 +1,4 @@
+ 
 /******************************************************************************
 * Copyright (c) 2019 - 2020 Xilinx, Inc.  All rights reserved.
 * SPDX-License-Identifier: MIT
@@ -717,7 +718,8 @@
 
 #if !(defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208))
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV))
 /*****************************************************************************/
 /**
  * This function computes DIMM parameters based upon the SPD information.
@@ -1894,7 +1896,8 @@
 
 #if !(defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208))
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV))
 /*****************************************************************************/
 /**
  * This function calculates the DDRC register values for DDR3
@@ -2966,7 +2969,8 @@
 
 #if !(defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208))
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV))
 /*****************************************************************************/
 /**
  * This function calculates and writes DDR controller registers
@@ -3437,7 +3441,8 @@
 
 #if !(defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208))
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV))
 /*****************************************************************************/
 /**
  * This function calculates the PHY register values for DDR3
@@ -5197,7 +5202,8 @@
 
 #if !(defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208))
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV))
 /*****************************************************************************/
 /**
  * This function calculates and writes the DDR-PHY registers
@@ -6521,7 +6527,8 @@
 
 #if defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208)
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV)
 /*****************************************************************************/
 /**
  * This function calculates and writes DDR controller registers
@@ -6644,6 +6651,7 @@
 		goto END;
 	}
 
+#if !defined(XPS_BOARD_GZU_3EG) && !defined(XPS_BOARD_GZU_5EV)
 	/*
 	 * Configure I2C Mux to select DDR4 SODIMM Slave
 	 * 0x08U - Enable DDR4 SODIMM module
@@ -6683,6 +6691,7 @@
 		UStatus = XFSBL_FAILURE;
 		goto END;
 	}
+#endif //!XPS_BOARD_GZU_3EG && !XPS_BOARD_GZU_5EV
 
 	/*
 	 * Set SODIMM control address to enable access to lower
@@ -6836,7 +6845,8 @@
 	u8 SpdData[512U];
 #if !(defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208)) || defined(XFSBL_ENABLE_DDR_SR)
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV)) || defined(XFSBL_ENABLE_DDR_SR)
 	u32 RegVal;
 #endif
 
@@ -6855,7 +6865,8 @@
 
 #if defined(XPS_BOARD_ZCU102) || defined(XPS_BOARD_ZCU106) \
 	|| defined(XPS_BOARD_ZCU111) || defined(XPS_BOARD_ZCU216) \
-	|| defined(XPS_BOARD_ZCU208)
+	|| defined(XPS_BOARD_ZCU208) \
+	|| defined(XPS_BOARD_GZU_3EG) || defined(XPS_BOARD_GZU_5EV)
 	/* ZCU102, ZCU106 and ZCU111, ZCU216 and ZCU208 Boards have support
 	 * only for DDR4 DIMMs. Skip checking for DDR type for these boards.
 	 */


--- xfsbl_board.c
+++ xfsbl_board.c
@@ -790,6 +790,93 @@
 }
 #endif
 #endif
+
+#include "sleep.h"
+#include "xgpiops.h"
+/*
+ * InitGpios is a board-specific init routine for the Digilent Genesys ZU.
+ * It resets the GPIO expander MCP23S08 using MIO13. Then through SS[1] of
+ * SPI0, it initializes it and cycles the USB PHY resets connected to it.
+ */
+static u32 InitGpios()
+{
+#if defined(XPAR_PSU_SPI_0_DEVICE_ID) && defined (XPAR_PSU_GPIO_0_DEVICE_ID)
+	u32 RegVal;
+	XStatus Status;
+	XGpioPs_Config* gpio_conf;
+	XGpioPs gpio_inst;
+
+	gpio_conf = XGpioPs_LookupConfig(XPAR_PSU_GPIO_0_DEVICE_ID);
+	if (NULL == gpio_conf) {
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIO_FAIL\r\n");
+		return XST_FAILURE;
+	}
+	if (XST_SUCCESS != XGpioPs_CfgInitialize(&gpio_inst, gpio_conf, gpio_conf->BaseAddr))
+	{
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIO_FAIL\r\n");
+		return XST_FAILURE;
+	}
+	//Set PORTEXP_RESETN_PIN as output and drive 0
+	XGpioPs_SetDirectionPin(&gpio_inst, PORTEXP_RESETN_PIN, 1);
+	XGpioPs_WritePin(&gpio_inst, PORTEXP_RESETN_PIN, 0);
+	XGpioPs_SetOutputEnablePin(&gpio_inst, PORTEXP_RESETN_PIN, 1);
+	(void)usleep(1);
+	//Set PORTEXP_RESETN_PIN tri-state (open-drain high).
+	XGpioPs_SetOutputEnablePin(&gpio_inst, PORTEXP_RESETN_PIN, 0);
+	(void)usleep(1);
+
+	//Init GPIO Expander
+	if (XST_SUCCESS != (Status = SpiGpioInit(MCP23S08_SPI_DEVID, MCP23S08_SS_ID)))
+	{
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIOE_INITFAIL\r\n");
+		return XST_FAILURE;
+	}
+
+	//Set default outputs
+	if (XST_SUCCESS != (SpiGpioWriteReg(MCP23S08_REG_PORT, MCP23S08_DEFAULTS)))
+	{
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIOE_DEFFAIL\r\n");
+		return XST_FAILURE;
+	}
+	//Set I/O direction
+	if (XST_SUCCESS != (SpiGpioWriteReg(MCP23S08_REG_IODIR, MCP23S08_IODIR)))
+	{
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIOE_DIRFAIL\r\n");
+		return XST_FAILURE;
+	}
+	// Set USB20_RESET, USB20H_RESET, USB20_HUB_RESETN
+	if (XST_SUCCESS != (SpiGpioReadReg(MCP23S08_REG_PORT, (u8*)&RegVal)))
+	{
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIOE_READFAIL\r\n");
+		return XST_FAILURE;
+	}
+	RegVal |= 0x10;
+	RegVal |= 0x20;
+	RegVal &= ~(0x40);
+	if (XST_SUCCESS != (SpiGpioWriteReg(MCP23S08_REG_PORT, (u8)RegVal)))
+	{
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIOE_SETRSTFAIL\r\n");
+		return XST_FAILURE;
+	}
+	//10us reset pulse covers it
+	//USB3320 tmin=1us
+	//USB2513 tmin=1us
+	(void)usleep(10);
+
+	//Set default outputs
+	if (XST_SUCCESS != (SpiGpioWriteReg(MCP23S08_REG_PORT, MCP23S08_DEFAULTS)))
+	{
+		XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_GPIOE_CLRRSTFAIL\r\n");
+		return XST_FAILURE;
+	}
+
+	return XST_SUCCESS;
+#else
+	XFsbl_Printf(DEBUG_GENERAL, "XFSBL_GZU_NOSPI0_NOGPIO0\r\n");
+	return XST_FAILURE;
+#endif
+}
+
 /*****************************************************************************/
 /**
  * This function does board specific initialization.
@@ -820,9 +907,13 @@
 #endif
 #else
 	Status = XFSBL_SUCCESS;
+	XFsbl_Printf(DEBUG_INFO,"Digilent Genesys ZU board-specific init\n\r");
+	Status = InitGpios();
 	goto END;
 #endif
 
+
+
 END:
 	return Status;
 }

 
--- xfsbl_board.h
+++ xfsbl_board.h
@@ -177,6 +177,41 @@
 
 /************************** Function Prototypes ******************************/
 #endif
+
+#include "xgpiops_hw.h"
+#include "spi_gpio.h"
+/*
+ * Digilent Genesys ZU has an MCP23S08 GPIO expander connected to MIO.
+ * Board init functions below will reset the expander, configure I/O
+ * direction, and cycle resets.
+ * If PSU_SPI_0 is not enabled and SS1 is not mapped to MIO14, init will fail.
+ * If PS GPIO is not enabled and MIO13 not mapped to it, init might fail.
+ */
+#define MCP23S08_SPI_DEVID 0
+#define MCP23S08_SS_ID 1
+#define PORTEXP_RESETN_PIN	13
+#define MCP23S08_DEFAULTS \
+	(0 << 0 /*WIFI_CE*/ \
+	|0 << 1 /*WIFI_IRQ*/ \
+	|1 << 2 /*WIFI_RSTN*/ \
+	|0 << 3 /*WIFI_WAKE*/ \
+	|0 << 4 /*USB20_RESET*/ \
+	|0 << 5 /*USB20H_RESET*/ \
+	|1 << 6 /*USB20_HUB_RESETN*/ \
+	|0 << 7 /*USB30_HC*/ \
+	)
+#define MCP23S08_IODIR \
+	(0 << 0 /*WIFI_CE*/ \
+	|1 << 1 /*WIFI_IRQ*/ \
+	|0 << 2 /*WIFI_RSTN*/ \
+	|0 << 3 /*WIFI_WAKE*/ \
+	|0 << 4 /*USB20_RESET*/ \
+	|0 << 5 /*USB20H_RESET*/ \
+	|0 << 6 /*USB20_HUB_RESETN*/ \
+	|0 << 7 /*USB30_HC*/ \
+	)
+
+
 u32 XFsbl_BoardInit(void);
 
 #ifdef __cplusplus
 
--- /dev/null
+++ spi_gpio.c
@@ -0,0 +1,178 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Digilent
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *  Created on: Oct 28, 2019
+ *      Author: Elod Gyorgy
+ */
+
+#include "spi_gpio.h"
+#include "xspips.h"
+#include "sleep.h"
+
+//MCP23S08
+#define SCLK_MAX_FREQ 10000000
+#define MCP23S08_READ 1
+#define MCP23S08_WRITE 0
+#define MCP23S08_ADDRESS 0x20
+#define RETRY_COUNT	10
+
+struct prescale_t
+{
+	u32 div;
+	u8 prescale;
+};
+static const struct prescale_t prescalers[] =
+{
+		{4, XSPIPS_CLK_PRESCALE_4},
+		{8, XSPIPS_CLK_PRESCALE_8},
+		{16, XSPIPS_CLK_PRESCALE_16},
+		{32, XSPIPS_CLK_PRESCALE_32},
+		{64, XSPIPS_CLK_PRESCALE_64},
+		{128, XSPIPS_CLK_PRESCALE_128},
+		{256, XSPIPS_CLK_PRESCALE_256}
+};
+
+static XSpiPs drv_inst;
+static u8 send_buf_[8];
+static u8 recv_buf_[8];
+
+/*
+ * @param dev_id SPI controller Device ID
+ * @param ssid slave-select ID of the GPIO expander (supported 0-2)
+ */
+XStatus SpiGpioInit(u32 dev_id, u8 ss_id)
+{
+	XSpiPs_Config *SpiConfig;
+	XStatus Status;
+
+	if (ss_id > 2) return XST_FAILURE;
+
+	/*
+	 * Initialize the SPI driver so that it's ready to use
+	 */
+	SpiConfig = XSpiPs_LookupConfig(dev_id);
+	if (NULL == SpiConfig) {
+		return XST_FAILURE;
+	}
+
+	Status = XSpiPs_CfgInitialize(&drv_inst, SpiConfig,
+				       SpiConfig->BaseAddress);
+	if (Status != XST_SUCCESS) {
+		return XST_FAILURE;
+	}
+
+	/*
+	 * Perform a self-test to check hardware build
+	 */
+	Status = XSpiPs_SelfTest(&drv_inst);
+	if (Status != XST_SUCCESS) {
+		return XST_FAILURE;
+	}
+
+	/*
+	 * Set the Spi device as a master
+	 * MODE 0 is having issues with clock not going low before SS goes low
+	 * MODE 3 (CPOL=1, CPHA=1) works fine
+	 */
+	XSpiPs_SetOptions(&drv_inst, XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION
+			| XSPIPS_CLK_ACTIVE_LOW_OPTION | XSPIPS_CLK_PHASE_1_OPTION);
+
+
+	size_t i;
+	for (i=0; i<sizeof(prescalers)/sizeof(prescalers[0]); ++i)
+	{
+		if (SpiConfig->InputClockHz / prescalers[i].div <= SCLK_MAX_FREQ)
+			break;
+	}
+
+	if (i>=sizeof(prescalers)/sizeof(prescalers[0]))
+	{
+		return XST_FAILURE;
+	}
+
+	XSpiPs_SetClkPrescaler(&drv_inst, prescalers[i].prescale);
+
+	XSpiPs_SetSlaveSelect(&drv_inst, ss_id);
+
+	u8 ipol;
+	//IPOL register should read 0x00 after reset
+	if (XST_SUCCESS != (Status = SpiGpioReadReg(MCP23S08_REG_IPOL, &ipol)))
+		return Status;
+	if (ipol != 0x00)
+		return XST_FAILURE;
+
+	return XST_SUCCESS;
+}
+/*
+ * @param reg is the register address to read
+ * @param value is a pointer to the variable to store the value read
+ * @returns 0 on success, non-zero on failure
+ */
+XStatus SpiGpioReadReg(u8 reg, u8* value)
+{
+	u32 timeout = RETRY_COUNT;
+	XStatus Status;
+
+	memset(send_buf_, 0xFF, sizeof(recv_buf_));
+	memset(recv_buf_, 0xFF, sizeof(recv_buf_));
+	send_buf_[0] = (MCP23S08_ADDRESS << 1) | MCP23S08_READ;
+	send_buf_[1] = reg;
+
+	while (XST_DEVICE_BUSY == (Status = XSpiPs_PolledTransfer(&drv_inst, send_buf_, recv_buf_, 3)) && --timeout)
+	{
+		usleep(1000);
+	}
+	if (!timeout)
+	{
+		return XST_FAILURE;
+	}
+
+	*value = recv_buf_[2];
+	return XST_SUCCESS;
+}
+/*
+ * @param reg is the register address to write
+ * @param value is the value write
+ * @returns 0 on success, non-zero on failure
+ */
+XStatus SpiGpioWriteReg(u8 reg, u8 value)
+{
+	u32 timeout = RETRY_COUNT;
+	XStatus Status;
+
+	memset(send_buf_, 0xFF, sizeof(recv_buf_));
+	memset(recv_buf_, 0xFF, sizeof(recv_buf_));
+	send_buf_[0] = (MCP23S08_ADDRESS << 1) | MCP23S08_WRITE;
+	send_buf_[1] = reg;
+	send_buf_[2] = value;
+
+	while (XST_DEVICE_BUSY == (Status = XSpiPs_PolledTransfer(&drv_inst, send_buf_, recv_buf_, 3)) && --timeout)
+	{
+		usleep(1000);
+	}
+	if (!timeout)
+	{
+		return XST_FAILURE;
+	}
+
+	return XST_SUCCESS;
+}

--- /dev/null
+++ spi_gpio.h
@@ -0,0 +1,41 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Digilent
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ *  Created on: Oct 28, 2019
+ *      Author: Elod Gyorgy
+ */
+
+#ifndef SRC_SPI_GPIO_H_
+#define SRC_SPI_GPIO_H_
+
+#include "xstatus.h"
+
+#define SPI_GPIO_DEVICE_ID XPAR_PSU_SPI_0_DEVICE_ID
+#define MCP23S08_REG_IODIR 0x00
+#define MCP23S08_REG_IPOL 0x01
+#define MCP23S08_REG_PORT 0x09
+
+XStatus SpiGpioInit(u32 dev_id, u8 ss_id);
+XStatus SpiGpioReadReg(u8 reg, u8* value);
+XStatus SpiGpioWriteReg(u8 reg, u8 value);
+
+#endif /* SRC_SPI_GPIO_H_ */
