[U-Boot] [PATCH 00/13] device model bringup of ti-qspi on dra72, dra74 and am437x-sk evm

This patch series enables ti_qspi to adopt driver model. This has been tested on dra72, dra74 and am437x-sk evms (logs [1]). Also pushed a branch for testing [2]
[1]: http://pastebin.ubuntu.com/12978685/ [2]: git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git dm-qspi
Mugunthan V N (13): drivers: spi: ti_qspi: prepare driver for DM conversion dm: core: Add a new api to get indexed device address spi: Add support for dual and quad mode drivers: spi: spi-uclass: fix spi slave device register dra7xx_evm: qspi: do not define DM_SPI and DM_SPI_FLASH for spl dts: dra7: add spi alias for qspi drivers: spi: ti_qspi: convert driver to adopt device driver model arm: dts: dra7: add qspi register maps for memory map and control module defconfig: dra72_evm: enable spi driver model defconfig: dra74_evm: enable spi driver model am43xx_evm: qspi: do not define DM_SPI and DM_SPI_FLASH for spl arm: dts: am4372: add qspi register maps for memory map defconfig: am437x_sk_evm: enable spi driver model
arch/arm/dts/am4372.dtsi | 4 +- arch/arm/dts/dra7.dtsi | 6 +- configs/am437x_sk_evm_defconfig | 3 + configs/dra72_evm_defconfig | 2 + configs/dra74_evm_defconfig | 2 + drivers/core/device.c | 20 ++ drivers/spi/spi-uclass.c | 71 +++++- drivers/spi/ti_qspi.c | 467 +++++++++++++++++++++++++++------------- include/configs/am43xx_evm.h | 2 + include/configs/dra7xx_evm.h | 5 + include/dm/device.h | 9 + include/spi.h | 4 + 12 files changed, 433 insertions(+), 162 deletions(-)

