Skip to content
Snippets Groups Projects
Commit 336450f5 authored by Tom Rini's avatar Tom Rini
Browse files

Merge branch 'master' of git://git.denx.de/u-boot-spi

parents dcdb61a0 f659b573
No related branches found
No related tags found
No related merge requests found
...@@ -2597,6 +2597,10 @@ CBFS (Coreboot Filesystem) support ...@@ -2597,6 +2597,10 @@ CBFS (Coreboot Filesystem) support
Enables the driver for the SPI controllers on i.MX and MXC Enables the driver for the SPI controllers on i.MX and MXC
SoCs. Currently i.MX31/35/51 are supported. SoCs. Currently i.MX31/35/51 are supported.
CONFIG_SYS_SPI_MXC_WAIT
Timeout for waiting until spi transfer completed.
default: (CONFIG_SYS_HZ/100) /* 10 ms */
- FPGA Support: CONFIG_FPGA - FPGA Support: CONFIG_FPGA
Enables FPGA subsystem. Enables FPGA subsystem.
......
...@@ -59,6 +59,8 @@ contain the following properties. ...@@ -59,6 +59,8 @@ contain the following properties.
used for MOSI. Defaults to 1 if not present. used for MOSI. Defaults to 1 if not present.
- spi-rx-bus-width - (optional) The bus width(number of data wires) that - spi-rx-bus-width - (optional) The bus width(number of data wires) that
used for MISO. Defaults to 1 if not present. used for MISO. Defaults to 1 if not present.
- spi-half-duplex - (optional) Indicates that the SPI bus should wait for
a header byte before reading data from the slave.
Some SPI controllers and devices support Dual and Quad SPI transfer mode. Some SPI controllers and devices support Dual and Quad SPI transfer mode.
It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD). It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD).
......
...@@ -98,7 +98,7 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, ...@@ -98,7 +98,7 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
} }
out = dev->dout; out = dev->dout;
out[0] = cmd_version; out[0] = EC_CMD_VERSION0 + cmd_version;
out[1] = cmd; out[1] = cmd;
out[2] = (uint8_t)dout_len; out[2] = (uint8_t)dout_len;
memcpy(out + 3, dout, dout_len); memcpy(out + 3, dout, dout_len);
...@@ -165,7 +165,7 @@ int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob) ...@@ -165,7 +165,7 @@ int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob)
*/ */
int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob) int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob)
{ {
dev->spi = spi_setup_slave_fdt(blob, dev->parent_node, dev->node); dev->spi = spi_setup_slave_fdt(blob, dev->node, dev->parent_node);
if (!dev->spi) { if (!dev->spi) {
debug("%s: Could not setup SPI slave\n", __func__); debug("%s: Could not setup SPI slave\n", __func__);
return -1; return -1;
......
...@@ -421,6 +421,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, ...@@ -421,6 +421,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
data += read_len; data += read_len;
} }
free(cmd);
return ret; return ret;
} }
......
...@@ -428,10 +428,6 @@ void spi_cs_activate(struct spi_slave *slave) ...@@ -428,10 +428,6 @@ void spi_cs_activate(struct spi_slave *slave)
clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); clrbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
debug("Activate CS, bus %d\n", spi_slave->slave.bus); debug("Activate CS, bus %d\n", spi_slave->slave.bus);
spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE; spi_slave->skip_preamble = spi_slave->mode & SPI_PREAMBLE;
/* Remember time of this transaction so we can honour the bus delay */
if (spi_slave->bus->deactivate_delay_us)
spi_slave->last_transaction_us = timer_get_us();
} }
/** /**
...@@ -445,6 +441,11 @@ void spi_cs_deactivate(struct spi_slave *slave) ...@@ -445,6 +441,11 @@ void spi_cs_deactivate(struct spi_slave *slave)
struct exynos_spi_slave *spi_slave = to_exynos_spi(slave); struct exynos_spi_slave *spi_slave = to_exynos_spi(slave);
setbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT); setbits_le32(&spi_slave->regs->cs_reg, SPI_SLAVE_SIG_INACT);
/* Remember time of this transaction so we can honour the bus delay */
if (spi_slave->bus->deactivate_delay_us)
spi_slave->last_transaction_us = timer_get_us();
debug("Deactivate CS, bus %d\n", spi_slave->slave.bus); debug("Deactivate CS, bus %d\n", spi_slave->slave.bus);
} }
......
...@@ -30,6 +30,10 @@ static unsigned long spi_bases[] = { ...@@ -30,6 +30,10 @@ static unsigned long spi_bases[] = {
#define reg_read readl #define reg_read readl
#define reg_write(a, v) writel(v, a) #define reg_write(a, v) writel(v, a)
#if !defined(CONFIG_SYS_SPI_MXC_WAIT)
#define CONFIG_SYS_SPI_MXC_WAIT (CONFIG_SYS_HZ/100) /* 10 ms */
#endif
struct mxc_spi_slave { struct mxc_spi_slave {
struct spi_slave slave; struct spi_slave slave;
unsigned long base; unsigned long base;
...@@ -212,6 +216,8 @@ int spi_xchg_single(struct spi_slave *slave, unsigned int bitlen, ...@@ -212,6 +216,8 @@ int spi_xchg_single(struct spi_slave *slave, unsigned int bitlen,
int nbytes = DIV_ROUND_UP(bitlen, 8); int nbytes = DIV_ROUND_UP(bitlen, 8);
u32 data, cnt, i; u32 data, cnt, i;
struct cspi_regs *regs = (struct cspi_regs *)mxcs->base; struct cspi_regs *regs = (struct cspi_regs *)mxcs->base;
u32 ts;
int status;
debug("%s: bitlen %d dout 0x%x din 0x%x\n", debug("%s: bitlen %d dout 0x%x din 0x%x\n",
__func__, bitlen, (u32)dout, (u32)din); __func__, bitlen, (u32)dout, (u32)din);
...@@ -272,9 +278,16 @@ int spi_xchg_single(struct spi_slave *slave, unsigned int bitlen, ...@@ -272,9 +278,16 @@ int spi_xchg_single(struct spi_slave *slave, unsigned int bitlen,
reg_write(&regs->ctrl, mxcs->ctrl_reg | reg_write(&regs->ctrl, mxcs->ctrl_reg |
MXC_CSPICTRL_EN | MXC_CSPICTRL_XCH); MXC_CSPICTRL_EN | MXC_CSPICTRL_XCH);
ts = get_timer(0);
status = reg_read(&regs->stat);
/* Wait until the TC (Transfer completed) bit is set */ /* Wait until the TC (Transfer completed) bit is set */
while ((reg_read(&regs->stat) & MXC_CSPICTRL_TC) == 0) while ((status & MXC_CSPICTRL_TC) == 0) {
; if (get_timer(ts) > CONFIG_SYS_SPI_MXC_WAIT) {
printf("spi_xchg_single: Timeout!\n");
return -1;
}
status = reg_read(&regs->stat);
}
/* Transfer completed, clear any pending request */ /* Transfer completed, clear any pending request */
reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF); reg_write(&regs->stat, MXC_CSPICTRL_TC | MXC_CSPICTRL_RXOVF);
......
...@@ -53,6 +53,8 @@ struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum, ...@@ -53,6 +53,8 @@ struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
mode |= SPI_CPHA; mode |= SPI_CPHA;
if (fdtdec_get_bool(blob, node, "spi-cs-high")) if (fdtdec_get_bool(blob, node, "spi-cs-high"))
mode |= SPI_CS_HIGH; mode |= SPI_CS_HIGH;
if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
mode |= SPI_PREAMBLE;
return spi_setup_slave(busnum, cs, max_hz, mode); return spi_setup_slave(busnum, cs, max_hz, mode);
} }
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment