[U-Boot] [PATCH v3 00/16] device model bring-up 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/13341771/ [2]: git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git qspi-v3
Changes from v2->v3: * removed usage of spi_slave structure in driver model and introduced required variables in qspi priv itself. * Used fdt_addr_cells() and fdt_size_cells() instead of hard-coding size of each address-size pair. * Changed qspi dts entries to be same as in kernel qspi dts patch for avoiding future conflicts. * Fixed some typos and added more info in commits. * Added error check on chip select passed from framework. * Removed un-used define QSPI_RD_DUAL.
Changes from Initial version: * Split "prepare driver for DM conversion" for easier review * added memory map mode to the driver * Fixed the cosmetic reviews from Simon * Modified the dev_get_addr_index to adopt OF_TRANSULATE as well and also removed code duplicate. * Added compatibles for spi flashed found in DRA7xx and AM437x SK
Mugunthan V N (16): drivers: spi: ti_qspi: do not hard code chip select for memory map configuration drivers: spi:ti_qspi: change ti_qspi_slave to ti_qspi_priv for driver model conversion 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 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 drivers: mtd: spi: sf_probe: add compatible for spansion spi flash drivers: mtd: spi: sf_probe: add compatible for Macronix spi flash 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 | 5 +- arch/arm/dts/dra7.dtsi | 8 +- configs/am437x_sk_evm_defconfig | 3 + configs/dra72_evm_defconfig | 2 + configs/dra74_evm_defconfig | 2 + drivers/core/device.c | 31 ++- drivers/mtd/spi/sf_probe.c | 2 + drivers/spi/spi-uclass.c | 33 +++ drivers/spi/ti_qspi.c | 519 ++++++++++++++++++++++++++++------------ include/configs/am43xx_evm.h | 2 + include/configs/dra7xx_evm.h | 5 + include/dm/device.h | 11 + include/spi.h | 4 + 13 files changed, 467 insertions(+), 160 deletions(-)

To enable memory map in dra7xx, specific chip select must be written to control module register. But this hard coded to chip select 1, fixing it by writing the specific chip select value to control module register.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com Reviewed-by: Jagan Teki jteki@openedev.com --- drivers/spi/ti_qspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index ecd9d78..36bf206 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -41,7 +41,7 @@ #define QSPI_WC_BUSY (QSPI_WC | QSPI_BUSY) #define QSPI_XFER_DONE QSPI_WC #define MM_SWITCH 0x01 -#define MEM_CS 0x100 +#define MEM_CS(cs) ((cs + 1) << 8) #define MEM_CS_UNSELECT 0xfffff0ff #define MMAP_START_ADDR_DRA 0x5c000000 #define MMAP_START_ADDR_AM43x 0x30000000 @@ -265,7 +265,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, writel(MM_SWITCH, &qslave->base->memswitch); #if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) val = readl(CORE_CTRL_IO); - val |= MEM_CS; + val |= MEM_CS(slave->cs); writel(val, CORE_CTRL_IO); #endif return 0;

