All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pratyush Yadav <ptyadav@amazon.de>
To: Dhruva Gole <d-gole@ti.com>
Cc: Jagan Teki <jagan@amarulasolutions.com>,
	Vignesh <vigneshr@ti.com>, Vaishnav Achath <vaishnav.a@ti.com>,
	<u-boot@lists.denx.de>, "Apurva Nandan" <a-nandan@ti.com>
Subject: Re: [PATCH 2/2] spi: cadence-quadspi: Use STIG mode for all ops with small payload
Date: Mon, 27 Mar 2023 17:50:42 +0200	[thread overview]
Message-ID: <mafs0pm8uqjl9.fsf_-_@amazon.de> (raw)
In-Reply-To: <20230323164408.1043725-3-d-gole@ti.com> (Dhruva Gole's message of "Thu, 23 Mar 2023 22:14:08 +0530")

On Thu, Mar 23 2023, Dhruva Gole wrote:

> OSPI controller supports all types of op variants in STIG mode,
> only limitation being that the data payload should be less than
> 8 bytes when not using memory banks.
>
> STIG mode is more stable for operations that send small data
> payload and is more efficient than using DMA for few bytes of
> memory accesses. It overcomes the limitation of minimum 4 bytes
> read from flash into RAM seen in DAC mode.
>
> Use STIG mode for all read and write operations that require
> data input/output of less than 8 bytes from the flash, and thereby
> support all four phases, cmd/address/dummy/data, through OSPI STIG.
>
> Signed-off-by: Apurva Nandan <a-nandan@ti.com>
> Signed-off-by: Dhruva Gole <d-gole@ti.com>
> ---
>  drivers/spi/cadence_qspi.c     |  5 ++--
>  drivers/spi/cadence_qspi_apb.c | 44 ++++++++++++++++++----------------
>  2 files changed, 26 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
> index a858a62888e4..f931e4cf3e2f 100644
> --- a/drivers/spi/cadence_qspi.c
> +++ b/drivers/spi/cadence_qspi.c
> @@ -312,13 +312,12 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi,
>                  * which is unsupported on some flash devices during register
>                  * reads, prefer STIG mode for such small reads.
>                  */
> -               if (!op->addr.nbytes ||

What if someone sends us a command that has no address phase but reads
more than CQSPI_STIG_DATA_LEN_MAX bytes? You would happily send it to
cadence_qspi_apb_read_setup(), which would then do reg |=
(op->addr.nbytes - 1) causing an underflow and having corrputing the
register.

Since there is no way to execute a command with no address phase and
data bytes > CQSPI_STIG_DATA_LEN_MAX, you should add a check for this in
the supports_op() hook.

> -                   op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
> +               if (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)
>                         mode = CQSPI_STIG_READ;
>                 else
>                         mode = CQSPI_READ;
>         } else {
> -               if (!op->addr.nbytes || !op->data.buf.out)
> +               if (op->data.nbytes <= CQSPI_STIG_DATA_LEN_MAX)

Same here.

>                         mode = CQSPI_STIG_WRITE;
>                 else
>                         mode = CQSPI_WRITE;
> diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c
> index 2b04b58124a5..25b5fc292e07 100644
> --- a/drivers/spi/cadence_qspi_apb.c
> +++ b/drivers/spi/cadence_qspi_apb.c
> @@ -374,6 +374,8 @@ int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg)
>         if (!cadence_qspi_wait_idle(reg_base))
>                 return -EIO;
>
> +       /* Flush the CMDCTRL reg after the execution */
> +       writel(0, reg_base + CQSPI_REG_CMDCTRL);

Do this in a separate patch with its own explanation please.

>         return 0;
>  }
>
> @@ -460,11 +462,6 @@ int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv,
>         unsigned int dummy_clk;
>         u8 opcode;
>
> -       if (rxlen > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
> -               printf("QSPI: Invalid input arguments rxlen %u\n", rxlen);
> -               return -EINVAL;
> -       }
> -

Ok.

>         if (priv->dtr)
>                 opcode = op->cmd.opcode >> 8;
>         else
> @@ -547,26 +544,12 @@ int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv,
>         unsigned int reg = 0;
>         unsigned int wr_data;
>         unsigned int wr_len;
> +       unsigned int dummy_clk;
>         unsigned int txlen = op->data.nbytes;
>         const void *txbuf = op->data.buf.out;
>         void *reg_base = priv->regbase;
> -       u32 addr;
>         u8 opcode;
>
> -       /* Reorder address to SPI bus order if only transferring address */
> -       if (!txlen) {
> -               addr = cpu_to_be32(op->addr.val);
> -               if (op->addr.nbytes == 3)
> -                       addr >>= 8;
> -               txbuf = &addr;
> -               txlen = op->addr.nbytes;
> -       }

You should explain why you are removing this.

> -
> -       if (txlen > CQSPI_STIG_DATA_LEN_MAX) {
> -               printf("QSPI: Invalid input arguments txlen %u\n", txlen);
> -               return -EINVAL;
> -       }
> -
>         if (priv->dtr)
>                 opcode = op->cmd.opcode >> 8;
>         else
> @@ -574,6 +557,27 @@ int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv,
>
>         reg |= opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
>
> +       /* setup ADDR BIT field */
> +       if (op->addr.nbytes) {
> +               writel(op->addr.val, priv->regbase + CQSPI_REG_CMDADDRESS);
> +               /*
> +                * address bytes are zero indexed
> +                */
> +               reg |= (((op->addr.nbytes - 1) &
> +                         CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
> +                         CQSPI_REG_CMDCTRL_ADD_BYTES_LSB);
> +               reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
> +       }
> +
> +       /* Set up dummy cycles. */
> +       dummy_clk = cadence_qspi_calc_dummy(op, priv->dtr);
> +       if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
> +               return -EOPNOTSUPP;
> +
> +       if (dummy_clk)
> +               reg |= (dummy_clk & CQSPI_REG_CMDCTRL_DUMMY_MASK)
> +                    << CQSPI_REG_CMDCTRL_DUMMY_LSB;
> +

Ok.

>         if (txlen) {
>                 /* writing data = yes */
>                 reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);

-- 
Regards,
Pratyush Yadav



Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




      reply	other threads:[~2023-03-27 16:26 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-23 16:44 [PATCH 0/2] spi: cadence_qspi: Fixes for DTR ops and improve STIG support Dhruva Gole
2023-03-23 16:44 ` [PATCH 1/2] spi: cadence-quadspi: Fix check condition for DTR ops Dhruva Gole
2023-03-27 15:19   ` Pratyush Yadav
2023-03-23 16:44 ` [PATCH 2/2] spi: cadence-quadspi: Use STIG mode for all ops with small payload Dhruva Gole
2023-03-27 15:50   ` Pratyush Yadav [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mafs0pm8uqjl9.fsf_-_@amazon.de \
    --to=ptyadav@amazon.de \
    --cc=a-nandan@ti.com \
    --cc=d-gole@ti.com \
    --cc=jagan@amarulasolutions.com \
    --cc=u-boot@lists.denx.de \
    --cc=vaishnav.a@ti.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.