mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
zynq: spi: Honour the activation / deactivation delay
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@ettus.com> Acked-by: Simon Glass <sjg@chromium.org> Reviewed-by: Jagan Teki <jagan@openedev.com>
This commit is contained in:
parent
61a77ce1d5
commit
ac6991fb5f
1 changed files with 24 additions and 0 deletions
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue