[U-Boot] [PATCH v2 00/12] ARM: Keystone2: Convert davinci_spi to DM

This series converts davinci_spi driver to adapt to driver model framework. And enables the driver on k2l, k2e, k2hk evms. Also, added support for davinci_spi on k2g evm.
Tested on k2l, k2e, k2hk and k2g evms.
v1: http://comments.gmane.org/gmane.comp.boot-loaders.u-boot/258285
Vignesh R (12): dm: core: implement dev_map_phsymem() spi: davinci_spi: Convert to driver to adapt to DM keystone2: spi: do not define DM_SPI and DM_SPI_FLASH for SPL build ARM: dts: keystone2: add SPI aliases for davinci SPI nodes ARM: dts: k2hk: Enable Davinci SPI controller defconfig: k2hk_evm_defconfig: enable SPI driver model ARM: dts: k2e: Enable Davinci SPI controller defconfig: k2e_evm_defconfig: enable SPI driver model ARM: dts: k2l: Enable Davinci SPI controller defconfig: k2l_evm_defconfig: enable SPI driver model ARM: dts: k2g: add support for Davinci SPI controller defconfig: k2g_evm_defconfig: enable SPI driver model
arch/arm/dts/k2e-evm.dts | 3 +- arch/arm/dts/k2g-evm.dts | 24 +++ arch/arm/dts/k2g.dtsi | 47 +++++ arch/arm/dts/k2hk-evm.dts | 3 +- arch/arm/dts/k2l-evm.dts | 3 +- arch/arm/dts/keystone.dtsi | 3 + configs/k2e_evm_defconfig | 2 + configs/k2g_evm_defconfig | 2 + configs/k2hk_evm_defconfig | 2 + configs/k2l_evm_defconfig | 2 + drivers/core/device.c | 5 + drivers/spi/davinci_spi.c | 327 +++++++++++++++++++++++++---------- include/configs/ti_armv7_keystone2.h | 4 + include/dm/device.h | 10 ++ 14 files changed, 344 insertions(+), 93 deletions(-)

