All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM
@ 2016-05-04 11:19 Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
                   ` (13 more replies)
  0 siblings, 14 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot


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.

Rebased on top of v2016.05-rc3

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                |   6 +
 drivers/spi/davinci_spi.c            | 327 +++++++++++++++++++++++++----------
 include/configs/ti_armv7_keystone2.h |   4 +
 include/dm/device.h                  |   9 +
 14 files changed, 344 insertions(+), 93 deletions(-)

-- 
2.8.2

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem()
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-05 17:44   ` Jagan Teki
                     ` (3 more replies)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM Vignesh R
                   ` (12 subsequent siblings)
  13 siblings, 4 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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>
---

v3: Explicitly include header file

v2: New patch

 drivers/core/device.c | 6 ++++++
 include/dm/device.h   | 9 +++++++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 1322991d6c7b..6b19b4b8c7a0 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <asm/io.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
 #include <malloc.h>
@@ -678,6 +679,11 @@ void *dev_get_addr_ptr(struct udevice *dev)
 	return (void *)(uintptr_t)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 8970fc015c7e..5253b5410d9a 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -463,6 +463,15 @@ fdt_addr_t dev_get_addr(struct udevice *dev);
  */
 void *dev_get_addr_ptr(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
  *
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-06 17:49   ` Tom Rini
                     ` (3 more replies)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 03/12] keystone2: spi: do not define DM_SPI and DM_SPI_FLASH for SPL build Vignesh R
                   ` (11 subsequent siblings)
  13 siblings, 4 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

Convert davinci_spi driver so that it complies with SPI DM framework.

Signed-off-by: Vignesh R <vigneshr@ti.com>
---

v3: No changes

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
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 03/12] keystone2: spi: do not define DM_SPI and DM_SPI_FLASH for SPL build
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 04/12] ARM: dts: keystone2: add SPI aliases for davinci SPI nodes Vignesh R
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 2c9028c73558..985dd0625ab0 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
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 04/12] ARM: dts: keystone2: add SPI aliases for davinci SPI nodes
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (2 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 03/12] keystone2: spi: do not define DM_SPI and DM_SPI_FLASH for SPL build Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 05/12] ARM: dts: k2hk: Enable Davinci SPI controller Vignesh R
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 {
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 05/12] ARM: dts: k2hk: Enable Davinci SPI controller
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (3 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 04/12] ARM: dts: keystone2: add SPI aliases for davinci SPI nodes Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 06/12] defconfig: k2hk_evm_defconfig: enable SPI driver model Vignesh R
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "Micron,n25q128a11";
+		compatible = "Micron,n25q128a11", "spi-flash";
 		spi-max-frequency = <54000000>;
 		m25p,fast-read;
 		reg = <0>;
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 06/12] defconfig: k2hk_evm_defconfig: enable SPI driver model
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (4 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 05/12] ARM: dts: k2hk: Enable Davinci SPI controller Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 07/12] ARM: dts: k2e: Enable Davinci SPI controller Vignesh R
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 3975e804e534..21b8e1d2d383 100644
--- a/configs/k2hk_evm_defconfig
+++ b/configs/k2hk_evm_defconfig
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_DM_ETH=y
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 07/12] ARM: dts: k2e: Enable Davinci SPI controller
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (5 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 06/12] defconfig: k2hk_evm_defconfig: enable SPI driver model Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 08/12] defconfig: k2e_evm_defconfig: enable SPI driver model Vignesh R
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "Micron,n25q128a11";
+		compatible = "Micron,n25q128a11", "spi-flash";
 		spi-max-frequency = <54000000>;
 		m25p,fast-read;
 		reg = <0>;
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 08/12] defconfig: k2e_evm_defconfig: enable SPI driver model
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (6 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 07/12] ARM: dts: k2e: Enable Davinci SPI controller Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 09/12] ARM: dts: k2l: Enable Davinci SPI controller Vignesh R
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 044a9bf5b6e3..1e5003e8d23c 100644
--- a/configs/k2e_evm_defconfig
+++ b/configs/k2e_evm_defconfig
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_DM_ETH=y
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 09/12] ARM: dts: k2l: Enable Davinci SPI controller
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (7 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 08/12] defconfig: k2e_evm_defconfig: enable SPI driver model Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 10/12] defconfig: k2l_evm_defconfig: enable SPI driver model Vignesh R
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "Micron,n25q128a11";
+		compatible = "Micron,n25q128a11", "spi-flash";
 		spi-max-frequency = <54000000>;
 		m25p,fast-read;
 		reg = <0>;
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 10/12] defconfig: k2l_evm_defconfig: enable SPI driver model
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (8 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 09/12] ARM: dts: k2l: Enable Davinci SPI controller Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 11/12] ARM: dts: k2g: add support for Davinci SPI controller Vignesh R
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 844dd57163f5..1ba7d23e9c78 100644
--- a/configs/k2l_evm_defconfig
+++ b/configs/k2l_evm_defconfig
@@ -28,6 +28,8 @@ CONFIG_CMD_FS_GENERIC=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM=y
 CONFIG_TI_AEMIF=y
+CONFIG_DM_SPI=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_DM_ETH=y
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 11/12] ARM: dts: k2g: add support for Davinci SPI controller
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (9 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 10/12] defconfig: k2l_evm_defconfig: enable SPI driver model Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 12/12] defconfig: k2g_evm_defconfig: enable SPI driver model Vignesh R
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 = <&ethphy0>;
 };
+
+&spi1 {
+	status = "okay";
+
+	spi_nor: flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spi-flash";
+		spi-max-frequency = <50000000>;
+		m25p,fast-read;
+		reg = <0>;
+
+		partition at 0 {
+			label = "u-boot-spl";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition at 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 at 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 at 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 at 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 at 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";
+		};
 	};
 };
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 12/12] defconfig: k2g_evm_defconfig: enable SPI driver model
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (10 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 11/12] ARM: dts: k2g: add support for Davinci SPI controller Vignesh R
@ 2016-05-04 11:19 ` Vignesh R
  2016-05-05 18:02 ` [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Jagan Teki
  2016-06-01 13:43 ` Vignesh R
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-04 11:19 UTC (permalink / raw)
  To: u-boot

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 d0b45ce3f8a5..33722ce9c421 100644
--- a/configs/k2g_evm_defconfig
+++ b/configs/k2g_evm_defconfig
@@ -27,6 +27,8 @@ CONFIG_CMD_FAT=y
 CONFIG_CMD_FS_GENERIC=y
 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
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem()
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
@ 2016-05-05 17:44   ` Jagan Teki
  2016-05-06  3:58   ` [U-Boot] [PATCH v4] " Vignesh R
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 34+ messages in thread
From: Jagan Teki @ 2016-05-05 17:44 UTC (permalink / raw)
  To: u-boot

On 4 May 2016 at 16:49, Vignesh R <vigneshr@ti.com> wrote:
> 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>

Reviewed-by: Jagan Teki <jteki@openedev.com>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (11 preceding siblings ...)
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 12/12] defconfig: k2g_evm_defconfig: enable SPI driver model Vignesh R
@ 2016-05-05 18:02 ` Jagan Teki
  2016-06-01 13:43 ` Vignesh R
  13 siblings, 0 replies; 34+ messages in thread
From: Jagan Teki @ 2016-05-05 18:02 UTC (permalink / raw)
  To: u-boot

On 4 May 2016 at 16:49, Vignesh R <vigneshr@ti.com> 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.
>
> Rebased on top of v2016.05-rc3
>
> 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                |   6 +
>  drivers/spi/davinci_spi.c            | 327 +++++++++++++++++++++++++--

Reviewed-by: Jagan Teki <jteki@openedev.com>

-- 
Jagan.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v4] dm: core: implement dev_map_phsymem()
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
  2016-05-05 17:44   ` Jagan Teki
@ 2016-05-06  3:58   ` Vignesh R
  2016-05-06 15:30     ` Jagan Teki
  2016-05-14 19:34   ` [U-Boot] [PATCH v3 01/12] " Simon Glass
  2016-05-16  9:16   ` [U-Boot] [PATCH v5] dm: core: implement dev_map_physmem() Vignesh R
  3 siblings, 1 reply; 34+ messages in thread
From: Vignesh R @ 2016-05-06  3:58 UTC (permalink / raw)
  To: u-boot

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>
Reviewed-by: Jagan Teki <jteki@openedev.com>

---

v4: Reorder include files to avoid build warning on dra7xx.

 drivers/core/device.c | 6 ++++++
 include/dm/device.h   | 9 +++++++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 1322991d6c7b..6b19b4b8c7a0 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <asm/io.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
 #include <malloc.h>
@@ -678,6 +679,11 @@ void *dev_get_addr_ptr(struct udevice *dev)
 	return (void *)(uintptr_t)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 8970fc015c7e..5253b5410d9a 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -463,6 +463,15 @@ fdt_addr_t dev_get_addr(struct udevice *dev);
  */
 void *dev_get_addr_ptr(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
  *
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v4] dm: core: implement dev_map_phsymem()
  2016-05-06  3:58   ` [U-Boot] [PATCH v4] " Vignesh R
