[U-Boot] [PATCH v2 1/2] spi: omap3: Skip set_mode, set_speed from claim

set_mode, set_seed functions has separate function pointers in dm_spi_ops, so use them in relevent one instead of calling from claim_bus.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com --- Changes for v2: - None
drivers/spi/omap3_spi.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index 1da4542af0..b8a0bf495a 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -456,9 +456,6 @@ static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv) conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
writel(conf, &priv->regs->modulctrl); - - _omap3_spi_set_mode(priv); - _omap3_spi_set_speed(priv); }
#ifndef CONFIG_DM_SPI @@ -594,8 +591,6 @@ static int omap3_spi_claim_bus(struct udevice *dev) struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
priv->cs = slave_plat->cs; - priv->mode = slave_plat->mode; - priv->freq = slave_plat->max_hz; _omap3_spi_claim_bus(priv);
return 0; @@ -652,11 +647,27 @@ static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
static int omap3_spi_set_speed(struct udevice *bus, 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); + + priv->cs = slave_plat->cs; + priv->freq = slave_plat->max_hz; + _omap3_spi_set_speed(priv); + return 0; }
static int omap3_spi_set_mode(struct udevice *bus, 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); + + priv->cs = slave_plat->cs; + priv->mode = slave_plat->mode; + _omap3_spi_set_mode(priv); + return 0; }

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 --- Changes for v2: - Fixes omap3_spi_ofdata_to_platdata, build
drivers/spi/Kconfig | 14 +- drivers/spi/omap3_spi.c | 342 +++++++++++------------------------ include/dm/platform_data/spi_omap3.h | 16 ++ 3 files changed, 125 insertions(+), 247 deletions(-) create mode 100644 include/dm/platform_data/spi_omap3.h
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index fd3f115ccf..56c337f664 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -99,6 +99,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 @@ -291,11 +298,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 b8a0bf495a..a6f1533985 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,61 +408,101 @@ 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 *bus, unsigned int speed) +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; }
-static int omap3_spi_set_mode(struct udevice *bus, uint mode) +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; } @@ -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 */

On Tue, Mar 6, 2018 at 11:00 PM, Jagan Teki jagannadh.teki@gmail.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
Changes for v2:
- Fixes omap3_spi_ofdata_to_platdata, build
Thanks for fixing that.
Tested-by: Adam Ford aford173@gmail.com #omap3_logic
drivers/spi/Kconfig | 14 +- drivers/spi/omap3_spi.c | 342 +++++++++++------------------------ include/dm/platform_data/spi_omap3.h | 16 ++ 3 files changed, 125 insertions(+), 247 deletions(-) create mode 100644 include/dm/platform_data/spi_omap3.h
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index fd3f115ccf..56c337f664 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -99,6 +99,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 @@ -291,11 +298,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 b8a0bf495a..a6f1533985 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,61 +408,101 @@ 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 *bus, unsigned int speed) +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;
}
-static int omap3_spi_set_mode(struct udevice *bus, uint mode) +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;
} @@ -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

On Wed, Mar 7, 2018 at 10:30 AM, Jagan Teki jagannadh.teki@gmail.com wrote:
set_mode, set_seed functions has separate function pointers in dm_spi_ops, so use them in relevent one instead of calling from claim_bus.
Signed-off-by: Jagan Teki jagan@amarulasolutions.com
Applied to u-boot-spi/master
participants (2)
-
Adam Ford
-
Jagan Teki