diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 6aa24d43590b68e24851cdc9919dab887e2a16de..fec3fecbdfbf0e8b06a37bf332f1237458f84240 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -17,5 +17,6 @@ obj-y += altera.o
 obj-$(CONFIG_FPGA_ACEX1K) += ACEX1K.o
 obj-$(CONFIG_FPGA_CYCLON2) += cyclon2.o
 obj-$(CONFIG_FPGA_STRATIX_II) += stratixII.o
+obj-$(CONFIG_FPGA_STRATIX_V) += stratixv.o
 obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o
 endif
diff --git a/drivers/fpga/altera.c b/drivers/fpga/altera.c
index a5bfe5dce19a3dce36d35053031bfe4bf24c775e..135a3572a83c9e9f8b9bbbc7b9faeac965aec770 100644
--- a/drivers/fpga/altera.c
+++ b/drivers/fpga/altera.c
@@ -37,6 +37,9 @@ static const struct altera_fpga {
 	{ Altera_StratixII, "StratixII", StratixII_load,
 	  StratixII_dump, StratixII_info },
 #endif
+#if defined(CONFIG_FPGA_STRATIX_V)
+	{ Altera_StratixV, "StratixV", stratixv_load, NULL, NULL },
+#endif
 #if defined(CONFIG_FPGA_SOCFPGA)
 	{ Altera_SoCFPGA, "SoC FPGA", socfpga_load, NULL, NULL },
 #endif
diff --git a/drivers/fpga/stratixv.c b/drivers/fpga/stratixv.c
new file mode 100644
index 0000000000000000000000000000000000000000..cc035eb2a14f50453d95ae814b3571b0f4ac32e0
--- /dev/null
+++ b/drivers/fpga/stratixv.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <altera.h>
+#include <spi.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+/* Write the RBF data to FPGA via SPI */
+static int program_write(int spi_bus, int spi_dev, const void *rbf_data,
+			 unsigned long rbf_size)
+{
+	struct spi_slave *slave;
+	int ret;
+
+	debug("%s (%d): data=%p size=%ld\n",
+	      __func__, __LINE__, rbf_data, rbf_size);
+
+	/* FIXME: How to get the max. SPI clock and SPI mode? */
+	slave = spi_setup_slave(spi_bus, spi_dev, 27777777, SPI_MODE_3);
+	if (!slave)
+		return -1;
+
+	if (spi_claim_bus(slave))
+		return -1;
+
+	ret = spi_xfer(slave, rbf_size * 8, rbf_data, (void *)rbf_data,
+		       SPI_XFER_BEGIN | SPI_XFER_END);
+
+	spi_release_bus(slave);
+
+	return ret;
+}
+
+/*
+ * This is the interface used by FPGA driver.
+ * Return 0 for sucess, non-zero for error.
+ */
+int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
+{
+	altera_board_specific_func *pfns = desc->iface_fns;
+	int cookie = desc->cookie;
+	int spi_bus;
+	int spi_dev;
+	int ret = 0;
+
+	if ((u32)rbf_data & 0x3) {
+		puts("FPGA: Unaligned data, realign to 32bit boundary.\n");
+		return -EINVAL;
+	}
+
+	/* Run the pre configuration function if there is one */
+	if (pfns->pre)
+		(pfns->pre)(cookie);
+
+	/* Establish the initial state */
+	if (pfns->config) {
+		/* De-assert nCONFIG */
+		(pfns->config)(false, true, cookie);
+
+		/* nConfig minimum low pulse width is 2us */
+		udelay(200);
+
+		/* Assert nCONFIG */
+		(pfns->config)(true, true, cookie);
+
+		/* nCONFIG high to first rising clock on DCLK min 1506 us */
+		udelay(1600);
+	}
+
+	/* Write the RBF data to FPGA */
+	if (pfns->write) {
+		/*
+		 * Use board specific data function to write bitstream
+		 * into the FPGA
+		 */
+		ret = (pfns->write)(rbf_data, rbf_size, true, cookie);
+	} else {
+		/*
+		 * Use common SPI functions to write bitstream into the
+		 * FPGA
+		 */
+		spi_bus = COOKIE2SPI_BUS(cookie);
+		spi_dev = COOKIE2SPI_DEV(cookie);
+		ret = program_write(spi_bus, spi_dev, rbf_data, rbf_size);
+	}
+	if (ret)
+		return ret;
+
+	/* Check done pin */
+	if (pfns->done) {
+		ret = (pfns->done)(cookie);
+
+		if (ret)
+			printf("Error: DONE not set (ret=%d)!\n", ret);
+	}
+
+	return ret;
+}
diff --git a/include/altera.h b/include/altera.h
index c2991ad800073b0de56c844456eade3d8e823023..48d3eb73c9899f67a44464c4b26dbf92f85cb816 100644
--- a/include/altera.h
+++ b/include/altera.h
@@ -10,6 +10,19 @@
 #ifndef _ALTERA_H_
 #define _ALTERA_H_
 
+/*
+ * For the StratixV FPGA programming via SPI, the following
+ * information is coded in the 32bit cookie:
+ * Bit 31 ... Bit 0
+ * SPI-Bus | SPI-Dev | Config-Pin | Done-Pin
+ */
+#define FPGA_COOKIE(bus, dev, config, done)			\
+	(((bus) << 24) | ((dev) << 16) | ((config) << 8) | (done))
+#define COOKIE2SPI_BUS(c)	(((c) >> 24) & 0xff)
+#define COOKIE2SPI_DEV(c)	(((c) >> 16) & 0xff)
+#define COOKIE2CONFIG(c)	(((c) >> 8) & 0xff)
+#define COOKIE2DONE(c)		((c) & 0xff)
+
 enum altera_iface {
 	/* insert all new types after this */
 	min_altera_iface_type,
@@ -40,6 +53,8 @@ enum altera_family {
 	Altera_CYC2,
 	/* StratixII Family */
 	Altera_StratixII,
+	/* StratixV Family */
+	Altera_StratixV,
 	/* SoCFPGA Family */
 	Altera_SoCFPGA,
 
@@ -89,6 +104,7 @@ typedef struct {
 	Altera_done_fn done;
 	Altera_clk_fn clk;
 	Altera_data_fn data;
+	Altera_write_fn write;
 	Altera_abort_fn abort;
 	Altera_post_fn post;
 } altera_board_specific_func;
@@ -97,4 +113,8 @@ typedef struct {
 int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
 #endif
 
+#ifdef CONFIG_FPGA_STRATIX_V
+int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
+#endif
+
 #endif /* _ALTERA_H_ */