This API helps to map physical register addresss pace of device to virtual address space easily. Its just a wrapper around map_physmem() with MAP_NOCACHE flag.
Signed-off-by: Vignesh R vigneshr@ti.com Suggested-by: Simon Glass sjg@chromium.org ---
v2: New patch
drivers/core/device.c | 5 +++++ include/dm/device.h | 10 ++++++++++ 2 files changed, 15 insertions(+)
diff --git a/drivers/core/device.c b/drivers/core/device.c index 269087a084cf..61af70efcef7 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -673,6 +673,11 @@ fdt_addr_t dev_get_addr(struct udevice *dev) return dev_get_addr_index(dev, 0); }
+void *dev_map_physmem(struct udevice *dev, unsigned long size) +{ + return map_physmem(dev_get_addr(dev), size, MAP_NOCACHE); +} + 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 dad7591dfacb..0d3e3ed34870 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -454,6 +454,16 @@ int device_find_next_child(struct udevice **devp); fdt_addr_t dev_get_addr(struct udevice *dev);
/** + * dev_map_physmem() - Map bus memory into CPU space + * + * @dev: Pointer to device + * @size: size of the memory to map + * + * @return addr + */ +void *dev_map_physmem(struct udevice *dev, unsigned long size); + +/** * dev_get_addr_index() - Get the indexed reg property of a device * * @dev: Pointer to a device

Convert davinci_spi driver so that it complies with SPI DM framework.
Signed-off-by: Vignesh R vigneshr@ti.com ---
v2: Add comments to struct davinci_spi_slave members. Use dev_map_physmem() added by previous patch.
drivers/spi/davinci_spi.c | 327 +++++++++++++++++++++++++++++++++------------- 1 file changed, 237 insertions(+), 90 deletions(-)
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 0bd4f88926f1..75c8681d4e93 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -14,6 +14,7 @@ #include <malloc.h> #include <asm/io.h> #include <asm/arch/hardware.h> +#include <dm.h>
/* SPIGCR0 */ #define SPIGCR0_SPIENA_MASK 0x1 @@ -51,6 +52,7 @@ /* SPIDEF */ #define SPIDEF_CSDEF0_MASK BIT(0)
+#ifndef CONFIG_DM_SPI #define SPI0_BUS 0 #define SPI0_BASE CONFIG_SYS_SPI_BASE /* @@ -83,6 +85,9 @@ #define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS #define SPI2_BASE CONFIG_SYS_SPI2_BASE #endif +#endif + +DECLARE_GLOBAL_DATA_PTR;
/* davinci spi register set */ struct davinci_spi_regs { @@ -114,16 +119,17 @@ struct davinci_spi_regs {
/* davinci spi slave */ struct davinci_spi_slave { +#ifndef CONFIG_DM_SPI struct spi_slave slave; +#endif struct davinci_spi_regs *regs; - unsigned int freq; + unsigned int freq; /* current SPI bus frequency */ + unsigned int mode; /* current SPI mode used */ + u8 num_cs; /* total no. of CS available */ + u8 cur_cs; /* CS of current slave */ + bool half_duplex; /* true, if master is half-duplex only */ };
-static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave) -{ - return container_of(slave, struct davinci_spi_slave, slave); -} - /* * This functions needs to act like a macro to avoid pipeline reloads in the * loops below. Use always_inline. This gains us about 160KiB/s and the bloat @@ -144,15 +150,14 @@ static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data) return buf_reg_val; }
-static int davinci_spi_read(struct spi_slave *slave, unsigned int len, +static int davinci_spi_read(struct davinci_spi_slave *ds, unsigned int len, u8 *rxp, unsigned long flags) { - struct davinci_spi_slave *ds = to_davinci_spi(slave); unsigned int data1_reg_val;
/* enable CS hold, CS[n] and clear the data bits */ data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) | - (slave->cs << SPIDAT1_CSNR_SHIFT)); + (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
/* wait till TXFULL is deasserted */ while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK) @@ -175,15 +180,14 @@ static int davinci_spi_read(struct spi_slave *slave, unsigned int len, return 0; }
-static int davinci_spi_write(struct spi_slave *slave, unsigned int len, +static int davinci_spi_write(struct davinci_spi_slave *ds, unsigned int len, const u8 *txp, unsigned long flags) { - struct davinci_spi_slave *ds = to_davinci_spi(slave); unsigned int data1_reg_val;
/* enable CS hold and clear the data bits */ data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) | - (slave->cs << SPIDAT1_CSNR_SHIFT)); + (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
/* wait till TXFULL is deasserted */ while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK) @@ -209,16 +213,15 @@ static int davinci_spi_write(struct spi_slave *slave, unsigned int len, return 0; }
-#ifndef CONFIG_SPI_HALF_DUPLEX -static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len, - u8 *rxp, const u8 *txp, unsigned long flags) +static int davinci_spi_read_write(struct davinci_spi_slave *ds, unsigned + int len, u8 *rxp, const u8 *txp, + unsigned long flags) { - struct davinci_spi_slave *ds = to_davinci_spi(slave); unsigned int data1_reg_val;
/* enable CS hold and clear the data bits */ data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) | - (slave->cs << SPIDAT1_CSNR_SHIFT)); + (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
/* wait till TXFULL is deasserted */ while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK) @@ -237,7 +240,115 @@ static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
return 0; } -#endif + + +static int __davinci_spi_claim_bus(struct davinci_spi_slave *ds, int cs) +{ + unsigned int mode = 0, scalar; + + /* Enable the SPI hardware */ + writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); + udelay(1000); + writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0); + + /* Set master mode, powered up and not activated */ + writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1); + + /* CS, CLK, SIMO and SOMI are functional pins */ + writel(((1 << cs) | SPIPC0_CLKFUN_MASK | + SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0); + + /* setup format */ + scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF; + + /* + * Use following format: + * character length = 8, + * MSB shifted out first + */ + if (ds->mode & SPI_CPOL) + mode |= SPI_CPOL; + if (!(ds->mode & SPI_CPHA)) + mode |= SPI_CPHA; + writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) | + (mode << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0); + + /* + * Including a minor delay. No science here. Should be good even with + * no delay + */ + writel((50 << SPI_C2TDELAY_SHIFT) | + (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay); + + /* default chip select register */ + writel(SPIDEF_CSDEF0_MASK, &ds->regs->def); + + /* no interrupts */ + writel(0, &ds->regs->int0); + writel(0, &ds->regs->lvl); + + /* enable SPI */ + writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1); + + return 0; +} + +static int __davinci_spi_release_bus(struct davinci_spi_slave *ds) +{ + /* Disable the SPI hardware */ + writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); + + return 0; +} + +static int __davinci_spi_xfer(struct davinci_spi_slave *ds, + unsigned int bitlen, const void *dout, void *din, + unsigned long flags) +{ + unsigned int len; + + if (bitlen == 0) + /* Finish any previously submitted transfers */ + goto out; + + /* + * It's not clear how non-8-bit-aligned transfers are supposed to be + * represented as a stream of bytes...this is a limitation of + * the current SPI interface - here we terminate on receiving such a + * transfer request. + */ + if (bitlen % 8) { + /* Errors always terminate an ongoing transfer */ + flags |= SPI_XFER_END; + goto out; + } + + len = bitlen / 8; + + if (!dout) + return davinci_spi_read(ds, len, din, flags); + if (!din) + return davinci_spi_write(ds, len, dout, flags); + if (!ds->half_duplex) + return davinci_spi_read_write(ds, len, din, dout, flags); + + printf("SPI full duplex not supported\n"); + flags |= SPI_XFER_END; + +out: + if (flags & SPI_XFER_END) { + u8 dummy = 0; + davinci_spi_write(ds, 1, &dummy, flags); + } + return 0; +} + +#ifndef CONFIG_DM_SPI + +static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave) +{ + return container_of(slave, struct davinci_spi_slave, slave); +}
int spi_cs_is_valid(unsigned int bus, unsigned int cs) { @@ -313,6 +424,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, }
ds->freq = max_hz; + ds->mode = mode;
return &ds->slave; } @@ -324,104 +436,139 @@ void spi_free_slave(struct spi_slave *slave) free(ds); }
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + + ds->cur_cs = slave->cs; + + return __davinci_spi_xfer(ds, bitlen, dout, din, flags); +} + int spi_claim_bus(struct spi_slave *slave) { struct davinci_spi_slave *ds = to_davinci_spi(slave); - unsigned int scalar;
- /* Enable the SPI hardware */ - writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); - udelay(1000); - writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0); +#ifdef CONFIG_SPI_HALF_DUPLEX + ds->half_duplex = true; +#else + ds->half_duplex = false; +#endif + return __davinci_spi_claim_bus(ds, ds->slave.cs); +}
- /* Set master mode, powered up and not activated */ - writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1); +void spi_release_bus(struct spi_slave *slave) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave);
- /* CS, CLK, SIMO and SOMI are functional pins */ - writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK | - SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0); + __davinci_spi_release_bus(ds); +}
- /* setup format */ - scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF; +#else +static int davinci_spi_set_speed(struct udevice *bus, uint max_hz) +{ + struct davinci_spi_slave *ds = dev_get_priv(bus);
- /* - * Use following format: - * character length = 8, - * clock signal delayed by half clk cycle, - * clock low in idle state - Mode 0, - * MSB shifted out first - */ - writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) | - (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0); + debug("%s speed %u\n", __func__, max_hz); + if (max_hz > CONFIG_SYS_SPI_CLK / 2) + return -EINVAL;
- /* - * Including a minor delay. No science here. Should be good even with - * no delay - */ - writel((50 << SPI_C2TDELAY_SHIFT) | - (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay); + ds->freq = max_hz;
- /* default chip select register */ - writel(SPIDEF_CSDEF0_MASK, &ds->regs->def); + return 0; +}
- /* no interrupts */ - writel(0, &ds->regs->int0); - writel(0, &ds->regs->lvl); +static int davinci_spi_set_mode(struct udevice *bus, uint mode) +{ + struct davinci_spi_slave *ds = dev_get_priv(bus);
- /* enable SPI */ - writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1); + debug("%s mode %u\n", __func__, mode); + ds->mode = mode;
return 0; }
-void spi_release_bus(struct spi_slave *slave) +static int davinci_spi_claim_bus(struct udevice *dev) { - struct davinci_spi_slave *ds = to_davinci_spi(slave); + struct dm_spi_slave_platdata *slave_plat = + dev_get_parent_platdata(dev); + struct udevice *bus = dev->parent; + struct davinci_spi_slave *ds = dev_get_priv(bus); + + if (slave_plat->cs >= ds->num_cs) { + printf("Invalid SPI chipselect\n"); + return -EINVAL; + } + ds->half_duplex = slave_plat->mode & SPI_PREAMBLE;
- /* Disable the SPI hardware */ - writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); + return __davinci_spi_claim_bus(ds, slave_plat->cs); }
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) +static int davinci_spi_release_bus(struct udevice *dev) { - unsigned int len; + struct davinci_spi_slave *ds = dev_get_priv(dev->parent);
- if (bitlen == 0) - /* Finish any previously submitted transfers */ - goto out; + return __davinci_spi_release_bus(ds); +}
- /* - * It's not clear how non-8-bit-aligned transfers are supposed to be - * represented as a stream of bytes...this is a limitation of - * the current SPI interface - here we terminate on receiving such a - * transfer request. - */ - if (bitlen % 8) { - /* Errors always terminate an ongoing transfer */ - flags |= SPI_XFER_END; - goto out; +static int davinci_spi_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 udevice *bus = dev->parent; + struct davinci_spi_slave *ds = dev_get_priv(bus); + + if (slave->cs >= ds->num_cs) { + printf("Invalid SPI chipselect\n"); + return -EINVAL; } + ds->cur_cs = slave->cs;
- len = bitlen / 8; + return __davinci_spi_xfer(ds, bitlen, dout, din, flags); +}
- if (!dout) - return davinci_spi_read(slave, len, din, flags); - else if (!din) - return davinci_spi_write(slave, len, dout, flags); -#ifndef CONFIG_SPI_HALF_DUPLEX - else - return davinci_spi_read_write(slave, len, din, dout, flags); -#else - printf("SPI full duplex transaction requested with " - "CONFIG_SPI_HALF_DUPLEX defined.\n"); - flags |= SPI_XFER_END; -#endif +static int davinci_spi_probe(struct udevice *bus) +{ + /* Nothing to do */ + return 0; +} + +static int davinci_ofdata_to_platadata(struct udevice *bus) +{ + struct davinci_spi_slave *ds = dev_get_priv(bus); + const void *blob = gd->fdt_blob; + int node = bus->of_offset; + + ds->regs = dev_map_physmem(bus, sizeof(struct davinci_spi_regs)); + ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
-out: - if (flags & SPI_XFER_END) { - u8 dummy = 0; - davinci_spi_write(slave, 1, &dummy, flags); - } return 0; } + +static const struct dm_spi_ops davinci_spi_ops = { + .claim_bus = davinci_spi_claim_bus, + .release_bus = davinci_spi_release_bus, + .xfer = davinci_spi_xfer, + .set_speed = davinci_spi_set_speed, + .set_mode = davinci_spi_set_mode, +}; + +static const struct udevice_id davinci_spi_ids[] = { + { .compatible = "ti,keystone-spi" }, + { .compatible = "ti,dm6441-spi" }, + { } +}; + +U_BOOT_DRIVER(davinci_spi) = { + .name = "davinci_spi", + .id = UCLASS_SPI, + .of_match = davinci_spi_ids, + .ops = &davinci_spi_ops, + .ofdata_to_platdata = davinci_ofdata_to_platadata, + .priv_auto_alloc_size = sizeof(struct davinci_spi_slave), + .probe = davinci_spi_probe, +}; +#endif

