Merge git://git.denx.de/u-boot-x86
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9908b43..506463c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -227,6 +227,9 @@
 	select CPU_V7
 	select DM
 	select DM_SERIAL
+	select DM_SPI
+	select DM_SPI_FLASH
+	select SPI_FLASH
 
 config TARGET_X600
 	bool "Support x600"
diff --git a/arch/arm/cpu/armv7/stv0991/clock.c b/arch/arm/cpu/armv7/stv0991/clock.c
index 70b8a8d..26c0d36 100644
--- a/arch/arm/cpu/armv7/stv0991/clock.c
+++ b/arch/arm/cpu/armv7/stv0991/clock.c
@@ -33,7 +33,9 @@
 		/* Clock selection for ethernet tx_clk & rx_clk*/
 		writel((readl(&stv0991_cgu_regs->eth_ctrl) & ETH_CLK_MASK)
 				| ETH_CLK_CTRL, &stv0991_cgu_regs->eth_ctrl);
-
+		break;
+	case QSPI_CLOCK_CFG:
+		writel(QSPI_CLK_CTRL, &stv0991_cgu_regs->qspi_freq);
 		break;
 	default:
 		break;
diff --git a/arch/arm/cpu/armv7/stv0991/pinmux.c b/arch/arm/cpu/armv7/stv0991/pinmux.c
index 1d086a2..24c67fa 100644
--- a/arch/arm/cpu/armv7/stv0991/pinmux.c
+++ b/arch/arm/cpu/armv7/stv0991/pinmux.c
@@ -55,6 +55,11 @@
 				ETH_M_VDD_CFG, &stv0991_creg->vdd_pad1);
 
 		break;
+	case QSPI_CS_CLK_PAD:
+		writel((readl(&stv0991_creg->mux13) & FLASH_CS_NC_MASK) |
+				CFG_FLASH_CS_NC, &stv0991_creg->mux13);
+		writel((readl(&stv0991_creg->mux13) & FLASH_CLK_MASK) |
+				CFG_FLASH_CLK, &stv0991_creg->mux13);
 	default:
 		break;
 	}
diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index bf791c5..9b12420 100644
--- a/arch/arm/dts/socfpga.dtsi
+++ b/arch/arm/dts/socfpga.dtsi
@@ -639,6 +639,7 @@
 			ext-decoder = <0>;  /* external decoder */
 			num-cs = <4>;
 			fifo-depth = <128>;
+			sram-size = <128>;
 			bus-num = <2>;
 			status = "disabled";
 		};
diff --git a/arch/arm/dts/stv0991.dts b/arch/arm/dts/stv0991.dts
index b25c48b..fa3fd64 100644
--- a/arch/arm/dts/stv0991.dts
+++ b/arch/arm/dts/stv0991.dts
@@ -20,4 +20,34 @@
 		reg = <0x80406000 0x1000>;
 		clock = <2700000>;
 	};
+
+	aliases {
+		spi0 = "/spi@80203000";		/* QSPI */
+	};
+
+	qspi: spi@80203000 {
+			compatible = "cadence,qspi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x80203000 0x100>,
+				<0x40000000 0x1000000>;
+			clocks = <3750000>;
+			sram-size = <256>;
+			status = "okay";
+
+			flash0: n25q32@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "spi-flash";
+				reg = <0>;		/* chip select */
+				spi-max-frequency = <50000000>;
+				m25p,fast-read;
+				page-size = <256>;
+				block-size = <16>; 	/* 2^16, 64KB */
+				tshsl-ns = <50>;
+				tsd2d-ns = <50>;
+				tchsh-ns = <4>;
+				tslch-ns = <4>;
+			};
+	};
 };
diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h b/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h
index ddcbb57..f0045f3 100644
--- a/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h
+++ b/arch/arm/include/asm/arch-stv0991/stv0991_cgu.h
@@ -113,4 +113,19 @@
 
 #define ETH_CLK_CTRL			(ETH_CLK_RX_EXT_PHY << RX_CLK_SHIFT \
 					| ETH_CLK_TX_EXT_PHY)
