Skip to contentSkip to conversation

spi: ompa3/davinci/ti_qspi: Full dm conversion

PATCH Superseded Jagan Teki 4 participants 8 messages Mar 15, 2018 – Apr 26, 2018 SPI

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Jagan Teki

author
#0 lore raw

v2 cover spi: ompa3/davinci/ti_qspi: Full dm conversion

This series add full dm conversion for omap3_spi, davanci and ti_qspi drivers. Now it call to respective board maintainers to switch DM_SPI and DM_SPI_FLASH before migration deadline.

Changes for v2:
- New patch for ti_qspi changes

Jagan Teki (3):
spi: omap3_spi: Full dm conversion
spi: davinci: Full dm conversion
spi: ti_qspi: Full dm conversion

 drivers/spi/Kconfig                    |  26 +-
 drivers/spi/davinci_spi.c              | 275 +++++-------------
 drivers/spi/omap3_spi.c                | 340 +++++++----------------
 drivers/spi/ti_qspi.c                  | 490 ++++++++++++---------------------
 include/dm/platform_data/spi_davinci.h |  15 +
 include/dm/platform_data/spi_omap3.h   |  16 ++
 include/dm/platform_data/spi_ti_qspi.h |  19 ++
 7 files changed, 410 insertions(+), 771 deletions(-)
 create mode 100644 include/dm/platform_data/spi_davinci.h
 create mode 100644 include/dm/platform_data/spi_omap3.h
 create mode 100644 include/dm/platform_data/spi_ti_qspi.h
Signature · 1 line
2.14.3
author
#1 lore raw

PATCH v2 1/3 spi: omap3_spi: Full dm conversion

omap3_spi now support dt along with platform data, respective boards need to switch into dm for the same.

---
 drivers/spi/Kconfig                  |  14 +-
 drivers/spi/omap3_spi.c              | 340 +++++++++++------------------------
 include/dm/platform_data/spi_omap3.h |  16 ++
 3 files changed, 124 insertions(+), 246 deletions(-)
 create mode 100644 include/dm/platform_data/spi_omap3.h
drivers/spi/Kconfig +7 -7
index 12dde8fb95..5e73dd4296 100644
@@ -106,6 +106,13 @@ config MVEBU_A3700_SPI
 	  used to access the SPI NOR flash on platforms embedding this
 	  Marvell IP core.
 
+config OMAP3_SPI
+	bool "McSPI driver for OMAP"
+	help
+	  SPI master controller for OMAP24XX and later Multichannel SPI
+	  (McSPI). This driver be used to access SPI chips on platforms
+	  embedding this OMAP3 McSPI IP core.
+
 config PIC32_SPI
 	bool "Microchip PIC32 SPI driver"
 	depends on MACH_PIC32
@@ -297,11 +304,4 @@ config MXS_SPI
 	  Enable the MXS SPI controller driver. This driver can be used
 	  on the i.MX23 and i.MX28 SoCs.
 
-config OMAP3_SPI
-	bool "McSPI driver for OMAP"
-	help
-	  SPI master controller for OMAP24XX and later Multichannel SPI
-	  (McSPI). This driver be used to access SPI chips on platforms
-	  embedding this OMAP3 McSPI IP core.
-
 endmenu # menu "SPI Support"
drivers/spi/omap3_spi.c +101 -239

440 lines not on this page · raw message

include/dm/platform_data/spi_omap3.h new file +16 -0
new file mode 100644
index 0000000000..9323266de7
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __spi_omap3_h
+#define __spi_omap3_h
+
+struct omap3_spi_platdata {
+	struct mcspi *regs;
+	unsigned int wordlen;
+	unsigned int pin_dir:1;
+};
+
+#endif /* __spi_omap3_h */
Signature · 1 line
2.14.3
#2 lore raw

PATCH v2 1/3 spi: omap3_spi: Full dm conversion

Quoted 5 lines · Jagan Teki

omap3_spi now support dt along with platform data, respective boards need to switch into dm for the same.

I tested this on the SPI branch, and it builds without error and boots on omap3_logic. I cannot get SSPI working, but it appears as if it's been broken since at least 2018.01, so I'll investigate. For now, go ahead and keep the 'Tested-by' but if someone else has SPI working on their board, it might not be a bad idea to test it on it.

adam

Quoted 517 lines
---
 drivers/spi/Kconfig                  |  14 +-
 drivers/spi/omap3_spi.c              | 340 +++++++++++------------------------
 include/dm/platform_data/spi_omap3.h |  16 ++
 3 files changed, 124 insertions(+), 246 deletions(-)
 create mode 100644 include/dm/platform_data/spi_omap3.h
drivers/spi/Kconfig +7 -7
index 12dde8fb95..5e73dd4296 100644
@@ -106,6 +106,13 @@ config MVEBU_A3700_SPI
          used to access the SPI NOR flash on platforms embedding this
          Marvell IP core.
 
+config OMAP3_SPI
+       bool "McSPI driver for OMAP"
+       help
+         SPI master controller for OMAP24XX and later Multichannel SPI
+         (McSPI). This driver be used to access SPI chips on platforms
+         embedding this OMAP3 McSPI IP core.
+
 config PIC32_SPI
        bool "Microchip PIC32 SPI driver"
        depends on MACH_PIC32
@@ -297,11 +304,4 @@ config MXS_SPI
          Enable the MXS SPI controller driver. This driver can be used
          on the i.MX23 and i.MX28 SoCs.
 
-config OMAP3_SPI
-       bool "McSPI driver for OMAP"
-       help
-         SPI master controller for OMAP24XX and later Multichannel SPI
-         (McSPI). This driver be used to access SPI chips on platforms
-         embedding this OMAP3 McSPI IP core.
-
 endmenu # menu "SPI Support"
drivers/spi/omap3_spi.c +101 -239
index 053a67bbe0..4760106f89 100644
@@ -22,6 +22,7 @@
 #include <spi.h>
 #include <malloc.h>
 #include <asm/io.h>
