diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c
index 5a8674ab2cff9b212af75ea43f74c84aa92c404f..52048c67662e7185ba854b402a0b433ef06ec718 100644
--- a/arch/arm/cpu/armv7/zynq/slcr.c
+++ b/arch/arm/cpu/armv7/zynq/slcr.c
@@ -28,6 +28,9 @@
 #define SLCR_LOCK_MAGIC		0x767B
 #define SLCR_UNLOCK_MAGIC	0xDF0D
 
+#define SLCR_IDCODE_MASK	0x1F000
+#define SLCR_IDCODE_SHIFT	12
+
 static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */
 
 void zynq_slcr_lock(void)
@@ -87,3 +90,35 @@ void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)
 out:
 	zynq_slcr_lock();
 }
+
+void zynq_slcr_devcfg_disable(void)
+{
+	zynq_slcr_unlock();
+
+	/* Disable AXI interface */
+	writel(0xFFFFFFFF, &slcr_base->fpga_rst_ctrl);
+
+	/* Set Level Shifters DT618760 */
+	writel(0xA, &slcr_base->lvl_shftr_en);
+
+	zynq_slcr_lock();
+}
+
+void zynq_slcr_devcfg_enable(void)
+{
+	zynq_slcr_unlock();
+
+	/* Set Level Shifters DT618760 */
+	writel(0xF, &slcr_base->lvl_shftr_en);
+
+	/* Disable AXI interface */
+	writel(0x0, &slcr_base->fpga_rst_ctrl);
+
+	zynq_slcr_lock();
+}
+
+u32 zynq_slcr_get_idcode(void)
+{
+	return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >>
+							SLCR_IDCODE_SHIFT;
+}
diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h
index 6af892a78930519151256b13d2db80e61e7e9f3b..8b8a91ae65ffbc9117cc7b39aa2da647513bafc2 100644
--- a/arch/arm/include/asm/arch-zynq/hardware.h
+++ b/arch/arm/include/asm/arch-zynq/hardware.h
@@ -53,11 +53,17 @@ struct slcr_regs {
 	u32 boot_mode; /* 0x25c */
 	u32 reserved4[116];
 	u32 trust_zone; /* 0x430 */ /* FIXME */
-	u32 reserved5[115];
+	u32 reserved5_1[63];
+	u32 pss_idcode; /* 0x530 */
+	u32 reserved5_2[51];
 	u32 ddr_urgent; /* 0x600 */
 	u32 reserved6[6];
 	u32 ddr_urgent_sel; /* 0x61c */
-	u32 reserved7[188];
+	u32 reserved7[56];
+	u32 mio_pin[54]; /* 0x700 - 0x7D4 */
+	u32 reserved8[74];
+	u32 lvl_shftr_en; /* 0x900 */
+	u32 reserved9[3];
 	u32 ocm_cfg; /* 0x910 */
 };
 
diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h
index af9e7f8d4cc78a5bce753ecaa60844b27e002893..2317121ca64aeb0b800fa295a6dd05a8dfebd467 100644
--- a/arch/arm/include/asm/arch-zynq/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynq/sys_proto.h
@@ -27,6 +27,9 @@ extern void zynq_slcr_lock(void);
 extern void zynq_slcr_unlock(void);
 extern void zynq_slcr_cpu_reset(void);
 extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);
+extern void zynq_slcr_devcfg_disable(void);
+extern void zynq_slcr_devcfg_enable(void);
+extern u32 zynq_slcr_get_idcode(void);
 
 /* Driver extern functions */
 extern int zynq_sdhci_init(u32 regbase);
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index 1589d21073befaaca369b7fbaacb09e4b5bd0d63..b02c364dc9bc6fb7264344ebd818a303e3aad1df 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -22,15 +22,52 @@
 
 #include <common.h>
 #include <netdev.h>