+/* CGU qspi clock */
+#define DIV_HCLK1_SHIFT			9
+#define DIV_CRYP_SHIFT			6
+#define MDIV_QSPI_SHIFT			3
+
+#define CLK_QSPI_OSC			0
+#define CLK_QSPI_MCLK			1
+#define CLK_QSPI_PLL1			2
+#define CLK_QSPI_PLL2			3
+
+#define QSPI_CLK_CTRL			(3 << DIV_HCLK1_SHIFT \
+					| 1 << DIV_CRYP_SHIFT \
+					| 0 << MDIV_QSPI_SHIFT \
+					| CLK_QSPI_OSC)
+
 #endif
diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_creg.h b/arch/arm/include/asm/arch-stv0991/stv0991_creg.h
index c804eb5..737c952 100644
--- a/arch/arm/include/asm/arch-stv0991/stv0991_creg.h
+++ b/arch/arm/include/asm/arch-stv0991/stv0991_creg.h
@@ -49,6 +49,15 @@
 	u32 vdd_comp1;		/* offset 0x400 */
 };
 
+/* CREG MUX 13 register */
+#define FLASH_CS_NC_SHIFT	4
+#define FLASH_CS_NC_MASK	~(7 << FLASH_CS_NC_SHIFT)
+#define CFG_FLASH_CS_NC		(0 << FLASH_CS_NC_SHIFT)
+
+#define FLASH_CLK_SHIFT		0
+#define FLASH_CLK_MASK		~(7 << FLASH_CLK_SHIFT)
+#define CFG_FLASH_CLK		(0 << FLASH_CLK_SHIFT)
+
 /* CREG MUX 12 register */
 #define GPIOC_30_MUX_SHIFT	24
 #define GPIOC_30_MUX_MASK	~(1 << GPIOC_30_MUX_SHIFT)
diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_periph.h b/arch/arm/include/asm/arch-stv0991/stv0991_periph.h
index f728c83..725da83 100644
--- a/arch/arm/include/asm/arch-stv0991/stv0991_periph.h
+++ b/arch/arm/include/asm/arch-stv0991/stv0991_periph.h
@@ -18,6 +18,7 @@
 	UART_GPIOC_30_31 = 0,
 	UART_GPIOB_16_17,
 	ETH_GPIOB_10_31_C_0_4,
+	QSPI_CS_CLK_PAD,
 	PERIPH_ID_I2C0,
 	PERIPH_ID_I2C1,
 	PERIPH_ID_I2C2,
@@ -39,6 +40,7 @@
 enum periph_clock {
 	UART_CLOCK_CFG = 0,
 	ETH_CLOCK_CFG,
+	QSPI_CLOCK_CFG,
 };
 
 #endif /* __ASM_ARM_ARCH_PERIPH_H */
diff --git a/board/st/stv0991/stv0991.c b/board/st/stv0991/stv0991.c
index 09f973f..add1ce1 100644
--- a/board/st/stv0991/stv0991.c
+++ b/board/st/stv0991/stv0991.c
@@ -55,12 +55,20 @@
 	return 0;
 }
 
+int board_qspi_enable(void)
+{
+	stv0991_pinmux_config(QSPI_CS_CLK_PAD);
+	clock_setup(QSPI_CLOCK_CFG);
+	return 0;
+}
+
 /*
  * Miscellaneous platform dependent initialisations
  */
 int board_init(void)
 {
 	board_eth_enable();
+	board_qspi_enable();
 	return 0;
 }
 
diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig
index 8e8ce9f..3bdb1fc 100644
--- a/configs/stv0991_defconfig
+++ b/configs/stv0991_defconfig
@@ -7,8 +7,8 @@
 CONFIG_AUTOBOOT_PROMPT="Hit SPACE in %d seconds to stop autoboot.\n"
 CONFIG_AUTOBOOT_STOP_STR=" "
 # CONFIG_CMD_IMLS is not set
-# CONFIG_CMD_SAVEENV is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_NETDEVICES=y
 CONFIG_ETH_DESIGNWARE=y
