Przeglądaj źródła

Merge branch 'master' of git://git.denx.de/u-boot-spi

Tom Rini 9 lat temu
rodzic
commit
4905dfc65d

+ 3 - 0
arch/arm/Kconfig

@@ -227,6 +227,9 @@ config TARGET_STV0991
 	select CPU_V7
 	select DM
 	select DM_SERIAL
+	select DM_SPI
+	select DM_SPI_FLASH
+	select SPI_FLASH
 
 config TARGET_X600
 	bool "Support x600"

+ 3 - 1
arch/arm/cpu/armv7/stv0991/clock.c

@@ -33,7 +33,9 @@ void clock_setup(int peripheral)
 		/* 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;

+ 5 - 0
arch/arm/cpu/armv7/stv0991/pinmux.c

@@ -55,6 +55,11 @@ int stv0991_pinmux_config(int peripheral)
 				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;
 	}

+ 1 - 0
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";
 		};

+ 30 - 0
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>;
+			};
+	};
 };

+ 15 - 0
arch/arm/include/asm/arch-stv0991/stv0991_cgu.h

@@ -113,4 +113,19 @@ struct stv0991_cgu_regs {
 
 #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

+ 9 - 0
arch/arm/include/asm/arch-stv0991/stv0991_creg.h

@@ -49,6 +49,15 @@ struct stv0991_creg {
 	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)

+ 2 - 0
arch/arm/include/asm/arch-stv0991/stv0991_periph.h

@@ -18,6 +18,7 @@ enum periph_id {
 	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_id {
 enum periph_clock {
 	UART_CLOCK_CFG = 0,
 	ETH_CLOCK_CFG,
+	QSPI_CLOCK_CFG,
 };
 
 #endif /* __ASM_ARM_ARCH_PERIPH_H */

+ 8 - 0
board/st/stv0991/stv0991.c

@@ -55,12 +55,20 @@ int board_eth_enable(void)
 	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;
 }
 

+ 1 - 1
configs/stv0991_defconfig

@@ -7,8 +7,8 @@ CONFIG_AUTOBOOT_KEYED=y
 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

+ 28 - 0
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

+ 1 - 0
drivers/spi/cadence_qspi.c

@@ -309,6 +309,7 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
 	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,

+ 1 - 0
drivers/spi/cadence_qspi.h

@@ -25,6 +25,7 @@ struct cadence_spi_platdata {
 	u32		tsd2d_ns;
 	u32		tchsh_ns;
 	u32		tslch_ns;
+	u32		sram_size;
 };
 
 struct cadence_spi_priv {

+ 26 - 36
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 @@ static void cadence_qspi_apb_read_fifo_data(void *dest,
 	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_read_fifo_data(void *dest,
 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 @@ void cadence_qspi_apb_controller_init(struct cadence_spi_platdata *plat)
 	/* 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 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
 	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 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
 	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);

+ 18 - 3
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 */