Skip to contentSkip to conversation

spi: cadence_qspi: optimize & fix indirect rd-writes

PATCH Superseded Vikas Manocha 2 participants 15 messages Aug 15, 2015 – Aug 20, 2015

Subsystems (2)

v3 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

v3 cover spi: cadence_qspi: optimize & fix indirect rd-writes

This patchset:
- fixes trigger base & transfer start address register programming. This fix superseeds the previous patch "spi: cadence_qspi: Fix the indirect ahb trigger address setting".
- adds support to get fifo width from device tree

Changes in v3:
- removed two patches which were bypassing the sram level check.
- format string in patch corrected 3/4
- added commit message in patch 1/4

Changes in v2:
- rebased to master.
- removed patch "spi: cadence_qspi: read can be independent of fifo width", it was implemented in other patchset, in mainline now.

Vikas Manocha (4):
spi: cadence_qspi: move trigger base configuration in init
spi: cadence_qspi: fix indirect read/write start address
spi: cadence_qspi: fix base trigger address & transfer start address
spi: cadence_qspi: get fifo width from device tree

 arch/arm/dts/socfpga.dtsi      |    4 +++-
 arch/arm/dts/stv0991.dts       |    4 +++-
 drivers/spi/cadence_qspi.c     |   15 +++++++-------
 drivers/spi/cadence_qspi.h     |    6 ++++--
 drivers/spi/cadence_qspi_apb.c |   42 ++++++++++++++++------------------------
 5 files changed, 35 insertions(+), 36 deletions(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v3 1/4 spi: cadence_qspi: move trigger base configuration in init

No need to configure indirect trigger address for every read/write.

---

Changes in v3: added commit message & removed extra bracket. Changes in v2: Rebased to master

 drivers/spi/cadence_qspi_apb.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/spi/cadence_qspi_apb.c +2 -7
index d053407..b46e5fe 100644
@@ -534,6 +534,8 @@ void cadence_qspi_apb_controller_init(struct cadence_spi_platdata *plat)
 
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
+	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+				plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
 	/* Disable all interrupts */
 	writel(0, plat->regbase + CQSPI_REG_IRQMASK);
@@ -693,10 +695,6 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
 		/* for normal read (only ramtron as of now) */
 		addr_bytes = cmdlen - 1;
 
-	/* Setup the indirect trigger address */
-	writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
-	       plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
-
 	/* Configure the opcode */
 	rd_reg = cmdbuf[0] << CQSPI_REG_RD_INSTR_OPCODE_LSB;
 
@@ -790,9 +788,6 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
 		       cmdlen, (unsigned int)cmdbuf);
 		return -EINVAL;
 	}
-	/* Setup the indirect trigger address */
-	writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
-	       plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
 	/* Configure the opcode */
 	reg = cmdbuf[0] << CQSPI_REG_WR_INSTR_OPCODE_LSB;
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v3 1/4 spi: cadence_qspi: move trigger base configuration in init

Quoted 16 lines · Vikas Manocha

No need to configure indirect trigger address for every read/write.

---

Changes in v3: added commit message & removed extra bracket. Changes in v2: Rebased to master

 drivers/spi/cadence_qspi_apb.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index d053407..b46e5fe 100644

drivers/spi/cadence_qspi_apb.c void cadence_qspi_apb_controller_init(struct · line 539

Quoted 6 lines
drivers/spi/cadence_qspi_apb.c +2 -0
@@ -534,6 +534,8 @@ void cadence_qspi_apb_controller_init(struct
 cadence_spi_platdata *plat)
 
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
+	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+				plat->regbase + CQSPI_REG_INDIRECTTRIGGER);

Please drop this (u32) cast, it's misleading and problematic.

Best regards,
Marek Vasut

author
#3 lore raw

PATCH v3 1/4 spi: cadence_qspi: move trigger base configuration in init

Hi,

Quoted 19 lines · Marek Vasut
Quoted 18 lines · Vikas Manocha

No need to configure indirect trigger address for every read/write.

---

Changes in v3: added commit message & removed extra bracket. Changes in v2: Rebased to master

 drivers/spi/cadence_qspi_apb.c |    9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index d053407..b46e5fe 100644

drivers/spi/cadence_qspi_apb.c +0 -0
@@ -534,6 +534,8 @@ void cadence_qspi_apb_controller_init(struct
 cadence_spi_platdata *plat)
 
Quoted 6 lines

drivers/spi/cadence_qspi_apb.c void cadence_qspi_apb_controller_init(struct cadence_spi_platdata *plat) · line 538

Quoted 4 lines
drivers/spi/cadence_qspi_apb.c +2 -0
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
+	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+				plat->regbase + CQSPI_REG_INDIRECTTRIGGER);

Please drop this (u32) cast, it's misleading and problematic.

ok, will fix in v4.

Rgds,
Vikas

Quoted 5 lines

Best regards,
Marek Vasut
.

#4 lore raw

PATCH v3 2/4 spi: cadence_qspi: fix indirect read/write start address

In reply to Vikas Manocha

Indirect read/write start addresses are flash start addresses for indirect read or write transfers. These should be absolute flash addresses instead of offsets.

---

Changes in v3: none
Changes in v2: Rebased to master

 drivers/spi/cadence_qspi_apb.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/spi/cadence_qspi_apb.c +4 -2
index b46e5fe..6b5ae30 100644
@@ -705,7 +705,8 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
 
 	/* Get address */
 	addr_value = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel(addr_value, plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
+	writel((u32)plat->ahbbase + addr_value,
+			plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
 
 	/* The remaining lenght is dummy bytes. */
 	dummy_bytes = cmdlen - addr_bytes - 1;
@@ -795,7 +796,8 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
 
 	/* Setup write address. */
 	reg = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel(reg, plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);
+	writel((u32)plat->ahbbase + reg,
+			plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);
 
 	reg = readl(plat->regbase + CQSPI_REG_SIZE);
 	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
Signature · 1 line
1.7.9.5
#5 lore raw

PATCH v3 2/4 spi: cadence_qspi: fix indirect read/write start address

Quoted 18 lines · Vikas Manocha

Indirect read/write start addresses are flash start addresses for indirect read or write transfers. These should be absolute flash addresses instead of offsets.

---

Changes in v3: none
Changes in v2: Rebased to master

 drivers/spi/cadence_qspi_apb.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index b46e5fe..6b5ae30 100644

drivers/spi/cadence_qspi_apb.c int cadence_qspi_apb_indirect_read_setup(struct · line 710

Quoted 7 lines
drivers/spi/cadence_qspi_apb.c +2 -1
@@ -705,7 +705,8 @@ int cadence_qspi_apb_indirect_read_setup(struct
 cadence_spi_platdata *plat,
 
 	/* Get address */
 	addr_value = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel(addr_value, plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
+	writel((u32)plat->ahbbase + addr_value,
+			plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);

Please drop this (u32) cast, it's misleading and problematic.

drivers/spi/cadence_qspi_apb.c int cadence_qspi_apb_indirect_write_setup(struct · line 801

Quoted 10 lines
drivers/spi/cadence_qspi_apb.c +2 -1
 	/* The remaining lenght is dummy bytes. */
 	dummy_bytes = cmdlen - addr_bytes - 1;
@@ -795,7 +796,8 @@ int cadence_qspi_apb_indirect_write_setup(struct
 cadence_spi_platdata *plat,
 
 	/* Setup write address. */
 	reg = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel(reg, plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);
+	writel((u32)plat->ahbbase + reg,
+			plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);

Please drop this (u32) cast, it's misleading and problematic.

Best regards,
Marek Vasut

author
#6 lore raw

PATCH v3 2/4 spi: cadence_qspi: fix indirect read/write start address

Hi,

Quoted 21 lines · Marek Vasut
Quoted 20 lines · Vikas Manocha

Indirect read/write start addresses are flash start addresses for indirect read or write transfers. These should be absolute flash addresses instead of offsets.

---

Changes in v3: none
Changes in v2: Rebased to master

 drivers/spi/cadence_qspi_apb.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index b46e5fe..6b5ae30 100644

drivers/spi/cadence_qspi_apb.c +0 -0
@@ -705,7 +705,8 @@ int cadence_qspi_apb_indirect_read_setup(struct
 cadence_spi_platdata *plat,
 
Quoted 7 lines

drivers/spi/cadence_qspi_apb.c int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat, · line 709

Quoted 5 lines
drivers/spi/cadence_qspi_apb.c +2 -1
 	/* Get address */
 	addr_value = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel(addr_value, plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
+	writel((u32)plat->ahbbase + addr_value,
+			plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);

Please drop this (u32) cast, it's misleading and problematic.

ok, Thanks for it.

Quoted 6 lines
Quoted 6 lines
drivers/spi/cadence_qspi_apb.c +0 -0
 	/* The remaining lenght is dummy bytes. */
 	dummy_bytes = cmdlen - addr_bytes - 1;
@@ -795,7 +796,8 @@ int cadence_qspi_apb_indirect_write_setup(struct
 cadence_spi_platdata *plat,
 
Quoted 7 lines

drivers/spi/cadence_qspi_apb.c int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat, · line 800

Quoted 5 lines
drivers/spi/cadence_qspi_apb.c +2 -1
 	/* Setup write address. */
 	reg = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel(reg, plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);
+	writel((u32)plat->ahbbase + reg,
+			plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);

Please drop this (u32) cast, it's misleading and problematic.

ok, Thanks for pointing it out.

Rgds,
Vikas

Quoted 5 lines

Best regards,
Marek Vasut
.

#7 lore raw

PATCH v3 3/4 spi: cadence_qspi: fix base trigger address & transfer start address

In reply to Vikas Manocha

This patch is to separate the base trigger from the read/write transfer start addresses.

Base trigger register address (0x1c register) corresponds to the address which should be put on AHB bus to handle indirect transfer triggered before.

To handle indirect transfer we need to issue addresses from (value of 0x1c) to (value of 0x1c) + 15*4 ("4" corresponds to size of SRAM location). There are no obstacles in issuing const address just equal to 0x1c. Important thing to note is that indirect trigger address has nothing in common with your physical or mapped NOR Flash address.

Transfer read/write start addresses (offset 0x68/0x78)should be programmed with the absolute flash address to be read/written.

plat->ahbbase has been renamed to plat->flashbase for clarity. plat->triggerbase is added in device tree for mapped spi flash address.

---

Changes in v3: formatted string breaking fixed.
Changes in v2: Rebased to master

 arch/arm/dts/socfpga.dtsi      |    3 ++-
 arch/arm/dts/stv0991.dts       |    3 ++-
 drivers/spi/cadence_qspi.c     |   14 +++++++-------
 drivers/spi/cadence_qspi.h     |    5 +++--
 drivers/spi/cadence_qspi_apb.c |   11 +++++------
 5 files changed, 19 insertions(+), 17 deletions(-)
arch/arm/dts/socfpga.dtsi +2 -1
index 9b12420..25053ec 100644
@@ -633,7 +633,8 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff705000 0x1000>,
-				<0xffa00000 0x1000>;
+				<0xffa00000 0x1000>,
+				<0xffa00000 0x0010>;
 			interrupts = <0 151 4>;
 			clocks = <&qspi_clk>;
 			ext-decoder = <0>;  /* external decoder */
arch/arm/dts/stv0991.dts +2 -1
index fa3fd64..e23d4fd 100644
@@ -30,7 +30,8 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x80203000 0x100>,
-				<0x40000000 0x1000000>;
+				<0x40000000 0x1000000>,
+				<0x40000000 0x0000010>;
 			clocks = <3750000>;
 			sram-size = <256>;
 			status = "okay";
drivers/spi/cadence_qspi.c +7 -7
index 34a0f46..01eff71 100644
@@ -150,7 +150,7 @@ static int cadence_spi_probe(struct udevice *bus)
 	struct cadence_spi_priv *priv = dev_get_priv(bus);
 
 	priv->regbase = plat->regbase;
-	priv->ahbbase = plat->ahbbase;
+	priv->flashbase = plat->flashbase;
 
 	if (!priv->qspi_is_init) {
 		cadence_qspi_apb_controller_init(plat);
@@ -278,7 +278,7 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
 	const void *blob = gd->fdt_blob;
 	int node = bus->of_offset;
 	int subnode;
-	u32 data[4];
+	u32 data[6];
 	int ret;
 
 	/* 2 base addresses are needed, lets get them from the DT */
@@ -289,7 +289,8 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
 	}
 
 	plat->regbase = (void *)data[0];
-	plat->ahbbase = (void *)data[2];
+	plat->flashbase = (void *)data[2];
+	plat->trigger_base = (void *)data[4];
 
 	/* Use 500KHz as a suitable default */
 	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
@@ -311,10 +312,9 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
 	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,
-	      plat->page_size);
-
+	debug("%s: regbase=%p flashbase=%p trigger_base=%p max-frequency=%d page-size=%d\n",
+		__func__, plat->regbase, plat->flashbase, plat->trigger_base,
+		plat->max_hz, plat->page_size);
 	return 0;
 }
 
drivers/spi/cadence_qspi.h +3 -2
index 98e57aa..7341339 100644
@@ -17,7 +17,8 @@
 struct cadence_spi_platdata {
 	unsigned int	max_hz;
 	void		*regbase;
-	void		*ahbbase;
+	void		*flashbase;
+	void		*trigger_base;
 
 	u32		page_size;
 	u32		block_size;
@@ -30,7 +31,7 @@ struct cadence_spi_platdata {
 
 struct cadence_spi_priv {
 	void		*regbase;
-	void		*ahbbase;
+	void		*flashbase;
 	size_t		cmd_len;
 	u8		cmd_buf[32];
 	size_t		data_len;
drivers/spi/cadence_qspi_apb.c +5 -6
index 6b5ae30..25a7ed2 100644
@@ -44,7 +44,6 @@
 #define CQSPI_INST_TYPE_QUAD			(2)
 
 #define CQSPI_STIG_DATA_LEN_MAX			(8)
-#define CQSPI_INDIRECTTRIGGER_ADDR_MASK		(0xFFFFF)
 
 #define CQSPI_DUMMY_CLKS_PER_BYTE		(8)
 #define CQSPI_DUMMY_BYTES_MAX			(4)
@@ -281,7 +280,7 @@ static int qpsi_write_sram_fifo_push(struct cadence_spi_platdata *plat,
 				const void *src_addr, unsigned int num_bytes)
 {
 	const void *reg_base = plat->regbase;
-	void *dest_addr = plat->ahbbase;
+	void *dest_addr = plat->trigger_base;
 	unsigned int retry = CQSPI_REG_RETRY;
 	unsigned int sram_level;
 	unsigned int wr_bytes;
@@ -534,7 +533,7 @@ void cadence_qspi_apb_controller_init(struct cadence_spi_platdata *plat)
 
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
-	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+	writel((u32)plat->trigger_base,
 				plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
 
 	/* Disable all interrupts */
@@ -705,7 +704,7 @@ int cadence_qspi_apb_indirect_read_setup(struct cadence_spi_platdata *plat,
 
 	/* Get address */
 	addr_value = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel((u32)plat->ahbbase + addr_value,
+	writel((u32)plat->flashbase + addr_value,
 			plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR);
 
 	/* The remaining lenght is dummy bytes. */
@@ -753,7 +752,7 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
 	       plat->regbase + CQSPI_REG_INDIRECTRD);
 
 	if (qspi_read_sram_fifo_poll(plat->regbase, (void *)rxbuf,
-				     (const void *)plat->ahbbase, rxlen))
+				     (const void *)plat->trigger_base, rxlen))
 		goto failrd;
 
 	/* Check flash indirect controller */
@@ -796,7 +795,7 @@ int cadence_qspi_apb_indirect_write_setup(struct cadence_spi_platdata *plat,
 
 	/* Setup write address. */
 	reg = cadence_qspi_apb_cmd2addr(&cmdbuf[1], addr_bytes);
-	writel((u32)plat->ahbbase + reg,
+	writel((u32)plat->flashbase + reg,
 			plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR);
 
 	reg = readl(plat->regbase + CQSPI_REG_SIZE);
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH v3 3/4 spi: cadence_qspi: fix base trigger address & transfer start address

Quoted 37 lines · Vikas Manocha

This patch is to separate the base trigger from the read/write transfer start addresses.

Base trigger register address (0x1c register) corresponds to the address which should be put on AHB bus to handle indirect transfer triggered before.

To handle indirect transfer we need to issue addresses from (value of 0x1c) to (value of 0x1c) + 15*4 ("4" corresponds to size of SRAM location). There are no obstacles in issuing const address just equal to 0x1c. Important thing to note is that indirect trigger address has nothing in common with your physical or mapped NOR Flash address.

Transfer read/write start addresses (offset 0x68/0x78)should be programmed with the absolute flash address to be read/written.

plat->ahbbase has been renamed to plat->flashbase for clarity. plat->triggerbase is added in device tree for mapped spi flash address.

---

Changes in v3: formatted string breaking fixed.
Changes in v2: Rebased to master

 arch/arm/dts/socfpga.dtsi      |    3 ++-
 arch/arm/dts/stv0991.dts       |    3 ++-
 drivers/spi/cadence_qspi.c     |   14 +++++++-------
 drivers/spi/cadence_qspi.h     |    5 +++--
 drivers/spi/cadence_qspi_apb.c |   11 +++++------
 5 files changed, 19 insertions(+), 17 deletions(-)
arch/arm/dts/socfpga.dtsi +0 -0
index 9b12420..25053ec 100644

arch/arm/dts/socfpga.dtsi line 637

Quoted 6 lines
arch/arm/dts/socfpga.dtsi +2 -1
@@ -633,7 +633,8 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff705000 0x1000>,
-				<0xffa00000 0x1000>;
+				<0xffa00000 0x1000>,
+				<0xffa00000 0x0010>;

Can you please follow the DT bindings Graham and me sent for Linux kernel instead of adding ad-hoc undocumented stuff ?

Quoted 22 lines
arch/arm/dts/socfpga.dtsi +0 -0
 			interrupts = <0 151 4>;
 			clocks = <&qspi_clk>;
 			ext-decoder = <0>;  /* external decoder */
arch/arm/dts/stv0991.dts +2 -1
index fa3fd64..e23d4fd 100644
@@ -30,7 +30,8 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x80203000 0x100>,
-				<0x40000000 0x1000000>;
+				<0x40000000 0x1000000>,
+				<0x40000000 0x0000010>;
 			clocks = <3750000>;
 			sram-size = <256>;
 			status = "okay";
drivers/spi/cadence_qspi.c +0 -0
index 34a0f46..01eff71 100644

drivers/spi/cadence_qspi.c static int cadence_spi_probe(struct udevice *bus) · line 153

Quoted 5 lines
drivers/spi/cadence_qspi.c +1 -1
@@ -150,7 +150,7 @@ static int cadence_spi_probe(struct udevice *bus)
 	struct cadence_spi_priv *priv = dev_get_priv(bus);
 
 	priv->regbase = plat->regbase;
-	priv->ahbbase = plat->ahbbase;
+	priv->flashbase = plat->flashbase;

If you need to rename anything, it should be in a separate patch. Please keep it separate.

Quoted 12 lines
drivers/spi/cadence_qspi.c +1 -1
 	if (!priv->qspi_is_init) {
 		cadence_qspi_apb_controller_init(plat);
@@ -278,7 +278,7 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) const void *blob = gd->fdt_blob;
 	int node = bus->of_offset;
 	int subnode;
-	u32 data[4];
+	u32 data[6];
 	int ret;
 
 	/* 2 base addresses are needed, lets get them from the DT */

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct · line 293

Quoted 6 lines
drivers/spi/cadence_qspi.c +2 -1
@@ -289,7 +289,8 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) }
 
 	plat->regbase = (void *)data[0];
-	plat->ahbbase = (void *)data[2];
+	plat->flashbase = (void *)data[2];
+	plat->trigger_base = (void *)data[4];

Please switch this to fdtdec_get_addr() instead ; if you use the Linux binding, you will be able to do this easily.

Quoted 5 lines
drivers/spi/cadence_qspi.c +0 -0
 	/* Use 500KHz as a suitable default */
 	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
@@ -311,10 +312,9 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns",
 20);

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct · line 319

Quoted 10 lines
drivers/spi/cadence_qspi.c +2 -4
 	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,
-	      plat->page_size);
-
+	debug("%s: regbase=%p flashbase=%p trigger_base=%p max-frequency=%d
 page-size=%d\n", +		__func__, plat->regbase, plat->flashbase,
 plat->trigger_base,
+		plat->max_hz, plat->page_size);

Please don't break the indent of the args. The original debug() statement had the args correctly indented ; this patch breaks the indent.

Quoted 48 lines
drivers/spi/cadence_qspi.c +0 -0
 	return 0;
 }
drivers/spi/cadence_qspi.h +3 -2
index 98e57aa..7341339 100644
@@ -17,7 +17,8 @@
 struct cadence_spi_platdata {
 	unsigned int	max_hz;
 	void		*regbase;
-	void		*ahbbase;
+	void		*flashbase;
+	void		*trigger_base;
 
 	u32		page_size;
 	u32		block_size;
@@ -30,7 +31,7 @@ struct cadence_spi_platdata {
 
 struct cadence_spi_priv {
 	void		*regbase;
-	void		*ahbbase;
+	void		*flashbase;
 	size_t		cmd_len;
 	u8		cmd_buf[32];
 	size_t		data_len;
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index 6b5ae30..25a7ed2 100644

drivers/spi/cadence_qspi_apb.c +1 -2
@@ -44,7 +44,6 @@
 #define CQSPI_INST_TYPE_QUAD			(2)
 
 #define CQSPI_STIG_DATA_LEN_MAX			(8)
-#define CQSPI_INDIRECTTRIGGER_ADDR_MASK		(0xFFFFF)
 
 #define CQSPI_DUMMY_CLKS_PER_BYTE		(8)
 #define CQSPI_DUMMY_BYTES_MAX			(4)
@@ -281,7 +280,7 @@ static int qpsi_write_sram_fifo_push(struct
 cadence_spi_platdata *plat, const void *src_addr, unsigned int num_bytes)
 {
 	const void *reg_base = plat->regbase;
-	void *dest_addr = plat->ahbbase;
+	void *dest_addr = plat->trigger_base;
 	unsigned int retry = CQSPI_REG_RETRY;
 	unsigned int sram_level;
 	unsigned int wr_bytes;

drivers/spi/cadence_qspi_apb.c void cadence_qspi_apb_controller_init(struct · line 538

Quoted 7 lines
drivers/spi/cadence_qspi_apb.c +1 -1
@@ -534,7 +533,7 @@ void cadence_qspi_apb_controller_init(struct
 cadence_spi_platdata *plat)
 
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
-	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+	writel((u32)plat->trigger_base,
 				plat->regbase + CQSPI_REG_INDIRECTTRIGGER);

Here you actually changed to logic of the code, which breaks it for SoCFPGA. plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK = 0x0 for SoCFPGA, but now you changed it such that 0xffa00000 is written into the register. Same does apply for all your changes below.

This patch needs fixing.

author
#9 lore raw

PATCH v3 3/4 spi: cadence_qspi: fix base trigger address & transfer start address

Hi,

Quoted 33 lines · Marek Vasut
Quoted 32 lines · Vikas Manocha

This patch is to separate the base trigger from the read/write transfer start addresses.

Base trigger register address (0x1c register) corresponds to the address which should be put on AHB bus to handle indirect transfer triggered before.

To handle indirect transfer we need to issue addresses from (value of 0x1c) to (value of 0x1c) + 15*4 ("4" corresponds to size of SRAM location). There are no obstacles in issuing const address just equal to 0x1c. Important thing to note is that indirect trigger address has nothing in common with your physical or mapped NOR Flash address.

Transfer read/write start addresses (offset 0x68/0x78)should be programmed with the absolute flash address to be read/written.

plat->ahbbase has been renamed to plat->flashbase for clarity. plat->triggerbase is added in device tree for mapped spi flash address.

---

Changes in v3: formatted string breaking fixed.
Changes in v2: Rebased to master

 arch/arm/dts/socfpga.dtsi      |    3 ++-
 arch/arm/dts/stv0991.dts       |    3 ++-
 drivers/spi/cadence_qspi.c     |   14 +++++++-------
 drivers/spi/cadence_qspi.h     |    5 +++--
 drivers/spi/cadence_qspi_apb.c |   11 +++++------
 5 files changed, 19 insertions(+), 17 deletions(-)
Quoted 14 lines

arch/arm/dts/socfpga.dtsi line 637

Quoted 11 lines
arch/arm/dts/socfpga.dtsi +2 -1
index 9b12420..25053ec 100644
@@ -633,7 +633,8 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff705000 0x1000>,
-				<0xffa00000 0x1000>;
+				<0xffa00000 0x1000>,
+				<0xffa00000 0x0010>;

Can you please follow the DT bindings Graham and me sent for Linux kernel instead of adding ad-hoc undocumented stuff ?

It is aligned to current DT binding of u-boot.
I agree to align it to linux kernel DT binding but that should be a separate patch.

Quoted 25 lines
Quoted 25 lines
arch/arm/dts/socfpga.dtsi +0 -0
 			interrupts = <0 151 4>;
 			clocks = <&qspi_clk>;
 			ext-decoder = <0>;  /* external decoder */
arch/arm/dts/stv0991.dts +2 -1
index fa3fd64..e23d4fd 100644
@@ -30,7 +30,8 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x80203000 0x100>,
-				<0x40000000 0x1000000>;
+				<0x40000000 0x1000000>,
+				<0x40000000 0x0000010>;
 			clocks = <3750000>;
 			sram-size = <256>;
 			status = "okay";
drivers/spi/cadence_qspi.c +0 -0
index 34a0f46..01eff71 100644
@@ -150,7 +150,7 @@ static int cadence_spi_probe(struct udevice *bus)
 	struct cadence_spi_priv *priv = dev_get_priv(bus);
 
Quoted 6 lines

drivers/spi/cadence_qspi.c static int cadence_spi_probe(struct udevice *bus) · line 153

Quoted 3 lines
drivers/spi/cadence_qspi.c +1 -1
 	priv->regbase = plat->regbase;
-	priv->ahbbase = plat->ahbbase;
+	priv->flashbase = plat->flashbase;

If you need to rename anything, it should be in a separate patch. Please keep it separate.

this renaming is done here for more clarity as the earlier ahbbase usage is split between "flashbase" & "trigger base". ahbbase is not relevant anymore.

Quoted 15 lines
Quoted 15 lines
drivers/spi/cadence_qspi.c +1 -1
 	if (!priv->qspi_is_init) {
 		cadence_qspi_apb_controller_init(plat);
@@ -278,7 +278,7 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) const void *blob = gd->fdt_blob;
 	int node = bus->of_offset;
 	int subnode;
-	u32 data[4];
+	u32 data[6];
 	int ret;
 
 	/* 2 base addresses are needed, lets get them from the DT */
@@ -289,7 +289,8 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) }
 
Quoted 7 lines

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct udevice *bus) · line 293

Quoted 4 lines
drivers/spi/cadence_qspi.c +2 -1
 	plat->regbase = (void *)data[0];
-	plat->ahbbase = (void *)data[2];
+	plat->flashbase = (void *)data[2];
+	plat->trigger_base = (void *)data[4];

Please switch this to fdtdec_get_addr() instead ; if you use the Linux binding, you will be able to do this easily.

As above, should be separate patch to align to Linux binding.

Quoted 8 lines
Quoted 8 lines
drivers/spi/cadence_qspi.c +0 -0
 	/* Use 500KHz as a suitable default */
 	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
@@ -311,10 +312,9 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns",
 20);
 	plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128);
 
Quoted 11 lines

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct udevice *bus) · line 317

Quoted 8 lines
drivers/spi/cadence_qspi.c +2 -4
-	debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
-	      __func__, plat->regbase, plat->ahbbase, plat->max_hz,
-	      plat->page_size);
-
+	debug("%s: regbase=%p flashbase=%p trigger_base=%p max-frequency=%d
 page-size=%d\n", +		__func__, plat->regbase, plat->flashbase,
 plat->trigger_base,
+		plat->max_hz, plat->page_size);

Please don't break the indent of the args. The original debug() statement had the args correctly indented ; this patch breaks the indent.

I think it looks like this here as the line length is more than 80 chars for args. After applying patch it looks ok. If not, please let me know how to fix it.

Quoted 51 lines
Quoted 51 lines
drivers/spi/cadence_qspi.c +0 -0
 	return 0;
 }
drivers/spi/cadence_qspi.h +3 -2
index 98e57aa..7341339 100644
@@ -17,7 +17,8 @@
 struct cadence_spi_platdata {
 	unsigned int	max_hz;
 	void		*regbase;
-	void		*ahbbase;
+	void		*flashbase;
+	void		*trigger_base;
 
 	u32		page_size;
 	u32		block_size;
@@ -30,7 +31,7 @@ struct cadence_spi_platdata {
 
 struct cadence_spi_priv {
 	void		*regbase;
-	void		*ahbbase;
+	void		*flashbase;
 	size_t		cmd_len;
 	u8		cmd_buf[32];
 	size_t		data_len;
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index 6b5ae30..25a7ed2 100644

drivers/spi/cadence_qspi_apb.c +1 -2
@@ -44,7 +44,6 @@
 #define CQSPI_INST_TYPE_QUAD			(2)
 
 #define CQSPI_STIG_DATA_LEN_MAX			(8)
-#define CQSPI_INDIRECTTRIGGER_ADDR_MASK		(0xFFFFF)
 
 #define CQSPI_DUMMY_CLKS_PER_BYTE		(8)
 #define CQSPI_DUMMY_BYTES_MAX			(4)
@@ -281,7 +280,7 @@ static int qpsi_write_sram_fifo_push(struct
 cadence_spi_platdata *plat, const void *src_addr, unsigned int num_bytes)
 {
 	const void *reg_base = plat->regbase;
-	void *dest_addr = plat->ahbbase;
+	void *dest_addr = plat->trigger_base;
 	unsigned int retry = CQSPI_REG_RETRY;
 	unsigned int sram_level;
 	unsigned int wr_bytes;
@@ -534,7 +533,7 @@ void cadence_qspi_apb_controller_init(struct
 cadence_spi_platdata *plat)
 
Quoted 10 lines

drivers/spi/cadence_qspi_apb.c void cadence_qspi_apb_controller_init(struct cadence_spi_platdata *plat) · line 537

Quoted 5 lines
drivers/spi/cadence_qspi_apb.c +1 -1
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
-	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+	writel((u32)plat->trigger_base,
 				plat->regbase + CQSPI_REG_INDIRECTTRIGGER);

Here you actually changed to logic of the code, which breaks it for SoCFPGA. plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK = 0x0 for SoCFPGA, but now you changed it such that 0xffa00000 is written into the register. Same does apply for all your changes below.

If we pass 0x00 from device tree, 0x0 would be written in the register. We have to check on SOCFpga platform is 0xFFA0_0000 is correct value or only 0x0. Anyways i will change the DT value to 0x0 for SOCFpga in next version.

Rgds,
Vikas

Quoted 4 lines

This patch needs fixing.
.

#10 lore raw

PATCH v3 3/4 spi: cadence_qspi: fix base trigger address & transfer start address

Quoted 53 lines · vikas

Hi,

Quoted 43 lines · Marek Vasut
Quoted 42 lines · Vikas Manocha

This patch is to separate the base trigger from the read/write transfer start addresses.

Base trigger register address (0x1c register) corresponds to the address which should be put on AHB bus to handle indirect transfer triggered before.

To handle indirect transfer we need to issue addresses from (value of 0x1c) to (value of 0x1c) + 15*4 ("4" corresponds to size of SRAM location). There are no obstacles in issuing const address just equal to 0x1c. Important thing to note is that indirect trigger address has nothing in common with your physical or mapped NOR Flash address.

Transfer read/write start addresses (offset 0x68/0x78)should be programmed with the absolute flash address to be read/written.

plat->ahbbase has been renamed to plat->flashbase for clarity. plat->triggerbase is added in device tree for mapped spi flash address.

---

Changes in v3: formatted string breaking fixed.
Changes in v2: Rebased to master

 arch/arm/dts/socfpga.dtsi      |    3 ++-
 arch/arm/dts/stv0991.dts       |    3 ++-
 drivers/spi/cadence_qspi.c     |   14 +++++++-------
 drivers/spi/cadence_qspi.h     |    5 +++--
 drivers/spi/cadence_qspi_apb.c |   11 +++++------
 5 files changed, 19 insertions(+), 17 deletions(-)
arch/arm/dts/socfpga.dtsi +0 -0
index 9b12420..25053ec 100644
@@ -633,7 +633,8 @@
 
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff705000 0x1000>,
 
Quoted 6 lines

arch/arm/dts/socfpga.dtsi line 637

Quoted 3 lines
arch/arm/dts/socfpga.dtsi +2 -1
-				<0xffa00000 0x1000>;
+				<0xffa00000 0x1000>,
+				<0xffa00000 0x0010>;

Can you please follow the DT bindings Graham and me sent for Linux kernel instead of adding ad-hoc undocumented stuff ?

Quoted 3 lines

It is aligned to current DT binding of u-boot.
I agree to align it to linux kernel DT binding but that should be a separate patch.

And this separate patch should come in FIRST, we do not want to support two sets of bindings, no way.

Quoted 38 lines
Quoted 30 lines
Quoted 30 lines
arch/arm/dts/socfpga.dtsi +0 -0
 			interrupts = <0 151 4>;
arch/arm/dts/socfpga.dtsi +0 -0
 			clocks = <&qspi_clk>;
 			ext-decoder = <0>;  /* external decoder */
arch/arm/dts/stv0991.dts +2 -1
index fa3fd64..e23d4fd 100644
@@ -30,7 +30,8 @@
 
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x80203000 0x100>,
 
-				<0x40000000 0x1000000>;
+				<0x40000000 0x1000000>,
+				<0x40000000 0x0000010>;
 
arch/arm/dts/stv0991.dts +0 -0
 			clocks = <3750000>;
 			sram-size = <256>;
 			status = "okay";
drivers/spi/cadence_qspi.c +0 -0
index 34a0f46..01eff71 100644
@@ -150,7 +150,7 @@ static int cadence_spi_probe(struct udevice *bus)
 
 	struct cadence_spi_priv *priv = dev_get_priv(bus);
 
Quoted 7 lines

drivers/spi/cadence_qspi.c static int cadence_spi_probe(struct udevice *bus) · line 153

Quoted 4 lines
drivers/spi/cadence_qspi.c +1 -1
 	priv->regbase = plat->regbase;
 
-	priv->ahbbase = plat->ahbbase;
+	priv->flashbase = plat->flashbase;

If you need to rename anything, it should be in a separate patch. Please keep it separate.

Quoted 3 lines

this renaming is done here for more clarity as the earlier ahbbase usage is split between "flashbase" & "trigger base". ahbbase is not relevant anymore.

Which is why it should happen in a separate patch :)

Quoted 22 lines
Quoted 22 lines
Quoted 22 lines
drivers/spi/cadence_qspi.c +0 -0
 	if (!priv->qspi_is_init) {
drivers/spi/cadence_qspi.c +1 -1
 		cadence_qspi_apb_controller_init(plat);
@@ -278,7 +278,7 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) const void *blob = gd->fdt_blob;
 
 	int node = bus->of_offset;
 	int subnode;
 
-	u32 data[4];
+	u32 data[6];
 
drivers/spi/cadence_qspi.c +0 -0
 	int ret;
 
 	/* 2 base addresses are needed, lets get them from the DT */
@@ -289,7 +289,8 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) }
 
 	plat->regbase = (void *)data[0];
 
Quoted 8 lines
Quoted 6 lines

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct udevice *bus) · line 293

Quoted 3 lines
drivers/spi/cadence_qspi.c +2 -1
-	plat->ahbbase = (void *)data[2];
+	plat->flashbase = (void *)data[2];
+	plat->trigger_base = (void *)data[4];

Please switch this to fdtdec_get_addr() instead ; if you use the Linux binding, you will be able to do this easily.

As above, should be separate patch to align to Linux binding.

Correct ; and it should go in before this one. We don't want to add crap we know about first and fix it afterward, we do it the other way around. First we remove the crap which is in the way, then we add features.

Quoted 21 lines
Quoted 9 lines
Quoted 9 lines
drivers/spi/cadence_qspi.c +0 -0
 	/* Use 500KHz as a suitable default */
 	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
@@ -311,10 +312,9 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns",
 20);
 
 	plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128);
 
Quoted 11 lines

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct udevice *bus) · line 317

Quoted 8 lines
drivers/spi/cadence_qspi.c +1 -4
-	debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n",
-	      __func__, plat->regbase, plat->ahbbase, plat->max_hz,
-	      plat->page_size);
-
+	debug("%s: regbase=%p flashbase=%p trigger_base=%p max-frequency=%d
 page-size=%d\n", +		__func__, plat->regbase, plat->flashbase,

plat->trigger_base,

drivers/spi/cadence_qspi.c +1 -0
+		plat->max_hz, plat->page_size);

Please don't break the indent of the args. The original debug() statement had the args correctly indented ; this patch breaks the indent.

Quoted 3 lines

I think it looks like this here as the line length is more than 80 chars for args. After applying patch it looks ok. If not, please let me know how to fix it.

I'm talking about the change from 6 spaces to one tab in front of the args.

Quoted 81 lines
Quoted 74 lines
Quoted 74 lines
drivers/spi/cadence_qspi.c +0 -0
 	return 0;
 
 }
drivers/spi/cadence_qspi.h +2 -1
index 98e57aa..7341339 100644
@@ -17,7 +17,8 @@
 
 struct cadence_spi_platdata {
 
 	unsigned int	max_hz;
 	void		*regbase;
 
-	void		*ahbbase;
+	void		*flashbase;
+	void		*trigger_base;
drivers/spi/cadence_qspi.h +1 -1
 	u32		page_size;
 	u32		block_size;
@@ -30,7 +31,7 @@ struct cadence_spi_platdata {
 
 struct cadence_spi_priv {
 
 	void		*regbase;
 
-	void		*ahbbase;
+	void		*flashbase;
 
drivers/spi/cadence_qspi.h +0 -0
 	size_t		cmd_len;
 	u8		cmd_buf[32];
 	size_t		data_len;
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index 6b5ae30..25a7ed2 100644

drivers/spi/cadence_qspi_apb.c +0 -1
@@ -44,7 +44,6 @@
 
 #define CQSPI_INST_TYPE_QUAD			(2)
 
 #define CQSPI_STIG_DATA_LEN_MAX			(8)
 
-#define CQSPI_INDIRECTTRIGGER_ADDR_MASK		(0xFFFFF)
 

#define CQSPI_DUMMY_CLKS_PER_BYTE (8)
#define CQSPI_DUMMY_BYTES_MAX (4)

drivers/spi/cadence_qspi_apb.c +0 -0
@@ -281,7 +280,7 @@ static int qpsi_write_sram_fifo_push(struct

cadence_spi_platdata *plat, const void *src_addr, unsigned int num_bytes)

{

drivers/spi/cadence_qspi_apb.c +2 -2
 	const void *reg_base = plat->regbase;
 
-	void *dest_addr = plat->ahbbase;
+	void *dest_addr = plat->trigger_base;
 
 	unsigned int retry = CQSPI_REG_RETRY;
 	unsigned int sram_level;
 	unsigned int wr_bytes;
@@ -534,7 +533,7 @@ void cadence_qspi_apb_controller_init(struct
 cadence_spi_platdata *plat)
 
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
 
-	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+	writel((u32)plat->trigger_base,
 
Quoted 6 lines
Quoted 1 line

plat->regbase + CQSPI_REG_INDIRECTTRIGGER);

Here you actually changed to logic of the code, which breaks it for SoCFPGA. plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK = 0x0 for SoCFPGA, but now you changed it such that 0xffa00000 is written into the register. Same does apply for all your changes below.

Quoted 4 lines

If we pass 0x00 from device tree, 0x0 would be written in the register. We have to check on SOCFpga platform is 0xFFA0_0000 is correct value or only 0x0. Anyways i will change the DT value to 0x0 for SOCFpga in next version.

Excellent.

author
#11 lore raw

PATCH v3 3/4 spi: cadence_qspi: fix base trigger address & transfer start address

Hi,

Quoted 54 lines · Marek Vasut
Quoted 53 lines · vikas

Hi,

Quoted 49 lines · Marek Vasut
Quoted 37 lines · Vikas Manocha

This patch is to separate the base trigger from the read/write transfer start addresses.

Base trigger register address (0x1c register) corresponds to the address which should be put on AHB bus to handle indirect transfer triggered before.

To handle indirect transfer we need to issue addresses from (value of 0x1c) to (value of 0x1c) + 15*4 ("4" corresponds to size of SRAM location). There are no obstacles in issuing const address just equal to 0x1c. Important thing to note is that indirect trigger address has nothing in common with your physical or mapped NOR Flash address.

Transfer read/write start addresses (offset 0x68/0x78)should be programmed with the absolute flash address to be read/written.

plat->ahbbase has been renamed to plat->flashbase for clarity. plat->triggerbase is added in device tree for mapped spi flash address.

---

Changes in v3: formatted string breaking fixed.
Changes in v2: Rebased to master

 arch/arm/dts/socfpga.dtsi      |    3 ++-
 arch/arm/dts/stv0991.dts       |    3 ++-
 drivers/spi/cadence_qspi.c     |   14 +++++++-------
 drivers/spi/cadence_qspi.h     |    5 +++--
 drivers/spi/cadence_qspi_apb.c |   11 +++++------
 5 files changed, 19 insertions(+), 17 deletions(-)
arch/arm/dts/socfpga.dtsi +0 -0
index 9b12420..25053ec 100644

arch/arm/dts/socfpga.dtsi line 639

Quoted 8 lines
arch/arm/dts/socfpga.dtsi +2 -1
@@ -633,7 +633,8 @@
 
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff705000 0x1000>,
 
-				<0xffa00000 0x1000>;
+				<0xffa00000 0x1000>,
+				<0xffa00000 0x0010>;

Can you please follow the DT bindings Graham and me sent for Linux kernel instead of adding ad-hoc undocumented stuff ?

Quoted 6 lines
Quoted 3 lines

It is aligned to current DT binding of u-boot.
I agree to align it to linux kernel DT binding but that should be a separate patch.

And this separate patch should come in FIRST, we do not want to support two sets of bindings, no way.

As you know linux DT binding is under review & current linux patch needs to be fixed. It does not make sense to support something which is under review & discussion are ongoing for it.

Quoted 39 lines
Quoted 39 lines
Quoted 38 lines
Quoted 28 lines
arch/arm/dts/socfpga.dtsi +0 -0
 			interrupts = <0 151 4>;
arch/arm/dts/socfpga.dtsi +0 -0
 			clocks = <&qspi_clk>;
 			ext-decoder = <0>;  /* external decoder */
arch/arm/dts/stv0991.dts +2 -1
index fa3fd64..e23d4fd 100644
@@ -30,7 +30,8 @@
 
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x80203000 0x100>,
 
-				<0x40000000 0x1000000>;
+				<0x40000000 0x1000000>,
+				<0x40000000 0x0000010>;
 
arch/arm/dts/stv0991.dts +0 -0
 			clocks = <3750000>;
 			sram-size = <256>;
 			status = "okay";
drivers/spi/cadence_qspi.c +0 -0
index 34a0f46..01eff71 100644

drivers/spi/cadence_qspi.c static int cadence_spi_probe(struct udevice *bus) · line 155

Quoted 7 lines
drivers/spi/cadence_qspi.c +1 -1
@@ -150,7 +150,7 @@ static int cadence_spi_probe(struct udevice *bus)
 
 	struct cadence_spi_priv *priv = dev_get_priv(bus);
 
 	priv->regbase = plat->regbase;
 
-	priv->ahbbase = plat->ahbbase;
+	priv->flashbase = plat->flashbase;

If you need to rename anything, it should be in a separate patch. Please keep it separate.

Quoted 5 lines
Quoted 3 lines

this renaming is done here for more clarity as the earlier ahbbase usage is split between "flashbase" & "trigger base". ahbbase is not relevant anymore.

Which is why it should happen in a separate patch :)

Hmmm.. Not adding any value but i will do it.

Quoted 30 lines
Quoted 30 lines
Quoted 29 lines
Quoted 19 lines
drivers/spi/cadence_qspi.c +0 -0
 	if (!priv->qspi_is_init) {
drivers/spi/cadence_qspi.c +1 -1
 		cadence_qspi_apb_controller_init(plat);
@@ -278,7 +278,7 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) const void *blob = gd->fdt_blob;
 
 	int node = bus->of_offset;
 	int subnode;
 
-	u32 data[4];
+	u32 data[6];
 
drivers/spi/cadence_qspi.c +0 -0
 	int ret;
 
 	/* 2 base addresses are needed, lets get them from the DT */

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct · line 294

Quoted 7 lines
drivers/spi/cadence_qspi.c +2 -1
@@ -289,7 +289,8 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) }
 
 	plat->regbase = (void *)data[0];
 
-	plat->ahbbase = (void *)data[2];
+	plat->flashbase = (void *)data[2];
+	plat->trigger_base = (void *)data[4];

Please switch this to fdtdec_get_addr() instead ; if you use the Linux binding, you will be able to do this easily.

Quoted 5 lines
Quoted 1 line

As above, should be separate patch to align to Linux binding.

Correct ; and it should go in before this one. We don't want to add crap we know about first and fix it afterward, we do it the other way around. First we remove the crap which is in the way, then we add features.

ditto.

Quoted 22 lines
Quoted 22 lines
Quoted 21 lines
Quoted 17 lines
drivers/spi/cadence_qspi.c +1 -4
 	/* Use 500KHz as a suitable default */
 	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
@@ -311,10 +312,9 @@ static int cadence_spi_ofdata_to_platdata(struct
 udevice *bus) 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,
-	      plat->page_size);
-
+	debug("%s: regbase=%p flashbase=%p trigger_base=%p max-frequency=%d
 page-size=%d\n", +		__func__, plat->regbase, plat->flashbase,

plat->trigger_base,

drivers/spi/cadence_qspi.c static int cadence_spi_ofdata_to_platdata(struct udevice *bus) · line 317

Quoted 1 line
drivers/spi/cadence_qspi.c +1 -0
+		plat->max_hz, plat->page_size);

Please don't break the indent of the args. The original debug() statement had the args correctly indented ; this patch breaks the indent.

Quoted 5 lines
Quoted 3 lines

I think it looks like this here as the line length is more than 80 chars for args. After applying patch it looks ok. If not, please let me know how to fix it.

I'm talking about the change from 6 spaces to one tab in front of the args.

ok.

Cheers,
Vikas

Quoted 90 lines
Quoted 82 lines
Quoted 75 lines
Quoted 75 lines
drivers/spi/cadence_qspi.c +0 -0
 	return 0;
 
 }