+CONFIG_OF_CONTROL=y
diff --git a/doc/device-tree-bindings/spi/spi-cadence.txt b/doc/device-tree-bindings/spi/spi-cadence.txt
new file mode 100644
index 0000000..c1e2233
--- /dev/null
+++ b/doc/device-tree-bindings/spi/spi-cadence.txt
@@ -0,0 +1,28 @@
+Cadence QSPI controller device tree bindings
+--------------------------------------------
+
+Required properties:
+- compatible		: should be "cadence,qspi".
+- reg			: 1.Physical base address and size of SPI registers map.
+			  2. Physical base address & size of NOR Flash.
+- clocks		: Clock phandles (see clock bindings for details).
+- sram-size		: spi controller sram size.
+- status		: enable in requried dts.
+
+connected flash properties
+--------------------------
+
+- spi-max-frequency	: Max supported spi frequency.
+- page-size		: Flash page size.
+- block-size		: Flash memory block size.
+- tshsl-ns		: Added delay in master reference clocks (ref_clk) for
+			  the length that the master mode chip select outputs
+			  are de-asserted between transactions.
+- tsd2d-ns		: Delay in master reference clocks (ref_clk) between one
+			  chip select being de-activated and the activation of
+			  another.
+- tchsh-ns		: Delay in master reference clocks between last bit of
+			  current transaction and de-asserting the device chip
+			  select (n_ss_out).
+- tslch-ns		: Delay in master reference clocks between setting
+			  n_ss_out low and first bit transfer
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index a75fc46..34a0f46 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -309,6 +309,7 @@
 	plat->tsd2d_ns = fdtdec_get_int(blob, subnode, "tsd2d-ns", 255);
 	plat->tchsh_ns = fdtdec_get_int(blob, subnode, "tchsh-ns", 20);
 	plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns", 20);
+	plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128);
 
 	debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
 	      __func__, plat->regbase, plat->ahbbase, plat->max_hz,
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index c9a6142..98e57aa 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -25,6 +25,7 @@
 	u32		tsd2d_ns;
 	u32		tchsh_ns;
 	u32		tslch_ns;
