[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(®s->cr, ZYNQ_SPI_CR_CS_MASK);
> cr = readl(®s->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, ®s->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(®s->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