@ 2016-05-06 15:30     ` Jagan Teki
  2016-05-06 15:46       ` R, Vignesh
  0 siblings, 1 reply; 34+ messages in thread
From: Jagan Teki @ 2016-05-06 15:30 UTC (permalink / raw)
  To: u-boot

On 6 May 2016 at 09:28, Vignesh R <vigneshr@ti.com> wrote:
> 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>
> Reviewed-by: Jagan Teki <jteki@openedev.com>
>
> ---
>
> v4: Reorder include files to avoid build warning on dra7xx.
>
>  drivers/core/device.c | 6 ++++++
>  include/dm/device.h   | 9 +++++++++
>  2 files changed, 15 insertions(+)
>
> diff --git a/drivers/core/device.c b/drivers/core/device.c
> index 1322991d6c7b..6b19b4b8c7a0 100644
> --- a/drivers/core/device.c
> +++ b/drivers/core/device.c
> @@ -10,6 +10,7 @@
>   */
>
>  #include <common.h>
> +#include <asm/io.h>

I think this look same as v3 [1] please check?

>  #include <fdtdec.h>
>  #include <fdt_support.h>
>  #include <malloc.h>

[1] https://patchwork.ozlabs.org/patch/618361/

-- 
Jagan.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v4] dm: core: implement dev_map_phsymem()
  2016-05-06 15:30     ` Jagan Teki
@ 2016-05-06 15:46       ` R, Vignesh
  2016-05-06 16:30         ` Jagan Teki
  0 siblings, 1 reply; 34+ messages in thread
From: R, Vignesh @ 2016-05-06 15:46 UTC (permalink / raw)
  To: u-boot



On 5/6/2016 9:00 PM, Jagan Teki wrote:
> On 6 May 2016 at 09:28, Vignesh R <vigneshr@ti.com> wrote:
>> 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>
>> Reviewed-by: Jagan Teki <jteki@openedev.com>
>>
>> ---
>>
>> v4: Reorder include files to avoid build warning on dra7xx.
>>
>>  drivers/core/device.c | 6 ++++++
>>  include/dm/device.h   | 9 +++++++++
>>  2 files changed, 15 insertions(+)
>>
>> diff --git a/drivers/core/device.c b/drivers/core/device.c
>> index 1322991d6c7b..6b19b4b8c7a0 100644
>> --- a/drivers/core/device.c
>> +++ b/drivers/core/device.c
>> @@ -10,6 +10,7 @@
>>   */
>>
>>  #include <common.h>
>> +#include <asm/io.h>
> 
> I think this look same as v3 [1] please check?

Yeah, v3 has the include files in correct. Please ignore this patch.
Sorry for the spam.

Regards
Vignesh.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v4] dm: core: implement dev_map_phsymem()
  2016-05-06 15:46       ` R, Vignesh
@ 2016-05-06 16:30         ` Jagan Teki
  2016-05-09  4:09           ` Vignesh R
  0 siblings, 1 reply; 34+ messages in thread
From: Jagan Teki @ 2016-05-06 16:30 UTC (permalink / raw)
  To: u-boot

On 6 May 2016 at 21:16, R, Vignesh <vigneshr@ti.com> wrote:
>
>
> On 5/6/2016 9:00 PM, Jagan Teki wrote:
>> On 6 May 2016 at 09:28, Vignesh R <vigneshr@ti.com> wrote:
>>> 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>
>>> Reviewed-by: Jagan Teki <jteki@openedev.com>
>>>
>>> ---
>>>
>>> v4: Reorder include files to avoid build warning on dra7xx.
>>>
>>>  drivers/core/device.c | 6 ++++++
>>>  include/dm/device.h   | 9 +++++++++
>>>  2 files changed, 15 insertions(+)
>>>
>>> diff --git a/drivers/core/device.c b/drivers/core/device.c
>>> index 1322991d6c7b..6b19b4b8c7a0 100644
>>> --- a/drivers/core/device.c
>>> +++ b/drivers/core/device.c
>>> @@ -10,6 +10,7 @@
>>>   */
>>>
>>>  #include <common.h>
>>> +#include <asm/io.h>
>>
>> I think this look same as v3 [1] please check?
>
> Yeah, v3 has the include files in correct. Please ignore this patch.
> Sorry for the spam.