Changing the ti_qspi_priv structure and its instance names from to priv for driver mode conversion.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com Reviewed-by: Jagan Teki jteki@openedev.com --- drivers/spi/ti_qspi.c | 118 +++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 59 deletions(-)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 36bf206..44c5762 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -85,8 +85,8 @@ 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; unsigned int mode; @@ -94,14 +94,14 @@ struct ti_qspi_slave { u32 dc; };
-static inline struct ti_qspi_slave *to_ti_qspi_slave(struct spi_slave *slave) +static inline struct ti_qspi_priv *to_ti_qspi_priv(struct spi_slave *slave) { - return container_of(slave, struct ti_qspi_slave, slave); + return container_of(slave, struct ti_qspi_priv, slave); }
-static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave) +static void ti_spi_setup_spi_register(struct ti_qspi_priv *priv) { - struct spi_slave *slave = &qslave->slave; + struct spi_slave *slave = &priv->slave; u32 memval = 0;
#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) @@ -123,12 +123,12 @@ static void ti_spi_setup_spi_register(struct ti_qspi_slave *qslave) QSPI_NUM_DUMMY_BITS; #endif
- writel(memval, &qslave->base->setup0); + writel(memval, &priv->base->setup0); }
static void ti_spi_set_speed(struct spi_slave *slave, uint hz) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); uint clk_div;
debug("ti_spi_set_speed: hz: %d, clock divider %d\n", hz, clk_div); @@ -139,8 +139,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,7 +149,7 @@ 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) @@ -165,11 +165,11 @@ void spi_cs_activate(struct spi_slave *slave)
void spi_cs_deactivate(struct spi_slave *slave) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave);
debug("spi_cs_deactivate: 0x%08x\n", (u32)slave);
- writel(qslave->cmd | QSPI_INVAL, &qslave->base->cmd); + writel(priv->cmd | QSPI_INVAL, &priv->base->cmd); }
void spi_init(void) @@ -180,73 +180,73 @@ void spi_init(void) struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { - struct ti_qspi_slave *qslave; + 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
- qslave = spi_alloc_slave(struct ti_qspi_slave, bus, cs); - if (!qslave) { - printf("SPI_error: Fail to allocate ti_qspi_slave\n"); + priv = spi_alloc_slave(struct ti_qspi_priv, bus, cs); + if (!priv) { + printf("SPI_error: Fail to allocate ti_qspi_priv\n"); return NULL; }
- qslave->base = (struct ti_qspi_regs *)QSPI_BASE; - qslave->mode = mode; + priv->base = (struct ti_qspi_regs *)QSPI_BASE; + priv->mode = mode;
- ti_spi_set_speed(&qslave->slave, max_hz); + ti_spi_set_speed(&priv->slave, max_hz);
#ifdef CONFIG_TI_SPI_MMAP - ti_spi_setup_spi_register(qslave); + ti_spi_setup_spi_register(priv); #endif
- return &qslave->slave; + return &priv->slave; }
void spi_free_slave(struct spi_slave *slave) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); - free(qslave); + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); + free(priv); }
int spi_claim_bus(struct spi_slave *slave) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); + struct ti_qspi_priv *priv = to_ti_qspi_priv(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); + priv->dc = 0; + if (priv->mode & SPI_CPHA) + priv->dc |= QSPI_CKPHA(slave->cs); + if (priv->mode & SPI_CPOL) + priv->dc |= QSPI_CKPOL(slave->cs); + if (priv->mode & SPI_CS_HIGH) + priv->dc |= QSPI_CSPOL(slave->cs);
- writel(qslave->dc, &qslave->base->dc); - writel(0, &qslave->base->cmd); - writel(0, &qslave->base->data); + writel(priv->dc, &priv->base->dc); + writel(0, &priv->base->cmd); + writel(0, &priv->base->data);
return 0; }
void spi_release_bus(struct spi_slave *slave) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave);
debug("spi_release_bus: bus:%i cs:%i\n", slave->bus, slave->cs);
- writel(0, &qslave->base->dc); - writel(0, &qslave->base->cmd); - writel(0, &qslave->base->data); + writel(0, &priv->base->dc); + writel(0, &priv->base->cmd); + writel(0, &priv->base->data); }
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { - struct ti_qspi_slave *qslave = to_ti_qspi_slave(slave); + struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); uint words = bitlen >> 3; /* fixed 8-bit word length */ const uchar *txp = dout; uchar *rxp = din; @@ -262,7 +262,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
/* Setup mmap flags */ if (flags & SPI_XFER_MMAP) { - writel(MM_SWITCH, &qslave->base->memswitch); + writel(MM_SWITCH, &priv->base->memswitch); #if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) val = readl(CORE_CTRL_IO); val |= MEM_CS(slave->cs); @@ -270,7 +270,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, #endif return 0; } else if (flags & SPI_XFER_MMAP_END) { - writel(~MM_SWITCH, &qslave->base->memswitch); + writel(~MM_SWITCH, &priv->base->memswitch); #if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) val = readl(CORE_CTRL_IO); val &= MEM_CS_UNSELECT; @@ -288,12 +288,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(slave->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 +305,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)); }

Prepare driver for DM conversion.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/spi/ti_qspi.c | 276 +++++++++++++++++++++++++++----------------------- 1 file changed, 151 insertions(+), 125 deletions(-)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 44c5762..a02cb25 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -89,46 +89,14 @@ struct ti_qspi_regs { struct ti_qspi_priv { struct spi_slave slave; struct ti_qspi_regs *base; + void *ctrl_mod_mmap; unsigned int mode; u32 cmd; u32 dc; };
-static inline struct ti_qspi_priv *to_ti_qspi_priv(struct spi_slave *slave) +static void ti_spi_set_speed(struct ti_qspi_priv *priv, uint hz) { - return container_of(slave, struct ti_qspi_priv, slave); -} - -static void ti_spi_setup_spi_register(struct ti_qspi_priv *priv) -{ - struct spi_slave *slave = &priv->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, &priv->base->setup0); -} - -static void ti_spi_set_speed(struct spi_slave *slave, uint hz) -{ - struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); uint clk_div;
debug("ti_spi_set_speed: hz: %d, clock divider %d\n", hz, clk_div); @@ -152,130 +120,74 @@ static void ti_spi_set_speed(struct spi_slave *slave, uint hz) writel(QSPI_CLK_EN | clk_div, &priv->base->clk_ctrl); }
-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) +static void ti_qspi_cs_deactivate(struct ti_qspi_priv *priv) { - struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); - - debug("spi_cs_deactivate: 0x%08x\n", (u32)slave); - writel(priv->cmd | QSPI_INVAL, &priv->base->cmd); }
-void spi_init(void) -{ - /* nothing to do */ -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) +static int __ti_qspi_set_mode(struct ti_qspi_priv *priv, 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; - - ti_spi_set_speed(&priv->slave, max_hz); - -#ifdef CONFIG_TI_SPI_MMAP - ti_spi_setup_spi_register(priv); -#endif - - return &priv->slave; -} + 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);
-void spi_free_slave(struct spi_slave *slave) -{ - struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); - free(priv); + return 0; }
-int spi_claim_bus(struct spi_slave *slave) +static int __ti_qspi_claim_bus(struct ti_qspi_priv *priv, int cs) { - struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); - - debug("spi_claim_bus: bus:%i cs:%i\n", slave->bus, slave->cs); - - priv->dc = 0; - if (priv->mode & SPI_CPHA) - priv->dc |= QSPI_CKPHA(slave->cs); - if (priv->mode & SPI_CPOL) - priv->dc |= QSPI_CKPOL(slave->cs); - if (priv->mode & SPI_CS_HIGH) - priv->dc |= QSPI_CSPOL(slave->cs); - writel(priv->dc, &priv->base->dc); writel(0, &priv->base->cmd); writel(0, &priv->base->data);
+ priv->dc <<= cs * 8; + writel(priv->dc, &priv->base->dc); return 0; }
-void spi_release_bus(struct spi_slave *slave) +static void __ti_qspi_release_bus(struct ti_qspi_priv *priv) { - struct ti_qspi_priv *priv = to_ti_qspi_priv(slave); - - debug("spi_release_bus: bus:%i cs:%i\n", slave->bus, slave->cs); - writel(0, &priv->base->dc); writel(0, &priv->base->cmd); writel(0, &priv->base->data); }
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) +static void ti_qspi_ctrl_mode_mmap(void *ctrl_mod_mmap, int cs, bool enable) +{ + u32 val; + + val = readl(ctrl_mod_mmap); + if (enable) + val |= MEM_CS(cs); + else + val &= MEM_CS_UNSELECT; + writel(val, ctrl_mod_mmap); +} + +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_priv *priv = to_ti_qspi_priv(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, &priv->base->memswitch); -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - val = readl(CORE_CTRL_IO); - val |= MEM_CS(slave->cs); - writel(val, CORE_CTRL_IO); -#endif + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, true); return 0; } else if (flags & SPI_XFER_MMAP_END) { writel(~MM_SWITCH, &priv->base->memswitch); -#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) - val = readl(CORE_CTRL_IO); - val &= MEM_CS_UNSELECT; - writel(val, CORE_CTRL_IO); -#endif + if (priv->ctrl_mod_mmap) + ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, false); return 0; }
@@ -290,7 +202,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, /* Setup command reg */ priv->cmd = 0; priv->cmd |= QSPI_WLEN(8); - priv->cmd |= QSPI_EN_CS(slave->cs); + priv->cmd |= QSPI_EN_CS(cs); if (flags & SPI_3WIRE) priv->cmd |= QSPI_3_PIN; priv->cmd |= 0xfff; @@ -345,7 +257,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 +284,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) +{ + u32 memval = 0; + +#ifdef CONFIG_QSPI_QUAD_SUPPORT + struct spi_slave *slave = &priv->slave; + 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); +}

Add new api to get device address based on index.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/core/device.c | 31 +++++++++++++++++++++++++++---- include/dm/device.h | 11 +++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/drivers/core/device.c b/drivers/core/device.c index 758f390..d3b2570 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -581,17 +581,35 @@ const char *dev_get_uclass_name(struct udevice *dev) return dev->uclass->uc_drv->name; }
-fdt_addr_t dev_get_addr(struct udevice *dev) +fdt_addr_t dev_get_addr_index(struct udevice *dev, int index) { #if CONFIG_IS_ENABLED(OF_CONTROL) fdt_addr_t addr;
if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { const fdt32_t *reg; + int len = 0; + int na, ns;
- reg = fdt_getprop(gd->fdt_blob, dev->of_offset, "reg", NULL); - if (!reg) + na = fdt_address_cells(gd->fdt_blob, dev->parent->of_offset); + if (na < 1) { + debug("bad #address-cells\n"); return FDT_ADDR_T_NONE; + } + + ns = fdt_size_cells(gd->fdt_blob, dev->parent->of_offset); + if (ns < 0) { + debug("bad #size-cells\n"); + return FDT_ADDR_T_NONE; + } + + reg = fdt_getprop(gd->fdt_blob, dev->of_offset, "reg", &len); + if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) { + debug("Req index out of range\n"); + return FDT_ADDR_T_NONE; + } + + reg += index * (na + ns);
/* * Use the full-fledged translate function for complex @@ -608,7 +626,7 @@ fdt_addr_t dev_get_addr(struct udevice *dev) addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, dev->parent->of_offset, dev->of_offset, "reg", - 0, NULL); + 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); @@ -620,6 +638,11 @@ fdt_addr_t dev_get_addr(struct udevice *dev) #endif }
+fdt_addr_t dev_get_addr(struct udevice *dev) +{ + return dev_get_addr_index(dev, 0); +} + 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 28ba4ca..7a776c9 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -454,6 +454,17 @@ int device_find_next_child(struct udevice **devp); fdt_addr_t dev_get_addr(struct udevice *dev);
/** + * dev_get_addr_index() - Get the indexed reg property of a device + * + * @dev: Pointer to a device + * @index: the 'reg' property can hold a list of <addr, size> pairs + * and @index is used to select which one is required + * + * @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

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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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 58388ef..62d8da7 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_uint(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_uint(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 b4d2723..40dbb4d 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 19 November 2015 at 12:35, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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 58388ef..62d8da7 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_uint(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_uint(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;
}
I think these are similar to SPI TX/RX operation modes in spi.h and I understand this is similar approach as with Linux but before this we need to do many changes on u-boot as well.
plat->mode = mode; return 0;
diff --git a/include/spi.h b/include/spi.h index b4d2723..40dbb4d 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 */
2.6.2.280.g74301d6
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On Thursday 03 December 2015 09:37 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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 58388ef..62d8da7 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_uint(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_uint(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;
}
I think these are similar to SPI TX/RX operation modes in spi.h and I understand this is similar approach as with Linux but before this we need to do many changes on u-boot as well.
I agree that op_mode_rx/op_mode_tx can be used. I just tried to follow Linux way of implementation to have consistency between Linux and U-Boot. If you feel that using op_mode_(rx/tx) will be the best approach, I can repost the series with the changes.
Regards Mugunthan V N

On 6 December 2015 at 11:33, Mugunthan V N mugunthanvnm@ti.com wrote:
On Thursday 03 December 2015 09:37 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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 58388ef..62d8da7 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_uint(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_uint(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;
}
I think these are similar to SPI TX/RX operation modes in spi.h and I understand this is similar approach as with Linux but before this we need to do many changes on u-boot as well.
I agree that op_mode_rx/op_mode_tx can be used. I just tried to follow Linux way of implementation to have consistency between Linux and
Agreed but the way these mode or flags handling in Linux vs u-boot is different.
U-Boot. If you feel that using op_mode_(rx/tx) will be the best approach, I can repost the series with the changes.
If this is a dependent patch wrt series pls- do otherwise bypass this with your series now once we handle these mode/flags with Linux way will add till now will mark it as "Under review" on patchwork.
thanks!

On Sunday 06 December 2015 08:13 PM, Jagan Teki wrote:
On 6 December 2015 at 11:33, Mugunthan V N mugunthanvnm@ti.com wrote:
On Thursday 03 December 2015 09:37 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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 58388ef..62d8da7 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_uint(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_uint(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;
}
I think these are similar to SPI TX/RX operation modes in spi.h and I understand this is similar approach as with Linux but before this we need to do many changes on u-boot as well.
I agree that op_mode_rx/op_mode_tx can be used. I just tried to follow Linux way of implementation to have consistency between Linux and
Agreed but the way these mode or flags handling in Linux vs u-boot is different.
U-Boot. If you feel that using op_mode_(rx/tx) will be the best approach, I can repost the series with the changes.
If this is a dependent patch wrt series pls- do otherwise bypass this with your series now once we handle these mode/flags with Linux way will add till now will mark it as "Under review" on patchwork.
08/16 patch is dependent on this patch where the mode is used to select dual/quad mode. I will respin 05 (this patch) and 08 patch as a follow-up patch.
Regards Mugunthan V N

On 8 December 2015 at 20:35, Mugunthan V N mugunthanvnm@ti.com wrote:
On Sunday 06 December 2015 08:13 PM, Jagan Teki wrote:
On 6 December 2015 at 11:33, Mugunthan V N mugunthanvnm@ti.com wrote:
On Thursday 03 December 2015 09:37 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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 58388ef..62d8da7 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_uint(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_uint(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;
}
I think these are similar to SPI TX/RX operation modes in spi.h and I understand this is similar approach as with Linux but before this we need to do many changes on u-boot as well.
I agree that op_mode_rx/op_mode_tx can be used. I just tried to follow Linux way of implementation to have consistency between Linux and
Agreed but the way these mode or flags handling in Linux vs u-boot is different.
U-Boot. If you feel that using op_mode_(rx/tx) will be the best approach, I can repost the series with the changes.
If this is a dependent patch wrt series pls- do otherwise bypass this with your series now once we handle these mode/flags with Linux way will add till now will mark it as "Under review" on patchwork.
08/16 patch is dependent on this patch where the mode is used to select dual/quad mode. I will respin 05 (this patch) and 08 patch as a follow-up patch.
Then go-ahead and reuse the existing macro's.
thanks!

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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com ---
Changes from v3->v4 * used op_mode_{t/r}x to hold flash tx/rx modes.
This has been tested on am437x-sk evm logs [1] and pushed a branch for others to test [2]
[1] - http://pastebin.ubuntu.com/14024895/ [2] - git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git dm-qspi-v4
--- drivers/spi/spi-uclass.c | 35 +++++++++++++++++++++++++++++++++++ include/spi.h | 8 ++++++++ 2 files changed, 43 insertions(+)
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index e0f6b25..3c7ca78 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -157,6 +157,8 @@ static int spi_child_pre_probe(struct udevice *dev)
slave->max_hz = plat->max_hz; slave->mode = plat->mode; + slave->op_mode_tx = plat->op_mode_tx; + slave->op_mode_rx = plat->op_mode_rx;
return 0; } @@ -369,6 +371,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); @@ -382,8 +385,40 @@ int spi_slave_ofdata_to_platdata(const void *blob, int node, mode |= SPI_3WIRE; if (fdtdec_get_bool(blob, node, "spi-half-duplex")) mode |= SPI_PREAMBLE; + plat->mode = mode;
+ /* Device DUAL/QUAD mode */ + value = fdtdec_get_uint(blob, node, "spi-tx-bus-width", 1); + switch (value) { + case 1: + break; + case 2: + plat->op_mode_tx |= SPI_OPM_TX_DUAL; + break; + case 4: + plat->op_mode_tx |= SPI_OPM_TX_QUAD; + break; + default: + error("spi-tx-bus-width %d not supported\n", value); + break; + } + + value = fdtdec_get_uint(blob, node, "spi-rx-bus-width", 1); + switch (value) { + case 1: + break; + case 2: + plat->op_mode_rx |= SPI_OPM_RX_DUAL; + break; + case 4: + plat->op_mode_rx |= SPI_OPM_RX_QUAD; + break; + default: + error("spi-rx-bus-width %d not supported\n", value); + break; + } + return 0; }
diff --git a/include/spi.h b/include/spi.h index b4d2723..090ae1f 100644 --- a/include/spi.h +++ b/include/spi.h @@ -35,6 +35,8 @@ /* SPI TX operation modes */ #define SPI_OPM_TX_QPP (1 << 0) #define SPI_OPM_TX_BP (1 << 1) +#define SPI_OPM_TX_DUAL (1 << 2) /* transmit with 2 wires */ +#define SPI_OPM_TX_QUAD (1 << 3) /* transmit with 4 wires */
/* SPI RX operation modes */ #define SPI_OPM_RX_AS (1 << 0) @@ -46,6 +48,8 @@ #define SPI_OPM_RX_EXTN (SPI_OPM_RX_AS | SPI_OPM_RX_AF | SPI_OPM_RX_DOUT | \ SPI_OPM_RX_DIO | SPI_OPM_RX_QOF | \ SPI_OPM_RX_QIOF) +#define SPI_OPM_RX_DUAL (1 << 6) /* receive with 2 wires */ +#define SPI_OPM_RX_QUAD (1 << 7) /* receive with 4 wires */
/* SPI bus connection options - see enum spi_dual_flash */ #define SPI_CONN_DUAL_SHARED (1 << 0) @@ -75,11 +79,15 @@ struct dm_spi_bus { * @cs: Chip select number (0..n-1) * @max_hz: Maximum bus speed that this slave can tolerate * @mode: SPI mode to use for this device (see SPI mode flags) + * @op_mode_rx: SPI RX operation mode. + * @op_mode_tx: SPI TX operation mode. */ struct dm_spi_slave_platdata { unsigned int cs; uint max_hz; uint mode; + u8 op_mode_rx; + u8 op_mode_tx; };
#endif /* CONFIG_DM_SPI */

On 15 December 2015 at 13:22, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com
Changes from v3->v4
- used op_mode_{t/r}x to hold flash tx/rx modes.
This has been tested on am437x-sk evm logs [1] and pushed a branch for others to test [2]
[1] - http://pastebin.ubuntu.com/14024895/ [2] - git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git dm-qspi-v4
Please rebase it on master, there is some changes regarding SPI_TX_* and also please send the whole series with next version, it easy for me to quantify all at once and pick.
thanks!

On Tuesday 15 December 2015 01:43 PM, Jagan Teki wrote:
On 15 December 2015 at 13:22, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com
Changes from v3->v4
- used op_mode_{t/r}x to hold flash tx/rx modes.
This has been tested on am437x-sk evm logs [1] and pushed a branch for others to test [2]
[1] - http://pastebin.ubuntu.com/14024895/ [2] - git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git dm-qspi-v4
Please rebase it on master, there is some changes regarding SPI_TX_* and also please send the whole series with next version, it easy for me to quantify all at once and pick.
Okay, will send v4 as a separate series. The branch which I pushed is based on u-boot/master only.
Regards Mugunthan V N

On Dec 17, 2015 12:01 PM, "Mugunthan V N" mugunthanvnm@ti.com wrote:
On Tuesday 15 December 2015 01:43 PM, Jagan Teki wrote:
On 15 December 2015 at 13:22, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com
Changes from v3->v4
- used op_mode_{t/r}x to hold flash tx/rx modes.
This has been tested on am437x-sk evm logs [1] and pushed a branch for others to test [2]
[1] - http://pastebin.ubuntu.com/14024895/ [2] - git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git
dm-qspi-v4
Please rebase it on master, there is some changes regarding SPI_TX_* and also please send the whole series with next version, it easy for me to quantify all at once and pick.
Okay, will send v4 as a separate series. The branch which I pushed is based on u-boot/master only.
Just wait will ping you back, I have some updated patches need to push.

On 17 December 2015 at 12:19, Jagan Teki jteki@openedev.com wrote:
On Dec 17, 2015 12:01 PM, "Mugunthan V N" mugunthanvnm@ti.com wrote:
On Tuesday 15 December 2015 01:43 PM, Jagan Teki wrote:
On 15 December 2015 at 13:22, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com
Changes from v3->v4
- used op_mode_{t/r}x to hold flash tx/rx modes.
This has been tested on am437x-sk evm logs [1] and pushed a branch for others to test [2]
[1] - http://pastebin.ubuntu.com/14024895/ [2] - git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git dm-qspi-v4
Please rebase it on master, there is some changes regarding SPI_TX_* and also please send the whole series with next version, it easy for me to quantify all at once and pick.
Okay, will send v4 as a separate series. The branch which I pushed is based on u-boot/master only.
Just wait will ping you back, I have some updated patches need to push.
Please use u-boot-spi/next - If possible please verify quad support I have added few changes for setting up quad bit.
thanks!

On Thursday 17 December 2015 10:10 PM, Jagan Teki wrote:
On 17 December 2015 at 12:19, Jagan Teki jteki@openedev.com wrote:
On Dec 17, 2015 12:01 PM, "Mugunthan V N" mugunthanvnm@ti.com wrote:
On Tuesday 15 December 2015 01:43 PM, Jagan Teki wrote:
On 15 December 2015 at 13:22, 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 Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com
Changes from v3->v4
- used op_mode_{t/r}x to hold flash tx/rx modes.
This has been tested on am437x-sk evm logs [1] and pushed a branch for others to test [2]
[1] - http://pastebin.ubuntu.com/14024895/ [2] - git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git dm-qspi-v4
Please rebase it on master, there is some changes regarding SPI_TX_* and also please send the whole series with next version, it easy for me to quantify all at once and pick.
Okay, will send v4 as a separate series. The branch which I pushed is based on u-boot/master only.
Just wait will ping you back, I have some updated patches need to push.
Please use u-boot-spi/next - If possible please verify quad support I have added few changes for setting up quad bit.
Will rebase to u-boot-spi/next and will submit my next version ASAP.
Regards Mugunthan V N

Since OMAP's 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 cb9544b..637ca8e 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -144,6 +144,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)

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

adopt ti_qspi driver to device driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com --- drivers/spi/ti_qspi.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index a02cb25..b5ee25b 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 @@ -48,12 +51,14 @@ #define CORE_CTRL_IO 0x4a002558
#define QSPI_CMD_READ (0x3 << 0) +#define QSPI_CMD_READ_DUAL (0x6b << 0) #define QSPI_CMD_READ_QUAD (0x6b << 0) #define QSPI_CMD_READ_FAST (0x0b << 0) #define QSPI_SETUP0_NUM_A_BYTES (0x2 << 8) #define QSPI_SETUP0_NUM_D_BYTES_NO_BITS (0x0 << 10) #define QSPI_SETUP0_NUM_D_BYTES_8_BITS (0x1 << 10) #define QSPI_SETUP0_READ_NORMAL (0x0 << 12) +#define QSPI_SETUP0_READ_DUAL (0x1 << 12) #define QSPI_SETUP0_READ_QUAD (0x3 << 12) #define QSPI_CMD_WRITE (0x2 << 16) #define QSPI_NUM_DUMMY_BITS (0x0 << 24) @@ -87,7 +92,13 @@ struct ti_qspi_regs {
/* ti qspi priv */ struct ti_qspi_priv { +#ifndef CONFIG_DM_SPI struct spi_slave slave; +#else + void *memory_map; + uint max_hz; + u32 num_cs; +#endif struct ti_qspi_regs *base; void *ctrl_mod_mmap; unsigned int mode; @@ -285,6 +296,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); @@ -398,3 +411,177 @@ 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 void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv, + struct spi_slave *slave, + bool enable) +{ + u32 memval; + u32 mode = slave->mode & (SPI_RX_QUAD | SPI_RX_DUAL); + + if (!enable) { + writel(0, &priv->base->setup0); + return; + } + + memval = QSPI_SETUP0_NUM_A_BYTES | QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS; + + switch (mode) { + case SPI_RX_QUAD: + memval |= QSPI_CMD_READ_QUAD; + memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + memval |= QSPI_SETUP0_READ_QUAD; + slave->op_mode_rx = SPI_OPM_RX_QOF; + break; + case SPI_RX_DUAL: + memval |= QSPI_CMD_READ_DUAL; + memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + memval |= QSPI_SETUP0_READ_DUAL; + break; + default: + memval |= QSPI_CMD_READ; + memval |= QSPI_SETUP0_NUM_D_BYTES_NO_BITS; + memval |= QSPI_SETUP0_READ_NORMAL; + break; + } + + writel(memval, &priv->base->setup0); +} + + +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_plat = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + if (slave_plat->cs > priv->num_cs) { + debug("invalid qspi chip select\n"); + return -EINVAL; + } + + __ti_qspi_setup_memorymap(priv, slave, true); + + return __ti_qspi_claim_bus(priv, slave_plat->cs); +} + +static int ti_qspi_release_bus(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + __ti_qspi_setup_memorymap(priv, slave, false); + __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); + + if (slave->cs > priv->num_cs) { + debug("invalid qspi chip select\n"); + return -EINVAL; + } + + 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; + fdt_addr_t addr; + + priv->base = (struct ti_qspi_regs *)dev_get_addr(bus); + priv->memory_map = (void *)dev_get_addr_index(bus, 1); + addr = dev_get_addr_index(bus, 2); + priv->ctrl_mod_mmap = (addr == FDT_ADDR_T_NONE) ? NULL : (void *)addr; + + priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1); + if (priv->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\n", __func__, + (int)priv->base, priv->max_hz); + + return 0; +} + +static int ti_qspi_child_pre_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + struct udevice *bus = dev_get_parent(dev); + struct ti_qspi_priv *priv = dev_get_priv(bus); + + slave->memory_map = priv->memory_map; + 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, + .child_pre_probe = ti_qspi_child_pre_probe, +}; +#endif /* CONFIG_DM_SPI */

adopt ti_qspi driver to device driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.com ---
Changes from v3->v4: * Use op_mode_{t/r}x for flash tx/rx operation modes.
This has been tested on am437x-sk evm logs [1] and pushed a branch for others to test [2]
[1] - http://pastebin.ubuntu.com/14024895/ [2] - git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git dm-qspi-v4
--- drivers/spi/ti_qspi.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+)
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index 41add38..5bacd7a 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 @@ -48,12 +51,14 @@ #define CORE_CTRL_IO 0x4a002558
#define QSPI_CMD_READ (0x3 << 0) +#define QSPI_CMD_READ_DUAL (0x6b << 0) #define QSPI_CMD_READ_QUAD (0x6b << 0) #define QSPI_CMD_READ_FAST (0x0b << 0) #define QSPI_SETUP0_NUM_A_BYTES (0x2 << 8) #define QSPI_SETUP0_NUM_D_BYTES_NO_BITS (0x0 << 10) #define QSPI_SETUP0_NUM_D_BYTES_8_BITS (0x1 << 10) #define QSPI_SETUP0_READ_NORMAL (0x0 << 12) +#define QSPI_SETUP0_READ_DUAL (0x1 << 12) #define QSPI_SETUP0_READ_QUAD (0x3 << 12) #define QSPI_CMD_WRITE (0x2 << 16) #define QSPI_NUM_DUMMY_BITS (0x0 << 24) @@ -87,7 +92,13 @@ struct ti_qspi_regs {
/* ti qspi priv */ struct ti_qspi_priv { +#ifndef CONFIG_DM_SPI struct spi_slave slave; +#else + void *memory_map; + uint max_hz; + u32 num_cs; +#endif struct ti_qspi_regs *base; void *ctrl_mod_mmap; unsigned int mode; @@ -288,6 +299,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); @@ -401,3 +414,177 @@ 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 void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv, + struct spi_slave *slave, + bool enable) +{ + u32 memval; + u32 mode = slave->op_mode_rx & (SPI_OPM_RX_QUAD | SPI_OPM_RX_DUAL); + + if (!enable) { + writel(0, &priv->base->setup0); + return; + } + + memval = QSPI_SETUP0_NUM_A_BYTES | QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS; + + switch (mode) { + case SPI_OPM_RX_QUAD: + memval |= QSPI_CMD_READ_QUAD; + memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + memval |= QSPI_SETUP0_READ_QUAD; + slave->op_mode_rx = SPI_OPM_RX_QOF; + break; + case SPI_OPM_RX_DUAL: + memval |= QSPI_CMD_READ_DUAL; + memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS; + memval |= QSPI_SETUP0_READ_DUAL; + break; + default: + memval |= QSPI_CMD_READ; + memval |= QSPI_SETUP0_NUM_D_BYTES_NO_BITS; + memval |= QSPI_SETUP0_READ_NORMAL; + break; + } + + writel(memval, &priv->base->setup0); +} + + +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_plat = dev_get_parent_platdata(dev); + struct spi_slave *slave = dev_get_parent_priv(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + if (slave_plat->cs > priv->num_cs) { + debug("invalid qspi chip select\n"); + return -EINVAL; + } + + __ti_qspi_setup_memorymap(priv, slave, true); + + return __ti_qspi_claim_bus(priv, slave_plat->cs); +} + +static int ti_qspi_release_bus(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + struct ti_qspi_priv *priv; + struct udevice *bus; + + bus = dev->parent; + priv = dev_get_priv(bus); + + __ti_qspi_setup_memorymap(priv, slave, false); + __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); + + if (slave->cs > priv->num_cs) { + debug("invalid qspi chip select\n"); + return -EINVAL; + } + + 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; + fdt_addr_t addr; + + priv->base = (struct ti_qspi_regs *)dev_get_addr(bus); + priv->memory_map = (void *)dev_get_addr_index(bus, 1); + addr = dev_get_addr_index(bus, 2); + priv->ctrl_mod_mmap = (addr == FDT_ADDR_T_NONE) ? NULL : (void *)addr; + + priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1); + if (priv->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\n", __func__, + (int)priv->base, priv->max_hz); + + return 0; +} + +static int ti_qspi_child_pre_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + struct udevice *bus = dev_get_parent(dev); + struct ti_qspi_priv *priv = dev_get_priv(bus); + + slave->memory_map = priv->memory_map; + 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, + .child_pre_probe = ti_qspi_child_pre_probe, +}; +#endif /* CONFIG_DM_SPI */

Add qspi memory map and control module register maps to device tree.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org --- arch/arm/dts/dra7.dtsi | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm/dts/dra7.dtsi b/arch/arm/dts/dra7.dtsi index 3060e9a..254c5e2 100644 --- a/arch/arm/dts/dra7.dtsi +++ b/arch/arm/dts/dra7.dtsi @@ -1104,8 +1104,11 @@
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";

Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" }, + { .compatible = "s25fl256s1" }, { } };

On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote:
Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" },
{ .compatible = "s25fl256s1" }, { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'

Jagan
On Thursday 19 November 2015 03:40 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote:
Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" },
{ .compatible = "s25fl256s1" }, { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'
I agree that spi flash will be probed even without addition of compatibles.
If there is no matching compatible between the dtb and driver, the dt properties like spi-max-frequency, spi clock phase/polarity and spi bus-width are not parsed from DT as the of_offset of the spi device will be '-1'. This check and dt parse is done in spi_child_post_bind() in spi-uclass driver.
Since spi bus-width is not read from DT, by default spi transfers are done in one wire mode and read throughput drops to 5.3Mbps. With Quad mode read throughput is 16.6Mbps in DRA74x EVM.
Adding spi-splash to DT is not possible now as it is not documented in Kernel binding documentation. Even if "spi-flash" compatible is added to u-boot DT then it will show diff when syncing the dts files from Kernel to U-boot and it has to be taken care for every sync. Tom Rini also has agreed to this [1].
[1]: http://patchwork.ozlabs.org/patch/539780/
Regards Mugunthan V N

On 20 November 2015 at 11:31, Mugunthan V N mugunthanvnm@ti.com wrote:
Jagan
On Thursday 19 November 2015 03:40 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote:
Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" },
{ .compatible = "s25fl256s1" }, { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'
I agree that spi flash will be probed even without addition of compatibles.
If there is no matching compatible between the dtb and driver, the dt properties like spi-max-frequency, spi clock phase/polarity and spi bus-width are not parsed from DT as the of_offset of the spi device will be '-1'. This check and dt parse is done in spi_child_post_bind() in spi-uclass driver.
Since spi bus-width is not read from DT, by default spi transfers are done in one wire mode and read throughput drops to 5.3Mbps. With Quad mode read throughput is 16.6Mbps in DRA74x EVM.
Why can't we try something like this [1] [2] I do agree with documentation missing, may be we add add that well.
[1] arch/arm/dts/socfpga_cyclone5_sockit.dts [2] arch/arm/dts/zynqmp-ep108.dts
Adding spi-splash to DT is not possible now as it is not documented in Kernel binding documentation. Even if "spi-flash" compatible is added to u-boot DT then it will show diff when syncing the dts files from Kernel to U-boot and it has to be taken care for every sync. Tom Rini also has agreed to this [1].

On Friday 20 November 2015 05:57 PM, Jagan Teki wrote:
On 20 November 2015 at 11:31, Mugunthan V N mugunthanvnm@ti.com wrote:
Jagan
On Thursday 19 November 2015 03:40 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote:
Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" },
{ .compatible = "s25fl256s1" }, { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'
I agree that spi flash will be probed even without addition of compatibles.
If there is no matching compatible between the dtb and driver, the dt properties like spi-max-frequency, spi clock phase/polarity and spi bus-width are not parsed from DT as the of_offset of the spi device will be '-1'. This check and dt parse is done in spi_child_post_bind() in spi-uclass driver.
Since spi bus-width is not read from DT, by default spi transfers are done in one wire mode and read throughput drops to 5.3Mbps. With Quad mode read throughput is 16.6Mbps in DRA74x EVM.
Why can't we try something like this [1] [2] I do agree with documentation missing, may be we add add that well.
[1] arch/arm/dts/socfpga_cyclone5_sockit.dts
This dts file is not in sync with kernel dts. There is no qspi support in kernel. It is going to be really tough time to sync this dts between kernel and u-boot ;)
[2] arch/arm/dts/zynqmp-ep108.dts
I don't see compatible string "spi-flash" in zynqmp-ep108.dts
Adding spi-flash compatible will be tough as spi-flash works with the existing compatibles and convincing spi maintainer (Mark Brown) for adding a generic compatible will be difficult.
If you still insist to add spi-flash compatible to the dts file and *Tom Rini* is also fine, I will re-spin the series with compatible changes to the dts files.
Regards Mugunthan V N

On 23 November 2015 at 16:59, Mugunthan V N mugunthanvnm@ti.com wrote:
On Friday 20 November 2015 05:57 PM, Jagan Teki wrote:
On 20 November 2015 at 11:31, Mugunthan V N mugunthanvnm@ti.com wrote:
Jagan
On Thursday 19 November 2015 03:40 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote:
Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" },
{ .compatible = "s25fl256s1" }, { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'
I agree that spi flash will be probed even without addition of compatibles.
If there is no matching compatible between the dtb and driver, the dt properties like spi-max-frequency, spi clock phase/polarity and spi bus-width are not parsed from DT as the of_offset of the spi device will be '-1'. This check and dt parse is done in spi_child_post_bind() in spi-uclass driver.
Since spi bus-width is not read from DT, by default spi transfers are done in one wire mode and read throughput drops to 5.3Mbps. With Quad mode read throughput is 16.6Mbps in DRA74x EVM.
Why can't we try something like this [1] [2] I do agree with documentation missing, may be we add add that well.
[1] arch/arm/dts/socfpga_cyclone5_sockit.dts
This dts file is not in sync with kernel dts. There is no qspi support in kernel. It is going to be really tough time to sync this dts between kernel and u-boot ;)
Since we are in starting point of adding dts files (unlike Linux) these dts files may not sync with Linux, we started adding these to make dm or related drivers need to work. Yes I agreed with your point and we really need to work on that as well.
[2] arch/arm/dts/zynqmp-ep108.dts
I don't see compatible string "spi-flash" in zynqmp-ep108.dts
Yes, cant you add "s25fl256s1" like n25q512a11 added in this dts.
Adding spi-flash compatible will be tough as spi-flash works with the existing compatibles and convincing spi maintainer (Mark Brown) for adding a generic compatible will be difficult.
This is what you pointed out - id_table.
static struct spi_driver m25p80_driver = { .driver = { .name = "m25p80", .of_match_table = m25p_of_table, }, .id_table = m25p_ids,
If you still insist to add spi-flash compatible to the dts file and *Tom Rini* is also fine, I will re-spin the series with compatible changes to the dts files.
I'm saying like s25fl256s1 few of compatible strings were added already on existing dts files, probably we may proceed with the same for now. will trimming up later.
thanks!

Hi Mugunthan,
On 23 November 2015 at 18:42, Jagan Teki jteki@openedev.com wrote:
On 23 November 2015 at 16:59, Mugunthan V N mugunthanvnm@ti.com wrote:
On Friday 20 November 2015 05:57 PM, Jagan Teki wrote:
On 20 November 2015 at 11:31, Mugunthan V N mugunthanvnm@ti.com wrote:
Jagan
On Thursday 19 November 2015 03:40 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote:
Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" },
{ .compatible = "s25fl256s1" }, { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'
I agree that spi flash will be probed even without addition of compatibles.
If there is no matching compatible between the dtb and driver, the dt properties like spi-max-frequency, spi clock phase/polarity and spi bus-width are not parsed from DT as the of_offset of the spi device will be '-1'. This check and dt parse is done in spi_child_post_bind() in spi-uclass driver.
Since spi bus-width is not read from DT, by default spi transfers are done in one wire mode and read throughput drops to 5.3Mbps. With Quad mode read throughput is 16.6Mbps in DRA74x EVM.
Why can't we try something like this [1] [2] I do agree with documentation missing, may be we add add that well.
[1] arch/arm/dts/socfpga_cyclone5_sockit.dts
This dts file is not in sync with kernel dts. There is no qspi support in kernel. It is going to be really tough time to sync this dts between kernel and u-boot ;)
Since we are in starting point of adding dts files (unlike Linux) these dts files may not sync with Linux, we started adding these to make dm or related drivers need to work. Yes I agreed with your point and we really need to work on that as well.
[2] arch/arm/dts/zynqmp-ep108.dts
I don't see compatible string "spi-flash" in zynqmp-ep108.dts
Yes, cant you add "s25fl256s1" like n25q512a11 added in this dts.
Adding spi-flash compatible will be tough as spi-flash works with the existing compatibles and convincing spi maintainer (Mark Brown) for adding a generic compatible will be difficult.
This is what you pointed out - id_table.
static struct spi_driver m25p80_driver = { .driver = { .name = "m25p80", .of_match_table = m25p_of_table, }, .id_table = m25p_ids,
Comments?
If you still insist to add spi-flash compatible to the dts file and *Tom Rini* is also fine, I will re-spin the series with compatible changes to the dts files.
I'm saying like s25fl256s1 few of compatible strings were added already on existing dts files, probably we may proceed with the same for now. will trimming up later.
Any comments? proceed with above suggestion.
thanks!

On Thursday 03 December 2015 09:32 PM, Jagan Teki wrote:
Hi Mugunthan,
On 23 November 2015 at 18:42, Jagan Teki jteki@openedev.com wrote:
On 23 November 2015 at 16:59, Mugunthan V N mugunthanvnm@ti.com wrote:
On Friday 20 November 2015 05:57 PM, Jagan Teki wrote:
On 20 November 2015 at 11:31, Mugunthan V N mugunthanvnm@ti.com wrote:
Jagan
On Thursday 19 November 2015 03:40 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote: > Add compatible for spansion 32MiB spi flash s25fl256s1. > > Signed-off-by: Mugunthan V N mugunthanvnm@ti.com > --- > drivers/mtd/spi/sf_probe.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c > index bc05d30..ffbce59 100644 > --- a/drivers/mtd/spi/sf_probe.c > +++ b/drivers/mtd/spi/sf_probe.c > @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = { > > static const struct udevice_id spi_flash_std_ids[] = { > { .compatible = "spi-flash" }, > + { .compatible = "s25fl256s1" }, > { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'
I agree that spi flash will be probed even without addition of compatibles.
If there is no matching compatible between the dtb and driver, the dt properties like spi-max-frequency, spi clock phase/polarity and spi bus-width are not parsed from DT as the of_offset of the spi device will be '-1'. This check and dt parse is done in spi_child_post_bind() in spi-uclass driver.
Since spi bus-width is not read from DT, by default spi transfers are done in one wire mode and read throughput drops to 5.3Mbps. With Quad mode read throughput is 16.6Mbps in DRA74x EVM.
Why can't we try something like this [1] [2] I do agree with documentation missing, may be we add add that well.
[1] arch/arm/dts/socfpga_cyclone5_sockit.dts
This dts file is not in sync with kernel dts. There is no qspi support in kernel. It is going to be really tough time to sync this dts between kernel and u-boot ;)
Since we are in starting point of adding dts files (unlike Linux) these dts files may not sync with Linux, we started adding these to make dm or related drivers need to work. Yes I agreed with your point and we really need to work on that as well.
[2] arch/arm/dts/zynqmp-ep108.dts
I don't see compatible string "spi-flash" in zynqmp-ep108.dts
Yes, cant you add "s25fl256s1" like n25q512a11 added in this dts.
Adding spi-flash compatible will be tough as spi-flash works with the existing compatibles and convincing spi maintainer (Mark Brown) for adding a generic compatible will be difficult.
This is what you pointed out - id_table.
static struct spi_driver m25p80_driver = { .driver = { .name = "m25p80", .of_match_table = m25p_of_table, }, .id_table = m25p_ids,
Comments?
Yes, I was pointing to this compatible only.
If you still insist to add spi-flash compatible to the dts file and *Tom Rini* is also fine, I will re-spin the series with compatible changes to the dts files.
I'm saying like s25fl256s1 few of compatible strings were added already on existing dts files, probably we may proceed with the same for now. will trimming up later.
Any comments? proceed with above suggestion.
I agree, we can add compatibles, if needed we can work on trimming it later.
Regards Mugunthan V N

On Mon, Nov 23, 2015 at 04:59:12PM +0530, Mugunthan V N wrote:
On Friday 20 November 2015 05:57 PM, Jagan Teki wrote:
On 20 November 2015 at 11:31, Mugunthan V N mugunthanvnm@ti.com wrote:
Jagan
On Thursday 19 November 2015 03:40 PM, Jagan Teki wrote:
On 19 November 2015 at 12:35, Mugunthan V N mugunthanvnm@ti.com wrote:
Add compatible for spansion 32MiB spi flash s25fl256s1.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com
drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index bc05d30..ffbce59 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -515,6 +515,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = {
static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" },
{ .compatible = "s25fl256s1" }, { }
Never compare with spi-flash vs s25fl256s1 here former is driver compatible string and later one is probed flash string name. we don't need to add them in compatible list, better to add it on dts node otherwise no issue the connected flash will detect while 'sf probe'
I agree that spi flash will be probed even without addition of compatibles.
If there is no matching compatible between the dtb and driver, the dt properties like spi-max-frequency, spi clock phase/polarity and spi bus-width are not parsed from DT as the of_offset of the spi device will be '-1'. This check and dt parse is done in spi_child_post_bind() in spi-uclass driver.
Since spi bus-width is not read from DT, by default spi transfers are done in one wire mode and read throughput drops to 5.3Mbps. With Quad mode read throughput is 16.6Mbps in DRA74x EVM.
Why can't we try something like this [1] [2] I do agree with documentation missing, may be we add add that well.
[1] arch/arm/dts/socfpga_cyclone5_sockit.dts
This dts file is not in sync with kernel dts. There is no qspi support in kernel. It is going to be really tough time to sync this dts between kernel and u-boot ;)
True, but you're pushing that too, right? I suppose the high level take-away here is that when you're posting the bindings for Linux you need to keep some of the U-Boot folks in CC as well. So first up, where / how far along is the kernel support today?

Add compatible for Macronix 64MiB spi flash mx66l51235l.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com --- drivers/mtd/spi/sf_probe.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index ffbce59..add6738 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -516,6 +516,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = { static const struct udevice_id spi_flash_std_ids[] = { { .compatible = "spi-flash" }, { .compatible = "s25fl256s1" }, + { .compatible = "mx66l51235l" }, { } };

enable mmc driver model for dra72_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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

enable spi driver model for dra74_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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

Since OMAP's 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 b02abd3..ebade04 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

On Thu, Nov 19, 2015 at 12:35:43PM +0530, Mugunthan V N wrote:
Since OMAP's 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
This should go in with everything else in the series so:
Reviewed-by: Tom Rini trini@konsulko.com

Add qspi memory map address to device tree.
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org --- arch/arm/dts/am4372.dtsi | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/am4372.dtsi b/arch/arm/dts/am4372.dtsi index ade28c7..eb0995d 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,9 @@
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";

enable spi driver model for am437x_sk_evm as ti_qspi supports driver model
Signed-off-by: Mugunthan V N mugunthanvnm@ti.com Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Tom Rini trini@konsulko.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

Jagan
On Thursday 19 November 2015 12:35 PM, Mugunthan V N wrote:
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]
[2]: git://git.ti.com/~mugunthanvnm/ti-u-boot/mugunth-ti-u-boot.git qspi-v3
Gentle ping...
Are you Okay with the series to be applied?
Regards Mugunthan V N
participants (3)
-
Jagan Teki
-
Mugunthan V N
-
Tom Rini