spi: cadence_qspi: optimize & fix indirect rd-writes
Subsystems (2)
v4 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 v4:
- fifo-width & trigger address alligned to linux device tree binding.
- renaming of one parameter splitted to separate patch.
- trigger address of socfpga reverted back to 0x0.
- code formatting done to avoid checkpatch CHECKS.
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 (5):
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: rename ahbbase to flashbase for clarity
spi: cadence_qspi: get fifo width from device tree
arch/arm/dts/socfpga.dtsi | 2 ++ arch/arm/dts/stv0991.dts | 2 ++ drivers/spi/cadence_qspi.c | 14 ++++++++------ drivers/spi/cadence_qspi.h | 6 ++++-- drivers/spi/cadence_qspi_apb.c | 42 ++++++++++++++++------------------------ 5 files changed, 33 insertions(+), 33 deletions(-)
Signature · 1 line
1.7.9.5
PATCH RESEND v4 1/5 spi: cadence_qspi: move trigger base configuration in init
No need to configure indirect trigger address for every read/write.
---
Changes in v4: fix checkpatch CHECK message. 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
@@ -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
PATCH RESEND v4 2/5 spi: cadence_qspi: fix indirect read/write start address
In reply to Vikas ManochaIndirect 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 v4: fixed CHECKPATCH CHECK message.
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
@@ -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
PATCH RESEND v4 3/5 spi: cadence_qspi: fix base trigger address & transfer start address
In reply to Vikas ManochaThis 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->triggerbase is added in device tree for mapped spi flash address.
---
Changes in v4:
- fifo-width & trigger address alligned to linux device tree binding.
- renaming of one parameter moved to separate patch.
- trigger address of socfpga reverted back to 0x0.
Changes in v3: formatted string breaking fixed.
Changes in v2: Rebased to master
arch/arm/dts/socfpga.dtsi | 1 + arch/arm/dts/stv0991.dts | 1 + drivers/spi/cadence_qspi.c | 9 +++++---- drivers/spi/cadence_qspi.h | 1 + drivers/spi/cadence_qspi_apb.c | 7 +++---- 5 files changed, 11 insertions(+), 8 deletions(-)
arch/arm/dts/socfpga.dtsi +1 -0
@@ -639,6 +639,7 @@ ext-decoder = <0>; /* external decoder */ num-cs = <4>; fifo-depth = <128>; + cdns,trigger-address = <0x0 0x0010>; sram-size = <128>; bus-num = <2>; status = "disabled";
arch/arm/dts/stv0991.dts +1 -0
@@ -33,6 +33,7 @@ <0x40000000 0x1000000>; clocks = <3750000>; sram-size = <256>; + cdns,trigger-address = <0x40000000 0x0000010>; status = "okay"; flash0: n25q32 at 0 {
drivers/spi/cadence_qspi.c +5 -4
@@ -290,6 +290,8 @@ static int cadence_spi_ofdata_to_platdata(struct udevice *bus) plat->regbase = (void *)data[0 ]; plat->ahbbase = (void *)data[2 ]; + plat->trigger_base = (u32 *)fdtdec_get_addr (blob, node, +"cdns,trigger-address" );/* Use 500KHz as a suitable default */ plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
@@ -311,10 +313,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 ahbbase=%p trigger_base=%p max-frequency=%d page-size=%d\n" , + __func__, plat->regbase, plat->ahbbase, plat->trigger_base, + plat->max_hz, plat->page_size);return 0 ; }
drivers/spi/cadence_qspi.h +1 -0
@@ -18,6 +18,7 @@ struct cadence_spi_platdata {unsigned int max_hz;void *regbase;void *ahbbase; +void *trigger_base;u32 page_size;u32 block_size;
drivers/spi/cadence_qspi_apb.c +3 -4
@@ -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 */
@@ -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 */
Signature · 1 line
1.7.9.5
PATCH RESEND v4 4/5 spi: cadence_qspi: rename ahbbase to flashbase for clarity
In reply to Vikas Manochaplat->ahbbase renamed to plat->flashbase for better clarity.
---
Changes in v4: new
drivers/spi/cadence_qspi.c | 8 ++++---- drivers/spi/cadence_qspi.h | 4 ++-- drivers/spi/cadence_qspi_apb.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-)
drivers/spi/cadence_qspi.c +4 -4
@@ -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);
@@ -289,7 +289,7 @@ 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 = (u32 *)fdtdec_get_addr (blob, node,"cdns,trigger-address" );
@@ -313,8 +313,8 @@ 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 trigger_base=%p max-frequency=%d page-size=%d\n" , - __func__, plat->regbase, plat->ahbbase, plat->trigger_base, +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 +2 -2
@@ -17,7 +17,7 @@struct cadence_spi_platdata {unsigned int max_hz;void *regbase; -void *ahbbase; +void *flashbase;void *trigger_base;u32 page_size;
@@ -31,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 +2 -2
@@ -704,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. */
@@ -795,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
PATCH RESEND v4 5/5 spi: cadence_qspi: get fifo width from device tree
In reply to Vikas ManochaFifo width could be different on different socs, e.g. stv0991 & altera soc have different fifo width.
---
Changes in v4: alligned to linux device tree binding. 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
@@ -640,6 +640,7 @@ num-cs = <4>; fifo-depth = <128>; cdns,trigger-address = <0x0 0x0010>; + cdns,fifo-width = <4>; sram-size = <128>; bus-num = <2>; status = "disabled";
arch/arm/dts/stv0991.dts +1 -0
@@ -34,6 +34,7 @@ clocks = <3750000>; sram-size = <256>; cdns,trigger-address = <0x40000000 0x0000010>; + cdns,fifo-width = <8>; status = "okay"; flash0: n25q32 at 0 {
drivers/spi/cadence_qspi.c +1 -0
@@ -312,6 +312,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,"cdns,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
@@ -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
@@ -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
v4 cover spi: cadence_qspi: optimize & fix indirect rd-writes
In reply to Vikas ManochaQuoted 11 lines · Vikas Manocha
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 treeChanges in v4:
- fifo-width & trigger address alligned to linux device tree binding.
- renaming of one parameter splitted to separate patch.
- trigger address of socfpga reverted back to0x0.
- code formatting done to avoid checkpatch CHECKS.
OK, this is obviously not 1:1 resend. The previous patchset had at least a different cover letter. So is this a V5 or what is this really ? Please do not tag "RESEND" stuff which actually contain modifications, this sort of behavior is absolutelly not helpful.
Best regards,
Marek Vasut
v4 cover spi: cadence_qspi: optimize & fix indirect rd-writes
Hi,
Quoted 13 lines · Marek Vasut
Quoted 11 lines · Vikas Manocha
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 treeChanges in v4:
- fifo-width & trigger address alligned to linux device tree binding.
- renaming of one parameter splitted to separate patch.
- trigger address of socfpga reverted back to0x0.
- code formatting done to avoid checkpatch CHECKS.
Quoted 4 lines
OK, this is obviously not 1:1 resend. The previous patchset had at least a different cover letter. So is this a V5 or what is this really ? Please do not tag "RESEND" stuff which actually contain modifications, this sort of behavior is absolutelly not helpful.
The intention of quick "RESEND v4" was for reviewers to ignore v4 to save their time. Let me know if i need to mark it v5.
Cheers,
Vikas
Quoted 5 lines
Best regards,
Marek Vasut
.
v4 cover spi: cadence_qspi: optimize & fix indirect rd-writes
Quoted 16 lines · vikas
Hi,
Quoted 13 lines · Marek Vasut
Quoted 11 lines · Vikas Manocha
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 treeChanges in v4:
- fifo-width & trigger address alligned to linux device tree binding.
- renaming of one parameter splitted to separate patch.
- trigger address of socfpga reverted back to0x0.
- code formatting done to avoid checkpatch CHECKS.
Quoted 7 lines
Quoted 4 lines
OK, this is obviously not 1:1 resend. The previous patchset had at least a different cover letter. So is this a V5 or what is this really ? Please do not tag "RESEND" stuff which actually contain modifications, this sort of behavior is absolutelly not helpful.
The intention of quick "RESEND v4" was for reviewers to ignore v4 to save their time. Let me know if i need to mark it v5.
Yes, it was supposed to be marked as V5 if it contained changes.
Best regards,
Marek Vasut