Did you test this series on top of master?

-- 
Jagan.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM Vignesh R
@ 2016-05-06 17:49   ` Tom Rini
  2016-05-16  9:38   ` [U-Boot] [PATCH v4 " Vignesh R
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 34+ messages in thread
From: Tom Rini @ 2016-05-06 17:49 UTC (permalink / raw)
  To: u-boot

On Wed, May 04, 2016 at 04:49:22PM +0530, Vignesh R wrote:

> Convert davinci_spi driver so that it complies with SPI DM framework.
> 
> Signed-off-by: Vignesh R <vigneshr@ti.com>

Reviewed-by: Tom Rini <trini@konsulko.com>

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160506/c5f81985/attachment.sig>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v4] dm: core: implement dev_map_phsymem()
  2016-05-06 16:30         ` Jagan Teki
@ 2016-05-09  4:09           ` Vignesh R
  0 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-09  4:09 UTC (permalink / raw)
  To: u-boot



On 05/06/2016 10:00 PM, Jagan Teki wrote:
> On 6 May 2016 at 21:16, R, Vignesh <vigneshr@ti.com> wrote:
>>
>>
>> On 5/6/2016 9:00 PM, Jagan Teki wrote:
>>> On 6 May 2016 at 09:28, Vignesh R <vigneshr@ti.com> wrote:
>>>> 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>
>>>> Reviewed-by: Jagan Teki <jteki@openedev.com>
>>>>
>>>> ---
>>>>
>>>> v4: Reorder include files to avoid build warning on dra7xx.
>>>>
>>>>  drivers/core/device.c | 6 ++++++
>>>>  include/dm/device.h   | 9 +++++++++
>>>>  2 files changed, 15 insertions(+)
>>>>
>>>> diff --git a/drivers/core/device.c b/drivers/core/device.c
>>>> index 1322991d6c7b..6b19b4b8c7a0 100644
>>>> --- a/drivers/core/device.c
>>>> +++ b/drivers/core/device.c
>>>> @@ -10,6 +10,7 @@
>>>>   */
>>>>
>>>>  #include <common.h>
>>>> +#include <asm/io.h>
>>>
>>> I think this look same as v3 [1] please check?
>>
>> Yeah, v3 has the include files in correct. Please ignore this patch.
>> Sorry for the spam.
> 
> Did you test this series on top of master?

Yes, this is tested on top of 2016.05-rc3

-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem()
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
  2016-05-05 17:44   ` Jagan Teki
  2016-05-06  3:58   ` [U-Boot] [PATCH v4] " Vignesh R