+#include <zynqpl.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_FPGA
+Xilinx_desc fpga;
+
+/* It can be done differently */
+Xilinx_desc fpga010 = XILINX_XC7Z010_DESC(0x10);
+Xilinx_desc fpga020 = XILINX_XC7Z020_DESC(0x20);
+Xilinx_desc fpga030 = XILINX_XC7Z030_DESC(0x30);
+Xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
+#endif
+
 int board_init(void)
 {
+#ifdef CONFIG_FPGA
+	u32 idcode;
+
+	idcode = zynq_slcr_get_idcode();
+
+	switch (idcode) {
+	case XILINX_ZYNQ_7010:
+		fpga = fpga010;
+		break;
+	case XILINX_ZYNQ_7020:
+		fpga = fpga020;
+		break;
+	case XILINX_ZYNQ_7030:
+		fpga = fpga030;
+		break;
+	case XILINX_ZYNQ_7045:
+		fpga = fpga045;
+		break;
+	}
+#endif
+
 	icache_enable();
 
+#ifdef CONFIG_FPGA
+	fpga_init();
+	fpga_add(fpga_xilinx, &fpga);
+#endif
+
 	return 0;
 }
 
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index b48f623c180364f600d45edf5cb584d1f3c32041..0b51dcdef370c585048fd5595707f7e5c4cab732 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -30,6 +30,7 @@ COBJS-y += fpga.o
 COBJS-$(CONFIG_FPGA_SPARTAN2) += spartan2.o
 COBJS-$(CONFIG_FPGA_SPARTAN3) += spartan3.o
 COBJS-$(CONFIG_FPGA_VIRTEX2) += virtex2.o
+COBJS-$(CONFIG_FPGA_ZYNQPL) += zynqpl.o
 COBJS-$(CONFIG_FPGA_XILINX) += xilinx.o
 COBJS-$(CONFIG_FPGA_LATTICE) += ivm_core.o lattice.o
 ifdef CONFIG_FPGA_ALTERA
diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c
index df5f9bf919bc4bff66b6e0fbb474062aa2bb9b33..496aa2f6eb750cf066946e315e3dbe7b9ec1de4a 100644
--- a/drivers/fpga/xilinx.c
+++ b/drivers/fpga/xilinx.c
@@ -1,4 +1,6 @@
 /*
+ * (C) Copyright 2012-2013, Xilinx, Michal Simek
+ *
  * (C) Copyright 2002
  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
  * Keith Outwater, keith_outwater@mvis.com
@@ -31,6 +33,7 @@
 #include <virtex2.h>
 #include <spartan2.h>
 #include <spartan3.h>
+#include <zynqpl.h>
 
 #if 0
 #define FPGA_DEBUG
@@ -170,6 +173,16 @@ int xilinx_load(Xilinx_desc *desc, const void *buf, size_t bsize)
 #else
 			printf ("%s: No support for Virtex-II devices.\n",
 					__FUNCTION__);
+#endif
+			break;
+		case xilinx_zynq:
+#if defined(CONFIG_FPGA_ZYNQPL)
+			PRINTF("%s: Launching the Zynq PL Loader...\n",
+			       __func__);
+			ret_val = zynq_load(desc, buf, bsize);
+#else
+			printf("%s: No support for Zynq devices.\n",
+			       __func__);
 #endif
 			break;
 
@@ -217,6 +230,16 @@ int xilinx_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
 #else
 			printf ("%s: No support for Virtex-II devices.\n",
 					__FUNCTION__);
+#endif
+			break;
+		case xilinx_zynq:
+#if defined(CONFIG_FPGA_ZYNQPL)
+			PRINTF("%s: Launching the Zynq PL Reader...\n",
+			       __func__);
+			ret_val = zynq_dump(desc, buf, bsize);
+#else
+			printf("%s: No support for Zynq devices.\n",
+			       __func__);
 #endif
 			break;
 
@@ -244,6 +267,9 @@ int xilinx_info (Xilinx_desc * desc)
 		case Xilinx_Virtex2:
 			printf ("Virtex-II\n");
 			break;
+		case xilinx_zynq:
+			printf("Zynq PL\n");
+			break;
 			/* Add new family types here */
 		default:
 			printf ("Unknown family type, %d\n", desc->family);
@@ -269,6 +295,9 @@ int xilinx_info (Xilinx_desc * desc)
 		case master_selectmap:
 			printf ("Master SelectMap Mode\n");
 			break;
+		case devcfg:
+			printf("Device configuration interface (Zynq)\n");
+			break;
 			/* Add new interface types here */
 		default:
 			printf ("Unsupported interface type, %d\n", desc->iface);
@@ -308,6 +337,14 @@ int xilinx_info (Xilinx_desc * desc)
 						__FUNCTION__);
 #endif
 				break;
