Read chipselect properties from DT which are populated using 'reg' property and save it in plat->cs[] array for later use.
Also read multi chipselect capability which is used for parallel-memories and return errors if they are passed on using DT but driver is not capable of handling it. Signed-off-by: Ashok Reddy Soma <ashok.reddy.s...@amd.com> Signed-off-by: Venkatesh Yadav Abbarapu <venkatesh.abbar...@amd.com> --- drivers/spi/spi-uclass.c | 21 ++++++++++++++++----- drivers/spi/xilinx_spi.c | 4 ++-- drivers/spi/zynq_qspi.c | 6 +++--- drivers/spi/zynq_spi.c | 6 +++--- include/spi.h | 2 +- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index c929e7c1d0..cdcf16d346 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -257,7 +257,7 @@ int spi_chip_select(struct udevice *dev) { struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev); - return plat ? plat->cs : -ENOENT; + return plat ? plat->cs[0] : -ENOENT; } int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp) @@ -294,8 +294,8 @@ int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp) struct dm_spi_slave_plat *plat; plat = dev_get_parent_plat(dev); - dev_dbg(bus, "%s: plat=%p, cs=%d\n", __func__, plat, plat->cs); - if (plat->cs == cs) { + dev_dbg(bus, "%s: plat=%p, cs=%d\n", __func__, plat, plat->cs[0]); + if (plat->cs[0] == cs) { *devp = dev; return 0; } @@ -448,7 +448,7 @@ int _spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, return ret; } plat = dev_get_parent_plat(dev); - plat->cs = cs; + plat->cs[0] = cs; if (speed) { plat->max_hz = speed; } else { @@ -479,6 +479,11 @@ int _spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, slave = dev_get_parent_priv(dev); bus_data = dev_get_uclass_priv(bus); + if ((dev_read_bool(dev, "parallel-memories")) && !slave->multi_cs_cap) { + dev_err(dev, "controller doesn't support multi CS\n"); + return -EINVAL; + } + /* * In case the operation speed is not yet established by * dm_spi_claim_bus() ensure the bus is configured properly. @@ -541,8 +546,14 @@ int spi_slave_of_to_plat(struct udevice *dev, struct dm_spi_slave_plat *plat) { int mode = 0; int value; + int ret; + + ret = dev_read_u32_array(dev, "reg", plat->cs, SPI_CS_CNT_MAX); + if (ret && ret != -EOVERFLOW) { + dev_err(dev, "has no valid 'reg' property (%d)\n", ret); + return ret; + } - plat->cs = dev_read_u32_default(dev, "reg", -1); plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", SPI_DEFAULT_SPEED_HZ); if (dev_read_bool(dev, "spi-cpol")) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index b58a3f632a..7c4a9b79bb 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -270,7 +270,7 @@ static void xilinx_spi_startup_block(struct spi_slave *spi) * Perform a dummy read as a work around for * the startup block issue. */ - spi_cs_activate(spi->dev, slave_plat->cs); + spi_cs_activate(spi->dev, slave_plat->cs[0]); txp = 0x9f; start_transfer(spi, (void *)&txp, NULL, 1); @@ -298,7 +298,7 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, startup++; } - spi_cs_activate(spi->dev, slave_plat->cs); + spi_cs_activate(spi->dev, slave_plat->cs[0]); if (op->cmd.opcode) { ret = start_transfer(spi, (void *)&op->cmd.opcode, NULL, 1); diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index cb52c0f307..069d2a77de 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -586,13 +586,13 @@ static int zynq_qspi_xfer(struct udevice *dev, unsigned int bitlen, struct zynq_qspi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); - priv->cs = slave_plat->cs; + priv->cs = slave_plat->cs[0]; priv->tx_buf = dout; priv->rx_buf = din; priv->len = bitlen / 8; - debug("zynq_qspi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n", - dev_seq(bus), slave_plat->cs, bitlen, priv->len, flags); + debug("zynq_qspi_xfer: bus:%i cs[0]:%i bitlen:%i len:%i flags:%lx\n", + dev_seq(bus), slave_plat->cs[0], bitlen, priv->len, flags); /* * Festering sore. diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c index b3e0858eb9..17bb1015fa 100644 --- a/drivers/spi/zynq_spi.c +++ b/drivers/spi/zynq_spi.c @@ -242,15 +242,15 @@ static int zynq_spi_xfer(struct udevice *dev, unsigned int bitlen, u8 *rx_buf = din, buf; u32 ts, status; - debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n", - dev_seq(bus), slave_plat->cs, bitlen, len, flags); + debug("spi_xfer: bus:%i cs[0]:%i bitlen:%i len:%i flags:%lx\n", + dev_seq(bus), slave_plat->cs[0], bitlen, len, flags); if (bitlen % 8) { debug("spi_xfer: Non byte aligned SPI transfer\n"); return -1; } - priv->cs = slave_plat->cs; + priv->cs = slave_plat->cs[0]; if (flags & SPI_XFER_BEGIN) spi_cs_activate(dev); diff --git a/include/spi.h b/include/spi.h index 2a3ccaa754..f050227168 100644 --- a/include/spi.h +++ b/include/spi.h @@ -82,7 +82,7 @@ struct dm_spi_bus { * @mode: SPI mode to use for this device (see SPI mode flags) */ struct dm_spi_slave_plat { - unsigned int cs; + unsigned int cs[SPI_CS_CNT_MAX]; uint max_hz; uint mode; }; -- 2.17.1