diff mbox

[U-Boot,RESEND,0/7] spi: cadence_qspi: optimize & fix indirect rd-writes

Message ID 9026814FBF99304F9FA3AC3FB72F3E2F029611BD@SAFEX1MAIL4.st.com
State Superseded
Headers show

Commit Message

Vikas MANOCHA July 6, 2015, 6:19 p.m. UTC
Hi Graham,

> -----Original Message-----
> From: Graham Moore [mailto:grmoore@opensource.altera.com]
> Sent: Monday, July 06, 2015 10:57 AM
> To: Vikas MANOCHA
> Cc: Stefan Roese; u-boot@lists.denx.de; dinguyen@opensource.altera.com;
> jteki@openedev.com
> Subject: Re: [PATCH RESEND 0/7] spi: cadence_qspi: optimize & fix indirect
> rd-writes
> 
> On 07/02/2015 12:50 PM, Vikas MANOCHA wrote:
> > Hi Graham,
> >
> >> -----Original Message-----
> >> From: Graham Moore [mailto:grmoore@opensource.altera.com]
> >> Sent: Tuesday, June 23, 2015 7:37 AM
> >> To: Vikas MANOCHA
> >> Cc: Stefan Roese; u-boot@lists.denx.de;
> >> dinguyen@opensource.altera.com; jteki@openedev.com
> >> Subject: Re: [PATCH RESEND 0/7] spi: cadence_qspi: optimize & fix
> >> indirect rd-writes
> >>
> >> On 06/22/2015 06:31 PM, Vikas MANOCHA wrote:
> >> ...
> >>
> >>>>> The point is if after applying above mentioned patch (...: fix
> >>>>> indirect read/write start address), Read/write are working fine,
> >>>>> then trigger_base value of 0xFFA00_0000 should also work fine.
> >>>>> Can you please modify the trigger_base value from 0x0 to
> >>>>> 0xFFA0_0000 in Socfpga.dtsi & check.
> >>>>> If it works, it would mean both (socfpga & stv0991) are behaving
> same.
> >>>>
> >>>> No. With this change, the "sf read" command crashes / hangs on the
> >>>> SoCFPGA board.
> >>>
> >>> Ok, I don't know why socfpga is not working with trigger_base to be
> >> 0xFFA0_0000.
> >>> Normally it should work, Graham also thinks the same, Let's wait for
> >>> his
> >> discussion with the Altera designers.
> >>>
> >>
> >> Wait a minute, on SoCFPGA, the flashbase is 0xffa00000, and the
> >> trigger base is 0x00000000.  The point of having a different address
> >> was that they needed to be different on SoCFPGA, right?
> >>
> >> As for why they're different, the Altera Cyclone5 SoCFPGA has a
> >> complex multilevel interconnect where the QSPI is three levels down,
> >> and is the only slave of an AHB master.  At that level of the
> >> interconnect, the base address has long been stripped off, it was used to
> select down to the final master.
> >> The QSPI is the only thing on that AHB bus, so its address is zero.
> >> Or at least that's how I understand it.
> >
> > If we check the code for reading/writing to the FIFO/SRAM of the
> controller, complete base address is being used.
> > Which means CPU is using address 0xFFA0_0000, so does not seems like
> base address is stripped off. It is only for the trigger address which needs
> programming to  0x0 ?
> >
> > Regardless, it is something specific to socfpga architecture & should not be
> part of cadence qspi driver.
> >
> 
> I'm sorry, I don't understand your comment.  What is 'it' that should not be
> part of the cadence qspi driver?

I meant : Trigger base address programming to one address (which is 0x0 in case of socfpga) & then reading/writing from 
another locations (NOR location 0xFFA0_0000 in case of socfpga) : It shouldn't be like this in the driver as per the definition of trigger base address.

Trigger base address is the location which should be used to read/write in indirect mode. It actually makes it like reading sram & hence called indirect mode.

It is what was explained & implemented in attached patch. Stefan tested it & it didn't work on socfpga platform, there seems something specific to arch, to be debugged.

Rgds,
Vikas

> 
> -Graham
> 
> > Rgds,
> > Vikas
> >
> >>
> >> -Graham
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.

Signed-off-by: Vikas Manocha <vikas.manocha@st.com>
---
 arch/arm/dts/socfpga.dtsi      |    1 +
 arch/arm/dts/stv0991.dts       |    3 ++-
 drivers/spi/cadence_qspi.c     |   13 +++++++------
 drivers/spi/cadence_qspi.h     |    5 +++--
 drivers/spi/cadence_qspi_apb.c |   12 +++++-------
 5 files changed, 18 insertions(+), 16 deletions(-)

--
1.7.9.5
diff mbox

Patch

diff --git a/arch/arm/dts/socfpga.dtsi b/arch/arm/dts/socfpga.dtsi
index bf791c5..d89c974 100644
--- a/arch/arm/dts/socfpga.dtsi
+++ b/arch/arm/dts/socfpga.dtsi
@@ -634,6 +634,7 @@ 
                        #size-cells = <0>;
                        reg = <0xff705000 0x1000>,
                                <0xffa00000 0x1000>;
+                               <0x00000000 0x0010>;
                        interrupts = <0 151 4>;
                        clocks = <&qspi_clk>;
                        ext-decoder = <0>;  /* external decoder */
diff --git a/arch/arm/dts/stv0991.dts b/arch/arm/dts/stv0991.dts
index 3b1efca..72399ff 100644
--- a/arch/arm/dts/stv0991.dts
+++ b/arch/arm/dts/stv0991.dts
@@ -30,7 +30,8 @@ 
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <0x80203000 0x100>,
-                               <0x40000000 0x1000000>;
+                               <0x40000000 0x1000000>,
+                               <0x40000000 0x0000010>;
                        clocks = <3750000>;
                        ext-decoder = <0>; /* external decoder */
                        num-cs = <4>;
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index a75fc46..b23461d 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -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",
@@ -310,9 +311,9 @@  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);

-       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;
 }
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index c9a6142..5ea4581 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -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;
@@ -29,7 +30,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;
diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
index 7be67a9..2994158 100644
--- a/drivers/spi/cadence_qspi_apb.c
+++ b/drivers/spi/cadence_qspi_apb.c
@@ -50,7 +50,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)
@@ -471,9 +470,8 @@  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);

-       /* Setup the indirect trigger address */
-       writel(((u32)plat->ahbbase & CQSPI_INDIRECTTRIGGER_ADDR_MASK),
-               plat->regbase + CQSPI_REG_INDIRECTTRIGGER);
+       writel((u32)plat->trigger_base,
+                       plat->regbase + CQSPI_REG_INDIRECTTRIGGER);

        /* Disable all interrupts */
        writel(0, plat->regbase + CQSPI_REG_IRQMASK);
@@ -647,7 +645,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. */
@@ -696,7 +694,7 @@  int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat,
        udelay(1);

        if (cadence_qspi_apb_read_fifo_data((void *)rxbuf,
-                               (const void *)plat->ahbbase, rxlen))
+                               (const void *)plat->trigger_base, rxlen))
                goto failrd;

        /* Check flash indirect controller */
@@ -742,7 +740,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);