diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 37 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/atmel_spi.c | 286 | ||||
-rw-r--r-- | drivers/spi/atmel_spi.h | 15 | ||||
-rw-r--r-- | drivers/spi/davinci_spi.c | 157 | ||||
-rw-r--r-- | drivers/spi/fsl_dspi.c | 132 | ||||
-rw-r--r-- | drivers/spi/mxs_spi.c | 158 | ||||
-rw-r--r-- | drivers/spi/soft_spi_legacy.c | 168 |
8 files changed, 120 insertions, 834 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 5941520..09b9cb1 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -119,6 +119,12 @@ config CF_SPI Enable the ColdFire SPI driver. This driver can be used on some m68k SoCs. +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 @@ -207,6 +213,12 @@ config MVEBU_A3700_SPI used to access the SPI NOR flash on platforms embedding this Marvell IP core. +config MXS_SPI + bool "MXS SPI Driver" + help + Enable the MXS SPI controller driver. This driver can be used + on the i.MX23 and i.MX28 SoCs. + config NXP_FSPI bool "NXP FlexSPI driver" depends on SPI_MEM @@ -280,6 +292,12 @@ config SPI_SIFIVE The SiFive SPI controller driver is found on various SiFive SoCs. +config SOFT_SPI + bool "Soft SPI driver" + help + Enable Soft SPI driver. This driver is to use GPIO simulate + the SPI protocol. + config SPI_SUNXI bool "Allwinner SoC SPI controllers" default ARCH_SUNXI @@ -385,13 +403,6 @@ config ZYNQMP_GQSPI endif # if DM_SPI -config SOFT_SPI - bool "Soft SPI driver" - depends on DM_SPI || (DEPRECATED && !DM_SPI) - help - Enable Soft SPI driver. This driver is to use GPIO simulate - the SPI protocol. - config FSL_ESPI bool "Freescale eSPI driver" imply SPI_FLASH_BAR @@ -400,12 +411,6 @@ config FSL_ESPI access the SPI interface and SPI NOR flash on platforms embedding this Freescale eSPI IP core. -config DAVINCI_SPI - bool "Davinci & Keystone SPI driver" - depends on ARCH_DAVINCI || ARCH_KEYSTONE - help - Enable the Davinci SPI driver - config SH_QSPI bool "Renesas Quad SPI driver" help @@ -424,12 +429,6 @@ config MXC_SPI Enable the MXC SPI controller driver. This driver can be used on various i.MX SoCs such as i.MX31/35/51/6/7. -config MXS_SPI - bool "MXS SPI Driver" - help - 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 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 3427764..54881a7 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_TI_QSPI) += ti_qspi.o else obj-y += spi.o obj-$(CONFIG_SPI_MEM) += spi-mem-nodm.o -obj-$(CONFIG_SOFT_SPI) += soft_spi_legacy.o endif obj-$(CONFIG_ALTERA_SPI) += altera_spi.o diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index f076e92..b120664 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -9,217 +9,102 @@ #include <spi.h> #include <malloc.h> #include <wait_bit.h> - #include <asm/io.h> - #include <asm/arch/clk.h> #include <asm/arch/hardware.h> -#ifdef CONFIG_DM_SPI #include <asm/arch/at91_spi.h> -#endif #if CONFIG_IS_ENABLED(DM_GPIO) #include <asm/gpio.h> #endif +#include <linux/bitops.h> -#include "atmel_spi.h" - -#ifndef CONFIG_DM_SPI - -static int spi_has_wdrbt(struct atmel_spi_slave *slave) -{ - unsigned int ver; - - ver = spi_readl(slave, VERSION); - - return (ATMEL_SPI_VERSION_REV(ver) >= 0x210); -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct atmel_spi_slave *as; - unsigned int scbr; - u32 csrx; - void *regs; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - switch (bus) { - case 0: - regs = (void *)ATMEL_BASE_SPI0; - break; -#ifdef ATMEL_BASE_SPI1 - case 1: - regs = (void *)ATMEL_BASE_SPI1; - break; -#endif -#ifdef ATMEL_BASE_SPI2 - case 2: - regs = (void *)ATMEL_BASE_SPI2; - break; -#endif -#ifdef ATMEL_BASE_SPI3 - case 3: - regs = (void *)ATMEL_BASE_SPI3; - break; -#endif - default: - return NULL; - } - - - scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz; - if (scbr > ATMEL_SPI_CSRx_SCBR_MAX) - /* Too low max SCK rate */ - return NULL; - if (scbr < 1) - scbr = 1; - - csrx = ATMEL_SPI_CSRx_SCBR(scbr); - csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8); - if (!(mode & SPI_CPHA)) - csrx |= ATMEL_SPI_CSRx_NCPHA; - if (mode & SPI_CPOL) - csrx |= ATMEL_SPI_CSRx_CPOL; - - as = spi_alloc_slave(struct atmel_spi_slave, bus, cs); - if (!as) - return NULL; - - as->regs = regs; - as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS - | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf); - if (spi_has_wdrbt(as)) - as->mr |= ATMEL_SPI_MR_WDRBT; - - spi_writel(as, CSR(cs), csrx); - - return &as->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - - free(as); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - - /* Enable the SPI hardware */ - spi_writel(as, CR, ATMEL_SPI_CR_SPIEN); - - /* - * Select the slave. This should set SCK to the correct - * initial state, etc. - */ - spi_writel(as, MR, as->mr); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - - /* Disable the SPI hardware */ - spi_writel(as, CR, ATMEL_SPI_CR_SPIDIS); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct atmel_spi_slave *as = to_atmel_spi(slave); - unsigned int len_tx; - unsigned int len_rx; - unsigned int len; - u32 status; - const u8 *txp = dout; - u8 *rxp = din; - u8 value; - - if (bitlen == 0) - /* Finish any previously submitted transfers */ - goto out; - - /* - * TODO: The controller can do non-multiple-of-8 bit - * transfers, but this driver currently doesn't support it. - * - * It's also not clear how such transfers are supposed to be - * represented as a stream of bytes...this is a limitation of - * the current SPI interface. - */ - if (bitlen % 8) { - /* Errors always terminate an ongoing transfer */ - flags |= SPI_XFER_END; - goto out; - } - - len = bitlen / 8; - - /* - * The controller can do automatic CS control, but it is - * somewhat quirky, and it doesn't really buy us much anyway - * in the context of U-Boot. - */ - if (flags & SPI_XFER_BEGIN) { - spi_cs_activate(slave); - /* - * sometimes the RDR is not empty when we get here, - * in theory that should not happen, but it DOES happen. - * Read it here to be on the safe side. - * That also clears the OVRES flag. Required if the - * following loop exits due to OVRES! - */ - spi_readl(as, RDR); - } - - for (len_tx = 0, len_rx = 0; len_rx < len; ) { - status = spi_readl(as, SR); - - if (status & ATMEL_SPI_SR_OVRES) - return -1; - - if (len_tx < len && (status & ATMEL_SPI_SR_TDRE)) { - if (txp) - value = *txp++; - else - value = 0; - spi_writel(as, TDR, value); - len_tx++; - } - if (status & ATMEL_SPI_SR_RDRF) { - value = spi_readl(as, RDR); - if (rxp) - *rxp++ = value; - len_rx++; - } - } - -out: - if (flags & SPI_XFER_END) { - /* - * Wait until the transfer is completely done before - * we deactivate CS. - */ - do { - status = spi_readl(as, SR); - } while (!(status & ATMEL_SPI_SR_TXEMPTY)); - - spi_cs_deactivate(slave); - } - - return 0; -} - -#else +/* + * Register definitions for the Atmel AT32/AT91 SPI Controller + */ +/* Register offsets */ +#define ATMEL_SPI_CR 0x0000 +#define ATMEL_SPI_MR 0x0004 +#define ATMEL_SPI_RDR 0x0008 +#define ATMEL_SPI_TDR 0x000c +#define ATMEL_SPI_SR 0x0010 +#define ATMEL_SPI_IER 0x0014 +#define ATMEL_SPI_IDR 0x0018 +#define ATMEL_SPI_IMR 0x001c +#define ATMEL_SPI_CSR(x) (0x0030 + 4 * (x)) +#define ATMEL_SPI_VERSION 0x00fc + +/* Bits in CR */ +#define ATMEL_SPI_CR_SPIEN BIT(0) +#define ATMEL_SPI_CR_SPIDIS BIT(1) +#define ATMEL_SPI_CR_SWRST BIT(7) +#define ATMEL_SPI_CR_LASTXFER BIT(24) + +/* Bits in MR */ +#define ATMEL_SPI_MR_MSTR BIT(0) +#define ATMEL_SPI_MR_PS BIT(1) +#define ATMEL_SPI_MR_PCSDEC BIT(2) +#define ATMEL_SPI_MR_FDIV BIT(3) +#define ATMEL_SPI_MR_MODFDIS BIT(4) +#define ATMEL_SPI_MR_WDRBT BIT(5) +#define ATMEL_SPI_MR_LLB BIT(7) +#define ATMEL_SPI_MR_PCS(x) (((x) & 15) << 16) +#define ATMEL_SPI_MR_DLYBCS(x) ((x) << 24) + +/* Bits in RDR */ +#define ATMEL_SPI_RDR_RD(x) (x) +#define ATMEL_SPI_RDR_PCS(x) ((x) << 16) + +/* Bits in TDR */ +#define ATMEL_SPI_TDR_TD(x) (x) +#define ATMEL_SPI_TDR_PCS(x) ((x) << 16) +#define ATMEL_SPI_TDR_LASTXFER BIT(24) + +/* Bits in SR/IER/IDR/IMR */ +#define ATMEL_SPI_SR_RDRF BIT(0) +#define ATMEL_SPI_SR_TDRE BIT(1) +#define ATMEL_SPI_SR_MODF BIT(2) +#define ATMEL_SPI_SR_OVRES BIT(3) +#define ATMEL_SPI_SR_ENDRX BIT(4) +#define ATMEL_SPI_SR_ENDTX BIT(5) +#define ATMEL_SPI_SR_RXBUFF BIT(6) +#define ATMEL_SPI_SR_TXBUFE BIT(7) +#define ATMEL_SPI_SR_NSSR BIT(8) +#define ATMEL_SPI_SR_TXEMPTY BIT(9) +#define ATMEL_SPI_SR_SPIENS BIT(16) + +/* Bits in CSRx */ +#define ATMEL_SPI_CSRx_CPOL BIT(0) +#define ATMEL_SPI_CSRx_NCPHA BIT(1) +#define ATMEL_SPI_CSRx_CSAAT BIT(3) +#define ATMEL_SPI_CSRx_BITS(x) ((x) << 4) +#define ATMEL_SPI_CSRx_SCBR(x) ((x) << 8) +#define ATMEL_SPI_CSRx_SCBR_MAX GENMASK(7, 0) +#define ATMEL_SPI_CSRx_DLYBS(x) ((x) << 16) +#define ATMEL_SPI_CSRx_DLYBCT(x) ((x) << 24) + +/* Bits in VERSION */ +#define ATMEL_SPI_VERSION_REV(x) ((x) & 0xfff) +#define ATMEL_SPI_VERSION_MFN(x) ((x) << 16) + +/* Constants for CSRx:BITS */ +#define ATMEL_SPI_BITS_8 0 +#define ATMEL_SPI_BITS_9 1 +#define ATMEL_SPI_BITS_10 2 +#define ATMEL_SPI_BITS_11 3 +#define ATMEL_SPI_BITS_12 4 +#define ATMEL_SPI_BITS_13 5 +#define ATMEL_SPI_BITS_14 6 +#define ATMEL_SPI_BITS_15 7 +#define ATMEL_SPI_BITS_16 8 #define MAX_CS_COUNT 4 +/* Register access macros */ +#define spi_readl(as, reg) \ + readl(as->regs + ATMEL_SPI_##reg) +#define spi_writel(as, reg, value) \ + writel(value, as->regs + ATMEL_SPI_##reg) + struct atmel_spi_platdata { struct at91_spi *regs; }; @@ -507,4 +392,3 @@ U_BOOT_DRIVER(atmel_spi) = { .priv_auto_alloc_size = sizeof(struct atmel_spi_priv), .probe = atmel_spi_probe, }; -#endif diff --git a/drivers/spi/atmel_spi.h b/drivers/spi/atmel_spi.h index 6167bd1..9663cca 100644 --- a/drivers/spi/atmel_spi.h +++ b/drivers/spi/atmel_spi.h @@ -79,23 +79,8 @@ #define ATMEL_SPI_BITS_15 7 #define ATMEL_SPI_BITS_16 8 -struct atmel_spi_slave { - struct spi_slave slave; - void *regs; - u32 mr; -}; - -static inline struct atmel_spi_slave *to_atmel_spi(struct spi_slave *slave) -{ - return container_of(slave, struct atmel_spi_slave, slave); -} - /* Register access macros */ #define spi_readl(as, reg) \ readl(as->regs + ATMEL_SPI_##reg) #define spi_writel(as, reg, value) \ writel(value, as->regs + ATMEL_SPI_##reg) - -#if !defined(CONFIG_SYS_SPI_WRITE_TOUT) -#define CONFIG_SYS_SPI_WRITE_TOUT (5 * CONFIG_SYS_HZ) -#endif diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 97ac97b..e1e9b45 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -55,41 +55,6 @@ /* SPIDEF */ #define SPIDEF_CSDEF0_MASK BIT(0) -#ifndef CONFIG_DM_SPI -#define SPI0_BUS 0 -#define SPI0_BASE CONFIG_SYS_SPI_BASE -/* - * Define default SPI0_NUM_CS as 1 for existing platforms that uses this - * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS - * if more than one CS is supported and by defining CONFIG_SYS_SPI0. - */ -#ifndef CONFIG_SYS_SPI0 -#define SPI0_NUM_CS 1 -#else -#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS -#endif - -/* - * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and - * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus - */ -#ifdef CONFIG_SYS_SPI1 -#define SPI1_BUS 1 -#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS -#define SPI1_BASE CONFIG_SYS_SPI1_BASE -#endif - -/* - * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and - * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus - */ -#ifdef CONFIG_SYS_SPI2 -#define SPI2_BUS 2 -#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS -#define SPI2_BASE CONFIG_SYS_SPI2_BASE -#endif -#endif - DECLARE_GLOBAL_DATA_PTR; /* davinci spi register set */ @@ -122,9 +87,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 */ @@ -346,124 +308,6 @@ out: 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 */ -} - -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); @@ -582,4 +426,3 @@ U_BOOT_DRIVER(davinci_spi) = { .ops = &davinci_spi_ops, .priv_auto_alloc_size = sizeof(struct davinci_spi_slave), }; -#endif diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c index 1cdb233..78ad61ca 100644 --- a/drivers/spi/fsl_dspi.c +++ b/drivers/spi/fsl_dspi.c @@ -100,13 +100,6 @@ struct fsl_dspi_priv { struct dspi *regs; }; -#ifndef CONFIG_DM_SPI -struct fsl_dspi { - struct spi_slave slave; - struct fsl_dspi_priv priv; -}; -#endif - __weak void cpu_dspi_port_conf(void) { } @@ -414,131 +407,7 @@ static int fsl_dspi_cfg_speed(struct fsl_dspi_priv *priv, uint speed) return 0; } -#ifndef CONFIG_DM_SPI -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - if (((cs >= 0) && (cs < 8)) && ((bus >= 0) && (bus < 8))) - return 1; - else - return 0; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct fsl_dspi *dspi; - uint mcr_cfg_val; - - dspi = spi_alloc_slave(struct fsl_dspi, bus, cs); - if (!dspi) - return NULL; - - cpu_dspi_port_conf(); - -#ifdef CONFIG_SYS_FSL_DSPI_BE - dspi->priv.flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG; -#endif - - dspi->priv.regs = (struct dspi *)MMAP_DSPI; - -#ifdef CONFIG_M68K - dspi->priv.bus_clk = gd->bus_clk; -#else - dspi->priv.bus_clk = mxc_get_clock(MXC_DSPI_CLK); -#endif - dspi->priv.speed_hz = FSL_DSPI_DEFAULT_SCK_FREQ; - - /* default: all CS signals inactive state is high */ - mcr_cfg_val = DSPI_MCR_MSTR | DSPI_MCR_PCSIS_MASK | - DSPI_MCR_CRXF | DSPI_MCR_CTXF; - fsl_dspi_init_mcr(&dspi->priv, mcr_cfg_val); - - for (i = 0; i < FSL_DSPI_MAX_CHIPSELECT; i++) - dspi->priv.ctar_val[i] = DSPI_CTAR_DEFAULT_VALUE; - -#ifdef CONFIG_SYS_DSPI_CTAR0 - if (FSL_DSPI_MAX_CHIPSELECT > 0) - dspi->priv.ctar_val[0] = CONFIG_SYS_DSPI_CTAR0; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR1 - if (FSL_DSPI_MAX_CHIPSELECT > 1) - dspi->priv.ctar_val[1] = CONFIG_SYS_DSPI_CTAR1; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR2 - if (FSL_DSPI_MAX_CHIPSELECT > 2) - dspi->priv.ctar_val[2] = CONFIG_SYS_DSPI_CTAR2; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR3 - if (FSL_DSPI_MAX_CHIPSELECT > 3) - dspi->priv.ctar_val[3] = CONFIG_SYS_DSPI_CTAR3; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR4 - if (FSL_DSPI_MAX_CHIPSELECT > 4) - dspi->priv.ctar_val[4] = CONFIG_SYS_DSPI_CTAR4; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR5 - if (FSL_DSPI_MAX_CHIPSELECT > 5) - dspi->priv.ctar_val[5] = CONFIG_SYS_DSPI_CTAR5; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR6 - if (FSL_DSPI_MAX_CHIPSELECT > 6) - dspi->priv.ctar_val[6] = CONFIG_SYS_DSPI_CTAR6; -#endif -#ifdef CONFIG_SYS_DSPI_CTAR7 - if (FSL_DSPI_MAX_CHIPSELECT > 7) - dspi->priv.ctar_val[7] = CONFIG_SYS_DSPI_CTAR7; -#endif - fsl_dspi_cfg_speed(&dspi->priv, max_hz); - - /* configure transfer mode */ - fsl_dspi_cfg_ctar_mode(&dspi->priv, cs, mode); - - /* configure active state of CSX */ - fsl_dspi_cfg_cs_active_state(&dspi->priv, cs, mode); - - return &dspi->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - free(slave); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - uint sr_val; - struct fsl_dspi *dspi = (struct fsl_dspi *)slave; - - cpu_dspi_claim_bus(slave->bus, slave->cs); - - fsl_dspi_clr_fifo(&dspi->priv); - - /* check module TX and RX status */ - sr_val = dspi_read32(dspi->priv.flags, &dspi->priv.regs->sr); - if ((sr_val & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) { - debug("DSPI RX/TX not ready!\n"); - return -EIO; - } - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct fsl_dspi *dspi = (struct fsl_dspi *)slave; - - dspi_halt(&dspi->priv, 1); - cpu_dspi_release_bus(slave->bus.slave->cs); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) -{ - struct fsl_dspi *dspi = (struct fsl_dspi *)slave; - return dspi_xfer(&dspi->priv, slave->cs, bitlen, dout, din, flags); -} -#else static int fsl_dspi_child_pre_probe(struct udevice *dev) { struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -745,4 +614,3 @@ U_BOOT_DRIVER(fsl_dspi) = { .child_pre_probe = fsl_dspi_child_pre_probe, .bind = fsl_dspi_bind, }; -#endif diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c index 0da4a80..e231e96 100644 --- a/drivers/spi/mxs_spi.c +++ b/drivers/spi/mxs_spi.c @@ -13,7 +13,10 @@ */ #include <common.h> +#include <dm.h> +#include <dt-structs.h> #include <cpu_func.h> +#include <errno.h> #include <log.h> #include <malloc.h> #include <memalign.h> @@ -34,34 +37,9 @@ #define MXSSSP_SMALL_TRANSFER 512 -static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs) -{ - writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set); - writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr); -} - -static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs) -{ - writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr); - writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set); -} - -#if !CONFIG_IS_ENABLED(DM_SPI) -struct mxs_spi_slave { - struct spi_slave slave; - uint32_t max_khz; - uint32_t mode; - struct mxs_ssp_regs *regs; -}; - -static inline struct mxs_spi_slave *to_mxs_slave(struct spi_slave *slave) -{ - return container_of(slave, struct mxs_spi_slave, slave); -} -#else -#include <dm.h> -#include <errno.h> -#include <dt-structs.h> +/* Base numbers of i.MX2[38] clk for ssp0 IP block */ +#define MXS_SSP_IMX23_CLKID_SSP0 33 +#define MXS_SSP_IMX28_CLKID_SSP0 46 #ifdef CONFIG_MX28 #define dtd_fsl_imx_spi dtd_fsl_imx28_spi @@ -87,20 +65,24 @@ struct mxs_spi_priv { unsigned int clk_id; unsigned int mode; }; -#endif -#if !CONFIG_IS_ENABLED(DM_SPI) -static int mxs_spi_xfer_pio(struct mxs_spi_slave *slave, - char *data, int length, int write, unsigned long flags) +static void mxs_spi_start_xfer(struct mxs_ssp_regs *ssp_regs) { - struct mxs_ssp_regs *ssp_regs = slave->regs; -#else + writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set); + writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr); +} + +static void mxs_spi_end_xfer(struct mxs_ssp_regs *ssp_regs) +{ + writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr); + writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set); +} + static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv, char *data, int length, int write, unsigned long flags) { struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif if (flags & SPI_XFER_BEGIN) mxs_spi_start_xfer(ssp_regs); @@ -156,17 +138,10 @@ static int mxs_spi_xfer_pio(struct mxs_spi_priv *priv, return 0; } -#if !CONFIG_IS_ENABLED(DM_SPI) -static int mxs_spi_xfer_dma(struct mxs_spi_slave *slave, - char *data, int length, int write, unsigned long flags) -{ - struct mxs_ssp_regs *ssp_regs = slave->regs; -#else static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, char *data, int length, int write, unsigned long flags) { struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif const int xfer_max_sz = 0xff00; const int desc_count = DIV_ROUND_UP(length, xfer_max_sz) + 1; struct mxs_dma_desc *dp; @@ -207,11 +182,7 @@ static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, /* Invalidate the area, so no writeback into the RAM races with DMA */ invalidate_dcache_range(dstart, dstart + cache_data_count); -#if !CONFIG_IS_ENABLED(DM_SPI) - dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + slave->slave.bus; -#else dmach = priv->dma_channel; -#endif dp = desc; while (length) { @@ -288,20 +259,12 @@ static int mxs_spi_xfer_dma(struct mxs_spi_priv *priv, return ret; } -#if !CONFIG_IS_ENABLED(DM_SPI) -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; -#else int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev_get_parent(dev); struct mxs_spi_priv *priv = dev_get_priv(bus); struct mxs_ssp_regs *ssp_regs = priv->regs; -#endif int len = bitlen / 8; char dummy; int write = 0; @@ -345,99 +308,13 @@ int mxs_spi_xfer(struct udevice *dev, unsigned int bitlen, if (!dma || (len < MXSSSP_SMALL_TRANSFER)) { writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr); -#if !CONFIG_IS_ENABLED(DM_SPI) - return mxs_spi_xfer_pio(mxs_slave, data, len, write, flags); -#else return mxs_spi_xfer_pio(priv, data, len, write, flags); -#endif } else { writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set); -#if !CONFIG_IS_ENABLED(DM_SPI) - return mxs_spi_xfer_dma(mxs_slave, data, len, write, flags); -#else return mxs_spi_xfer_dma(priv, data, len, write, flags); -#endif } } -#if !CONFIG_IS_ENABLED(DM_SPI) -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - /* MXS SPI: 4 ports and 3 chip selects maximum */ - if (!mxs_ssp_bus_id_valid(bus) || cs > 2) - return 0; - else - return 1; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct mxs_spi_slave *mxs_slave; - - if (!spi_cs_is_valid(bus, cs)) { - printf("mxs_spi: invalid bus %d / chip select %d\n", bus, cs); - return NULL; - } - - mxs_slave = spi_alloc_slave(struct mxs_spi_slave, bus, cs); - if (!mxs_slave) - return NULL; - - if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + bus)) - goto err_init; - - mxs_slave->max_khz = max_hz / 1000; - mxs_slave->mode = mode; - mxs_slave->regs = mxs_ssp_regs_by_bus(bus); - - return &mxs_slave->slave; - -err_init: - free(mxs_slave); - return NULL; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - - free(mxs_slave); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct mxs_spi_slave *mxs_slave = to_mxs_slave(slave); - struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; - u32 reg = 0; - - mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg); - - writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) | - SSP_CTRL0_BUS_WIDTH_ONE_BIT, - &ssp_regs->hw_ssp_ctrl0); - - reg = SSP_CTRL1_SSP_MODE_SPI | SSP_CTRL1_WORD_LENGTH_EIGHT_BITS; - reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0; - reg |= (mxs_slave->mode & SPI_CPHA) ? SSP_CTRL1_PHASE : 0; - writel(reg, &ssp_regs->hw_ssp_ctrl1); - - writel(0, &ssp_regs->hw_ssp_cmd0); - - mxs_set_ssp_busclock(slave->bus, mxs_slave->max_khz); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ -} - -#else /* CONFIG_DM_SPI */ -/* Base numbers of i.MX2[38] clk for ssp0 IP block */ -#define MXS_SSP_IMX23_CLKID_SSP0 33 -#define MXS_SSP_IMX28_CLKID_SSP0 46 - static int mxs_spi_probe(struct udevice *bus) { struct mxs_spi_platdata *plat = dev_get_platdata(bus); @@ -625,4 +502,3 @@ U_BOOT_DRIVER(mxs_spi) = { .priv_auto_alloc_size = sizeof(struct mxs_spi_priv), .probe = mxs_spi_probe, }; -#endif diff --git a/drivers/spi/soft_spi_legacy.c b/drivers/spi/soft_spi_legacy.c deleted file mode 100644 index cc5ab5f..0000000 --- a/drivers/spi/soft_spi_legacy.c +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2002 - * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. - * - * Influenced by code from: - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - */ - -#include <common.h> -#include <spi.h> - -#include <malloc.h> - -/*----------------------------------------------------------------------- - * Definitions - */ - -#ifdef DEBUG_SPI -#define PRINTD(fmt,args...) printf (fmt ,##args) -#else -#define PRINTD(fmt,args...) -#endif - -struct soft_spi_slave { - struct spi_slave slave; - unsigned int mode; -}; - -static inline struct soft_spi_slave *to_soft_spi(struct spi_slave *slave) -{ - return container_of(slave, struct soft_spi_slave, slave); -} - -/*=====================================================================*/ -/* Public Functions */ -/*=====================================================================*/ - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct soft_spi_slave *ss; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - ss = spi_alloc_slave(struct soft_spi_slave, bus, cs); - if (!ss) - return NULL; - - ss->mode = mode; - - /* TODO: Use max_hz to limit the SCK rate */ - - return &ss->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct soft_spi_slave *ss = to_soft_spi(slave); - - free(ss); -} - -int spi_claim_bus(struct spi_slave *slave) -{ -#ifdef CONFIG_SYS_IMMR - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; -#endif - struct soft_spi_slave *ss = to_soft_spi(slave); - - /* - * Make sure the SPI clock is in idle state as defined for - * this slave. - */ - if (ss->mode & SPI_CPOL) - SPI_SCL(1); - else - SPI_SCL(0); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Nothing to do */ -} - -/*----------------------------------------------------------------------- - * SPI transfer - * - * This writes "bitlen" bits out the SPI MOSI port and simultaneously clocks - * "bitlen" bits in the SPI MISO port. That's just the way SPI works. - * - * The source of the outgoing bits is the "dout" parameter and the - * destination of the input bits is the "din" parameter. Note that "dout" - * and "din" can point to the same memory location, in which case the - * input data overwrites the output data (since both are buffered by - * temporary variables, this is OK). - */ -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ -#ifdef CONFIG_SYS_IMMR - volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; -#endif - struct soft_spi_slave *ss = to_soft_spi(slave); - uchar tmpdin = 0; - uchar tmpdout = 0; - const u8 *txd = dout; - u8 *rxd = din; - int cpol = ss->mode & SPI_CPOL; - int cpha = ss->mode & SPI_CPHA; - unsigned int j; - - PRINTD("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", - slave->bus, slave->cs, *(uint *)txd, *(uint *)rxd, bitlen); - - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); - - for(j = 0; j < bitlen; j++) { - /* - * Check if it is time to work on a new byte. - */ - if ((j % 8) == 0) { - if (txd) - tmpdout = *txd++; - else - tmpdout = 0; - if(j != 0) { - if (rxd) - *rxd++ = tmpdin; - } - tmpdin = 0; - } - - if (!cpha) - SPI_SCL(!cpol); - SPI_SDA(tmpdout & 0x80); - SPI_DELAY; - if (cpha) - SPI_SCL(!cpol); - else - SPI_SCL(cpol); - tmpdin <<= 1; - tmpdin |= SPI_READ; - tmpdout <<= 1; - SPI_DELAY; - if (cpha) - SPI_SCL(cpol); - } - /* - * If the number of bits isn't a multiple of 8, shift the last - * bits over to left-justify them. Then store the last byte - * read in. - */ - if (rxd) { - if ((bitlen % 8) != 0) - tmpdin <<= 8 - (bitlen % 8); - *rxd++ = tmpdin; - } - - if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); - - return(0); -} |