* [U-Boot] [PATCH v2 0/3] spi: ompa3/davinci/ti_qspi: Full dm conversion
@ 2018-03-15 5:59 Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 1/3] spi: omap3_spi: " Jagan Teki
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Jagan Teki @ 2018-03-15 5:59 UTC (permalink / raw)
To: u-boot
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
--
2.14.3
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/3] spi: omap3_spi: Full dm conversion
2018-03-15 5:59 [U-Boot] [PATCH v2 0/3] spi: ompa3/davinci/ti_qspi: Full dm conversion Jagan Teki
@ 2018-03-15 5:59 ` Jagan Teki
2018-03-16 20:12 ` Adam Ford
2018-03-15 5:59 ` [U-Boot] [PATCH v2 2/3] spi: davinci: " Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 3/3] spi: ti_qspi: " Jagan Teki
2 siblings, 1 reply; 8+ messages in thread
From: Jagan Teki @ 2018-03-15 5:59 UTC (permalink / raw)
To: u-boot
omap3_spi now support dt along with platform data,
respective boards need to switch into dm for the same.
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
Tested-by: Adam Ford <aford173@gmail.com> #omap3_logic
---
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
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 12dde8fb95..5e73dd4296 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -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"
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 053a67bbe0..4760106f89 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -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, ®s->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
diff --git a/include/dm/platform_data/spi_omap3.h b/include/dm/platform_data/spi_omap3.h
new file mode 100644
index 0000000000..9323266de7
--- /dev/null
+++ b/include/dm/platform_data/spi_omap3.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * 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
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 2/3] spi: davinci: Full dm conversion
2018-03-15 5:59 [U-Boot] [PATCH v2 0/3] spi: ompa3/davinci/ti_qspi: Full dm conversion Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 1/3] spi: omap3_spi: " Jagan Teki
@ 2018-03-15 5:59 ` Jagan Teki
2018-04-26 8:15 ` Gajjar Akash
2018-03-15 5:59 ` [U-Boot] [PATCH v2 3/3] spi: ti_qspi: " Jagan Teki
2 siblings, 1 reply; 8+ messages in thread
From: Jagan Teki @ 2018-03-15 5:59 UTC (permalink / raw)
To: u-boot
From: Jagan Teki <jagannadh.teki@gmail.com>
davinci_spi now support dt along with platform data,
respective boards need to switch into dm for the same.
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
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
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 5e73dd4296..9e3c290e42 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -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
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index eda252d0b3..8fa5a22c78 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -15,6 +15,7 @@
#include <asm/io.h>
#include <asm/arch/hardware.h>
#include <dm.h>
+#include <dm/platform_data/spi_davinci.h>
/* SPIGCR0 */
#define SPIGCR0_SPIENA_MASK 0x1
@@ -119,9 +120,6 @@ 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; /* current SPI bus frequency */
unsigned int mode; /* current SPI mode used */
@@ -241,11 +239,43 @@ static int davinci_spi_read_write(struct davinci_spi_slave *ds, unsigned
return 0;
}
+static int davinci_spi_set_speed(struct udevice *bus, uint max_hz)
+{
+ struct davinci_spi_slave *ds = dev_get_priv(bus);
+
+ debug("%s speed %u\n", __func__, max_hz);
+ if (max_hz > CONFIG_SYS_SPI_CLK / 2)
+ return -EINVAL;
-static int __davinci_spi_claim_bus(struct davinci_spi_slave *ds, int cs)
+ ds->freq = max_hz;
+
+ return 0;
+}
+
+static int davinci_spi_set_mode(struct udevice *bus, uint mode)
{
+ struct davinci_spi_slave *ds = dev_get_priv(bus);
+
+ debug("%s mode %u\n", __func__, mode);
+ ds->mode = mode;
+
+ return 0;
+}
+
+static int davinci_spi_claim_bus(struct udevice *dev)
+{
+ 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);
unsigned int mode = 0, scalar;
+ if (slave_plat->cs >= ds->num_cs) {
+ printf("Invalid SPI chipselect\n");
+ return -EINVAL;
+ }
+ ds->half_duplex = slave_plat->mode & SPI_PREAMBLE;
+
/* Enable the SPI hardware */
writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
udelay(1000);
@@ -255,7 +285,7 @@ static int __davinci_spi_claim_bus(struct davinci_spi_slave *ds, int cs)
writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
/* CS, CLK, SIMO and SOMI are functional pins */
- writel(((1 << cs) | SPIPC0_CLKFUN_MASK |
+ writel(((1 << slave_plat->cs) | SPIPC0_CLKFUN_MASK |
SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
/* setup format */
@@ -293,20 +323,32 @@ static int __davinci_spi_claim_bus(struct davinci_spi_slave *ds, int cs)
return 0;
}
-static int __davinci_spi_release_bus(struct davinci_spi_slave *ds)
+static int davinci_spi_release_bus(struct udevice *dev)
{
+ struct davinci_spi_slave *ds = dev_get_priv(dev->parent);
+
/* 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)
+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);
unsigned int len;
+ if (slave->cs >= ds->num_cs) {
+ printf("Invalid SPI chipselect\n");
+ return -EINVAL;
+ }
+ ds->cur_cs = slave->cs;
+
if (bitlen == 0)
/* Finish any previously submitted transfers */
goto out;
@@ -340,214 +382,32 @@ out:
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)
-{
- int ret = 0;
-
- switch (bus) {
- case SPI0_BUS:
- if (cs < SPI0_NUM_CS)
- ret = 1;
- break;
-#ifdef CONFIG_SYS_SPI1
- case SPI1_BUS:
- if (cs < SPI1_NUM_CS)
- ret = 1;
- break;
-#endif
-#ifdef CONFIG_SYS_SPI2
- case SPI2_BUS:
- if (cs < SPI2_NUM_CS)
- ret = 1;
- break;
-#endif
- default:
- /* Invalid bus number. Do nothing */
- break;
- }
- return ret;
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
- /* do nothing */
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
- /* do nothing */
-}
-
-void spi_init(void)
-{
- /* do nothing */
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
- unsigned int max_hz, unsigned int mode)
-{
- struct davinci_spi_slave *ds;
-
- if (!spi_cs_is_valid(bus, cs))
- return NULL;
-
- ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs);
- if (!ds)
- return NULL;
-
- switch (bus) {
- case SPI0_BUS:
- ds->regs = (struct davinci_spi_regs *)SPI0_BASE;
- break;
-#ifdef CONFIG_SYS_SPI1
- case SPI1_BUS:
- ds->regs = (struct davinci_spi_regs *)SPI1_BASE;
- break;
-#endif
-#ifdef CONFIG_SYS_SPI2
- case SPI2_BUS:
- ds->regs = (struct davinci_spi_regs *)SPI2_BASE;
- break;
-#endif
- default: /* Invalid bus number */
- return NULL;
- }
-
- ds->freq = max_hz;
- ds->mode = mode;
-
- return &ds->slave;
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
- struct davinci_spi_slave *ds = to_davinci_spi(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);
-
-#ifdef CONFIG_SPI_HALF_DUPLEX
- ds->half_duplex = true;
-#else
- ds->half_duplex = false;
-#endif
- return __davinci_spi_claim_bus(ds, ds->slave.cs);
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
- struct davinci_spi_slave *ds = to_davinci_spi(slave);
-
- __davinci_spi_release_bus(ds);
-}
-
-#else
-static int davinci_spi_set_speed(struct udevice *bus, uint max_hz)
-{
- struct davinci_spi_slave *ds = dev_get_priv(bus);
-
- debug("%s speed %u\n", __func__, max_hz);
- if (max_hz > CONFIG_SYS_SPI_CLK / 2)
- return -EINVAL;
-
- ds->freq = max_hz;
-
- return 0;
-}
-
-static int davinci_spi_set_mode(struct udevice *bus, uint mode)
-{
- struct davinci_spi_slave *ds = dev_get_priv(bus);
-
- debug("%s mode %u\n", __func__, mode);
- ds->mode = mode;
return 0;
}
-static int davinci_spi_claim_bus(struct udevice *dev)
-{
- 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;
-
- return __davinci_spi_claim_bus(ds, slave_plat->cs);
-}
-
-static int davinci_spi_release_bus(struct udevice *dev)
-{
- struct davinci_spi_slave *ds = dev_get_priv(dev->parent);
-
- return __davinci_spi_release_bus(ds);
-}
-
-static int davinci_spi_xfer(struct udevice *dev, unsigned int bitlen,
- const void *dout, void *din,
- unsigned long flags)
+static int davinci_spi_probe(struct udevice *bus)
{
- 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);
+ struct davinci_spi_platdata *plat = bus->platdata;
+ ds->regs = plat->regs;
+ ds->num_cs = plat->num_cs;
- if (slave->cs >= ds->num_cs) {
- printf("Invalid SPI chipselect\n");
- return -EINVAL;
- }
- ds->cur_cs = slave->cs;
-
- return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
-}
-
-static int davinci_spi_probe(struct udevice *bus)
-{
- /* Nothing to do */
return 0;
}
+#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));
- 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;
}
@@ -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,
+#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,
+ .priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
};
-#endif
diff --git a/include/dm/platform_data/spi_davinci.h b/include/dm/platform_data/spi_davinci.h
new file mode 100644
index 0000000000..fbc62c262a
--- /dev/null
+++ b/include/dm/platform_data/spi_davinci.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * 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 */
--
2.14.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 3/3] spi: ti_qspi: Full dm conversion
2018-03-15 5:59 [U-Boot] [PATCH v2 0/3] spi: ompa3/davinci/ti_qspi: Full dm conversion Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 1/3] spi: omap3_spi: " Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 2/3] spi: davinci: " Jagan Teki
@ 2018-03-15 5:59 ` Jagan Teki
2 siblings, 0 replies; 8+ messages in thread
From: Jagan Teki @ 2018-03-15 5:59 UTC (permalink / raw)
To: u-boot
ti_qspi now support dt along with platform data,
respective boards need to switch into dm for the same.
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
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
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index bea3aff943..2f62016422 100644
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
@@ -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 */
diff --git a/include/dm/platform_data/spi_ti_qspi.h b/include/dm/platform_data/spi_ti_qspi.h
new file mode 100644
index 0000000000..3f5355284e
--- /dev/null
+++ b/include/dm/platform_data/spi_ti_qspi.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
+ *
+ * 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 */
--
2.14.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/3] spi: omap3_spi: Full dm conversion
2018-03-15 5:59 ` [U-Boot] [PATCH v2 1/3] spi: omap3_spi: " Jagan Teki
@ 2018-03-16 20:12 ` Adam Ford
2018-04-26 6:25 ` Jagan Teki
0 siblings, 1 reply; 8+ messages in thread
From: Adam Ford @ 2018-03-16 20:12 UTC (permalink / raw)
To: u-boot
On Thu, Mar 15, 2018 at 12:59 AM, Jagan Teki <jagan@amarulasolutions.com> wrote:
> omap3_spi now support dt along with platform data,
> respective boards need to switch into dm for the same.
>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> Tested-by: Adam Ford <aford173@gmail.com> #omap3_logic
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
> ---
> 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
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 12dde8fb95..5e73dd4296 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -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"
> diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
> index 053a67bbe0..4760106f89 100644
> --- a/drivers/spi/omap3_spi.c
> +++ b/drivers/spi/omap3_spi.c
> @@ -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, ®s->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
> diff --git a/include/dm/platform_data/spi_omap3.h b/include/dm/platform_data/spi_omap3.h
> new file mode 100644
> index 0000000000..9323266de7
> --- /dev/null
> +++ b/include/dm/platform_data/spi_omap3.h
> @@ -0,0 +1,16 @@
> +/*
> + * Copyright (C) 2018 Jagan Teki <jagan@amarulasolutions.com>
> + *
> + * 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
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 1/3] spi: omap3_spi: Full dm conversion
2018-03-16 20:12 ` Adam Ford
@ 2018-04-26 6:25 ` Jagan Teki
0 siblings, 0 replies; 8+ messages in thread
From: Jagan Teki @ 2018-04-26 6:25 UTC (permalink / raw)
To: u-boot
On Sat, Mar 17, 2018 at 1:42 AM, Adam Ford <aford173@gmail.com> wrote:
> On Thu, Mar 15, 2018 at 12:59 AM, Jagan Teki <jagan@amarulasolutions.com> wrote:
>> 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.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 2/3] spi: davinci: Full dm conversion
2018-03-15 5:59 ` [U-Boot] [PATCH v2 2/3] spi: davinci: " Jagan Teki
@ 2018-04-26 8:15 ` Gajjar Akash
2018-04-26 11:00 ` Jagan Teki
0 siblings, 1 reply; 8+ messages in thread
From: Gajjar Akash @ 2018-04-26 8:15 UTC (permalink / raw)
To: u-boot
Hi Jagan,
> +#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));
> - 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;
> }
> @@ -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,
> +#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.
> + .priv_auto_alloc_size = sizeof(struct davinci_spi_slave),
> };
>
>
Thanks,
Akash
^ permalink raw reply [flat|nested] 8+ messages in thread
* [U-Boot] [PATCH v2 2/3] spi: davinci: Full dm conversion
2018-04-26 8:15 ` Gajjar Akash
@ 2018-04-26 11:00 ` Jagan Teki
0 siblings, 0 replies; 8+ messages in thread
From: Jagan Teki @ 2018-04-26 11:00 UTC (permalink / raw)
To: u-boot
On Thu, Apr 26, 2018 at 1:45 PM, Gajjar Akash <gajjar04aka@gmail.com> wrote:
> Hi Jagan,
>
>
>> +#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));
>> - 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;
>> }
>> @@ -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,
>> +#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.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-04-26 11:00 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-15 5:59 [U-Boot] [PATCH v2 0/3] spi: ompa3/davinci/ti_qspi: Full dm conversion Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 1/3] spi: omap3_spi: " Jagan Teki
2018-03-16 20:12 ` Adam Ford
2018-04-26 6:25 ` Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 2/3] spi: davinci: " Jagan Teki
2018-04-26 8:15 ` Gajjar Akash
2018-04-26 11:00 ` Jagan Teki
2018-03-15 5:59 ` [U-Boot] [PATCH v2 3/3] spi: ti_qspi: " Jagan Teki
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.