Since Keystone2 devices do not have support DM in SPL, do not define DM_SPI and DM_SPI_FLASH for SPL build.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- include/configs/ti_armv7_keystone2.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/configs/ti_armv7_keystone2.h b/include/configs/ti_armv7_keystone2.h index be3c29955f20..474f61a619fc 100644 --- a/include/configs/ti_armv7_keystone2.h +++ b/include/configs/ti_armv7_keystone2.h @@ -89,6 +89,10 @@ #define CONFIG_SYS_SPI2 #define CONFIG_SYS_SPI2_BASE KS2_SPI2_BASE #define CONFIG_SYS_SPI2_NUM_CS 4 +#ifdef CONFIG_SPL_BUILD +#undef CONFIG_DM_SPI +#undef CONFIG_DM_SPI_FLASH +#endif
/* Network Configuration */ #define CONFIG_PHYLIB

Add aliases for SPI nodes in order for it to be probed by the DM framework.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- arch/arm/dts/keystone.dtsi | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm/dts/keystone.dtsi b/arch/arm/dts/keystone.dtsi index f39b969f8d43..be97f3f21f92 100644 --- a/arch/arm/dts/keystone.dtsi +++ b/arch/arm/dts/keystone.dtsi @@ -19,6 +19,9 @@
aliases { serial0 = &uart0; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &spi2; };
chosen {

Now that davinci_spi driver has been converted to DM framework, enable the same in DT. Also add "spi-flash" as compatible property to n25q128a11 node as it is required for flash device to be probed in U-Boot.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- arch/arm/dts/k2hk-evm.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/k2hk-evm.dts b/arch/arm/dts/k2hk-evm.dts index 660ebf58d547..c5cad2c9da80 100644 --- a/arch/arm/dts/k2hk-evm.dts +++ b/arch/arm/dts/k2hk-evm.dts @@ -147,10 +147,11 @@ };
&spi0 { + status = "okay"; nor_flash: n25q128a11@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "Micron,n25q128a11"; + compatible = "Micron,n25q128a11", "spi-flash"; spi-max-frequency = <54000000>; m25p,fast-read; reg = <0>;

Enable SPI and SPI Flash driver model as K2HK SPI controller driver supports driver model.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- configs/k2hk_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig index 16270659375e..48732cdfa470 100644 --- a/configs/k2hk_evm_defconfig +++ b/configs/k2hk_evm_defconfig @@ -11,6 +11,8 @@ CONFIG_SYS_PROMPT="K2HK EVM # " # CONFIG_CMD_SETEXPR is not set CONFIG_OF_CONTROL=y CONFIG_DM=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_DM_ETH=y

Now that davinci_spi driver has been converted to DM framework, enable the same in DT. Also add "spi-flash" as compatible property to n25q128a11 node as it is required for flash device to be probed in U-Boot.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- arch/arm/dts/k2e-evm.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/k2e-evm.dts b/arch/arm/dts/k2e-evm.dts index 50c83c21d911..e2c3fb49102a 100644 --- a/arch/arm/dts/k2e-evm.dts +++ b/arch/arm/dts/k2e-evm.dts @@ -119,10 +119,11 @@ };
&spi0 { + status = "okay"; nor_flash: n25q128a11@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "Micron,n25q128a11"; + compatible = "Micron,n25q128a11", "spi-flash"; spi-max-frequency = <54000000>; m25p,fast-read; reg = <0>;

Enable SPI and SPI Flash driver model as K2E SPI controller driver supports driver model.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- configs/k2e_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig index c843508516c4..35e9db0f624f 100644 --- a/configs/k2e_evm_defconfig +++ b/configs/k2e_evm_defconfig @@ -11,6 +11,8 @@ CONFIG_SYS_PROMPT="K2E EVM # " # CONFIG_CMD_SETEXPR is not set CONFIG_OF_CONTROL=y CONFIG_DM=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_DM_ETH=y

Now that davinci_spi driver has been converted to DM framework, enable the same in DT. Also add "spi-flash" as compatible property to n25q128a11 node as it is required for flash device to be probed in U-Boot.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- arch/arm/dts/k2l-evm.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/dts/k2l-evm.dts b/arch/arm/dts/k2l-evm.dts index 9a69a6b55374..da0661ba3e8a 100644 --- a/arch/arm/dts/k2l-evm.dts +++ b/arch/arm/dts/k2l-evm.dts @@ -96,10 +96,11 @@ };
&spi0 { + status ="okay"; nor_flash: n25q128a11@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "Micron,n25q128a11"; + compatible = "Micron,n25q128a11", "spi-flash"; spi-max-frequency = <54000000>; m25p,fast-read; reg = <0>;

Enable SPI and SPI Flash driver model as K2L SPI controller driver supports driver model.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- configs/k2l_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig index 255f6d152ed6..7d4261767447 100644 --- a/configs/k2l_evm_defconfig +++ b/configs/k2l_evm_defconfig @@ -11,6 +11,8 @@ CONFIG_SYS_PROMPT="K2L EVM # " # CONFIG_CMD_SETEXPR is not set CONFIG_OF_CONTROL=y CONFIG_DM=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_DM_ETH=y

K2G SoC has 4 SPI instances that are compatible with davinci_spi controller(present on previous generation of Keystone2 devices). Add DT nodes for the same. K2G EVM has a N25Q128A13 SPI NOR flash connected on SPI-1. Add DT bindings for the same.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- arch/arm/dts/k2g-evm.dts | 24 ++++++++++++++++++++++++ arch/arm/dts/k2g.dtsi | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+)
diff --git a/arch/arm/dts/k2g-evm.dts b/arch/arm/dts/k2g-evm.dts index 0ca36ef39ad3..38ca7ae1b6b9 100644 --- a/arch/arm/dts/k2g-evm.dts +++ b/arch/arm/dts/k2g-evm.dts @@ -31,3 +31,27 @@ &gbe0 { phy-handle = <ðphy0>; }; + +&spi1 { + status = "okay"; + + spi_nor: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-flash"; + spi-max-frequency = <50000000>; + m25p,fast-read; + reg = <0>; + + partition@0 { + label = "u-boot-spl"; + reg = <0x0 0x80000>; + read-only; + }; + + partition@1 { + label = "misc"; + reg = <0x80000 0xf80000>; + }; + }; +}; diff --git a/arch/arm/dts/k2g.dtsi b/arch/arm/dts/k2g.dtsi index a3ed444d3c31..88b1a8e998ac 100644 --- a/arch/arm/dts/k2g.dtsi +++ b/arch/arm/dts/k2g.dtsi @@ -19,6 +19,10 @@
aliases { serial0 = &uart0; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &spi2; + spi3 = &spi3; };
memory { @@ -88,5 +92,48 @@ ti,lpsc_module = <1>; };
+ spi0: spi@21805400 { + compatible = "ti,keystone-spi", "ti,dm6441-spi"; + reg = <0x21805400 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 64 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@21805800 { + compatible = "ti,keystone-spi", "ti,dm6441-spi"; + reg = <0x21805800 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 66 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@21805c00 { + compatible = "ti,keystone-spi", "ti,dm6441-spi"; + reg = <0x21805C00 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 68 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi3: spi@21806000 { + compatible = "ti,keystone-spi", "ti,dm6441-spi"; + reg = <0x21806000 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 70 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; };

Enable SPI and SPI Flash driver model as K2G SPI controller driver supports driver model.
Signed-off-by: Vignesh R vigneshr@ti.com Reviewed-by: Tom Rini trini@konsulko.com --- configs/k2g_evm_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig index 054581297801..c39e3cedf685 100644 --- a/configs/k2g_evm_defconfig +++ b/configs/k2g_evm_defconfig @@ -11,6 +11,8 @@ CONFIG_CMD_REMOTEPROC=y # CONFIG_CMD_SETEXPR is not set CONFIG_OF_CONTROL=y CONFIG_DM=y +CONFIG_DM_SPI=y +CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_DM_ETH=y

On 04/25/2016 04:29 PM, Vignesh R wrote:
This series converts davinci_spi driver to adapt to driver model framework. And enables the driver on k2l, k2e, k2hk evms. Also, added support for davinci_spi on k2g evm.
Tested on k2l, k2e, k2hk and k2g evms.
I have posted a v3 rebasing on top of 2016.05-rc3 and fixing a build issue.
v1: http://comments.gmane.org/gmane.comp.boot-loaders.u-boot/258285
Vignesh R (12): dm: core: implement dev_map_phsymem() spi: davinci_spi: Convert to driver to adapt to DM keystone2: spi: do not define DM_SPI and DM_SPI_FLASH for SPL build ARM: dts: keystone2: add SPI aliases for davinci SPI nodes ARM: dts: k2hk: Enable Davinci SPI controller defconfig: k2hk_evm_defconfig: enable SPI driver model ARM: dts: k2e: Enable Davinci SPI controller defconfig: k2e_evm_defconfig: enable SPI driver model ARM: dts: k2l: Enable Davinci SPI controller defconfig: k2l_evm_defconfig: enable SPI driver model ARM: dts: k2g: add support for Davinci SPI controller defconfig: k2g_evm_defconfig: enable SPI driver model
arch/arm/dts/k2e-evm.dts | 3 +- arch/arm/dts/k2g-evm.dts | 24 +++ arch/arm/dts/k2g.dtsi | 47 +++++ arch/arm/dts/k2hk-evm.dts | 3 +- arch/arm/dts/k2l-evm.dts | 3 +- arch/arm/dts/keystone.dtsi | 3 + configs/k2e_evm_defconfig | 2 + configs/k2g_evm_defconfig | 2 + configs/k2hk_evm_defconfig | 2 + configs/k2l_evm_defconfig | 2 + drivers/core/device.c | 5 + drivers/spi/davinci_spi.c | 327 +++++++++++++++++++++++++---------- include/configs/ti_armv7_keystone2.h | 4 + include/dm/device.h | 10 ++ 14 files changed, 344 insertions(+), 93 deletions(-)
participants (1)
-
Vignesh R