+#include <dm/platform_data/spi_omap3.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -109,9 +110,6 @@ struct mcspi {
 };
 
 struct omap3_spi_priv {
-#ifndef CONFIG_DM_SPI
-       struct spi_slave slave;
-#endif
        struct mcspi *regs;
        unsigned int cs;
        unsigned int freq;
@@ -312,12 +310,16 @@ static int omap3_spi_txrx(struct omap3_spi_priv *priv, unsigned int len,
        return 0;
 }
 
-static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen,
-                    const void *dout, void *din, unsigned long flags)
+static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
+                         const void *dout, void *din, unsigned long flags)
 {
-       unsigned int    len;
+       struct udevice *bus = dev->parent;
+       struct omap3_spi_priv *priv = dev_get_priv(bus);
+       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+       unsigned int len;
        int ret = -1;
 
+       priv->cs = slave_plat->cs;
        if (priv->wordlen < 4 || priv->wordlen > 32) {
                printf("omap3_spi: invalid wordlen %d\n", priv->wordlen);
                return -1;
@@ -353,78 +355,6 @@ static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen,
        return ret;
 }
 
-static void _omap3_spi_set_speed(struct omap3_spi_priv *priv)
-{
-       uint32_t confr, div = 0;
-
-       confr = readl(&priv->regs->channel[priv->cs].chconf);
-
-       /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
-       if (priv->freq) {
-               while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div))
-                                       > priv->freq)
-                       div++;
-       } else {
-                div = 0xC;
-       }
-
-       /* set clock divisor */
-       confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK;
-       confr |= div << 2;
-
-       omap3_spi_write_chconf(priv, confr);
-}
-
-static void _omap3_spi_set_mode(struct omap3_spi_priv *priv)
-{
-       uint32_t confr;
-
-       confr = readl(&priv->regs->channel[priv->cs].chconf);
-
-       /* standard 4-wire master mode:  SCK, MOSI/out, MISO/in, nCS
-        * REVISIT: this controller could support SPI_3WIRE mode.
-        */
-       if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
-               confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
-               confr |= OMAP3_MCSPI_CHCONF_DPE0;
-       } else {
-               confr &= ~OMAP3_MCSPI_CHCONF_DPE0;
-               confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1;
-       }
-
-       /* set SPI mode 0..3 */
-       confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA);
-       if (priv->mode & SPI_CPHA)
-               confr |= OMAP3_MCSPI_CHCONF_PHA;
-       if (priv->mode & SPI_CPOL)
-               confr |= OMAP3_MCSPI_CHCONF_POL;
-
-       /* set chipselect polarity; manage with FORCE */
-       if (!(priv->mode & SPI_CS_HIGH))
-               confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */
-       else
-               confr &= ~OMAP3_MCSPI_CHCONF_EPOL;
-
-       /* Transmit & receive mode */
-       confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
-
-       omap3_spi_write_chconf(priv, confr);
-}
-
-static void _omap3_spi_set_wordlen(struct omap3_spi_priv *priv)
-{
-       unsigned int confr;
-
-       /* McSPI individual channel configuration */
-       confr = readl(&priv->regs->channel[priv->wordlen].chconf);
-
-       /* wordlength */
-       confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
-       confr |= (priv->wordlen - 1) << 7;
-
-       omap3_spi_write_chconf(priv, confr);
-}
-
 static void spi_reset(struct mcspi *regs)
 {
        unsigned int tmp;
@@ -441,8 +371,10 @@ static void spi_reset(struct mcspi *regs)
        writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &regs->wakeupenable);
 }
 
-static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
+static int omap3_spi_claim_bus(struct udevice *dev)
 {
+       struct udevice *bus = dev->parent;
+       struct omap3_spi_priv *priv = dev_get_priv(bus);
        unsigned int conf;
 
        spi_reset(priv->regs);
@@ -456,142 +388,6 @@ static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
        conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
 
        writel(conf, &priv->regs->modulctrl);
-}
-
-#ifndef CONFIG_DM_SPI
-
-static inline struct omap3_spi_priv *to_omap3_spi(struct spi_slave *slave)
-{
-       return container_of(slave, struct omap3_spi_priv, slave);
-}
-
-void spi_init(void)
-{
-       /* do nothing */
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
-       struct omap3_spi_priv *priv = to_omap3_spi(slave);
-
-       free(priv);
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-       struct omap3_spi_priv *priv = to_omap3_spi(slave);
-
-       _omap3_spi_claim_bus(priv);
-       _omap3_spi_set_wordlen(priv);
-       _omap3_spi_set_mode(priv);
-       _omap3_spi_set_speed(priv);
-
-       return 0;
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
-       struct omap3_spi_priv *priv = to_omap3_spi(slave);
-
-       /* Reset the SPI hardware */
-       spi_reset(priv->regs);
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-                                    unsigned int max_hz, unsigned int mode)
-{
-       struct omap3_spi_priv *priv;
-       struct mcspi *regs;
-
-       /*
-        * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules)
-        * with different number of chip selects (CS, channels):
-        * McSPI1 has 4 CS (bus 0, cs 0 - 3)
-        * McSPI2 has 2 CS (bus 1, cs 0 - 1)
-        * McSPI3 has 2 CS (bus 2, cs 0 - 1)
-        * McSPI4 has 1 CS (bus 3, cs 0)
-        */
-
-       switch (bus) {
-       case 0:
-                regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
-                break;
-#ifdef OMAP3_MCSPI2_BASE
-       case 1:
-                regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
-                break;
-#endif
-#ifdef OMAP3_MCSPI3_BASE
-       case 2:
-                regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
-                break;
-#endif
-#ifdef OMAP3_MCSPI4_BASE
-       case 3:
-                regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
-                break;
-#endif
-       default:
-                printf("SPI error: unsupported bus %i.  Supported busses 0 - 3\n", bus);
-                return NULL;
-       }
-
-       if (((bus == 0) && (cs > 3)) ||
-           ((bus == 1) && (cs > 1)) ||
-           ((bus == 2) && (cs > 1)) ||
-           ((bus == 3) && (cs > 0))) {
-               printf("SPI error: unsupported chip select %i on bus %i\n", cs, bus);
-               return NULL;
-       }
-
-       if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
-               printf("SPI error: unsupported frequency %i Hz. Max frequency is 48 MHz\n",
-                      max_hz);
-               return NULL;
-       }
-
-       if (mode > SPI_MODE_3) {
-               printf("SPI error: unsupported SPI mode %i\n", mode);
-               return NULL;
-       }
-
-       priv = spi_alloc_slave(struct omap3_spi_priv, bus, cs);
-       if (!priv) {
-               printf("SPI error: malloc of SPI structure failed\n");
-               return NULL;
-       }
-
-       priv->regs = regs;
-       priv->cs = cs;
-       priv->freq = max_hz;
-       priv->mode = mode;
-       priv->wordlen = priv->slave.wordlen;
-#if 0
-       /* Please migrate to DM_SPI support for this feature. */
-       priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
-#endif
-
-       return &priv->slave;
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
-            const void *dout, void *din, unsigned long flags)
-{
-       struct omap3_spi_priv *priv = to_omap3_spi(slave);
-
-       return _spi_xfer(priv, bitlen, dout, din, flags);
-}
-
-#else
-
-static int omap3_spi_claim_bus(struct udevice *dev)
-{
-       struct udevice *bus = dev->parent;
-       struct omap3_spi_priv *priv = dev_get_priv(bus);
-       struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
-
-       priv->cs = slave_plat->cs;
-       _omap3_spi_claim_bus(priv);
 
        return 0;
 }
@@ -612,48 +408,59 @@ static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
        struct udevice *bus = dev->parent;
        struct omap3_spi_priv *priv = dev_get_priv(bus);
        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+       unsigned int confr;
+
+       /* McSPI individual channel configuration */
+       confr = readl(&priv->regs->channel[wordlen].chconf);
+
+       /* wordlength */
+       confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
+       confr |= (wordlen - 1) << 7;
 
        priv->cs = slave_plat->cs;
+       omap3_spi_write_chconf(priv, confr);
+
        priv->wordlen = wordlen;
-       _omap3_spi_set_wordlen(priv);
 
        return 0;
 }
 
 static int omap3_spi_probe(struct udevice *dev)
 {
+       struct omap3_spi_platdata *plat = dev->platdata;
        struct omap3_spi_priv *priv = dev_get_priv(dev);
-       const void *blob = gd->fdt_blob;
-       int node = dev_of_offset(dev);
 
-       struct omap2_mcspi_platform_config* data =
-               (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
+       priv->regs = plat->regs;
+       priv->pin_dir = plat->pin_dir;
+       priv->wordlen = plat->wordlen;
 
-       priv->regs = (struct mcspi *)(devfdt_get_addr(dev) + data->regs_offset);
-       priv->pin_dir = fdtdec_get_uint(blob, node, "ti,pindir-d0-out-d1-in",
-                                           MCSPI_PINDIR_D0_IN_D1_OUT);
-       priv->wordlen = SPI_DEFAULT_WORDLEN;
        return 0;
 }
 
-static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
-                           const void *dout, void *din, unsigned long flags)
-{
-       struct udevice *bus = dev->parent;
-       struct omap3_spi_priv *priv = dev_get_priv(bus);
-
-       return _spi_xfer(priv, bitlen, dout, din, flags);
-}
-
 static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed)
 {
        struct udevice *bus = dev->parent;
        struct omap3_spi_priv *priv = dev_get_priv(bus);
        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+       uint32_t confr, div = 0;
 
        priv->cs = slave_plat->cs;
-       priv->freq = slave_plat->max_hz;
-       _omap3_spi_set_speed(priv);
+       confr = readl(&priv->regs->channel[priv->cs].chconf);
+
+       /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
+       if (speed) {
+               while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div))
+                                       > speed)
+                       div++;
+       } else {
+                div = 0xC;
+       }
+
+       /* set clock divisor */
+       confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK;
+       confr |= div << 2;
+
+       omap3_spi_write_chconf(priv, confr);
 
        return 0;
 }
@@ -663,10 +470,39 @@ static int omap3_spi_set_mode(struct udevice *dev, uint mode)
        struct udevice *bus = dev->parent;
        struct omap3_spi_priv *priv = dev_get_priv(bus);
        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+       uint32_t confr;
 
        priv->cs = slave_plat->cs;
-       priv->mode = slave_plat->mode;
-       _omap3_spi_set_mode(priv);
+       confr = readl(&priv->regs->channel[priv->cs].chconf);
+
+       /* standard 4-wire master mode:  SCK, MOSI/out, MISO/in, nCS
+        * REVISIT: this controller could support SPI_3WIRE mode.
+        */
+       if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
+               confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
+               confr |= OMAP3_MCSPI_CHCONF_DPE0;
+       } else {
+               confr &= ~OMAP3_MCSPI_CHCONF_DPE0;
+               confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1;
+       }
+
+       /* set SPI mode 0..3 */
+       confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA);
+       if (mode & SPI_CPHA)
+               confr |= OMAP3_MCSPI_CHCONF_PHA;
+       if (mode & SPI_CPOL)
+               confr |= OMAP3_MCSPI_CHCONF_POL;
+
+       /* set chipselect polarity; manage with FORCE */
+       if (!(mode & SPI_CS_HIGH))
+               confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */
+       else
+               confr &= ~OMAP3_MCSPI_CHCONF_EPOL;
+
+       /* Transmit & receive mode */
+       confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
+
+       omap3_spi_write_chconf(priv, confr);
 
        return 0;
 }
@@ -675,7 +511,7 @@ static const struct dm_spi_ops omap3_spi_ops = {
        .claim_bus      = omap3_spi_claim_bus,
        .release_bus    = omap3_spi_release_bus,
        .set_wordlen    = omap3_spi_set_wordlen,
-       .xfer       = omap3_spi_xfer,
+       .xfer           = omap3_spi_xfer,
        .set_speed      = omap3_spi_set_speed,
        .set_mode       = omap3_spi_set_mode,
        /*
@@ -684,6 +520,28 @@ static const struct dm_spi_ops omap3_spi_ops = {
         */
 };
 
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+static int omap3_spi_ofdata_to_platdata(struct udevice *dev)
+{
+       struct omap3_spi_platdata *plat = dev->platdata;
+       struct omap2_mcspi_platform_config* data =
+               (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
+       fdt_addr_t addr;
+
+       addr = devfdt_get_addr(dev);
+       if (addr == FDT_ADDR_T_NONE)
+               return -EINVAL;
+
+       plat->regs = (struct mcspi *)addr;
+       plat->regs += data->regs_offset;
+       plat->pin_dir = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
+                                       "ti,pindir-d0-out-d1-in",
+                                       MCSPI_PINDIR_D0_IN_D1_OUT);
+       plat->wordlen = SPI_DEFAULT_WORDLEN;
+
+       return 0;
+}
+
 static struct omap2_mcspi_platform_config omap2_pdata = {
        .regs_offset = 0,
 };