+	u32		sram_size;
 };
 
 struct cadence_spi_priv {
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index 00a115f..d053407 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -36,12 +36,6 @@
 
 #define CQSPI_FIFO_WIDTH			(4)
 
-/* Controller sram size in word */
-#define CQSPI_REG_SRAM_SIZE_WORD		(128)
-#define CQSPI_REG_SRAM_RESV_WORDS		(2)
-#define CQSPI_REG_SRAM_PARTITION_WR		(1)
-#define CQSPI_REG_SRAM_PARTITION_RD		\
-	(CQSPI_REG_SRAM_SIZE_WORD - CQSPI_REG_SRAM_RESV_WORDS)
 #define CQSPI_REG_SRAM_THRESHOLD_WORDS		(50)
 
 /* Transfer mode */
@@ -206,18 +200,16 @@
 	unsigned int *dest_ptr = (unsigned int *)dest;
 	unsigned int *src_ptr = (unsigned int *)src_ahb_addr;
 
-	while (remaining > 0) {
-		if (remaining >= CQSPI_FIFO_WIDTH) {
-			*dest_ptr = readl(src_ptr);
-			remaining -= CQSPI_FIFO_WIDTH;
-		} else {
-			/* dangling bytes */
-			temp = readl(src_ptr);
-			memcpy(dest_ptr, &temp, remaining);
-			break;
-		}
+	while (remaining >= sizeof(dest_ptr)) {
+		*dest_ptr = readl(src_ptr);
+		remaining -= sizeof(src_ptr);
 		dest_ptr++;
 	}
+	if (remaining) {
+		/* dangling bytes */
+		temp = readl(src_ptr);
+		memcpy(dest_ptr, &temp, remaining);
+	}
 
 	return;
 }
@@ -225,24 +217,26 @@
 static void cadence_qspi_apb_write_fifo_data(const void *dest_ahb_addr,
 	const void *src, unsigned int bytes)
 {
-	unsigned int temp;
+	unsigned int temp = 0;
+	int i;
 	int remaining = bytes;
 	unsigned int *dest_ptr = (unsigned int *)dest_ahb_addr;
 	unsigned int *src_ptr = (unsigned int *)src;
 
-	while (remaining > 0) {
-		if (remaining >= CQSPI_FIFO_WIDTH) {
-			writel(*src_ptr, dest_ptr);
-			remaining -= sizeof(unsigned int);
-		} else {
-			/* dangling bytes */
-			memcpy(&temp, src_ptr, remaining);
-			writel(temp, dest_ptr);
-			break;
-		}
-		src_ptr++;
+	while (remaining >= CQSPI_FIFO_WIDTH) {
+		for (i = CQSPI_FIFO_WIDTH/sizeof(src_ptr) - 1; i >= 0; i--)
+			writel(*(src_ptr+i), dest_ptr+i);
+		src_ptr += CQSPI_FIFO_WIDTH/sizeof(src_ptr);
+		remaining -= CQSPI_FIFO_WIDTH;
 	}
-
+	if (remaining) {
+		/* dangling bytes */
+		i = remaining/sizeof(dest_ptr);
+		memcpy(&temp, src_ptr+i, remaining % sizeof(dest_ptr));
+		writel(temp, dest_ptr+i);
+		for (--i; i >= 0; i--)
+			writel(*(src_ptr+i), dest_ptr+i);
+	}
 	return;
 }
 
@@ -538,6 +532,9 @@
 	/* Configure the remap address register, no remap */
 	writel(0, plat->regbase + CQSPI_REG_REMAP);
 
+	/* Indirect mode configurations */
+	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
+
 	/* Disable all interrupts */
 	writel(0, plat->regbase + CQSPI_REG_IRQMASK);
 
@@ -700,10 +697,6 @@
 	writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
 	       plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
-	/* Configure SRAM partition for read. */
-	writel(CQSPI_REG_SRAM_PARTITION_RD, plat->regbase +
-	       CQSPI_REG_SRAMPARTITION);
-
 	/* Configure the opcode */
 	rd_reg = cmdbuf[0] << CQSPI_REG_RD_INSTR_OPCODE_LSB;
 
@@ -801,9 +794,6 @@
 	writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
 	       plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
-	writel(CQSPI_REG_SRAM_PARTITION_WR,
-	       plat->regbase + CQSPI_REG_SRAMPARTITION);
-
 	/* Configure the opcode */
 	reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB;
 	writel(reg, plat->regbase + CQSPI_REG_WR_INSTR);
diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h
index 6379fd3..887f31a 100644
--- a/include/configs/stv0991.h
+++ b/include/configs/stv0991.h
@@ -23,7 +23,9 @@
 #define PHYS_SDRAM_1_SIZE			0x00198000
 
 #define CONFIG_ENV_SIZE				0x10000
-#define CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_SECT_SIZE			CONFIG_ENV_SIZE
+#define CONFIG_ENV_OFFSET			0x30000
 #define CONFIG_ENV_ADDR				\
 	(PHYS_SDRAM_1_SIZE - CONFIG_ENV_SIZE)
 #define CONFIG_SYS_MAXARGS			16
@@ -72,7 +74,20 @@
 #define CONFIG_BOOTDELAY                       3
 #define CONFIG_BOOTCOMMAND                     "go 0x40040000"
 
-#define CONFIG_OF_SEPARATE
-#define CONFIG_OF_CONTROL
 #define CONFIG_OF_LIBFDT
+
+/*
++ * QSPI support
++ */
+#ifdef CONFIG_OF_CONTROL		/* QSPI is controlled via DT */
+#define CONFIG_CADENCE_QSPI
+#define CONFIG_CQSPI_DECODER		0
+#define CONFIG_CQSPI_REF_CLK		((30/4)/2)*1000*1000
+#define CONFIG_CMD_SPI
+
+#define CONFIG_SPI_FLASH_STMICRO	/* Micron/Numonyx flash */
+#define CONFIG_SPI_FLASH_WINBOND	/* WINBOND */
+#define CONFIG_CMD_SF
+#endif
+
 #endif /* __CONFIG_H */