Prepare driver for DM conversion.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/spi/ti_qspi.c | 341 ++++++++++++++++++++++++++++---------------------- 1 file changed, 188 insertions(+), 153 deletions(-)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index bd63db8..4893472 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -28,6 +28,7 @@ #define QSPI_3_PIN (1 << 18) #define QSPI_RD_SNGL (1 << 16) #define QSPI_WR_SNGL (2 << 16) +#define QSPI_RD_DUAL (7 << 16) #define QSPI_INVAL (4 << 16) #define QSPI_RD_QUAD (7 << 16) /* device control */ @@ -85,50 +86,20 @@ struct ti_qspi_regs { u32 data3; };
-/* ti qspi slave */ -struct ti_qspi_slave { +/* ti qspi priv */ +struct ti_qspi_priv { struct spi_slave slave; struct ti_qspi_regs *base; + void *ctrl_mod_mmap; unsigned int mode; u32 cmd; u32 dc; + u32 num_cs; + u32 rx_bus_width; };
-static inline struct ti_qspi_slave *to_ti_qspi_slave(struct spi_slave *slave) +static void ti_spi_set_speed(struct ti_qspi_priv *priv, uint hz) { - return container_of(slave, struct ti_qspi_slave, slave); -} - -static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave) -{ - struct spi_slave *slave = &qslave->slave; - u32 memval = 0; - -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - slave->memory_map = (void *)MMAP_START_ADDR_DRA; -#else - slave->memory_map = (void *)MMAP_START_ADDR_AM43x; -#endif - -#ifdef CONFIG_QSPI_QUAD_SUPPORT - memval |= (QSPI_CMD_READ_QUAD | QSPI_SETUP0_NUM_A_BYTES | - QSPI_SETUP0_NUM_D_BYTES_8_BITS | - QSPI_SETUP0_READ_QUAD | QSPI_CMD_WRITE | - QSPI_NUM_DUMMY_BITS); - slave->op_mode_rx = SPI_OPM_RX_QOF; -#else - memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES | - QSPI_SETUP0_NUM_D_BYTES_NO_BITS | - QSPI_SETUP0_READ_NORMAL | QSPI_CMD_WRITE | - QSPI_NUM_DUMMY_BITS; -#endif - - writel(memval, &qslave->base->setup0); -} - -static void ti_spi_set_speed(struct spi_slave *slave, uint hz) -{ - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); uint clk_div;
debug("ti_spi_set_speed: hz: %d, clock divider %d\n", hz, clk_div); @@ -139,8 +110,8 @@ static void ti_spi_set_speed(struct spi_slave *slave, uint hz) clk_div = (QSPI_FCLK / hz) - 1;
/* disable SCLK */ - writel(readl(&qslave->base->clk_ctrl) & ~QSPI_CLK_EN, - &qslave->base->clk_ctrl); + writel(readl(&priv->base->clk_ctrl) & ~QSPI_CLK_EN, + &priv->base->clk_ctrl);
/* assign clk_div values */ if (clk_div < 0) @@ -149,133 +120,83 @@ static void ti_spi_set_speed(struct spi_slave *slave, uint hz) clk_div = QSPI_CLK_DIV_MAX;
/* enable SCLK */ - writel(QSPI_CLK_EN | clk_div, &qslave->base->clk_ctrl); + writel(QSPI_CLK_EN | clk_div, &priv->base->clk_ctrl); }
-int spi_cs_is_valid(unsigned int bus, unsigned int cs) +static void ti_qspi_cs_deactivate(struct ti_qspi_priv *priv) { - return 1; + writel(priv->cmd | QSPI_INVAL, &priv->base->cmd); }
-void spi_cs_activate(struct spi_slave *slave) +static int __ti_qspi_set_mode(struct ti_qspi_priv *priv, unsigned int mode) { - /* CS handled in xfer */ - return; -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - - debug("spi_cs_deactivate: 0x%08x\n", (u32)slave); - - writel(qslave->cmd | QSPI_INVAL, &qslave->base->cmd); -} - -void spi_init(void) -{ - /* nothing to do */ + priv->dc = 0; + if (mode & SPI_CPHA) + priv->dc |= QSPI_CKPHA(0); + if (mode & SPI_CPOL) + priv->dc |= QSPI_CKPOL(0); + if (mode & SPI_CS_HIGH) + priv->dc |= QSPI_CSPOL(0); + + if (mode & SPI_RX_QUAD) + priv->rx_bus_width = QSPI_RD_QUAD; + else if (mode & SPI_RX_QUAD) + priv->rx_bus_width = QSPI_RD_DUAL; + else + priv->rx_bus_width = QSPI_RD_SNGL; + return 0; }
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) +static int __ti_qspi_claim_bus(struct ti_qspi_priv *priv, int cs) { - struct ti_qspi_slave *qslave; - -#ifdef CONFIG_AM43XX - gpio_request(CONFIG_QSPI_SEL_GPIO, "qspi_gpio"); - gpio_direction_output(CONFIG_QSPI_SEL_GPIO, 1); -#endif - - qslave = spi_alloc_slave(struct ti_qspi_slave, bus, cs); - if (!qslave) { - printf("SPI_error: Fail to allocate ti_qspi_slave\n"); - return NULL; - } + writel(priv->dc, &priv->base->dc); + writel(0, &priv->base->cmd); + writel(0, &priv->base->data);
- qslave->base = (struct ti_qspi_regs *)QSPI_BASE; - qslave->mode = mode; - - ti_spi_set_speed(&qslave->slave, max_hz); - -#ifdef CONFIG_TI_SPI_MMAP - ti_spi_setup_spi_register(qslave); -#endif - - return &qslave->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - free(qslave); + priv->dc <<= cs * 8; + writel(priv->dc, &priv->base->dc); + return 0; }
-int spi_claim_bus(struct spi_slave *slave) +static void __ti_qspi_release_bus(struct ti_qspi_priv *priv) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - - debug("spi_claim_bus: bus:%i cs:%i\n", slave->bus, slave->cs); - - qslave->dc = 0; - if (qslave->mode & SPI_CPHA) - qslave->dc |= QSPI_CKPHA(slave->cs); - if (qslave->mode & SPI_CPOL) - qslave->dc |= QSPI_CKPOL(slave->cs); - if (qslave->mode & SPI_CS_HIGH) - qslave->dc |= QSPI_CSPOL(slave->cs); - - writel(qslave->dc, &qslave->base->dc); - writel(0, &qslave->base->cmd); - writel(0, &qslave->base->data); - - return 0; + writel(0, &priv->base->dc); + writel(0, &priv->base->cmd); + writel(0, &priv->base->data); }
-void spi_release_bus(struct spi_slave *slave) +static void ti_qspi_ctrl_mode_mmap(struct ti_qspi_priv *priv, bool enable) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - - debug("spi_release_bus: bus:%i cs:%i\n", slave->bus, slave->cs); + u32 val;
- writel(0, &qslave->base->dc); - writel(0, &qslave->base->cmd); - writel(0, &qslave->base->data); + val = readl(priv->ctrl_mod_mmap); + if(enable) + val |= MEM_CS; + else + val &= MEM_CS_UNSELECT; + writel(val, priv->ctrl_mod_mmap); }
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) +static int __ti_qspi_xfer(struct ti_qspi_priv *priv, unsigned int bitlen, + const void *dout, void *din, unsigned long flags, + u32 cs) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); uint words = bitlen >> 3; /* fixed 8-bit word length */ const uchar *txp = dout; uchar *rxp = din; uint status; int timeout;
-#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - int val; -#endif - - debug("spi_xfer: bus:%i cs:%i bitlen:%i words:%i flags:%lx\n", - slave->bus, slave->cs, bitlen, words, flags); - /* Setup mmap flags */ if (flags & SPI_XFER_MMAP) { - writel(MM_SWITCH, &qslave->base->memswitch); -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - val = readl(CORE_CTRL_IO); - val |= MEM_CS; - writel(val, CORE_CTRL_IO); -#endif + writel(MM_SWITCH, &priv->base->memswitch); + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv, true); return 0; } else if (flags & SPI_XFER_MMAP_END) { - writel(~MM_SWITCH, &qslave->base->memswitch); -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - val = readl(CORE_CTRL_IO); - val &= MEM_CS_UNSELECT; - writel(val, CORE_CTRL_IO); -#endif + writel(~MM_SWITCH, &priv->base->memswitch); + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv, false); return 0; }
@@ -288,12 +209,12 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, }
/* Setup command reg */ - qslave->cmd = 0; - qslave->cmd |= QSPI_WLEN(8); - qslave->cmd |= QSPI_EN_CS(slave->cs); + priv->cmd = 0; + priv->cmd |= QSPI_WLEN(8); + priv->cmd |= QSPI_EN_CS(cs); if (flags & SPI_3WIRE) - qslave->cmd |= QSPI_3_PIN; - qslave->cmd |= 0xfff; + priv->cmd |= QSPI_3_PIN; + priv->cmd |= 0xfff;
/* FIXME: This delay is required for successfull * completion of read/write/erase. Once its root @@ -305,39 +226,39 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, while (words--) { if (txp) { debug("tx cmd %08x dc %08x data %02x\n", - qslave->cmd | QSPI_WR_SNGL, qslave->dc, *txp); - writel(*txp++, &qslave->base->data); - writel(qslave->cmd | QSPI_WR_SNGL, - &qslave->base->cmd); - status = readl(&qslave->base->status); + priv->cmd | QSPI_WR_SNGL, priv->dc, *txp); + writel(*txp++, &priv->base->data); + writel(priv->cmd | QSPI_WR_SNGL, + &priv->base->cmd); + status = readl(&priv->base->status); timeout = QSPI_TIMEOUT; while ((status & QSPI_WC_BUSY) != QSPI_XFER_DONE) { if (--timeout < 0) { printf("spi_xfer: TX timeout!\n"); return -1; } - status = readl(&qslave->base->status); + status = readl(&priv->base->status); } debug("tx done, status %08x\n", status); } if (rxp) { - qslave->cmd |= QSPI_RD_SNGL; + priv->cmd |= QSPI_RD_SNGL; debug("rx cmd %08x dc %08x\n", - qslave->cmd, qslave->dc); + priv->cmd, priv->dc); #ifdef CONFIG_DRA7XX udelay(500); #endif - writel(qslave->cmd, &qslave->base->cmd); - status = readl(&qslave->base->status); + writel(priv->cmd, &priv->base->cmd); + status = readl(&priv->base->status); timeout = QSPI_TIMEOUT; while ((status & QSPI_WC_BUSY) != QSPI_XFER_DONE) { if (--timeout < 0) { printf("spi_xfer: RX timeout!\n"); return -1; } - status = readl(&qslave->base->status); + status = readl(&priv->base->status); } - *rxp++ = readl(&qslave->base->data); + *rxp++ = readl(&priv->base->data); debug("rx done, status %08x, read %02x\n", status, *(rxp-1)); } @@ -345,7 +266,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
/* Terminate frame */ if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); + ti_qspi_cs_deactivate(priv);
return 0; } @@ -372,3 +293,117 @@ void spi_flash_copy_mmap(void *data, void *offset, size_t len) *((unsigned int *)offset) += len; } #endif + +static inline struct ti_qspi_priv *to_ti_qspi_priv(struct spi_slave *slave) +{ + return container_of(slave, struct ti_qspi_priv, slave); +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return 1; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + /* CS handled in xfer */ + return; +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + ti_qspi_cs_deactivate(priv); +} + +void spi_init(void) +{ + /* nothing to do */ +} + +static void ti_spi_setup_spi_register(struct ti_qspi_priv *priv) +{ + struct spi_slave *slave = &priv->slave; + u32 memval = 0; + +#ifdef CONFIG_QSPI_QUAD_SUPPORT + memval |= (QSPI_CMD_READ_QUAD | QSPI_SETUP0_NUM_A_BYTES | + QSPI_SETUP0_NUM_D_BYTES_8_BITS | + QSPI_SETUP0_READ_QUAD | QSPI_CMD_WRITE | + QSPI_NUM_DUMMY_BITS); + slave->op_mode_rx = SPI_OPM_RX_QOF; +#else + memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES | + QSPI_SETUP0_NUM_D_BYTES_NO_BITS | + QSPI_SETUP0_READ_NORMAL | QSPI_CMD_WRITE | + QSPI_NUM_DUMMY_BITS; +#endif + + writel(memval, &priv->base->setup0); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct ti_qspi_priv *priv; + +#ifdef CONFIG_AM43XX + gpio_request(CONFIG_QSPI_SEL_GPIO, "qspi_gpio"); + gpio_direction_output(CONFIG_QSPI_SEL_GPIO, 1); +#endif + + priv = spi_alloc_slave(struct ti_qspi_priv, bus, cs); + if (!priv) { + printf("SPI_error: Fail to allocate ti_qspi_priv\n"); + return NULL; + } + + priv->base = (struct ti_qspi_regs *)QSPI_BASE; + priv->mode = mode; +#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) + priv->ctrl_mod_mmap = (void *)CORE_CTRL_IO; + priv->slave.memory_map = (void *)MMAP_START_ADDR_DRA; +#else + priv->slave.memory_map = (void *)MMAP_START_ADDR_AM43x; +#endif + + ti_spi_set_speed(priv, max_hz); + +#ifdef CONFIG_TI_SPI_MMAP + ti_spi_setup_spi_register(priv); +#endif + + return &priv->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + free(priv); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + + debug("%s: bus:%i cs:%i\n", __func__, priv->slave.bus, priv->slave.cs); + __ti_qspi_set_mode(priv, priv->mode); + return __ti_qspi_claim_bus(priv, priv->slave.cs); +} +void spi_release_bus(struct spi_slave *slave) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + + debug("%s: bus:%i cs:%i\n", __func__, priv->slave.bus, priv->slave.cs); + __ti_qspi_release_bus(priv); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + + debug("spi_xfer: bus:%i cs:%i bitlen:%i flags:%lx\n", + priv->slave.bus, priv->slave.cs, bitlen, flags); + return __ti_qspi_xfer(priv, bitlen, dout, din, flags, priv->slave.cs); +}