@ 2016-05-14 19:34   ` Simon Glass
  2016-05-16  9:18     ` Vignesh R
  2016-05-16  9:16   ` [U-Boot] [PATCH v5] dm: core: implement dev_map_physmem() Vignesh R
  3 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2016-05-14 19:34 UTC (permalink / raw)
  To: u-boot

Hi,

On 4 May 2016 at 05:19, Vignesh R <vigneshr@ti.com> wrote:
> 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>
> ---
>
> v3: Explicitly include header file

A few nits, sorry this review is late.

Please fix spelling of dev_map_phsymemin the commit subject.

>
> v2: New patch
>
>  drivers/core/device.c | 6 ++++++
>  include/dm/device.h   | 9 +++++++++
>  2 files changed, 15 insertions(+)
>
> diff --git a/drivers/core/device.c b/drivers/core/device.c
> index 1322991d6c7b..6b19b4b8c7a0 100644
> --- a/drivers/core/device.c
> +++ b/drivers/core/device.c
> @@ -10,6 +10,7 @@
>   */
>
>  #include <common.h>
> +#include <asm/io.h>
>  #include <fdtdec.h>
>  #include <fdt_support.h>
>  #include <malloc.h>
> @@ -678,6 +679,11 @@ void *dev_get_addr_ptr(struct udevice *dev)
>         return (void *)(uintptr_t)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);

What happens if dev_get_addr() returns 0. Does it work OK? If not,
please add a check for it.

> +}
> +
>  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 8970fc015c7e..5253b5410d9a 100644
> --- a/include/dm/device.h
> +++ b/include/dm/device.h
> @@ -463,6 +463,15 @@ fdt_addr_t dev_get_addr(struct udevice *dev);
>   */
>  void *dev_get_addr_ptr(struct udevice *dev);
>
> +/* * dev_map_physmem() - Map bus memory into CPU space

This is fine, but please add more detail on following lines. You need
to mention that it reads the device address from the 'reg' property
using dev_get_addr().

> + *
> + * @dev: Pointer to device
> + * @size: size of the memory to map
> + *
> + * @return addr

Something like:

@return mapped address, or 0 if the device does not have an address or
the mapping failed

> + */
> +void *dev_map_physmem(struct udevice *dev, unsigned long size);
> +
>  /**
>   * dev_get_addr_index() - Get the indexed reg property of a device
>   *
> --
> 2.8.2
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v5] dm: core: implement dev_map_physmem()
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
                     ` (2 preceding siblings ...)
  2016-05-14 19:34   ` [U-Boot] [PATCH v3 01/12] " Simon Glass
@ 2016-05-16  9:16   ` Vignesh R
  2016-05-19  4:02     ` Simon Glass
  3 siblings, 1 reply; 34+ messages in thread
From: Vignesh R @ 2016-05-16  9:16 UTC (permalink / raw)
  To: u-boot

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>
Reviewed-by: Jagan Teki <jteki@openedev.com>
---

v5: Fix comments by Simon Glass <sjg@chromium.org>

 drivers/core/device.c | 11 +++++++++++
 include/dm/device.h   | 13 +++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 1322991d6c7b..0406fc82f8d1 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -10,6 +10,7 @@
  */
 
 #include <common.h>
+#include <asm/io.h>
 #include <fdtdec.h>
 #include <fdt_support.h>
 #include <malloc.h>
@@ -678,6 +679,16 @@ void *dev_get_addr_ptr(struct udevice *dev)
 	return (void *)(uintptr_t)dev_get_addr_index(dev, 0);
 }
 
+void *dev_map_physmem(struct udevice *dev, unsigned long size)
+{
+	fdt_addr_t addr = dev_get_addr(dev);
+
+	if (addr == FDT_ADDR_T_NONE)
+		return NULL;
+
+	return map_physmem(addr, 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 8970fc015c7e..9509c0b72ccb 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -464,6 +464,19 @@ fdt_addr_t dev_get_addr(struct udevice *dev);
 void *dev_get_addr_ptr(struct udevice *dev);
 
 /**
+ * dev_map_physmem() - Read device address from reg property of the
+ *                     device node and map the address into CPU address
+ *                     space.
+ *
+ * @dev: Pointer to device
+ * @size: size of the memory to map
+ *
+ * @return  mapped address, or NULL if the device does not have reg
+ *          property.
+ */
+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
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem()
  2016-05-14 19:34   ` [U-Boot] [PATCH v3 01/12] " Simon Glass
@ 2016-05-16  9:18     ` Vignesh R
  0 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-16  9:18 UTC (permalink / raw)
  To: u-boot



On 05/15/2016 01:04 AM, Simon Glass wrote:
> Hi,
> 
> On 4 May 2016 at 05:19, Vignesh R <vigneshr@ti.com> wrote:
>> 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>
>> ---
>>
>> v3: Explicitly include header file
> 
> A few nits, sorry this review is late.

Posted a v5 in reply to this thread.


-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v4 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM Vignesh R
  2016-05-06 17:49   ` Tom Rini
@ 2016-05-16  9:38   ` Vignesh R
  2016-05-20 15:23     ` Simon Glass
  2016-05-20  5:01   ` [U-Boot] [PATCH v5 " Vignesh R
  2016-05-24  4:24   ` [U-Boot] [PATCH v6 " Vignesh R
  3 siblings, 1 reply; 34+ messages in thread
From: Vignesh R @ 2016-05-16  9:38 UTC (permalink / raw)
  To: u-boot

Convert davinci_spi driver so that it complies with SPI DM framework.

Signed-off-by: Vignesh R <vigneshr@ti.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
---

v4: Check error returned by dev_map_physmem().

v3: No changes

v2: Add comments to struct davinci_spi_slave members.
    Use dev_map_physmem() added by previous patch.

 drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 240 insertions(+), 89 deletions(-)

diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 0bd4f88926f1..39a3801df231 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,143 @@ 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;
+}
 
