[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(®s->spicr) & ~SPICR_MASTER_INHIBIT;
> + writel(reg, ®s->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