@@ -697,13 +555,17 @@ static const struct udevice_id omap3_spi_ids[] = {
        { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
        { }
 };
+#endif
 
 U_BOOT_DRIVER(omap3_spi) = {
        .name   = "omap3_spi",
        .id     = UCLASS_SPI,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        .of_match = omap3_spi_ids,
+        .ofdata_to_platdata = omap3_spi_ofdata_to_platdata,
+        .platdata_auto_alloc_size = sizeof(struct omap3_spi_platdata),
+#endif
        .probe = omap3_spi_probe,
        .ops    = &omap3_spi_ops,
        .priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
 };
-#endif
include/dm/platform_data/spi_omap3.h new file +16 -1
new file mode 100644
index 0000000000..9323266de7
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __spi_omap3_h
+#define __spi_omap3_h
+
+struct omap3_spi_platdata {
+       struct mcspi *regs;
+       unsigned int wordlen;
+       unsigned int pin_dir:1;
+};
+
+#endif /* __spi_omap3_h */
--

2.14.3

#3 lore raw

PATCH v2 1/3 spi: omap3_spi: Full dm conversion

Quoted 3 lines · Adam Ford
Quoted 2 lines · Jagan Teki

omap3_spi now support dt along with platform data, respective boards need to switch into dm for the same.

Added all board maintainers, using this driver on their relevant boards. So try to switch to DM_SPI(SPI_FLASH) before migration deadline expires.

Jagan.

author
#4 lore raw

PATCH v2 2/3 spi: davinci: Full dm conversion

In reply to Jagan Teki

From: Jagan Teki <[email protected]>

davinci_spi now support dt along with platform data, respective boards need to switch into dm for the same.

---
 drivers/spi/Kconfig                    |  12 +-
 drivers/spi/davinci_spi.c              | 275 +++++++++------------------------
 include/dm/platform_data/spi_davinci.h |  15 ++
 3 files changed, 90 insertions(+), 212 deletions(-)
 create mode 100644 include/dm/platform_data/spi_davinci.h
drivers/spi/Kconfig +6 -6
index 5e73dd4296..9e3c290e42 100644
@@ -70,6 +70,12 @@ config CADENCE_QSPI
 	  used to access the SPI NOR flash on platforms embedding this
 	  Cadence IP core.
 
+config DAVINCI_SPI
+	bool "Davinci & Keystone SPI driver"
+	depends on ARCH_DAVINCI || ARCH_KEYSTONE
+	help
+	  Enable the Davinci SPI driver
+
 config DESIGNWARE_SPI
 	bool "Designware SPI driver"
 	help
@@ -246,12 +252,6 @@ config FSL_QSPI
 	  used to access the SPI NOR flash on platforms embedding this
 	  Freescale IP core.
 
-config DAVINCI_SPI
-	bool "Davinci & Keystone SPI driver"
-	depends on ARCH_DAVINCI || ARCH_KEYSTONE
-	help
-	  Enable the Davinci SPI driver
-
 config SH_SPI
 	bool "SuperH SPI driver"
 	help
drivers/spi/davinci_spi.c +69 -206

350 lines not on this page · raw message

include/dm/platform_data/spi_davinci.h new file +15 -0
new file mode 100644
index 0000000000..fbc62c262a
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __spi_davinci_h
+#define __spi_davinci_h
+
+struct davinci_spi_platdata {
+	struct davinci_spi_regs *regs;
+	u8 num_cs;	   /* total no. of CS available */
+};
+
+#endif /* __spi_davinci_h */
Signature · 1 line
2.14.3
#5 lore raw

PATCH v2 2/3 spi: davinci: Full dm conversion

Hi Jagan,

Quoted 34 lines
drivers/spi/davinci_spi.c +3 -4
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 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 = dev_of_offset(bus);
+       struct davinci_spi_platdata *plat = bus->platdata;
+       fdt_addr_t addr;
 
-       ds->regs = devfdt_map_physmem(bus, sizeof(struct

davinci_spi_regs));

drivers/spi/davinci_spi.c +5 -4
-       if (!ds->regs) {
-               printf("%s: could not map device address\n", __func__);
+       addr = devfdt_get_addr(bus);
+       if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
-       }
-       ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
+       plat->regs = (struct davinci_spi_regs *)addr;
+       plat->num_cs = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),

"num-cs", 4);

        return 0;

}

drivers/spi/davinci_spi.c +1 -0
@@ -566,14 +426,17 @@ static const struct udevice_id davinci_spi_ids[] = {
        { .compatible = "ti,da830-spi" },
        { }
 };
+#endif
 
 U_BOOT_DRIVER(davinci_spi) = {
        .name = "davinci_spi",
        .id = UCLASS_SPI,

drivers/spi/davinci_spi.c static const struct udevice_id davinci_spi_ids[] = { · line 441

Quoted 10 lines
drivers/spi/davinci_spi.c +4 -2
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        .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),
+        .platdata_auto_alloc_size = sizeof(struct davinci_spi_platdata),
+#endif
        .probe = davinci_spi_probe,
+       .ops = &davinci_spi_ops,
 

In this patch definition of davinci_spi_ops is being guarded by OF_CONTROL, It should be out side of OF_CONTROL.

drivers/spi/davinci_spi.c static const struct udevice_id davinci_spi_ids[] = { · line 442

Quoted 4 lines
drivers/spi/davinci_spi.c +1 -0
+       .priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
 };

Thanks,
Akash

#6 lore raw

PATCH v2 2/3 spi: davinci: Full dm conversion

Quoted 34 lines · Gajjar Akash

Hi Jagan,

Quoted 31 lines
drivers/spi/davinci_spi.c +3 -4
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 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 = dev_of_offset(bus);
+       struct davinci_spi_platdata *plat = bus->platdata;
+       fdt_addr_t addr;
 
-       ds->regs = devfdt_map_physmem(bus, sizeof(struct

davinci_spi_regs));

drivers/spi/davinci_spi.c +5 -4
-       if (!ds->regs) {
-               printf("%s: could not map device address\n", __func__);
+       addr = devfdt_get_addr(bus);
+       if (addr == FDT_ADDR_T_NONE)
                return -EINVAL;
-       }
-       ds->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+
+       plat->regs = (struct davinci_spi_regs *)addr;
+       plat->num_cs = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),

"num-cs", 4);

        return 0;

}

drivers/spi/davinci_spi.c +1 -0
@@ -566,14 +426,17 @@ static const struct udevice_id davinci_spi_ids[] = {
        { .compatible = "ti,da830-spi" },
        { }
 };
+#endif
 
Quoted 16 lines

