[U-Boot] [UBOOT PATCH v4 3/4] spi: xilinx_spi: Added support to read JEDEC-id twice at the boot time

Jagan Teki jagan at amarulasolutions.com
Fri Jun 29 07:27:59 UTC 2018


On Thu, Jun 28, 2018 at 1:14 PM, Vipul Kumar <vipul.kumar at xilinx.com> wrote:
> This patch is for the startup block issue in the spi controller.
> SPI clock is passing through STARTUP block to FLASH. STARTUP block
> don't provide clock as soon as QSPI provides command. So, first
> command fails.
>
> This patch added support to read JEDEC id in xilinx_spi_xfer ().
>
> Signed-off-by: Vipul Kumar <vipul.kumar at xilinx.com>
> ---
> Changes in v4:
> - Moved static startup variable to private data structure
> - Link to AR: https://www.xilinx.com/support/answers/52626.html
> ---
>  drivers/spi/xilinx_spi.c | 41 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
>
> diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
> index 11b7343..f66ea15 100644
> --- a/drivers/spi/xilinx_spi.c
> +++ b/drivers/spi/xilinx_spi.c
> @@ -105,6 +105,7 @@ struct xilinx_spi_priv {
>         unsigned int freq;
>         unsigned int mode;
>         unsigned int fifo_depth;
> +       u8 startup;
>  };
>
>  static int xilinx_spi_probe(struct udevice *bus)
> @@ -205,6 +206,39 @@ static u32 xilinx_spi_read_rxfifo(struct udevice *bus, u8 *rxp, u32 rxbytes)
>         return i;
>  }
>
> +static void xilinx_startup_block(struct udevice *dev, unsigned int bytes,
> +                                const void *dout, void *din)
> +{
> +       struct udevice *bus = dev_get_parent(dev);
> +       struct xilinx_spi_priv *priv = dev_get_priv(bus);
> +       struct xilinx_spi_regs *regs = priv->regs;
> +       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
> +       const unsigned char *txp = dout;
> +       unsigned char *rxp = din;
> +       u32 reg, count;
> +       u32 txbytes = bytes;
> +       u32 rxbytes = bytes;
> +
> +       /*
> +        * This loop runs two times. First time to send the command.
> +        * Second time to transfer data. After transferring data,
> +        * it sets txp to the initial value for the normal operation.
> +        */
> +       for ( ; priv->startup < 2; priv->startup++) {
> +               count = xilinx_spi_fill_txfifo(bus, txp, txbytes);
> +               reg = readl(&regs->spicr) & ~SPICR_MASTER_INHIBIT;
> +               writel(reg, &regs->spicr);
> +               count = xilinx_spi_read_rxfifo(bus, rxp, rxbytes);
> +               txp = din;
> +
> +               if (priv->startup) {
> +                       spi_cs_deactivate(dev);
> +                       spi_cs_activate(dev, slave_plat->cs);
> +                       txp = dout;
> +               }
> +       }
> +}
> +
>  static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen,
>                             const void *dout, void *din, unsigned long flags)
>  {
> @@ -237,6 +271,13 @@ static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen,
>         if (flags & SPI_XFER_BEGIN)
>                 spi_cs_activate(dev, slave_plat->cs);
>
> +       /*
> +        * This is the work around for the startup block issue in
> +        * the spi controller. SPI clock is passing through STARTUP
> +        * block to FLASH. STARTUP block don't provide clock as soon
> +        * as QSPI provides command. So first command fails.
> +        */
> +       xilinx_startup_block(dev, bytes, dout, din);

Can this be xilinx_spi_startup_block? otherwise it look like generic
startup function for processor or soc.


More information about the U-Boot mailing list