[U-Boot] [PATCH] zynq: spi: Honour the activation / deactivation delay

Moritz Fischer moritz.fischer at ettus.com
Wed Dec 14 20:13:05 CET 2016


Whoops,

On Thu, Dec 8, 2016 at 12:11 PM, Moritz Fischer
<moritz.fischer at ettus.com> wrote:
> This is not currently implemented. Add support for this so that the
> Chrome OS EC can be used reliably.
>
> Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
> Cc: Jagan Teki <jagan at openedev.com>
> Cc: Simon Glass <sjg at chromium.org>
> Cc: u-boot at lists.denx.de
Cc: Michal Simek <michal.simek at xilinx.com>

> ---
>  drivers/spi/zynq_spi.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>
> diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c
> index 15ca271..5e7954c 100644
> --- a/drivers/spi/zynq_spi.c
> +++ b/drivers/spi/zynq_spi.c
> @@ -56,6 +56,8 @@ struct zynq_spi_platdata {
>         struct zynq_spi_regs *regs;
>         u32 frequency;          /* input frequency */
>         u32 speed_hz;
> +       uint deactivate_delay_us;       /* Delay to wait after deactivate */
> +       uint activate_delay_us;         /* Delay to wait after activate */
>  };
>
>  /* zynq spi priv */
> @@ -63,6 +65,7 @@ struct zynq_spi_priv {
>         struct zynq_spi_regs *regs;
>         u8 cs;
>         u8 mode;
> +       ulong last_transaction_us;      /* Time of last transaction end */
>         u8 fifo_depth;
>         u32 freq;               /* required frequency */
>  };
> @@ -78,6 +81,10 @@ static int zynq_spi_ofdata_to_platdata(struct udevice *bus)
>         /* FIXME: Use 250MHz as a suitable default */
>         plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
>                                         250000000);
> +       plat->deactivate_delay_us = fdtdec_get_int(blob, node,
> +                                       "spi-deactivate-delay", 0);
> +       plat->activate_delay_us = fdtdec_get_int(blob, node,
> +                                                "spi-activate-delay", 0);
>         plat->speed_hz = plat->frequency / 2;
>
>         debug("%s: regs=%p max-frequency=%d\n", __func__,
> @@ -133,10 +140,19 @@ static int zynq_spi_probe(struct udevice *bus)
>  static void spi_cs_activate(struct udevice *dev)
>  {
>         struct udevice *bus = dev->parent;
> +       struct zynq_spi_platdata *plat = bus->platdata;
>         struct zynq_spi_priv *priv = dev_get_priv(bus);
>         struct zynq_spi_regs *regs = priv->regs;
>         u32 cr;
>
> +       /* If it's too soon to do another transaction, wait */
> +       if (plat->deactivate_delay_us && priv->last_transaction_us) {
> +               ulong delay_us;         /* The delay completed so far */
> +               delay_us = timer_get_us() - priv->last_transaction_us;
> +               if (delay_us < plat->deactivate_delay_us)
> +                       udelay(plat->deactivate_delay_us - delay_us);
> +       }
> +
>         clrbits_le32(&regs->cr, ZYNQ_SPI_CR_CS_MASK);
>         cr = readl(&regs->cr);
>         /*
> @@ -147,15 +163,23 @@ static void spi_cs_activate(struct udevice *dev)
>          */
>         cr |= (~(1 << priv->cs) << ZYNQ_SPI_CR_SS_SHIFT) & ZYNQ_SPI_CR_CS_MASK;
>         writel(cr, &regs->cr);
> +
> +       if (plat->activate_delay_us)
> +               udelay(plat->activate_delay_us);
>  }
>
>  static void spi_cs_deactivate(struct udevice *dev)
>  {
>         struct udevice *bus = dev->parent;
> +       struct zynq_spi_platdata *plat = bus->platdata;
>         struct zynq_spi_priv *priv = dev_get_priv(bus);
>         struct zynq_spi_regs *regs = priv->regs;
>
>         setbits_le32(&regs->cr, ZYNQ_SPI_CR_CS_MASK);
> +
> +       /* Remember time of this transaction so we can honour the bus delay */
> +       if (plat->deactivate_delay_us)
> +               priv->last_transaction_us = timer_get_us();
>  }
>
>  static int zynq_spi_claim_bus(struct udevice *dev)
> --
> 2.7.4
>

Thanks,

Moritz


More information about the U-Boot mailing list