drivers/spi/davinci_spi.c static const struct udevice_id davinci_spi_ids[] = {

Quoted 13 lines
drivers/spi/davinci_spi.c +4 -2
 U_BOOT_DRIVER(davinci_spi) = {
        .name = "davinci_spi",
        .id = UCLASS_SPI,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
        .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),
+        .platdata_auto_alloc_size = sizeof(struct davinci_spi_platdata),
+#endif
        .probe = davinci_spi_probe,
+       .ops = &davinci_spi_ops,
 

In this patch definition of davinci_spi_ops is being guarded by OF_CONTROL, It should be out side of OF_CONTROL.

Nice catch, will fix it on next version.

thanks, Jagan.

author
#7 lore raw

PATCH v2 3/3 spi: ti_qspi: Full dm conversion

In reply to Jagan Teki

ti_qspi now support dt along with platform data, respective boards need to switch into dm for the same.

---
 drivers/spi/ti_qspi.c                  | 490 ++++++++++++---------------------
 include/dm/platform_data/spi_ti_qspi.h |  19 ++
 2 files changed, 196 insertions(+), 313 deletions(-)
 create mode 100644 include/dm/platform_data/spi_ti_qspi.h
drivers/spi/ti_qspi.c +177 -313
index bea3aff943..2f62016422 100644
@@ -20,6 +20,8 @@
 #include <regmap.h>
 #include <syscon.h>
 
+#include <dm/platform_data/spi_ti_qspi.h>
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* ti qpsi register bit masks */
@@ -34,17 +36,17 @@ DECLARE_GLOBAL_DATA_PTR;
 #define QSPI_CLK_DIV_MAX                0xffff
 /* command */
 #define QSPI_EN_CS(n)                   (n << 28)
-#define QSPI_WLEN(n)                    ((n-1) << 19)
+#define QSPI_WLEN(n)                    ((n - 1) << 19)
 #define QSPI_3_PIN                      BIT(18)
 #define QSPI_RD_SNGL                    BIT(16)
 #define QSPI_WR_SNGL                    (2 << 16)
 #define QSPI_INVAL                      (4 << 16)
 #define QSPI_RD_QUAD                    (7 << 16)
 /* device control */
-#define QSPI_DD(m, n)                   (m << (3 + n*8))
-#define QSPI_CKPHA(n)                   (1 << (2 + n*8))
-#define QSPI_CSPOL(n)                   (1 << (1 + n*8))
-#define QSPI_CKPOL(n)                   (1 << (n*8))
+#define QSPI_DD(m, n)                   (m << (3 + n * 8))
+#define QSPI_CKPHA(n)                   (1 << (2 + n * 8))
+#define QSPI_CSPOL(n)                   (1 << (1 + n * 8))
+#define QSPI_CKPOL(n)                   (1 << (n * 8))
 /* status */
 #define QSPI_WC                         BIT(1)
 #define QSPI_BUSY                       BIT(0)
@@ -99,13 +101,9 @@ struct ti_qspi_regs {
 
 /* ti qspi priv */
 struct ti_qspi_priv {
-#ifndef CONFIG_DM_SPI
-	struct spi_slave slave;
-#else
 	void *memory_map;
 	uint max_hz;
 	u32 num_cs;
-#endif
 	struct ti_qspi_regs *base;
 	void *ctrl_mod_mmap;
 	ulong fclk;
@@ -114,37 +112,113 @@ struct ti_qspi_priv {
 	u32 dc;
 };
 
-static void ti_spi_set_speed(struct ti_qspi_priv *priv, uint hz)
+/* TODO: control from sf layer to here through dm-spi */
+#if defined(CONFIG_TI_EDMA3) && !defined(CONFIG_DMA)
+void spi_flash_copy_mmap(void *data, void *offset, size_t len)
+{
+	unsigned int			addr = (unsigned int)(data);
+	unsigned int			edma_slot_num = 1;
+
+	/* Invalidate the area, so no writeback into the RAM races with DMA */
+	invalidate_dcache_range(addr, addr + roundup(len, ARCH_DMA_MINALIGN));
+
+	/* enable edma3 clocks */
+	enable_edma3_clocks();
+
+	/* Call edma3 api to do actual DMA transfer	*/
+	edma3_transfer(EDMA3_BASE, edma_slot_num, data, offset, len);
+
+	/* disable edma3 clocks */
+	disable_edma3_clocks();
+
+	*((unsigned int *)offset) += len;
+}
+#endif
+
+static void ti_qspi_cs_deactivate(struct ti_qspi_priv *priv)
+{
+	writel(priv->cmd | QSPI_INVAL, &priv->base->cmd);
+	/* dummy readl to ensure bus sync */
+	readl(&priv->base->cmd);
+}
+
+static void ti_qspi_ctrl_mode_mmap(void *ctrl_mod_mmap, int cs, bool enable)
+{
+	u32 val;
+
+	val = readl(ctrl_mod_mmap);
+	if (enable)
+		val |= MEM_CS(cs);
+	else
+		val &= MEM_CS_UNSELECT;
+	writel(val, ctrl_mod_mmap);
+}
+
+static void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv,
+				      struct spi_slave *slave,
+				      bool enable)
+{
+	u32 memval;
+	u32 mode = slave->mode & (SPI_RX_QUAD | SPI_RX_DUAL);
+
+	if (!enable) {
+		writel(0, &priv->base->setup0);
+		return;
+	}
+
+	memval = QSPI_SETUP0_NUM_A_BYTES | QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS;
+
+	switch (mode) {
+	case SPI_RX_QUAD:
+		memval |= QSPI_CMD_READ_QUAD;
+		memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS;
+		memval |= QSPI_SETUP0_READ_QUAD;
+		slave->mode |= SPI_RX_QUAD;
+		break;
+	case SPI_RX_DUAL:
+		memval |= QSPI_CMD_READ_DUAL;
+		memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS;
+		memval |= QSPI_SETUP0_READ_DUAL;
+		break;
+	default:
+		memval |= QSPI_CMD_READ;
+		memval |= QSPI_SETUP0_NUM_D_BYTES_NO_BITS;
+		memval |= QSPI_SETUP0_READ_NORMAL;
+		break;
+	}
+
+	writel(memval, &priv->base->setup0);
+}
+
+static int ti_qspi_set_speed(struct udevice *bus, uint max_hz)
 {
+	struct ti_qspi_priv *priv = dev_get_priv(bus);
 	uint clk_div;
 
-	if (!hz)
+	if (!max_hz)
 		clk_div = 0;
 	else
-		clk_div = DIV_ROUND_UP(priv->fclk, hz) - 1;
+		clk_div = DIV_ROUND_UP(priv->fclk, max_hz) - 1;
 
 	/* truncate clk_div value to QSPI_CLK_DIV_MAX */
 	if (clk_div > QSPI_CLK_DIV_MAX)
 		clk_div = QSPI_CLK_DIV_MAX;
 
-	debug("ti_spi_set_speed: hz: %d, clock divider %d\n", hz, clk_div);
+	debug("%s: max_hz: %d, clock divider %d\n", __func__, max_hz, clk_div);
 
 	/* disable SCLK */
 	writel(readl(&priv->base->clk_ctrl) & ~QSPI_CLK_EN,
 	       &priv->base->clk_ctrl);
 	/* enable SCLK and program the clk divider */
 	writel(QSPI_CLK_EN | clk_div, &priv->base->clk_ctrl);
-}
 
-static void ti_qspi_cs_deactivate(struct ti_qspi_priv *priv)
-{
-	writel(priv->cmd | QSPI_INVAL, &priv->base->cmd);
-	/* dummy readl to ensure bus sync */
-	readl(&priv->base->cmd);
+	return 0;
 }
 
-static int __ti_qspi_set_mode(struct ti_qspi_priv *priv, unsigned int mode)
+static int ti_qspi_set_mode(struct udevice *bus, uint mode)
 {
+	struct ti_qspi_priv *priv = dev_get_priv(bus);
+
 	priv->dc = 0;
 	if (mode & SPI_CPHA)
 		priv->dc |= QSPI_CKPHA(0);
@@ -156,57 +230,83 @@ static int __ti_qspi_set_mode(struct ti_qspi_priv *priv, unsigned int mode)
 	return 0;
 }
 
-static int __ti_qspi_claim_bus(struct ti_qspi_priv *priv, int cs)
+static int ti_qspi_claim_bus(struct udevice *dev)
 {
+	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+	struct spi_slave *slave = dev_get_parent_priv(dev);
+	struct ti_qspi_priv *priv;
+	struct udevice *bus;
+
+	bus = dev->parent;
+	priv = dev_get_priv(bus);
+
+	if (slave_plat->cs > priv->num_cs) {
+		debug("invalid qspi chip select\n");
+		return -EINVAL;
+	}
+
+	__ti_qspi_setup_memorymap(priv, slave, true);
+
 	writel(priv->dc, &priv->base->dc);
 	writel(0, &priv->base->cmd);
 	writel(0, &priv->base->data);
 
-	priv->dc <<= cs * 8;
+	priv->dc <<= slave_plat->cs * 8;
 	writel(priv->dc, &priv->base->dc);
 
 	return 0;
 }
 
-static void __ti_qspi_release_bus(struct ti_qspi_priv *priv)
+static int ti_qspi_release_bus(struct udevice *dev)
 {
+	struct spi_slave *slave = dev_get_parent_priv(dev);
+	struct ti_qspi_priv *priv;
+	struct udevice *bus;
+
+	bus = dev->parent;
+	priv = dev_get_priv(bus);
+
+	__ti_qspi_setup_memorymap(priv, slave, false);
+
 	writel(0, &priv->base->dc);
 	writel(0, &priv->base->cmd);
 	writel(0, &priv->base->data);
-}
-
-static void ti_qspi_ctrl_mode_mmap(void *ctrl_mod_mmap, int cs, bool enable)
-{
-	u32 val;
 
-	val = readl(ctrl_mod_mmap);
-	if (enable)
-		val |= MEM_CS(cs);
-	else
-		val &= MEM_CS_UNSELECT;
-	writel(val, ctrl_mod_mmap);
+	return 0;
 }
 
-static int __ti_qspi_xfer(struct ti_qspi_priv *priv, unsigned int bitlen,
-			const void *dout, void *din, unsigned long flags,
-			u32 cs)
+static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen,
+			const void *dout, void *din, unsigned long flags)
 {
-	uint words = bitlen >> 3; /* fixed 8-bit word length */
 	const uchar *txp = dout;
+	struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
+	uint words = bitlen >> 3; /* fixed 8-bit word length */
 	uchar *rxp = din;
+	struct ti_qspi_priv *priv;
+	struct udevice *bus;
 	uint status;
 	int timeout;
 
+	bus = dev->parent;
+	priv = dev_get_priv(bus);
+
+	if (slave->cs > priv->num_cs) {
+		debug("invalid qspi chip select\n");
+		return -EINVAL;
+	}
+
 	/* Setup mmap flags */
 	if (flags & SPI_XFER_MMAP) {
 		writel(MM_SWITCH, &priv->base->memswitch);
 		if (priv->ctrl_mod_mmap)
-			ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, true);
+			ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap,
+					       slave->cs, true);
 		return 0;
 	} else if (flags & SPI_XFER_MMAP_END) {
 		writel(~MM_SWITCH, &priv->base->memswitch);
 		if (priv->ctrl_mod_mmap)
-			ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap, cs, false);
+			ti_qspi_ctrl_mode_mmap(priv->ctrl_mod_mmap,
+					       slave->cs, false);
 		return 0;
 	}
 