Hi Mugunthan,
On 27 October 2015 at 05:12, Mugunthan V N mugunthanvnm@ti.com wrote:
Prepare driver for DM conversion.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/spi/ti_qspi.c | 341 ++++++++++++++++++++++++++++---------------------- 1 file changed, 188 insertions(+), 153 deletions(-)
This could usefully be split - e.g. one commit to move the code, one to rename priv, and one for the rest of the changes. Still, it looks right to me.
Reviewed-by: Simon Glass sjg@chromium.org

Add new api to get device address based on index.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/core/device.c | 20 ++++++++++++++++++++ include/dm/device.h | 9 +++++++++ 2 files changed, 29 insertions(+)
diff --git a/drivers/core/device.c b/drivers/core/device.c index a3dc2ca..7557e5c 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -620,6 +620,26 @@ fdt_addr_t dev_get_addr(struct udevice *dev) #endif }
+fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL) + fdt_addr_t addr; + + addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, + dev->parent->of_offset, + dev->of_offset, "reg", + index, NULL); + if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { + if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS) + addr = simple_bus_translate(dev->parent, addr); + } + + return addr; +#else + return FDT_ADDR_T_NONE; +#endif +} + bool device_has_children(struct udevice *dev) { return !list_empty(&dev->child_head); diff --git a/include/dm/device.h b/include/dm/device.h index 8519612..e6506b4 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -441,6 +441,15 @@ int device_find_next_child(struct udevice **devp); fdt_addr_t dev_get_addr(struct udevice *dev);
/** + * dev_get_addr() - Get the reg property of a device + * + * @dev: Pointer to a device + * + * @return addr + */ +fdt_addr_t dev_get_addr_index(struct udevice *dev, int index); + +/** * device_has_children() - check if a device has any children * * @dev: Device to check

Hi Mugunthan,
On 27 October 2015 at 05:12, Mugunthan V N mugunthanvnm@ti.com wrote:
Add new api to get device address based on index.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/core/device.c | 20 ++++++++++++++++++++ include/dm/device.h | 9 +++++++++ 2 files changed, 29 insertions(+)
diff --git a/drivers/core/device.c b/drivers/core/device.c index a3dc2ca..7557e5c 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -620,6 +620,26 @@ fdt_addr_t dev_get_addr(struct udevice *dev) #endif }
+fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL)
fdt_addr_t addr;
I think you are missing the 'if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {' logic from dev_get_addr(). Also that function should call your new function I think to avoid duplicated code.
addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
dev->parent->of_offset,
dev->of_offset, "reg",
index, NULL);
if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS)
addr = simple_bus_translate(dev->parent, addr);
}
return addr;
+#else
return FDT_ADDR_T_NONE;
+#endif +}
bool device_has_children(struct udevice *dev) { return !list_empty(&dev->child_head); diff --git a/include/dm/device.h b/include/dm/device.h index 8519612..e6506b4 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -441,6 +441,15 @@ int device_find_next_child(struct udevice **devp); fdt_addr_t dev_get_addr(struct udevice *dev);
/**
- dev_get_addr() - Get the reg property of a device
- @dev: Pointer to a device
- @return addr
Please update the comment here with the new parameter and what it does.
- */
+fdt_addr_t dev_get_addr_index(struct udevice *dev, int index);
+/**
- device_has_children() - check if a device has any children
- @dev: Device to check
-- 2.6.2.280.g74301d6
Regards, Simon

On Thursday 29 October 2015 10:47 PM, Simon Glass wrote:
Hi Mugunthan,
On 27 October 2015 at 05:12, Mugunthan V N mugunthanvnm@ti.com wrote:
Add new api to get device address based on index.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/core/device.c | 20 ++++++++++++++++++++ include/dm/device.h | 9 +++++++++ 2 files changed, 29 insertions(+)
diff --git a/drivers/core/device.c b/drivers/core/device.c index a3dc2ca..7557e5c 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -620,6 +620,26 @@ fdt_addr_t dev_get_addr(struct udevice *dev) #endif }
+fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) +{ +#if CONFIG_IS_ENABLED(OF_CONTROL)
fdt_addr_t addr;
I think you are missing the 'if (CONFIG_IS_ENABLED(OF_TRANSLATE)) {' logic from dev_get_addr(). Also that function should call your new function I think to avoid duplicated code.
Agreed, will fix in v2.
addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob,
dev->parent->of_offset,
dev->of_offset, "reg",
index, NULL);
if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) {
if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS)
addr = simple_bus_translate(dev->parent, addr);
}
return addr;
+#else
return FDT_ADDR_T_NONE;
+#endif +}
bool device_has_children(struct udevice *dev) { return !list_empty(&dev->child_head); diff --git a/include/dm/device.h b/include/dm/device.h index 8519612..e6506b4 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -441,6 +441,15 @@ int device_find_next_child(struct udevice **devp); fdt_addr_t dev_get_addr(struct udevice *dev);
/**
- dev_get_addr() - Get the reg property of a device
- @dev: Pointer to a device
- @return addr
Please update the comment here with the new parameter and what it does.
Will fix in v2.
Regards Mugunthan V N

spi bus can support dual and quad wire data transfers for tx and rx. So defining dual and quad modes for both tx and rx. Also add support to parse bus width used for spi tx and rx transfers.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/spi/spi-uclass.c | 33 +++++++++++++++++++++++++++++++++ include/spi.h | 4 ++++ 2 files changed, 37 insertions(+)
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index d666272..9a32b6c 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -349,6 +349,7 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node, struct dm_spi_slave_platdata *plat) { int mode = 0; + int value;
plat->cs = fdtdec_get_int(blob, node, "reg", -1); plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0); @@ -360,6 +361,38 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node, mode |= SPI_CS_HIGH; if (fdtdec_get_bool(blob, node, "spi-half-duplex")) mode |= SPI_PREAMBLE; + + /* Device DUAL/QUAD mode */ + value = fdtdec_get_int(blob, node, "spi-tx-bus-width", 1); + switch (value) { + case 1: + break; + case 2: + mode |= SPI_TX_DUAL; + break; + case 4: + mode |= SPI_TX_QUAD; + break; + default: + error("spi-tx-bus-width %d not supported\n", value); + break; + } + + value = fdtdec_get_int(blob, node, "spi-rx-bus-width", 1); + switch (value) { + case 1: + break; + case 2: + mode |= SPI_RX_DUAL; + break; + case 4: + mode |= SPI_RX_QUAD; + break; + default: + error("spi-rx-bus-width %d not supported\n", value); + break; + } + plat->mode = mode;
return 0; diff --git a/include/spi.h b/include/spi.h index 51fdfd6..57f6ffe 100644 --- a/include/spi.h +++ b/include/spi.h @@ -23,6 +23,10 @@ #define SPI_LOOP 0x20 /* loopback mode */ #define SPI_SLAVE 0x40 /* slave mode */ #define SPI_PREAMBLE 0x80 /* Skip preamble bytes */ +#define SPI_TX_DUAL 0x100 /* transmit with 2 wires */ +#define SPI_TX_QUAD 0x200 /* transmit with 4 wires */ +#define SPI_RX_DUAL 0x400 /* receive with 2 wires */ +#define SPI_RX_QUAD 0x800 /* receive with 4 wires */
/* SPI transfer flags */ #define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */

On 27 October 2015 at 05:12, Mugunthan V N mugunthanvnm@ti.com wrote:
spi bus can support dual and quad wire data transfers for tx and rx. So defining dual and quad modes for both tx and rx. Also add support to parse bus width used for spi tx and rx transfers.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/spi/spi-uclass.c | 33 +++++++++++++++++++++++++++++++++ include/spi.h | 4 ++++ 2 files changed, 37 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

when a device registered with device_bind_driver(), its fdt node is not added to the device. Due to this, in spi_child_post_bind() dev->of_offset is -1 and spi device fdt is never parsed. So changing the device register by device_bind_driver_to_node() so that the spi slave device is registered with of_offset and its fdt is parsed properly.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/spi/spi-uclass.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 9a32b6c..cfd14b1 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -138,6 +138,7 @@ static int spi_child_pre_probe(struct udevice *dev) slave->max_hz = plat->max_hz; slave->mode = plat->mode;
+ return 0; }
@@ -258,17 +259,42 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, * SPI flash chip - we will bind to the correct driver. */ if (ret == -ENODEV && drv_name) { - struct dm_spi_slave_platdata *plat; + const void *fdt = gd->fdt_blob; + int node = bus->of_offset; + int subnode = -1; + int slave_cs = -1;
debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n", __func__, dev_name, busnum, cs, drv_name); - ret = device_bind_driver(bus, drv_name, dev_name, &dev); + + fdt_for_each_subnode(fdt, subnode, node) { + slave_cs = fdtdec_get_int(fdt, subnode, "reg", -1); + if(cs == slave_cs) + break; + } + + if(cs != slave_cs) { + printf("%s: device not found in device tree blob\n", + __func__); + subnode = -1; + } + + ret = device_bind_driver_to_node(bus, drv_name, dev_name, + subnode, &dev); if (ret) return ret; - plat = dev_get_parent_platdata(dev); - plat->cs = cs; - plat->max_hz = speed; - plat->mode = mode; + /* + * If a Device tree spi slave is found, then use settings + * from Device tree. + */ + if (subnode < 0) { + struct dm_spi_slave_platdata *plat; + + plat = dev_get_parent_platdata(dev); + plat->cs = cs; + plat->max_hz = speed; + plat->mode = mode; + } created = true; } else if (ret) { printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,

Hi Muganthan,
On 27 October 2015 at 05:12, Mugunthan V N mugunthanvnm@ti.com wrote:
when a device registered with device_bind_driver(), its fdt node is not added to the device. Due to this, in spi_child_post_bind() dev->of_offset is -1 and spi device fdt is never parsed. So changing the device register by device_bind_driver_to_node() so that the spi slave device is registered with of_offset and its fdt is parsed properly.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/spi/spi-uclass.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 9a32b6c..cfd14b1 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -138,6 +138,7 @@ static int spi_child_pre_probe(struct udevice *dev) slave->max_hz = plat->max_hz; slave->mode = plat->mode;
return 0;
}
@@ -258,17 +259,42 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode, * SPI flash chip - we will bind to the correct driver. */ if (ret == -ENODEV && drv_name) {
struct dm_spi_slave_platdata *plat;
const void *fdt = gd->fdt_blob;
int node = bus->of_offset;
int subnode = -1;
int slave_cs = -1; debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n", __func__, dev_name, busnum, cs, drv_name);
ret = device_bind_driver(bus, drv_name, dev_name, &dev);
Please see the comment above:
/* * If there is no such device, create one automatically. This means * that we don't need a device tree node or platform data for the * SPI flash chip - we will bind to the correct driver. */
This code is used when there is no device attached. It should not happen that you have a device tree node which is ignored when the SPI bus is bound. spi_post_bind() should pick up these node and create drivers for them.
fdt_for_each_subnode(fdt, subnode, node) {
slave_cs = fdtdec_get_int(fdt, subnode, "reg", -1);
if(cs == slave_cs)
break;
}
if(cs != slave_cs) {
printf("%s: device not found in device tree blob\n",
__func__);
subnode = -1;
}
ret = device_bind_driver_to_node(bus, drv_name, dev_name,
subnode, &dev); if (ret) return ret;
plat = dev_get_parent_platdata(dev);
plat->cs = cs;
plat->max_hz = speed;
plat->mode = mode;
/*
* If a Device tree spi slave is found, then use settings
* from Device tree.
*/
if (subnode < 0) {
struct dm_spi_slave_platdata *plat;
plat = dev_get_parent_platdata(dev);
plat->cs = cs;
plat->max_hz = speed;
plat->mode = mode;
} created = true; } else if (ret) { printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,
-- 2.6.2.280.g74301d6
Regards, Simon

On Thursday 29 October 2015 10:47 PM, Simon Glass wrote:
Please see the comment above:
/*
- If there is no such device, create one automatically. This means
- that we don't need a device tree node or platform data for the
- SPI flash chip - we will bind to the correct driver.
*/
This code is used when there is no device attached. It should not happen that you have a device tree node which is ignored when the SPI bus is bound. spi_post_bind() should pick up these node and create drivers for them.
Hmmmm, will drop this patch.
Regards Mugunthan V N

Since spl doesn't support DM currently, do not define DM_SPI and DM_SPI_FLASH for spl build.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- include/configs/dra7xx_evm.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h index 6e32de8..525dce7 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -131,6 +131,11 @@ #define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3 #define CONFIG_QSPI_QUAD_SUPPORT
+#ifdef CONFIG_SPL_BUILD +#undef CONFIG_DM_SPI +#undef CONFIG_DM_SPI_FLASH +#endif + /* * Default to using SPI for environment, etc. * 0x000000 - 0x010000 : QSPI.SPL (64KiB)

Hi Mugunthan,
On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
Since spl doesn't support DM currently, do not define DM_SPI and DM_SPI_FLASH for spl build.
SPL does support driver model. I'm not sure what this change is trying to do.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
include/configs/dra7xx_evm.h | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h index 6e32de8..525dce7 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -131,6 +131,11 @@ #define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3 #define CONFIG_QSPI_QUAD_SUPPORT
+#ifdef CONFIG_SPL_BUILD +#undef CONFIG_DM_SPI +#undef CONFIG_DM_SPI_FLASH +#endif
/*
- Default to using SPI for environment, etc.
- 0x000000 - 0x010000 : QSPI.SPL (64KiB)
-- 2.6.2.280.g74301d6
Regards, Simon

On Thursday 29 October 2015 10:47 PM, Simon Glass wrote:
Hi Mugunthan,
On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
Since spl doesn't support DM currently, do not define DM_SPI and DM_SPI_FLASH for spl build.
SPL does support driver model. I'm not sure what this change is trying to do.
For TI platforms, DM/DT platform is not supported yet for SPL. Similar patch [1] was already accepted by Tom.
[1]: http://patchwork.ozlabs.org/patch/523758/
Regards Mugunthan V N

Hi,
On 31 October 2015 at 05:39, Mugunthan V N mugunthanvnm@ti.com wrote:
On Thursday 29 October 2015 10:47 PM, Simon Glass wrote:
Hi Mugunthan,
On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
Since spl doesn't support DM currently, do not define DM_SPI and DM_SPI_FLASH for spl build.
SPL does support driver model. I'm not sure what this change is trying to do.
For TI platforms, DM/DT platform is not supported yet for SPL. Similar patch [1] was already accepted by Tom.
Perhaps you could reword this to say that TI platforms do not support driver model, instead?
Regards, Simon

add spi alias for qspi so that spi probes the device and driver successfully.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- arch/arm/dts/dra7.dtsi | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi index 8f1e25b..7357b0e 100644 --- a/arch/arm/dts/dra7.dtsi +++ b/arch/arm/dts/dra7.dtsi @@ -41,6 +41,8 @@ ethernet1 = &cpsw_emac1; d_can0 = &dcan1; d_can1 = &dcan2; + spi0 = &qspi; + };
timer {

On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
add spi alias for qspi so that spi probes the device and driver successfully.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
arch/arm/dts/dra7.dtsi | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
But I don't think you should add the blank line.
diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi index 8f1e25b..7357b0e 100644 --- a/arch/arm/dts/dra7.dtsi +++ b/arch/arm/dts/dra7.dtsi @@ -41,6 +41,8 @@ ethernet1 = &cpsw_emac1; d_can0 = &dcan1; d_can1 = &dcan2;
spi0 = &qspi;
}; timer {
-- 2.6.2.280.g74301d6

On Thursday 29 October 2015 10:48 PM, Simon Glass wrote:
On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
add spi alias for qspi so that spi probes the device and driver successfully.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
arch/arm/dts/dra7.dtsi | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
But I don't think you should add the blank line.
Will fix in v2
Regards Mugunthan V N

adopt ti_qspi driver to device driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/spi/ti_qspi.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 4893472..4cc26bf 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -11,11 +11,14 @@ #include <asm/arch/omap.h> #include <malloc.h> #include <spi.h> +#include <dm.h> #include <asm/gpio.h> #include <asm/omap_gpio.h> #include <asm/omap_common.h> #include <asm/ti-common/ti-edma3.h>
+DECLARE_GLOBAL_DATA_PTR; + /* ti qpsi register bit masks */ #define QSPI_TIMEOUT 2000000 #define QSPI_FCLK 192000000 @@ -294,6 +297,8 @@ void spi_flash_copy_mmap(void *data, void *offset, size_t len) } #endif
+#ifndef CONFIG_DM_SPI + static inline struct ti_qspi_priv *to_ti_qspi_priv(struct spi_slave *slave) { return container_of(slave, struct ti_qspi_priv, slave); @@ -407,3 +412,124 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, priv->slave.bus, priv->slave.cs, bitlen, flags); return __ti_qspi_xfer(priv, bitlen, dout, din, flags, priv->slave.cs); } + +#else /* CONFIG_DM_SPI */ + +static int ti_qspi_set_speed(struct udevice *bus, uint max_hz) +{ + struct ti_qspi_priv *priv = dev_get_priv(bus); + + ti_spi_set_speed(priv, max_hz); + + return 0; +} + +static int ti_qspi_set_mode(struct udevice *bus, uint mode) +{ + struct ti_qspi_priv *priv = dev_get_priv(bus); + + return __ti_qspi_set_mode(priv, mode); +} + +static int ti_qspi_claim_bus(struct udevice *dev) +{ + struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + return __ti_qspi_claim_bus(priv, slave->cs); +} + +static int ti_qspi_release_bus(struct udevice *dev) +{ + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + __ti_qspi_release_bus(priv); + + return 0; +} + +static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + return __ti_qspi_xfer(priv, bitlen, dout, din, flags, slave->cs); +} + +static int ti_qspi_probe(struct udevice *bus) +{ + /* Nothing to do in probe */ + return 0; +} + +static int ti_qspi_ofdata_to_platdata(struct udevice *bus) +{ + struct ti_qspi_priv *priv = dev_get_priv(bus); + const void *blob = gd->fdt_blob; + int node = bus->of_offset; + int flash_num = 0, subnode; + + priv->base = (struct ti_qspi_regs *)dev_get_addr(bus); + priv->slave.memory_map = (void *)dev_get_addr_index(bus, 1); + priv->ctrl_mod_mmap = (void *)dev_get_addr_index(bus, 2); + + /* Count flash numbers */ + fdt_for_each_subnode(blob, subnode, node) + ++flash_num; + + if (flash_num == 0) { + debug("Error: Missing flashes!\n"); + return -ENODEV; + } + + priv->slave.max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", + -1); + if (priv->slave.max_hz < 0) { + debug("Error: Max frequency missing\n"); + return -ENODEV; + } + priv->num_cs = fdtdec_get_int(blob, node, "num-cs", 4); + + debug("%s: regs=<0x%x>, max-frequency=%d, num flash = %d\n", + __func__, (int)priv->base, priv->slave.max_hz, flash_num); + + return 0; +} + +static const struct dm_spi_ops ti_qspi_ops = { + .claim_bus = ti_qspi_claim_bus, + .release_bus = ti_qspi_release_bus, + .xfer = ti_qspi_xfer, + .set_speed = ti_qspi_set_speed, + .set_mode = ti_qspi_set_mode, +}; + +static const struct udevice_id ti_qspi_ids[] = { + { .compatible = "ti,dra7xxx-qspi" }, + { .compatible = "ti,am4372-qspi" }, + { } +}; + +U_BOOT_DRIVER(ti_qspi) = { + .name = "ti_qspi", + .id = UCLASS_SPI, + .of_match = ti_qspi_ids, + .ops = &ti_qspi_ops, + .ofdata_to_platdata = ti_qspi_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct ti_qspi_priv), + .probe = ti_qspi_probe, +}; +#endif /* CONFIG_DM_SPI */

Hi Mugunthan,
On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
adopt ti_qspi driver to device driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/spi/ti_qspi.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 4893472..4cc26bf 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -11,11 +11,14 @@ #include <asm/arch/omap.h> #include <malloc.h> #include <spi.h> +#include <dm.h> #include <asm/gpio.h> #include <asm/omap_gpio.h> #include <asm/omap_common.h> #include <asm/ti-common/ti-edma3.h>
+DECLARE_GLOBAL_DATA_PTR;
/* ti qpsi register bit masks */ #define QSPI_TIMEOUT 2000000 #define QSPI_FCLK 192000000 @@ -294,6 +297,8 @@ void spi_flash_copy_mmap(void *data, void *offset, size_t len) } #endif
+#ifndef CONFIG_DM_SPI
static inline struct ti_qspi_priv *to_ti_qspi_priv(struct spi_slave *slave) { return container_of(slave, struct ti_qspi_priv, slave); @@ -407,3 +412,124 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, priv->slave.bus, priv->slave.cs, bitlen, flags); return __ti_qspi_xfer(priv, bitlen, dout, din, flags, priv->slave.cs); }
+#else /* CONFIG_DM_SPI */
+static int ti_qspi_set_speed(struct udevice *bus, uint max_hz) +{
struct ti_qspi_priv *priv = dev_get_priv(bus);
ti_spi_set_speed(priv, max_hz);
return 0;
+}
+static int ti_qspi_set_mode(struct udevice *bus, uint mode) +{
struct ti_qspi_priv *priv = dev_get_priv(bus);
return __ti_qspi_set_mode(priv, mode);
+}
+static int ti_qspi_claim_bus(struct udevice *dev) +{
struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
struct ti_qspi_priv *priv;
struct udevice *bus;
bus = dev->parent;
priv = dev_get_priv(bus);
return __ti_qspi_claim_bus(priv, slave->cs);
+}
+static int ti_qspi_release_bus(struct udevice *dev) +{
struct ti_qspi_priv *priv;
struct udevice *bus;
bus = dev->parent;
priv = dev_get_priv(bus);
__ti_qspi_release_bus(priv);
return 0;
+}
+static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
+{
struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
struct ti_qspi_priv *priv;
struct udevice *bus;
bus = dev->parent;
priv = dev_get_priv(bus);
return __ti_qspi_xfer(priv, bitlen, dout, din, flags, slave->cs);
+}
+static int ti_qspi_probe(struct udevice *bus) +{
/* Nothing to do in probe */
return 0;
+}
+static int ti_qspi_ofdata_to_platdata(struct udevice *bus) +{
struct ti_qspi_priv *priv = dev_get_priv(bus);
const void *blob = gd->fdt_blob;
int node = bus->of_offset;
int flash_num = 0, subnode;
priv->base = (struct ti_qspi_regs *)dev_get_addr(bus);
priv->slave.memory_map = (void *)dev_get_addr_index(bus, 1);
priv->ctrl_mod_mmap = (void *)dev_get_addr_index(bus, 2);
/* Count flash numbers */
fdt_for_each_subnode(blob, subnode, node)
++flash_num;
if (flash_num == 0) {
debug("Error: Missing flashes!\n");
return -ENODEV;
}
It looks like flash_num is only used for the debug message. Why not just drop this? The driver should not be scanning the device tree - it should be able to look at the number of child devices instead.
priv->slave.max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
-1);
if (priv->slave.max_hz < 0) {
debug("Error: Max frequency missing\n");
return -ENODEV;
}
priv->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
debug("%s: regs=<0x%x>, max-frequency=%d, num flash = %d\n",
__func__, (int)priv->base, priv->slave.max_hz, flash_num);
return 0;
+}
+static const struct dm_spi_ops ti_qspi_ops = {
.claim_bus = ti_qspi_claim_bus,
.release_bus = ti_qspi_release_bus,
.xfer = ti_qspi_xfer,
.set_speed = ti_qspi_set_speed,
.set_mode = ti_qspi_set_mode,
+};
+static const struct udevice_id ti_qspi_ids[] = {
{ .compatible = "ti,dra7xxx-qspi" },
{ .compatible = "ti,am4372-qspi" },
{ }
+};
+U_BOOT_DRIVER(ti_qspi) = {
.name = "ti_qspi",
.id = UCLASS_SPI,
.of_match = ti_qspi_ids,
.ops = &ti_qspi_ops,
.ofdata_to_platdata = ti_qspi_ofdata_to_platdata,
.priv_auto_alloc_size = sizeof(struct ti_qspi_priv),
.probe = ti_qspi_probe,
+};
+#endif /* CONFIG_DM_SPI */
2.6.2.280.g74301d6
Regards, Simon