+			case xilinx_zynq:
+#if defined(CONFIG_FPGA_ZYNQPL)
+				zynq_info(desc);
+#else
+				/* just in case */
+				printf("%s: No support for Zynq devices.\n",
+				       __func__);
+#endif
 				/* Add new family types here */
 			default:
 				/* we don't need a message here - we give one up above */
diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c
new file mode 100644
index 0000000000000000000000000000000000000000..8feccdea482b9202801f3dfcfc2a72e1c0e33ea5
--- /dev/null
+++ b/drivers/fpga/zynqpl.c
@@ -0,0 +1,355 @@
+/*
+ * (C) Copyright 2012-2013, Xilinx, Michal Simek
+ *
+ * (C) Copyright 2012
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <zynqpl.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+#define DEVCFG_CTRL_PCFG_PROG_B		0x40000000
+#define DEVCFG_ISR_FATAL_ERROR_MASK	0x00740040
+#define DEVCFG_ISR_ERROR_FLAGS_MASK	0x00340840
+#define DEVCFG_ISR_RX_FIFO_OV		0x00040000
+#define DEVCFG_ISR_DMA_DONE		0x00002000
+#define DEVCFG_ISR_PCFG_DONE		0x00000004
+#define DEVCFG_STATUS_DMA_CMD_Q_F	0x80000000
+#define DEVCFG_STATUS_DMA_CMD_Q_E	0x40000000
+#define DEVCFG_STATUS_DMA_DONE_CNT_MASK	0x30000000
+#define DEVCFG_STATUS_PCFG_INIT		0x00000010
+#define DEVCFG_MCTRL_RFIFO_FLUSH	0x00000002
+#define DEVCFG_MCTRL_WFIFO_FLUSH	0x00000001
+
+#ifndef CONFIG_SYS_FPGA_WAIT
+#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100	/* 10 ms */
+#endif
+
+#ifndef CONFIG_SYS_FPGA_PROG_TIME
+#define CONFIG_SYS_FPGA_PROG_TIME CONFIG_SYS_HZ	/* 1 s */
+#endif
+
+int zynq_info(Xilinx_desc *desc)
+{
+	return FPGA_SUCCESS;
+}
+
+#define DUMMY_WORD	0xffffffff
+
+/* Xilinx binary format header */
+static const u32 bin_format[] = {
+	DUMMY_WORD, /* Dummy words */
+	DUMMY_WORD,
+	DUMMY_WORD,
+	DUMMY_WORD,
+	DUMMY_WORD,
+	DUMMY_WORD,
+	DUMMY_WORD,
+	DUMMY_WORD,
+	0x000000bb, /* Sync word */
+	0x11220044, /* Sync word */
+	DUMMY_WORD,
+	DUMMY_WORD,
+	0xaa995566, /* Sync word */
+};
+
+#define SWAP_NO		1
+#define SWAP_DONE	2
+
+/*
+ * Load the whole word from unaligned buffer
+ * Keep in your mind that it is byte loading on little-endian system
+ */
+static u32 load_word(const void *buf, u32 swap)
+{
+	u32 word = 0;
+	u8 *bitc = (u8 *)buf;
+	int p;
+
+	if (swap == SWAP_NO) {
+		for (p = 0; p < 4; p++) {
+			word <<= 8;
+			word |= bitc[p];
+		}
+	} else {
+		for (p = 3; p >= 0; p--) {
+			word <<= 8;
+			word |= bitc[p];
+		}
+	}
+
+	return word;
+}
+
+static u32 check_header(const void *buf)
+{
+	u32 i, pattern;
+	int swap = SWAP_NO;
+	u32 *test = (u32 *)buf;
+
+	debug("%s: Let's check bitstream header\n", __func__);
+
+	/* Checking that passing bin is not a bitstream */
+	for (i = 0; i < ARRAY_SIZE(bin_format); i++) {
+		pattern = load_word(&test[i], swap);
+
+		/*
+		 * Bitstreams in binary format are swapped
+		 * compare to regular bistream.
+		 * Do not swap dummy word but if swap is done assume
+		 * that parsing buffer is binary format
+		 */
+		if ((__swab32(pattern) != DUMMY_WORD) &&
+		    (__swab32(pattern) == bin_format[i])) {
+			pattern = __swab32(pattern);
+			swap = SWAP_DONE;
+			debug("%s: data swapped - let's swap\n", __func__);
+		}
+
+		debug("%s: %d/%x: pattern %x/%x bin_format\n", __func__, i,
+		      (u32)&test[i], pattern, bin_format[i]);
+		if (pattern != bin_format[i]) {
+			debug("%s: Bitstream is not recognized\n", __func__);
+			return 0;
+		}
+	}
+	debug("%s: Found bitstream header at %x %s swapinng\n", __func__,
+	      (u32)buf, swap == SWAP_NO ? "without" : "with");
+
+	return swap;
+}
+
+static void *check_data(u8 *buf, size_t bsize, u32 *swap)
+{
+	u32 word, p = 0; /* possition */
+
+	/* Because buf doesn't need to be aligned let's read it by chars */
+	for (p = 0; p < bsize; p++) {
+		word = load_word(&buf[p], SWAP_NO);
+		debug("%s: word %x %x/%x\n", __func__, word, p, (u32)&buf[p]);
+
+		/* Find the first bitstream dummy word */
+		if (word == DUMMY_WORD) {
+			debug("%s: Found dummy word at position %x/%x\n",
+			      __func__, p, (u32)&buf[p]);
+			*swap = check_header(&buf[p]);
+			if (*swap) {
+				/* FIXME add full bitstream checking here */
+				return &buf[p];
+			}
+		}
+		/* Loop can be huge - support CTRL + C */
+		if (ctrlc())
+			return 0;
+	}
+	return 0;
+}
+
+
+int zynq_load(Xilinx_desc *desc, const void *buf, size_t bsize)
+{
+	unsigned long ts; /* Timestamp */
+	u32 partialbit = 0;
+	u32 i, control, isr_status, status, swap, diff;
+	u32 *buf_start;
+
+	/* Detect if we are going working with partial or full bitstream */
+	if (bsize != desc->size) {
+		printf("%s: Working with partial bitstream\n", __func__);
+		partialbit = 1;
+	}
+
+	buf_start = check_data((u8 *)buf, bsize, &swap);
+	if (!buf_start)
+		return FPGA_FAIL;
+
+	/* Check if data is postpone from start */
+	diff = (u32)buf_start - (u32)buf;
+	if (diff) {
+		printf("%s: Bitstream is not validated yet (diff %x)\n",
+		       __func__, diff);
+		return FPGA_FAIL;
+	}
+
+	if ((u32)buf_start & 0x3) {
+		u32 *new_buf = (u32 *)((u32)buf & ~0x3);
+
+		printf("%s: Align buffer at %x to %x(swap %d)\n", __func__,
+		       (u32)buf_start, (u32)new_buf, swap);
+
+		for (i = 0; i < (bsize/4); i++)
+			new_buf[i] = load_word(&buf_start[i], swap);
+
+		swap = SWAP_DONE;
+		buf = new_buf;
+	} else if (swap != SWAP_DONE) {
+		/* For bitstream which are aligned */
+		u32 *new_buf = (u32 *)buf;
+
+		printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__,
+		       swap);
+
+		for (i = 0; i < (bsize/4); i++)
+			new_buf[i] = load_word(&buf_start[i], swap);
+
+		swap = SWAP_DONE;
+	}
+
+	if (!partialbit) {
+		zynq_slcr_devcfg_disable();
+
+		/* Setting PCFG_PROG_B signal to high */
+		control = readl(&devcfg_base->ctrl);
+		writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+		/* Setting PCFG_PROG_B signal to low */
+		writel(control & ~DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+
+		/* Polling the PCAP_INIT status for Reset */
+		ts = get_timer(0);
+		while (readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT) {
+			if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+				printf("%s: Timeout wait for INIT to clear\n",
+				       __func__);
+				return FPGA_FAIL;
+			}
+		}
+
+		/* Setting PCFG_PROG_B signal to high */
+		writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
+
+		/* Polling the PCAP_INIT status for Set */
+		ts = get_timer(0);
+		while (!(readl(&devcfg_base->status) &
+			DEVCFG_STATUS_PCFG_INIT)) {
+			if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+				printf("%s: Timeout wait for INIT to set\n",
+				       __func__);
+				return FPGA_FAIL;
+			}
+		}
+	}
+
+	isr_status = readl(&devcfg_base->int_sts);
+
+	/* Clear it all, so if Boot ROM comes back, it can proceed */
+	writel(0xFFFFFFFF, &devcfg_base->int_sts);
+
+	if (isr_status & DEVCFG_ISR_FATAL_ERROR_MASK) {
+		debug("%s: Fatal errors in PCAP 0x%X\n", __func__, isr_status);
+
+		/* If RX FIFO overflow, need to flush RX FIFO first */
+		if (isr_status & DEVCFG_ISR_RX_FIFO_OV) {
+			writel(DEVCFG_MCTRL_RFIFO_FLUSH, &devcfg_base->mctrl);
+			writel(0xFFFFFFFF, &devcfg_base->int_sts);
+		}
+		return FPGA_FAIL;
+	}
+
+	status = readl(&devcfg_base->status);
+
+	debug("%s: Status = 0x%08X\n", __func__, status);
+
+	if (status & DEVCFG_STATUS_DMA_CMD_Q_F) {
+		debug("%s: Error: device busy\n", __func__);
+		return FPGA_FAIL;
+	}
+
+	debug("%s: Device ready\n", __func__);
+
+	if (!(status & DEVCFG_STATUS_DMA_CMD_Q_E)) {
+		if (!(readl(&devcfg_base->int_sts) & DEVCFG_ISR_DMA_DONE)) {
+			/* Error state, transfer cannot occur */
+			debug("%s: ISR indicates error\n", __func__);
+			return FPGA_FAIL;
+		} else {
+			/* Clear out the status */
+			writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts);
+		}
+	}
+
+	if (status & DEVCFG_STATUS_DMA_DONE_CNT_MASK) {
+		/* Clear the count of completed DMA transfers */
+		writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status);
+	}
+
+	debug("%s: Source = 0x%08X\n", __func__, (u32)buf);
+	debug("%s: Size = %zu\n", __func__, bsize);
+
+	/* Set up the transfer */
+	writel((u32)buf | 1, &devcfg_base->dma_src_addr);
+	writel(0xFFFFFFFF, &devcfg_base->dma_dst_addr);
+	writel(bsize >> 2, &devcfg_base->dma_src_len);
+	writel(0, &devcfg_base->dma_dst_len);
+
+	isr_status = readl(&devcfg_base->int_sts);
+
+	/* Polling the PCAP_INIT status for Set */
+	ts = get_timer(0);
+	while (!(isr_status & DEVCFG_ISR_DMA_DONE)) {
+		if (isr_status & DEVCFG_ISR_ERROR_FLAGS_MASK) {
+			debug("%s: Error: isr = 0x%08X\n", __func__,
+			      isr_status);
+			debug("%s: Write count = 0x%08X\n", __func__,
+			      readl(&devcfg_base->write_count));
+			debug("%s: Read count = 0x%08X\n", __func__,
+			      readl(&devcfg_base->read_count));
+
+			return FPGA_FAIL;
+		}
+		if (get_timer(ts) > CONFIG_SYS_FPGA_PROG_TIME) {
+			printf("%s: Timeout wait for DMA to complete\n",
+			       __func__);
+			return FPGA_FAIL;
+		}
+		isr_status = readl(&devcfg_base->int_sts);
+	}
+
+	debug("%s: DMA transfer is done\n", __func__);
+
+	/* Check FPGA configuration completion */
+	ts = get_timer(0);
+	while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) {
+		if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
+			printf("%s: Timeout wait for FPGA to config\n",
+			       __func__);
+			return FPGA_FAIL;
+		}
+		isr_status = readl(&devcfg_base->int_sts);
+	}
+
+	debug("%s: FPGA config done\n", __func__);
+
+	/* Clear out the DMA status */
+	writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts);
+
+	if (!partialbit)
+		zynq_slcr_devcfg_enable();
+
+	return FPGA_SUCCESS;
+}
+
+int zynq_dump(Xilinx_desc *desc, const void *buf, size_t bsize)
+{
+	return FPGA_FAIL;
+}
diff --git a/include/configs/zynq.h b/include/configs/zynq.h
index f1f182edfb9e243757a500f2a85255f1ad0213a3..38f04f642b93197c3135cd094b714907e516c8a6 100644
--- a/include/configs/zynq.h
+++ b/include/configs/zynq.h
@@ -88,6 +88,12 @@
 # define CONFIG_CPU_V6 /* Required by CONFIG_ARM_DCC */
 #endif
 
+/* Enable the PL to be downloaded */
+#define CONFIG_FPGA
+#define CONFIG_FPGA_XILINX
+#define CONFIG_FPGA_ZYNQPL
+#define CONFIG_CMD_FPGA
+
 #define CONFIG_BOOTP_SERVERIP
 #define CONFIG_BOOTP_BOOTPATH
 #define CONFIG_BOOTP_GATEWAY
diff --git a/include/xilinx.h b/include/xilinx.h
index 5f25b7a8a96be3a231f4c99b7fd714569f1149ec..592cbea1f301ad452f904621f41dc77786a3d1d2 100644
--- a/include/xilinx.h
+++ b/include/xilinx.h
@@ -33,10 +33,12 @@
 #define CONFIG_SYS_VIRTEX_E			CONFIG_SYS_FPGA_DEV( 0x2 )
 #define CONFIG_SYS_VIRTEX2			CONFIG_SYS_FPGA_DEV( 0x4 )
 #define CONFIG_SYS_SPARTAN3			CONFIG_SYS_FPGA_DEV( 0x8 )
+#define CONFIG_SYS_ZYNQ				CONFIG_SYS_FPGA_DEV(0x10)
 #define CONFIG_SYS_XILINX_SPARTAN2	(CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_SPARTAN2)
 #define CONFIG_SYS_XILINX_VIRTEX_E	(CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_VIRTEX_E)
 #define CONFIG_SYS_XILINX_VIRTEX2	(CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_VIRTEX2)
 #define CONFIG_SYS_XILINX_SPARTAN3	(CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_SPARTAN3)