@@ -221,7 +321,7 @@ static int __ti_qspi_xfer(struct ti_qspi_priv *priv, unsigned int bitlen,
 	/* Setup command reg */
 	priv->cmd = 0;
 	priv->cmd |= QSPI_WLEN(8);
-	priv->cmd |= QSPI_EN_CS(cs);
+	priv->cmd |= QSPI_EN_CS(slave->cs);
 	if (priv->mode & SPI_3WIRE)
 		priv->cmd |= QSPI_3_PIN;
 	priv->cmd |= 0xfff;
@@ -282,7 +382,7 @@ static int __ti_qspi_xfer(struct ti_qspi_priv *priv, unsigned int bitlen,
 			*rxp++ = readl(&priv->base->data);
 			xfer_len = 1;
 			debug("rx done, status %08x, read %02x\n",
-			      status, *(rxp-1));
+			      status, *(rxp - 1));
 		}
 		words -= xfer_len;
 	}
@@ -294,263 +394,40 @@ static int __ti_qspi_xfer(struct ti_qspi_priv *priv, unsigned int bitlen,
 	return 0;
 }
 
-/* TODO: control from sf layer to here through dm-spi */
-#if defined(CONFIG_TI_EDMA3) && !defined(CONFIG_DMA)
-void spi_flash_copy_mmap(void *data, void *offset, size_t len)
-{
-	unsigned int			addr = (unsigned int) (data);
-	unsigned int			edma_slot_num = 1;
-
-	/* Invalidate the area, so no writeback into the RAM races with DMA */
-	invalidate_dcache_range(addr, addr + roundup(len, ARCH_DMA_MINALIGN));
-
-	/* enable edma3 clocks */
-	enable_edma3_clocks();
-
-	/* Call edma3 api to do actual DMA transfer	*/
-	edma3_transfer(EDMA3_BASE, edma_slot_num, data, offset, len);
-
-	/* disable edma3 clocks */
-	disable_edma3_clocks();
-
-	*((unsigned int *)offset) += len;
-}
-#endif
-
-#ifndef CONFIG_DM_SPI
-
-static inline struct ti_qspi_priv *to_ti_qspi_priv(struct spi_slave *slave)
-{
-	return container_of(slave, struct ti_qspi_priv, slave);
-}
-
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-	return 1;
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
-	/* CS handled in xfer */
-	return;
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-	struct ti_qspi_priv *priv = to_ti_qspi_priv(slave);
-	ti_qspi_cs_deactivate(priv);
-}
-
-void spi_init(void)
-{
-	/* nothing to do */
-}
-
-static void ti_spi_setup_spi_register(struct ti_qspi_priv *priv)
-{
-	u32 memval = 0;
-
-#ifdef CONFIG_QSPI_QUAD_SUPPORT
-	struct spi_slave *slave = &priv->slave;
-	memval |= (QSPI_CMD_READ_QUAD | QSPI_SETUP0_NUM_A_BYTES |
-			QSPI_SETUP0_NUM_D_BYTES_8_BITS |
-			QSPI_SETUP0_READ_QUAD | QSPI_CMD_WRITE |
-			QSPI_NUM_DUMMY_BITS);
-	slave->mode |= SPI_RX_QUAD;
-#else
-	memval |= QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES |
-			QSPI_SETUP0_NUM_D_BYTES_NO_BITS |
-			QSPI_SETUP0_READ_NORMAL | QSPI_CMD_WRITE |
-			QSPI_NUM_DUMMY_BITS;
-#endif
-
-	writel(memval, &priv->base->setup0);
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-				  unsigned int max_hz, unsigned int mode)
-{
-	struct ti_qspi_priv *priv;
-
-#ifdef CONFIG_AM43XX
-	gpio_request(CONFIG_QSPI_SEL_GPIO, "qspi_gpio");
-	gpio_direction_output(CONFIG_QSPI_SEL_GPIO, 1);
-#endif
-
-	priv = spi_alloc_slave(struct ti_qspi_priv, bus, cs);
-	if (!priv) {
-		printf("SPI_error: Fail to allocate ti_qspi_priv\n");
-		return NULL;
-	}
-
-	priv->base = (struct ti_qspi_regs *)QSPI_BASE;
-	priv->mode = mode;
-#if defined(CONFIG_DRA7XX)
-	priv->ctrl_mod_mmap = (void *)CORE_CTRL_IO;
-	priv->slave.memory_map = (void *)MMAP_START_ADDR_DRA;
-	priv->fclk = QSPI_DRA7XX_FCLK;
-#else
-	priv->slave.memory_map = (void *)MMAP_START_ADDR_AM43x;
-	priv->fclk = QSPI_FCLK;
-#endif
-
-	ti_spi_set_speed(priv, max_hz);
-
-#ifdef CONFIG_TI_SPI_MMAP
-	ti_spi_setup_spi_register(priv);
-#endif
-
-	return &priv->slave;
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
-	struct ti_qspi_priv *priv = to_ti_qspi_priv(slave);
-	free(priv);
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-	struct ti_qspi_priv *priv = to_ti_qspi_priv(slave);
-
-	debug("%s: bus:%i cs:%i\n", __func__, priv->slave.bus, priv->slave.cs);
-	__ti_qspi_set_mode(priv, priv->mode);
-	return __ti_qspi_claim_bus(priv, priv->slave.cs);
-}
-void spi_release_bus(struct spi_slave *slave)
-{
-	struct ti_qspi_priv *priv = to_ti_qspi_priv(slave);
-
-	debug("%s: bus:%i cs:%i\n", __func__, priv->slave.bus, priv->slave.cs);
-	__ti_qspi_release_bus(priv);
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
-	     void *din, unsigned long flags)
-{
-	struct ti_qspi_priv *priv = to_ti_qspi_priv(slave);
-
-	debug("spi_xfer: bus:%i cs:%i bitlen:%i flags:%lx\n",
-	      priv->slave.bus, priv->slave.cs, bitlen, flags);
-	return __ti_qspi_xfer(priv, bitlen, dout, din, flags, priv->slave.cs);
-}
-
-#else /* CONFIG_DM_SPI */
-
-static void __ti_qspi_setup_memorymap(struct ti_qspi_priv *priv,
-				      struct spi_slave *slave,
-				      bool enable)
-{
-	u32 memval;
-	u32 mode = slave->mode & (SPI_RX_QUAD | SPI_RX_DUAL);
-
-	if (!enable) {
-		writel(0, &priv->base->setup0);
-		return;
-	}
-
-	memval = QSPI_SETUP0_NUM_A_BYTES | QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS;
-
-	switch (mode) {
-	case SPI_RX_QUAD:
-		memval |= QSPI_CMD_READ_QUAD;
-		memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS;
-		memval |= QSPI_SETUP0_READ_QUAD;
-		slave->mode |= SPI_RX_QUAD;
-		break;
-	case SPI_RX_DUAL:
-		memval |= QSPI_CMD_READ_DUAL;
-		memval |= QSPI_SETUP0_NUM_D_BYTES_8_BITS;
-		memval |= QSPI_SETUP0_READ_DUAL;
-		break;
-	default:
-		memval |= QSPI_CMD_READ;
-		memval |= QSPI_SETUP0_NUM_D_BYTES_NO_BITS;
-		memval |= QSPI_SETUP0_READ_NORMAL;
-		break;
-	}
-
-	writel(memval, &priv->base->setup0);
-}
-
+static const struct dm_spi_ops ti_qspi_ops = {
+	.claim_bus	= ti_qspi_claim_bus,
+	.release_bus	= ti_qspi_release_bus,
+	.xfer		= ti_qspi_xfer,
+	.set_speed	= ti_qspi_set_speed,
+	.set_mode	= ti_qspi_set_mode,
+};
 
-static int ti_qspi_set_speed(struct udevice *bus, uint max_hz)
+static int ti_qspi_probe(struct udevice *bus)
 {
+	struct ti_qspi_platdata *plat = bus->platdata;
 	struct ti_qspi_priv *priv = dev_get_priv(bus);
 
-	ti_spi_set_speed(priv, max_hz);
+	priv->fclk = plat->fclk;
+	priv->ctrl_mod_mmap = plat->ctrl_mod_mmap;
+	priv->base = plat->base;
+	priv->memory_map = plat->memory_map;
+	priv->max_hz = plat->max_hz;
+	priv->num_cs = plat->num_cs;
 
 	return 0;
 }
 
-static int ti_qspi_set_mode(struct udevice *bus, uint mode)
-{
-	struct ti_qspi_priv *priv = dev_get_priv(bus);
-	return __ti_qspi_set_mode(priv, mode);
-}
-
-static int ti_qspi_claim_bus(struct udevice *dev)
-{
-	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
-	struct spi_slave *slave = dev_get_parent_priv(dev);
-	struct ti_qspi_priv *priv;
-	struct udevice *bus;
-
-	bus = dev->parent;
-	priv = dev_get_priv(bus);
-
-	if (slave_plat->cs > priv->num_cs) {
-		debug("invalid qspi chip select\n");
-		return -EINVAL;
-	}
-
-	__ti_qspi_setup_memorymap(priv, slave, true);
-
-	return __ti_qspi_claim_bus(priv, slave_plat->cs);
-}
-
-static int ti_qspi_release_bus(struct udevice *dev)
+static int ti_qspi_child_pre_probe(struct udevice *dev)
 {
 	struct spi_slave *slave = dev_get_parent_priv(dev);
-	struct ti_qspi_priv *priv;
-	struct udevice *bus;
-
-	bus = dev->parent;
-	priv = dev_get_priv(bus);
-
-	__ti_qspi_setup_memorymap(priv, slave, false);
-	__ti_qspi_release_bus(priv);
-
-	return 0;
-}
-
-static int ti_qspi_xfer(struct udevice *dev, unsigned int bitlen,
-			const void *dout, void *din, unsigned long flags)
-{
-	struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
-	struct ti_qspi_priv *priv;
-	struct udevice *bus;
-
-	bus = dev->parent;
-	priv = dev_get_priv(bus);
-
-	if (slave->cs > priv->num_cs) {
-		debug("invalid qspi chip select\n");
-		return -EINVAL;
-	}
-
-	return __ti_qspi_xfer(priv, bitlen, dout, din, flags, slave->cs);
-}
-
-static int ti_qspi_probe(struct udevice *bus)
-{
+	struct udevice *bus = dev_get_parent(dev);
 	struct ti_qspi_priv *priv = dev_get_priv(bus);
 
-	priv->fclk = dev_get_driver_data(bus);
-
+	slave->memory_map = priv->memory_map;
 	return 0;
 }
 
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 static void *map_syscon_chipselects(struct udevice *bus)
 {
 #if CONFIG_IS_ENABLED(SYSCON)
@@ -576,7 +453,7 @@ static void *map_syscon_chipselects(struct udevice *bus)
 
 	cell = fdt_getprop(gd->fdt_blob, dev_of_offset(bus),
 			   "syscon-chipselects", &len);
-	if (len < 2*sizeof(fdt32_t)) {
+	if (len < 2 * sizeof(fdt32_t)) {
 		debug("%s: offset not available\n", __func__);
 		return NULL;
 	}
@@ -584,6 +461,7 @@ static void *map_syscon_chipselects(struct udevice *bus)
 	return fdtdec_get_number(cell + 1, 1) + regmap_get_range(regmap, 0);
 #else
 	fdt_addr_t addr;
+
 	addr = devfdt_get_addr_index(bus, 2);
 	return (addr == FDT_ADDR_T_NONE) ? NULL :
 		map_physmem(addr, 0, MAP_NOCACHE);
@@ -592,61 +470,47 @@ static void *map_syscon_chipselects(struct udevice *bus)
 
 static int ti_qspi_ofdata_to_platdata(struct udevice *bus)
 {
-	struct ti_qspi_priv *priv = dev_get_priv(bus);
+	struct ti_qspi_platdata *plat = bus->platdata;
 	const void *blob = gd->fdt_blob;
 	int node = dev_of_offset(bus);
 
-	priv->ctrl_mod_mmap = map_syscon_chipselects(bus);
-	priv->base = map_physmem(devfdt_get_addr(bus),
+	plat->fclk = dev_get_driver_data(bus);
+	plat->ctrl_mod_mmap = map_syscon_chipselects(bus);
+	plat->base = map_physmem(devfdt_get_addr(bus),
 				 sizeof(struct ti_qspi_regs), MAP_NOCACHE);
-	priv->memory_map = map_physmem(devfdt_get_addr_index(bus, 1), 0,
+	plat->memory_map = map_physmem(devfdt_get_addr_index(bus, 1), 0,
 				       MAP_NOCACHE);
 
-	priv->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1);
-	if (priv->max_hz < 0) {
+	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -1);
+	if (plat->max_hz < 0) {
 		debug("Error: Max frequency missing\n");
 		return -ENODEV;
 	}
-	priv->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
+	plat->num_cs = fdtdec_get_int(blob, node, "num-cs", 4);
 
 	debug("%s: regs=<0x%x>, max-frequency=%d\n", __func__,
-	      (int)priv->base, priv->max_hz);
+	      (int)plat->base, plat->max_hz);
 
 	return 0;
 }
 
-static int ti_qspi_child_pre_probe(struct udevice *dev)
-{
-	struct spi_slave *slave = dev_get_parent_priv(dev);
-	struct udevice *bus = dev_get_parent(dev);
-	struct ti_qspi_priv *priv = dev_get_priv(bus);
-
-	slave->memory_map = priv->memory_map;
-	return 0;
-}
-
-static const struct dm_spi_ops ti_qspi_ops = {
-	.claim_bus	= ti_qspi_claim_bus,
-	.release_bus	= ti_qspi_release_bus,
-	.xfer		= ti_qspi_xfer,
-	.set_speed	= ti_qspi_set_speed,
-	.set_mode	= ti_qspi_set_mode,
-};
-
 static const struct udevice_id ti_qspi_ids[] = {
 	{ .compatible = "ti,dra7xxx-qspi",	.data = QSPI_DRA7XX_FCLK},
 	{ .compatible = "ti,am4372-qspi",	.data = QSPI_FCLK},
 	{ }
 };
+#endif
 
 U_BOOT_DRIVER(ti_qspi) = {
 	.name	= "ti_qspi",
 	.id	= UCLASS_SPI,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
 	.of_match = ti_qspi_ids,
-	.ops	= &ti_qspi_ops,
 	.ofdata_to_platdata = ti_qspi_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct ti_qspi_platdata),
+#endif
+	.ops	= &ti_qspi_ops,
 	.priv_auto_alloc_size = sizeof(struct ti_qspi_priv),
 	.probe	= ti_qspi_probe,
 	.child_pre_probe = ti_qspi_child_pre_probe,
 };
-#endif /* CONFIG_DM_SPI */
include/dm/platform_data/spi_ti_qspi.h new file +19 -0
new file mode 100644
index 0000000000..3f5355284e
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __spi_ti_qspi_h
+#define __spi_ti_qspi_h
+
+struct ti_qspi_platdata {
+	struct ti_qspi_regs *base;
+	void *ctrl_mod_mmap;
+	ulong fclk;
+	void *memory_map;
+	uint max_hz;
+	u32 num_cs;
+};
+
+#endif /* __spi_ti_qspi_h */
Signature · 1 line
2.14.3