On Thursday 29 October 2015 10:48 PM, Simon Glass wrote:
if (flash_num == 0) {
debug("Error: Missing flashes!\n");
return -ENODEV;
}
It looks like flash_num is only used for the debug message. Why not just drop this? The driver should not be scanning the device tree - it should be able to look at the number of child devices instead.
Hmmm, will fix in v2
Regards Mugunthan V N

Add qspi memory map and control module register maps to device tree.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- arch/arm/dts/dra7.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi index 7357b0e..b72c1fa 100644 --- a/arch/arm/dts/dra7.dtsi +++ b/arch/arm/dts/dra7.dtsi @@ -1105,8 +1105,8 @@
qspi: qspi@4b300000 { compatible = "ti,dra7xxx-qspi"; - reg = <0x4b300000 0x100>; - reg-names = "qspi_base"; + reg = <0x4b300000 0x100>, <0x5c000000 0x4000000>, <0x4a002558 0x4>; + reg-names = "qspi_base", "qspi_mmap", "qspi_ctrlmod"; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "qspi";

On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
Add qspi memory map and control module register maps to device tree.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
arch/arm/dts/dra7.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Simon Glass sjg@chromium.org

enable mmc driver model for dra72_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- configs/dra72_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/dra72_evm_defconfig b/configs/dra72_evm_defconfig index cce3255..d88b2b7 100644 --- a/configs/dra72_evm_defconfig +++ b/configs/dra72_evm_defconfig @@ -16,3 +16,5 @@ CONFIG_OF_CONTROL=y CONFIG_DM=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y

On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
enable mmc driver model for dra72_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
configs/dra72_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

enable mmc driver model for dra74_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- configs/dra74_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/dra74_evm_defconfig b/configs/dra74_evm_defconfig index a57cd7f..b7c541b 100644 --- a/configs/dra74_evm_defconfig +++ b/configs/dra74_evm_defconfig @@ -15,3 +15,5 @@ CONFIG_DM=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_DM_GPIO=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y

On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
enable mmc driver model for dra74_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
configs/dra74_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

Since spl doesn't support DM currently, do not define DM_SPI and DM_SPI_FLASH for spl build.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- include/configs/am43xx_evm.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index d93e3e7..1258492 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -146,6 +146,8 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC +#undef CONFIG_DM_SPI +#undef CONFIG_DM_SPI_FLASH #endif
#ifndef CONFIG_SPL_BUILD

Hi Mugunthan,
On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
Since spl doesn't support DM currently, do not define DM_SPI and DM_SPI_FLASH for spl build.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
include/configs/am43xx_evm.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index d93e3e7..1258492 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -146,6 +146,8 @@ */ #ifdef CONFIG_SPL_BUILD #undef CONFIG_DM_MMC +#undef CONFIG_DM_SPI +#undef CONFIG_DM_SPI_FLASH #endif
I'm hoping you can avoid this change.
#ifndef CONFIG_SPL_BUILD
2.6.2.280.g74301d6
Regards, Simon

Add qspi memory map address to device tree.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- arch/arm/dts/am4372.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/am4372.dtsi b/arch/arm/dts/am4372.dtsi index ade28c7..1b30d53 100644 --- a/arch/arm/dts/am4372.dtsi +++ b/arch/arm/dts/am4372.dtsi @@ -25,6 +25,7 @@ serial0 = &uart0; ethernet0 = &cpsw_emac0; ethernet1 = &cpsw_emac1; + spi0 = &qspi; };
cpus { @@ -902,7 +903,8 @@
qspi: qspi@47900000 { compatible = "ti,am4372-qspi"; - reg = <0x47900000 0x100>; + reg = <0x47900000 0x100>, <0x30000000 0x4000000>; + reg-names = "qspi_base", "qspi_mmap"; #address-cells = <1>; #size-cells = <0>; ti,hwmods = "qspi";

On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
Add qspi memory map address to device tree.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
arch/arm/dts/am4372.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Simon Glass sjg@chromium.org

enable mmc driver model for am437x_sk_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- configs/am437x_sk_evm_defconfig | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/configs/am437x_sk_evm_defconfig b/configs/am437x_sk_evm_defconfig index 02485f8..ba0ab84 100644 --- a/configs/am437x_sk_evm_defconfig +++ b/configs/am437x_sk_evm_defconfig @@ -15,3 +15,6 @@ CONFIG_SPI_FLASH=y CONFIG_DM_GPIO=y CONFIG_DM_SERIAL=y CONFIG_DM_MMC=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y

On 27 October 2015 at 05:13, Mugunthan V N mugunthanvnm@ti.com wrote:
enable mmc driver model for am437x_sk_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
configs/am437x_sk_evm_defconfig | 3 +++ 1 file changed, 3 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
participants (2)
-
Mugunthan V N
-
Simon Glass