drivers/spi/cadence_qspi.h +2 -1
index 98e57aa..7341339 100644
@@ -17,7 +17,8 @@
 
 struct cadence_spi_platdata {
 
 	unsigned int	max_hz;
 	void		*regbase;
 
-	void		*ahbbase;
+	void		*flashbase;
+	void		*trigger_base;
drivers/spi/cadence_qspi.h +1 -1
 	u32		page_size;
 	u32		block_size;
@@ -30,7 +31,7 @@ struct cadence_spi_platdata {
 
 struct cadence_spi_priv {
 
 	void		*regbase;
 
-	void		*ahbbase;
+	void		*flashbase;
 
drivers/spi/cadence_qspi.h +0 -0
 	size_t		cmd_len;
 	u8		cmd_buf[32];
 	size_t		data_len;
(quoted diff) +0 -0

b/drivers/spi/cadence_qspi_apb.c index 6b5ae30..25a7ed2 100644

drivers/spi/cadence_qspi_apb.c +0 -1
@@ -44,7 +44,6 @@
 
 #define CQSPI_INST_TYPE_QUAD			(2)
 
 #define CQSPI_STIG_DATA_LEN_MAX			(8)
 
-#define CQSPI_INDIRECTTRIGGER_ADDR_MASK		(0xFFFFF)
 

#define CQSPI_DUMMY_CLKS_PER_BYTE (8)
#define CQSPI_DUMMY_BYTES_MAX (4)

drivers/spi/cadence_qspi_apb.c +0 -0
@@ -281,7 +280,7 @@ static int qpsi_write_sram_fifo_push(struct

cadence_spi_platdata *plat, const void *src_addr, unsigned int num_bytes)

{

drivers/spi/cadence_qspi_apb.c +2 -2
 	const void *reg_base = plat->regbase;
 
-	void *dest_addr = plat->ahbbase;
+	void *dest_addr = plat->trigger_base;
 
 	unsigned int retry = CQSPI_REG_RETRY;
 	unsigned int sram_level;
 	unsigned int wr_bytes;
@@ -534,7 +533,7 @@ void cadence_qspi_apb_controller_init(struct
 cadence_spi_platdata *plat)
 
 	/* Indirect mode configurations */
 	writel((plat->sram_size/2), plat->regbase + CQSPI_REG_SRAMPARTITION);
 
-	writel((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK,
+	writel((u32)plat->trigger_base,
 
Quoted 6 lines
Quoted 1 line

plat->regbase + CQSPI_REG_INDIRECTTRIGGER);

Here you actually changed to logic of the code, which breaks it for SoCFPGA. plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK = 0x0 for SoCFPGA, but now you changed it such that 0xffa00000 is written into the register. Same does apply for all your changes below.

Quoted 4 lines

If we pass 0x00 from device tree, 0x0 would be written in the register. We have to check on SOCFpga platform is 0xFFA0_0000 is correct value or only 0x0. Anyways i will change the DT value to 0x0 for SOCFpga in next version.

Excellent.
.

#12 lore raw

PATCH v3 3/4 spi: cadence_qspi: fix base trigger address & transfer start address

Quoted 1 line · vikas

Hi,

Hi,

Quoted 60 lines · Marek Vasut
Quoted 59 lines · vikas
Quoted 57 lines

Hi,

Quoted 44 lines · Marek Vasut
Quoted 43 lines · Vikas Manocha

This patch is to separate the base trigger from the read/write transfer start addresses.

Base trigger register address (0x1c register) corresponds to the address which should be put on AHB bus to handle indirect transfer triggered before.

To handle indirect transfer we need to issue addresses from (value of 0x1c) to (value of 0x1c) + 15*4 ("4" corresponds to size of SRAM location). There are no obstacles in issuing const address just equal to 0x1c. Important thing to note is that indirect trigger address has nothing in common with your physical or mapped NOR Flash address.

Transfer read/write start addresses (offset 0x68/0x78)should be programmed with the absolute flash address to be read/written.

plat->ahbbase has been renamed to plat->flashbase for clarity. plat->triggerbase is added in device tree for mapped spi flash address.

---

Changes in v3: formatted string breaking fixed.
Changes in v2: Rebased to master

 arch/arm/dts/socfpga.dtsi      |    3 ++-
 arch/arm/dts/stv0991.dts       |    3 ++-
 drivers/spi/cadence_qspi.c     |   14 +++++++-------
 drivers/spi/cadence_qspi.h     |    5 +++--
 drivers/spi/cadence_qspi_apb.c |   11 +++++------
 5 files changed, 19 insertions(+), 17 deletions(-)
arch/arm/dts/socfpga.dtsi +0 -0
index 9b12420..25053ec 100644
@@ -633,7 +633,8 @@
 
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0xff705000 0x1000>,
 
Quoted 6 lines

arch/arm/dts/socfpga.dtsi line 637

Quoted 3 lines
arch/arm/dts/socfpga.dtsi +2 -1
-				<0xffa00000 0x1000>;
+				<0xffa00000 0x1000>,
+				<0xffa00000 0x0010>;

Can you please follow the DT bindings Graham and me sent for Linux kernel instead of adding ad-hoc undocumented stuff ?

It is aligned to current DT binding of u-boot.
I agree to align it to linux kernel DT binding but that should be a separate patch.

Quoted 6 lines
Quoted 2 lines

And this separate patch should come in FIRST, we do not want to support two sets of bindings, no way.

As you know linux DT binding is under review & current linux patch needs to be fixed. It does not make sense to support something which is under review & discussion are ongoing for it.

So you propose that in the meantime, we grow our own, completely different, in-house set of binding instead of using the ones which are currently being reviewed for inclusion into Linux kernel. The only comments on those bindings are from you and are about wording of some piece of text, not even about the binding themselves.

No, sorry, I'm not buying this.

Quoted 38 lines
Quoted 38 lines
Quoted 38 lines
Quoted 37 lines
Quoted 27 lines
arch/arm/dts/socfpga.dtsi +0 -0
 			interrupts = <0 151 4>;
arch/arm/dts/socfpga.dtsi +0 -0
 			clocks = <&qspi_clk>;
 			ext-decoder = <0>;  /* external decoder */
arch/arm/dts/stv0991.dts +2 -1
index fa3fd64..e23d4fd 100644
@@ -30,7 +30,8 @@
 
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <0x80203000 0x100>,
 
-				<0x40000000 0x1000000>;
+				<0x40000000 0x1000000>,
+				<0x40000000 0x0000010>;
 
arch/arm/dts/stv0991.dts +0 -0
 			clocks = <3750000>;
 			sram-size = <256>;
 			status = "okay";
drivers/spi/cadence_qspi.c +0 -0
index 34a0f46..01eff71 100644

drivers/spi/cadence_qspi.c static int cadence_spi_probe(struct udevice *bus) · line 155

Quoted 7 lines
drivers/spi/cadence_qspi.c +1 -1
@@ -150,7 +150,7 @@ static int cadence_spi_probe(struct udevice *bus)
 
 	struct cadence_spi_priv *priv = dev_get_priv(bus);
 
 	priv->regbase = plat->regbase;
 
-	priv->ahbbase = plat->ahbbase;
+	priv->flashbase = plat->flashbase;

If you need to rename anything, it should be in a separate patch. Please keep it separate.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

this renaming is done here for more clarity as the earlier ahbbase usage is split between "flashbase" & "trigger base". ahbbase is not relevant anymore.

Which is why it should happen in a separate patch :)

Hmmm.. Not adding any value but i will do it.

The value is in keeping separate changes separate, reviewable and bisectable. You might want to read up on this.

[...]

#13 lore raw

PATCH v3 4/4 spi: cadence_qspi: get fifo width from device tree

In reply to Vikas Manocha

Fifo width could be different on different socs, e.g. stv0991 & altera soc have different fifo width.

---

Changes in v3: none
Changes in v2: Rebased to master

 arch/arm/dts/socfpga.dtsi      |    1 +
 arch/arm/dts/stv0991.dts       |    1 +
 drivers/spi/cadence_qspi.c     |    1 +
 drivers/spi/cadence_qspi.h     |    1 +
 drivers/spi/cadence_qspi_apb.c |   24 ++++++++++--------------
 5 files changed, 14 insertions(+), 14 deletions(-)
arch/arm/dts/socfpga.dtsi +1 -0
index 25053ec..265a5b8 100644
@@ -640,6 +640,7 @@
 			ext-decoder = <0>;  /* external decoder */
 			num-cs = <4>;
 			fifo-depth = <128>;
+			fifo-width = <4>;
 			sram-size = <128>;
 			bus-num = <2>;
 			status = "disabled";
arch/arm/dts/stv0991.dts +1 -0
index e23d4fd..f0f450b 100644
@@ -34,6 +34,7 @@
 				<0x40000000 0x0000010>;
 			clocks = <3750000>;
 			sram-size = <256>;
+			fifo-width = <8>;
 			status = "okay";
 
 			flash0: n25q32 at 0 {
drivers/spi/cadence_qspi.c +1 -0
index 01eff71..54b3c36 100644
@@ -311,6 +311,7 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus)
 	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);
+	plat->fifo_width = fdtdec_get_int(blob, node, "fifo-width", 4);
 
 	debug("%s: regbase=%p flashbase=%p trigger_base=%p max-frequency=%d page-size=%d\n",
 		__func__, plat->regbase, plat->flashbase, plat->trigger_base,
drivers/spi/cadence_qspi.h +1 -0
index 7341339..91f38f1 100644
@@ -27,6 +27,7 @@ struct cadence_spi_platdata {
 	u32		tchsh_ns;
 	u32		tslch_ns;
 	u32		sram_size;
+	u32		fifo_width;
 };
 
 struct cadence_spi_priv {
drivers/spi/cadence_qspi_apb.c +10 -14
index 25a7ed2..e534c06 100644
@@ -34,8 +34,6 @@
 #define CQSPI_REG_RETRY				(10000)
 #define CQSPI_POLL_IDLE_RETRY			(3)
 
-#define CQSPI_FIFO_WIDTH			(4)
-
 #define CQSPI_REG_SRAM_THRESHOLD_WORDS		(50)
 
 /* Transfer mode */
@@ -48,9 +46,6 @@
 #define CQSPI_DUMMY_CLKS_PER_BYTE		(8)
 #define CQSPI_DUMMY_BYTES_MAX			(4)
 
-
-#define CQSPI_REG_SRAM_FILL_THRESHOLD	\
-	((CQSPI_REG_SRAM_SIZE_WORD / 2) * CQSPI_FIFO_WIDTH)
 /****************************************************************************
  * Controller's configuration and status register (offset from QSPI_BASE)
  ****************************************************************************/
@@ -214,7 +209,7 @@ 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)
+	const void *src, unsigned int fifo_width, unsigned int bytes)
 {
 	unsigned int temp = 0;
 	int i;
@@ -222,11 +217,11 @@ static void cadence_qspi_apb_write_fifo_data(const void *dest_ahb_addr,
 	unsigned int *dest_ptr = (unsigned int *)dest_ahb_addr;
 	unsigned int *src_ptr = (unsigned int *)src;
 
-	while (remaining >= CQSPI_FIFO_WIDTH) {
-		for (i = CQSPI_FIFO_WIDTH/sizeof(src_ptr) - 1; i >= 0; i--)
+	while (remaining >= fifo_width) {
+		for (i = 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;
+		src_ptr += fifo_width/sizeof(src_ptr);
+		remaining -= fifo_width;
 	}
 	if (remaining) {
 		/* dangling bytes */
@@ -241,7 +236,7 @@ static void cadence_qspi_apb_write_fifo_data(const void *dest_ahb_addr,
 
 /* Read from SRAM FIFO with polling SRAM fill level. */
 static int qspi_read_sram_fifo_poll(const void *reg_base, void *dest_addr,
-			const void *src_addr,  unsigned int num_bytes)
+	const void *src_addr, unsigned int fifo_width, unsigned int num_bytes)
 {
 	unsigned int remaining = num_bytes;
 	unsigned int retry;
@@ -263,7 +258,7 @@ static int qspi_read_sram_fifo_poll(const void *reg_base, void *dest_addr,
 			return -1;
 		}
 
-		sram_level *= CQSPI_FIFO_WIDTH;
+		sram_level *= fifo_width;
 		sram_level = sram_level > remaining ? remaining : sram_level;
 
 		/* Read data from FIFO. */
@@ -305,7 +300,8 @@ static int qpsi_write_sram_fifo_push(struct cadence_spi_platdata *plat,
 		wr_bytes = (remaining > page_size) ?
 					page_size : remaining;
 
-		cadence_qspi_apb_write_fifo_data(dest_addr, src, wr_bytes);
+		cadence_qspi_apb_write_fifo_data(dest_addr, src, \
+				plat->fifo_width, wr_bytes);
 		src += wr_bytes;
 		remaining -= wr_bytes;
 	}
@@ -752,7 +748,7 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
 	       plat->regbase + CQSPI_REG_INDIRECTRD);
 
 	if (qspi_read_sram_fifo_poll(plat->regbase, (void *)rxbuf,
-				     (const void *)plat->trigger_base, rxlen))
+		(const void *)plat->trigger_base, plat->fifo_width, rxlen))
 		goto failrd;
 
 	/* Check flash indirect controller */
Signature · 1 line
1.7.9.5
#14 lore raw

PATCH v3 4/4 spi: cadence_qspi: get fifo width from device tree

Quoted 9 lines · Vikas Manocha

Fifo width could be different on different socs, e.g. stv0991 & altera soc have different fifo width.

---

Changes in v3: none
Changes in v2: Rebased to master

Quoted 6 lines
 arch/arm/dts/socfpga.dtsi      |    1 +
 arch/arm/dts/stv0991.dts       |    1 +
 drivers/spi/cadence_qspi.c     |    1 +
 drivers/spi/cadence_qspi.h     |    1 +
 drivers/spi/cadence_qspi_apb.c |   24 ++++++++++--------------
 5 files changed, 14 insertions(+), 14 deletions(-)

Please use the Linux bindings, not this ad-hoc stuff.

Best regards,
Marek Vasut