summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/cpu/armv7/stv0991/clock.c4
-rw-r--r--arch/arm/cpu/armv7/stv0991/pinmux.c5
-rw-r--r--arch/arm/dts/socfpga.dtsi1
-rw-r--r--arch/arm/dts/stv0991.dts30
-rw-r--r--arch/arm/include/asm/arch-stv0991/stv0991_cgu.h15
-rw-r--r--arch/arm/include/asm/arch-stv0991/stv0991_creg.h9
-rw-r--r--arch/arm/include/asm/arch-stv0991/stv0991_periph.h2
-rw-r--r--board/st/stv0991/stv0991.c8
-rw-r--r--configs/stv0991_defconfig2
-rw-r--r--doc/device-tree-bindings/spi/spi-cadence.txt28
-rw-r--r--drivers/spi/cadence_qspi.c1
-rw-r--r--drivers/spi/cadence_qspi.h1
-rw-r--r--drivers/spi/cadence_qspi_apb.c62
-rw-r--r--include/configs/stv0991.h21
15 files changed, 151 insertions, 41 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9908b430d6..506463c12c 100644
--- a/arch/arm/Kconfig
+++ b/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"
diff --git a/arch/arm/cpu/armv7/stv0991/clock.c b/arch/arm/cpu/armv7/stv0991/clock.c
index 70b8a8d984..26c0d3637d 100644
--- a/arch/arm/cpu/armv7/stv0991/clock.c
+++ b/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;
diff --git a/arch/arm/cpu/armv7/stv0991/pinmux.c b/arch/arm/cpu/armv7/stv0991/pinmux.c
index 1d086a235d..24c67faaea 100644
--- a/arch/arm/cpu/armv7/stv0991/pinmux.c
+++ b/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;
}
diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index bf791c5dde..9b1242025d 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 b25c48bcec..fa3fd641b2 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 ddcbb57a92..f0045f3e04 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 @@ 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
diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_creg.h b/arch/arm/include/asm/arch-stv0991/stv0991_creg.h
index c804eb5e4c..737c95253b 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 @@ 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)
diff --git a/arch/arm/include/asm/arch-stv0991/stv0991_periph.h b/arch/arm/include/asm/arch-stv0991/stv0991_periph.h
index f728c83cb7..725da838b8 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 @@ 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 */
diff --git a/board/st/stv0991/stv0991.c b/board/st/stv0991/stv0991.c
index 09f973f403..add1ce1a79 100644
--- a/board/st/stv0991/stv0991.c
+++ b/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;
}
diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig
index 8e8ce9fb2d..3bdb1fc101 100644
--- a/configs/stv0991_defconfig
+++ b/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
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 0000000000..c1e2233d7c
--- /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 a75fc46e95..34a0f46a1a 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/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,
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index c9a6142e82..98e57aa5bc 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/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 {
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index 00a115f3fb..d05340716e 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 @@ 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);
diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h
index 6379fd3ab7..887f31a84d 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 */
OpenPOWER on IntegriCloud