-out:
-	if (flags & SPI_XFER_END) {
-		u8 dummy = 0;
-		davinci_spi_write(slave, 1, &dummy, flags);
+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));
+	if (!ds->regs) {
+		printf("%s: could not map device address\n");
+		return -ENODEV;
 	}
+	ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
 	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
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v5] dm: core: implement dev_map_physmem()
  2016-05-16  9:16   ` [U-Boot] [PATCH v5] dm: core: implement dev_map_physmem() Vignesh R
@ 2016-05-19  4:02     ` Simon Glass
  0 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2016-05-19  4:02 UTC (permalink / raw)
  To: u-boot

On 16 May 2016 at 03:16, Vignesh R <vigneshr@ti.com> wrote:
> 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>
> Reviewed-by: Jagan Teki <jteki@openedev.com>
> ---
>
> v5: Fix comments by Simon Glass <sjg@chromium.org>
>
>  drivers/core/device.c | 11 +++++++++++
>  include/dm/device.h   | 13 +++++++++++++
>  2 files changed, 24 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v5 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM Vignesh R
  2016-05-06 17:49   ` Tom Rini
  2016-05-16  9:38   ` [U-Boot] [PATCH v4 " Vignesh R
@ 2016-05-20  5:01   ` Vignesh R
  2016-05-20 15:24     ` Simon Glass
  2016-05-24  4:24   ` [U-Boot] [PATCH v6 " Vignesh R
  3 siblings, 1 reply; 34+ messages in thread
From: Vignesh R @ 2016-05-20  5:01 UTC (permalink / raw)
  To: u-boot

Convert davinci_spi driver so that it complies with SPI DM framework.

Signed-off-by: Vignesh R <vigneshr@ti.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
---

v5: correct error message.

v4: Check error returned by dev_map_physmem().

v3: No changes

v2: Add comments to struct davinci_spi_slave members.
    Use dev_map_physmem() added by previous patch.

 drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 240 insertions(+), 89 deletions(-)

diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 0bd4f88926f1..22274c91a2f1 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,143 @@ 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;
+}
 
-out:
-	if (flags & SPI_XFER_END) {
-		u8 dummy = 0;
-		davinci_spi_write(slave, 1, &dummy, flags);
+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));
+	if (!ds->regs) {
+		printf("%s: could not map device address\n", __func__);
+		return -ENODEV;
 	}
+	ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
 	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
-- 
2.8.3

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v4 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-16  9:38   ` [U-Boot] [PATCH v4 " Vignesh R
@ 2016-05-20 15:23     ` Simon Glass
  0 siblings, 0 replies; 34+ messages in thread
From: Simon Glass @ 2016-05-20 15:23 UTC (permalink / raw)
  To: u-boot

On 16 May 2016 at 03:38, Vignesh R <vigneshr@ti.com> wrote:
> Convert davinci_spi driver so that it complies with SPI DM framework.
>
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> Reviewed-by: Tom Rini <trini@konsulko.com>
> ---
>
> v4: Check error returned by dev_map_physmem().
>
> v3: No changes
>
> v2: Add comments to struct davinci_spi_slave members.
>     Use dev_map_physmem() added by previous patch.
>
>  drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
>  1 file changed, 240 insertions(+), 89 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v5 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-20  5:01   ` [U-Boot] [PATCH v5 " Vignesh R
@ 2016-05-20 15:24     ` Simon Glass
  2016-05-24  4:26       ` Vignesh R
  0 siblings, 1 reply; 34+ messages in thread
From: Simon Glass @ 2016-05-20 15:24 UTC (permalink / raw)
  To: u-boot

Hi Vignesh,

On 19 May 2016 at 23:01, Vignesh R <vigneshr@ti.com> wrote:
>
> Convert davinci_spi driver so that it complies with SPI DM framework.
>
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> Reviewed-by: Tom Rini <trini@konsulko.com>
> ---
>
> v5: correct error message.
>
> v4: Check error returned by dev_map_physmem().
>
> v3: No changes
>
> v2: Add comments to struct davinci_spi_slave members.
>     Use dev_map_physmem() added by previous patch.
>
>  drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
>  1 file changed, 240 insertions(+), 89 deletions(-)

Sorry I missed something below.
[snip]

> +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));
> +       if (!ds->regs) {
> +               printf("%s: could not map device address\n", __func__);
> +               return -ENODEV;

-EINVAL

We use -ENODEV to say there is no device. Here, we have a device but
the configuration is wrong.

>         }
> +       ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
> +
>         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
> --
> 2.8.3
>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v6 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-04 11:19 ` [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM Vignesh R
                     ` (2 preceding siblings ...)
  2016-05-20  5:01   ` [U-Boot] [PATCH v5 " Vignesh R
@ 2016-05-24  4:24   ` Vignesh R
  2016-06-16 10:42     ` Vignesh R
  2016-06-16 23:29     ` Simon Glass
  3 siblings, 2 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-24  4:24 UTC (permalink / raw)
  To: u-boot

Convert davinci_spi driver so that it complies with SPI DM framework.

Signed-off-by: Vignesh R <vigneshr@ti.com>
---

v6: Fix retval on dev_map_physmem() failure.

 drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 240 insertions(+), 89 deletions(-)

diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 0bd4f88926f1..20aa99a451dc 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,143 @@ 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;
+}
 