+#define CONFIG_SYS_XILINX_ZYNQ	(CONFIG_SYS_FPGA_XILINX | CONFIG_SYS_ZYNQ)
 /* XXX - Add new models here */
 
 
@@ -59,6 +61,7 @@ typedef enum {			/* typedef Xilinx_iface */
 	jtag_mode,		/* jtag/tap serial (not used ) */
 	master_selectmap,	/* master SelectMap (virtex2)           */
 	slave_selectmap,	/* slave SelectMap (virtex2)            */
+	devcfg,			/* devcfg interface (zynq) */
 	max_xilinx_iface_type	/* insert all new types before this */
 } Xilinx_iface;			/* end, typedef Xilinx_iface */
 
@@ -68,6 +71,7 @@ typedef enum {			/* typedef Xilinx_Family */
 	Xilinx_VirtexE,		/* Virtex-E Family */
 	Xilinx_Virtex2,		/* Virtex2 Family */
 	Xilinx_Spartan3,	/* Spartan-III Family */
+	xilinx_zynq,		/* Zynq Family */
 	max_xilinx_type		/* insert all new types before this */
 } Xilinx_Family;		/* end, typedef Xilinx_Family */
 
diff --git a/include/zynqpl.h b/include/zynqpl.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc9b94815950616db1ca60768a673f964096e3ea
--- /dev/null
+++ b/include/zynqpl.h
@@ -0,0 +1,59 @@
+/*
+ * (C) Copyright 2012-2013, Xilinx, Michal Simek
+ *
+ * (C) Copyright 2012
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _ZYNQPL_H_
+#define _ZYNQPL_H_
+
+#include <xilinx.h>
+
+extern int zynq_load(Xilinx_desc *desc, const void *image, size_t size);
+extern int zynq_dump(Xilinx_desc *desc, const void *buf, size_t bsize);
+extern int zynq_info(Xilinx_desc *desc);
+
+#define XILINX_ZYNQ_7010	0x2
+#define XILINX_ZYNQ_7020	0x7
+#define XILINX_ZYNQ_7030	0xc
+#define XILINX_ZYNQ_7045	0x11
+
+/* Device Image Sizes */
+#define XILINX_XC7Z010_SIZE	16669920/8
+#define XILINX_XC7Z020_SIZE	32364512/8
+#define XILINX_XC7Z030_SIZE	47839328/8
+#define XILINX_XC7Z045_SIZE	106571232/8
+
+/* Descriptor Macros */
+#define XILINX_XC7Z010_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z010_SIZE, NULL, cookie }
+
+#define XILINX_XC7Z020_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z020_SIZE, NULL, cookie }
+
+#define XILINX_XC7Z030_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z030_SIZE, NULL, cookie }
+
+#define XILINX_XC7Z045_DESC(cookie) \
+{ xilinx_zynq, devcfg, XILINX_XC7Z045_SIZE, NULL, cookie }
+
+#endif /* _ZYNQPL_H_ */