-out:
-	if (flags & SPI_XFER_END) {
-		u8 dummy = 0;
-		davinci_spi_write(slave, 1, &dummy, flags);
+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));
+	if (!ds->regs) {
+		printf("%s: could not map device address\n", __func__);
+		return -EINVAL;
 	}
+	ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
 	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
-- 
2.8.3

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v5 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-20 15:24     ` Simon Glass
@ 2016-05-24  4:26       ` Vignesh R
  0 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-05-24  4:26 UTC (permalink / raw)
  To: u-boot



On 05/20/2016 08:54 PM, Simon Glass wrote:
> Hi Vignesh,
> 
> On 19 May 2016 at 23:01, Vignesh R <vigneshr@ti.com> wrote:
>>
>> Convert davinci_spi driver so that it complies with SPI DM framework.
>>
>> Signed-off-by: Vignesh R <vigneshr@ti.com>
>> Reviewed-by: Tom Rini <trini@konsulko.com>
>> ---
>>
>> v5: correct error message.
>>
>> v4: Check error returned by dev_map_physmem().
>>
>> v3: No changes
>>
>> v2: Add comments to struct davinci_spi_slave members.
>>     Use dev_map_physmem() added by previous patch.
>>
>>  drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
>>  1 file changed, 240 insertions(+), 89 deletions(-)
> 
> Sorry I missed something below.
> [snip]
> 
>> +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));
>> +       if (!ds->regs) {
>> +               printf("%s: could not map device address\n", __func__);
>> +               return -ENODEV;
> 
> -EINVAL
> 
> We use -ENODEV to say there is no device. Here, we have a device but
> the configuration is wrong.

Ok, I posted in v6 with above change.


-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM
  2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
                   ` (12 preceding siblings ...)
  2016-05-05 18:02 ` [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Jagan Teki
@ 2016-06-01 13:43 ` Vignesh R
  13 siblings, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-06-01 13:43 UTC (permalink / raw)
  To: u-boot



On 05/04/2016 04:49 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.
> 
> Rebased on top of v2016.05-rc3
> 

Gentle ping on the series...

> 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                |   6 +
>  drivers/spi/davinci_spi.c            | 327 +++++++++++++++++++++++++----------
>  include/configs/ti_armv7_keystone2.h |   4 +
>  include/dm/device.h                  |   9 +
>  14 files changed, 344 insertions(+), 93 deletions(-)
> 

-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v6 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-24  4:24   ` [U-Boot] [PATCH v6 " Vignesh R
@ 2016-06-16 10:42     ` Vignesh R
  2016-06-16 23:29     ` Simon Glass
  1 sibling, 0 replies; 34+ messages in thread
From: Vignesh R @ 2016-06-16 10:42 UTC (permalink / raw)
  To: u-boot



On Tuesday 24 May 2016 09:54 AM, Vignesh R wrote:
> Convert davinci_spi driver so that it complies with SPI DM framework.
> 
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> ---
> 
> v6: Fix retval on dev_map_physmem() failure.


Gentle ping....

> 
>  drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
>  1 file changed, 240 insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
> index 0bd4f88926f1..20aa99a451dc 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,143 @@ 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;
> +}
>  
> -out:
> -	if (flags & SPI_XFER_END) {
> -		u8 dummy = 0;
> -		davinci_spi_write(slave, 1, &dummy, flags);
> +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));
> +	if (!ds->regs) {
> +		printf("%s: could not map device address\n", __func__);
> +		return -EINVAL;
>  	}
> +	ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
> +
>  	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
> 

-- 
Regards
Vignesh

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [U-Boot] [PATCH v6 02/12] spi: davinci_spi: Convert to driver to adapt to DM
  2016-05-24  4:24   ` [U-Boot] [PATCH v6 " Vignesh R
  2016-06-16 10:42     ` Vignesh R
@ 2016-06-16 23:29     ` Simon Glass
  1 sibling, 0 replies; 34+ messages in thread
From: Simon Glass @ 2016-06-16 23:29 UTC (permalink / raw)
  To: u-boot

Hi Vignesh,

On 23 May 2016 at 22:24, Vignesh R <vigneshr@ti.com> wrote:
> Convert davinci_spi driver so that it complies with SPI DM framework.
>
> Signed-off-by: Vignesh R <vigneshr@ti.com>
> ---
>
> v6: Fix retval on dev_map_physmem() failure.
>
>  drivers/spi/davinci_spi.c | 329 +++++++++++++++++++++++++++++++++-------------
>  1 file changed, 240 insertions(+), 89 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Who is picking this one up? I can pull it into dm if you like, but I
assumed it would be a SPI patch.

Regards,
Simon

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2016-06-16 23:29 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-04 11:19 [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 01/12] dm: core: implement dev_map_phsymem() Vignesh R
2016-05-05 17:44   ` Jagan Teki
2016-05-06  3:58   ` [U-Boot] [PATCH v4] " Vignesh R
2016-05-06 15:30     ` Jagan Teki
2016-05-06 15:46       ` R, Vignesh
2016-05-06 16:30         ` Jagan Teki
2016-05-09  4:09           ` Vignesh R
2016-05-14 19:34   ` [U-Boot] [PATCH v3 01/12] " Simon Glass
2016-05-16  9:18     ` Vignesh R
2016-05-16  9:16   ` [U-Boot] [PATCH v5] dm: core: implement dev_map_physmem() Vignesh R
2016-05-19  4:02     ` Simon Glass
2016-05-04 11:19 ` [U-Boot] [PATCH v3 02/12] spi: davinci_spi: Convert to driver to adapt to DM Vignesh R
2016-05-06 17:49   ` Tom Rini
2016-05-16  9:38   ` [U-Boot] [PATCH v4 " Vignesh R
2016-05-20 15:23     ` Simon Glass
2016-05-20  5:01   ` [U-Boot] [PATCH v5 " Vignesh R
2016-05-20 15:24     ` Simon Glass
2016-05-24  4:26       ` Vignesh R
2016-05-24  4:24   ` [U-Boot] [PATCH v6 " Vignesh R
2016-06-16 10:42     ` Vignesh R
2016-06-16 23:29     ` Simon Glass
2016-05-04 11:19 ` [U-Boot] [PATCH v3 03/12] keystone2: spi: do not define DM_SPI and DM_SPI_FLASH for SPL build Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 04/12] ARM: dts: keystone2: add SPI aliases for davinci SPI nodes Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 05/12] ARM: dts: k2hk: Enable Davinci SPI controller Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 06/12] defconfig: k2hk_evm_defconfig: enable SPI driver model Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 07/12] ARM: dts: k2e: Enable Davinci SPI controller Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 08/12] defconfig: k2e_evm_defconfig: enable SPI driver model Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 09/12] ARM: dts: k2l: Enable Davinci SPI controller Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 10/12] defconfig: k2l_evm_defconfig: enable SPI driver model Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 11/12] ARM: dts: k2g: add support for Davinci SPI controller Vignesh R
2016-05-04 11:19 ` [U-Boot] [PATCH v3 12/12] defconfig: k2g_evm_defconfig: enable SPI driver model Vignesh R
2016-05-05 18:02 ` [U-Boot] [PATCH v3 00/12] Convert davinci_spi to DM Jagan Teki
2016-06-01 13:43 ` Vignesh R

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.