[U-Boot] [PATCH 1/4] SPI:rewrite the Freescale DSPI driver.

Chao Fu b44548 at freescale.com
Mon Nov 18 07:34:37 CET 2013


From: Chao Fu <B44548 at freescale.com>

Freescale DSPI module is used on both the ColdFire platform and the ARM
platform. The original DSPI driver is written for ColdFire platform only, this patch
rewrite the driver to make it be used across the platforms. The rewrite including the 
following changes:

Rename the file name :
	cf_spi.c -> fsl_dspi.c
Move the file:
	arch/m68k/include/asm/coldfire/dspi.h -> include/fsl_dspi.h
Rename the functions and variables:
	cfxxx -> dspixxx
Keep the following functions for ColdFire: 
	cfspi_port_conf()
	cfspi_claim_bus()
	cfspi_release_bus()

Signed-off-by: Chao Fu <B44548 at freescale.com>
---
 arch/m68k/include/asm/coldfire/dspi.h | 142 --------------
 drivers/spi/Makefile                  |   2 +-
 drivers/spi/cf_spi.c                  | 347 ---------------------------------
 drivers/spi/fsl_dspi.c                | 352 ++++++++++++++++++++++++++++++++++
 include/fsl_dspi.h                    | 147 ++++++++++++++
 5 files changed, 500 insertions(+), 490 deletions(-)
 delete mode 100644 arch/m68k/include/asm/coldfire/dspi.h
 delete mode 100644 drivers/spi/cf_spi.c
 create mode 100644 drivers/spi/fsl_dspi.c
 create mode 100644 include/fsl_dspi.h

diff --git a/arch/m68k/include/asm/coldfire/dspi.h b/arch/m68k/include/asm/coldfire/dspi.h
deleted file mode 100644
index fda7138..0000000
--- a/arch/m68k/include/asm/coldfire/dspi.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * MCF5227x Internal Memory Map
- *
- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
- * TsiChung Liew (Tsi-Chung.Liew at freescale.com)
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#ifndef __DSPI_H__
-#define __DSPI_H__
-
-/* DMA Serial Peripheral Interface (DSPI) */
-typedef struct dspi {
-	u32 mcr;	/* 0x00 */
-	u32 resv0;	/* 0x04 */
-	u32 tcr;	/* 0x08 */
-	u32 ctar[8];	/* 0x0C - 0x28 */
-	u32 sr;		/* 0x2C */
-	u32 irsr;	/* 0x30 */
-	u32 tfr;	/* 0x34 - PUSHR */
-	u16 resv1;	/* 0x38 */
-	u16 rfr;	/* 0x3A - POPR */
-#ifdef CONFIG_MCF547x_8x
-	u32 tfdr[4];	/* 0x3C */
-	u8 resv2[0x30];	/* 0x40 */
-	u32 rfdr[4];	/* 0x7C */
-#else
-	u32 tfdr[16];	/* 0x3C */
-	u32 rfdr[16];	/* 0x7C */
-#endif
-} dspi_t;
-
-/* Module configuration */
-#define DSPI_MCR_MSTR			(0x80000000)
-#define DSPI_MCR_CSCK			(0x40000000)
-#define DSPI_MCR_DCONF(x)		(((x)&0x03)<<28)
-#define DSPI_MCR_FRZ			(0x08000000)
-#define DSPI_MCR_MTFE			(0x04000000)
-#define DSPI_MCR_PCSSE			(0x02000000)
-#define DSPI_MCR_ROOE			(0x01000000)
-#define DSPI_MCR_CSIS7			(0x00800000)
-#define DSPI_MCR_CSIS6			(0x00400000)
-#define DSPI_MCR_CSIS5			(0x00200000)
-#define DSPI_MCR_CSIS4			(0x00100000)
-#define DSPI_MCR_CSIS3			(0x00080000)
-#define DSPI_MCR_CSIS2			(0x00040000)
-#define DSPI_MCR_CSIS1			(0x00020000)
-#define DSPI_MCR_CSIS0			(0x00010000)
-#define DSPI_MCR_MDIS			(0x00004000)
-#define DSPI_MCR_DTXF			(0x00002000)
-#define DSPI_MCR_DRXF			(0x00001000)
-#define DSPI_MCR_CTXF			(0x00000800)
-#define DSPI_MCR_CRXF			(0x00000400)
-#define DSPI_MCR_SMPL_PT(x)		(((x)&0x03)<<8)
-#define DSPI_MCR_HALT			(0x00000001)
-
-/* Transfer count */
-#define DSPI_TCR_SPI_TCNT(x)		(((x)&0x0000FFFF)<<16)
-
-/* Clock and transfer attributes */
-#define DSPI_CTAR_DBR			(0x80000000)
-#define DSPI_CTAR_TRSZ(x)		(((x)&0x0F)<<27)
-#define DSPI_CTAR_CPOL			(0x04000000)
-#define DSPI_CTAR_CPHA			(0x02000000)
-#define DSPI_CTAR_LSBFE			(0x01000000)
-#define DSPI_CTAR_PCSSCK(x)		(((x)&0x03)<<22)
-#define DSPI_CTAR_PCSSCK_7CLK		(0x00A00000)
-#define DSPI_CTAR_PCSSCK_5CLK		(0x00800000)
-#define DSPI_CTAR_PCSSCK_3CLK		(0x00400000)
-#define DSPI_CTAR_PCSSCK_1CLK		(0x00000000)
-#define DSPI_CTAR_PASC(x)		(((x)&0x03)<<20)
-#define DSPI_CTAR_PASC_7CLK		(0x00300000)
-#define DSPI_CTAR_PASC_5CLK		(0x00200000)
-#define DSPI_CTAR_PASC_3CLK		(0x00100000)
-#define DSPI_CTAR_PASC_1CLK		(0x00000000)
-#define DSPI_CTAR_PDT(x)		(((x)&0x03)<<18)
-#define DSPI_CTAR_PDT_7CLK		(0x000A0000)
-#define DSPI_CTAR_PDT_5CLK		(0x00080000)
-#define DSPI_CTAR_PDT_3CLK		(0x00040000)
-#define DSPI_CTAR_PDT_1CLK		(0x00000000)
-#define DSPI_CTAR_PBR(x)		(((x)&0x03)<<16)
-#define DSPI_CTAR_PBR_7CLK		(0x00030000)
-#define DSPI_CTAR_PBR_5CLK		(0x00020000)
-#define DSPI_CTAR_PBR_3CLK		(0x00010000)
-#define DSPI_CTAR_PBR_1CLK		(0x00000000)
-#define DSPI_CTAR_CSSCK(x)		(((x)&0x0F)<<12)
-#define DSPI_CTAR_ASC(x)		(((x)&0x0F)<<8)
-#define DSPI_CTAR_DT(x)			(((x)&0x0F)<<4)
-#define DSPI_CTAR_BR(x)			(((x)&0x0F))
-
-/* Status */
-#define DSPI_SR_TCF			(0x80000000)
-#define DSPI_SR_TXRXS			(0x40000000)
-#define DSPI_SR_EOQF			(0x10000000)
-#define DSPI_SR_TFUF			(0x08000000)
-#define DSPI_SR_TFFF			(0x02000000)
-#define DSPI_SR_RFOF			(0x00080000)
-#define DSPI_SR_RFDF			(0x00020000)
-#define DSPI_SR_TXCTR(x)		(((x)&0x0F)<<12)
-#define DSPI_SR_TXPTR(x)		(((x)&0x0F)<<8)
-#define DSPI_SR_RXCTR(x)		(((x)&0x0F)<<4)
-#define DSPI_SR_RXPTR(x)		(((x)&0x0F))
-
-/* DMA/interrupt request selct and enable */
-#define DSPI_IRSR_TCFE			(0x80000000)
-#define DSPI_IRSR_EOQFE			(0x10000000)
-#define DSPI_IRSR_TFUFE			(0x08000000)
-#define DSPI_IRSR_TFFFE			(0x02000000)
-#define DSPI_IRSR_TFFFS			(0x01000000)
-#define DSPI_IRSR_RFOFE			(0x00080000)
-#define DSPI_IRSR_RFDFE			(0x00020000)
-#define DSPI_IRSR_RFDFS			(0x00010000)
-
-/* Transfer control - 32-bit access */
-#define DSPI_TFR_CONT			(0x80000000)
-#define DSPI_TFR_CTAS(x)		(((x)&0x07)<<12)
-#define DSPI_TFR_EOQ			(0x08000000)
-#define DSPI_TFR_CTCNT			(0x04000000)
-#define DSPI_TFR_CS7			(0x00800000)
-#define DSPI_TFR_CS6			(0x00400000)
-#define DSPI_TFR_CS5			(0x00200000)
-#define DSPI_TFR_CS4			(0x00100000)
-#define DSPI_TFR_CS3			(0x00080000)
-#define DSPI_TFR_CS2			(0x00040000)
-#define DSPI_TFR_CS1			(0x00020000)
-#define DSPI_TFR_CS0			(0x00010000)
-
-/* Transfer Fifo */
-#define DSPI_TFR_TXDATA(x)		(((x)&0xFFFF))
-
-/* Bit definitions and macros for DRFR */
-#define DSPI_RFR_RXDATA(x)		(((x)&0xFFFF))
-
-/* Bit definitions and macros for DTFDR group */
-#define DSPI_TFDR_TXDATA(x)		(((x)&0x0000FFFF))
-#define DSPI_TFDR_TXCMD(x)		(((x)&0x0000FFFF)<<16)
-
-/* Bit definitions and macros for DRFDR group */
-#define DSPI_RFDR_RXDATA(x)		(((x)&0x0000FFFF))
-
-#endif				/* __DSPI_H__ */
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 27902fe..a047f02 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
 obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
 obj-$(CONFIG_BFIN_SPI) += bfin_spi.o
 obj-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o
-obj-$(CONFIG_CF_SPI) += cf_spi.o
+obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o
 obj-$(CONFIG_CF_QSPI) += cf_qspi.o
 obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
 obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
diff --git a/drivers/spi/cf_spi.c b/drivers/spi/cf_spi.c
deleted file mode 100644
index 879a809..0000000
--- a/drivers/spi/cf_spi.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- *
- * (C) Copyright 2000-2003
- * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
- *
- * Copyright (C) 2004-2009 Freescale Semiconductor, Inc.
- * TsiChung Liew (Tsi-Chung.Liew at freescale.com)
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <spi.h>
-#include <malloc.h>
-#include <asm/immap.h>
-
-struct cf_spi_slave {
-	struct spi_slave slave;
-	uint baudrate;
-	int charbit;
-};
-
-int cfspi_xfer(struct spi_slave *slave, uint bitlen, const void *dout,
-	       void *din, ulong flags);
-struct spi_slave *cfspi_setup_slave(struct cf_spi_slave *cfslave, uint mode);
-void cfspi_init(void);
-void cfspi_tx(u32 ctrl, u16 data);
-u16 cfspi_rx(void);
-
-extern void cfspi_port_conf(void);
-extern int cfspi_claim_bus(uint bus, uint cs);
-extern void cfspi_release_bus(uint bus, uint cs);
-
-DECLARE_GLOBAL_DATA_PTR;
-
-#ifndef CONFIG_SPI_IDLE_VAL
-#if defined(CONFIG_SPI_MMC)
-#define CONFIG_SPI_IDLE_VAL	0xFFFF
-#else
-#define CONFIG_SPI_IDLE_VAL	0x0
-#endif
-#endif
-
-#if defined(CONFIG_CF_DSPI)
-/* DSPI specific mode */
-#define SPI_MODE_MOD	0x00200000
-#define SPI_DBLRATE	0x00100000
-
-void cfspi_init(void)
-{
-	volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
-
-	cfspi_port_conf();	/* port configuration */
-
-	dspi->mcr = DSPI_MCR_MSTR | DSPI_MCR_CSIS7 | DSPI_MCR_CSIS6 |
-	    DSPI_MCR_CSIS5 | DSPI_MCR_CSIS4 | DSPI_MCR_CSIS3 |
-	    DSPI_MCR_CSIS2 | DSPI_MCR_CSIS1 | DSPI_MCR_CSIS0 |
-	    DSPI_MCR_CRXF | DSPI_MCR_CTXF;
-
-	/* Default setting in platform configuration */
-#ifdef CONFIG_SYS_DSPI_CTAR0
-	dspi->ctar[0] = CONFIG_SYS_DSPI_CTAR0;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR1
-	dspi->ctar[1] = CONFIG_SYS_DSPI_CTAR1;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR2
-	dspi->ctar[2] = CONFIG_SYS_DSPI_CTAR2;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR3
-	dspi->ctar[3] = CONFIG_SYS_DSPI_CTAR3;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR4
-	dspi->ctar[4] = CONFIG_SYS_DSPI_CTAR4;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR5
-	dspi->ctar[5] = CONFIG_SYS_DSPI_CTAR5;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR6
-	dspi->ctar[6] = CONFIG_SYS_DSPI_CTAR6;
-#endif
-#ifdef CONFIG_SYS_DSPI_CTAR7
-	dspi->ctar[7] = CONFIG_SYS_DSPI_CTAR7;
-#endif
-}
-
-void cfspi_tx(u32 ctrl, u16 data)
-{
-	volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
-
-	while ((dspi->sr & 0x0000F000) >= 4) ;
-
-	dspi->tfr = (ctrl | data);
-}
-
-u16 cfspi_rx(void)
-{
-	volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
-
-	while ((dspi->sr & 0x000000F0) == 0) ;
-
-	return (dspi->rfr & 0xFFFF);
-}
-
-int cfspi_xfer(struct spi_slave *slave, uint bitlen, const void *dout,
-	       void *din, ulong flags)
-{
-	struct cf_spi_slave *cfslave = (struct cf_spi_slave *)slave;
-	u16 *spi_rd16 = NULL, *spi_wr16 = NULL;
-	u8 *spi_rd = NULL, *spi_wr = NULL;
-	static u32 ctrl = 0;
-	uint len = bitlen >> 3;
-
-	if (cfslave->charbit == 16) {
-		bitlen >>= 1;
-		spi_wr16 = (u16 *) dout;
-		spi_rd16 = (u16 *) din;
-	} else {
-		spi_wr = (u8 *) dout;
-		spi_rd = (u8 *) din;
-	}
-
-	if ((flags & SPI_XFER_BEGIN) == SPI_XFER_BEGIN)
-		ctrl |= DSPI_TFR_CONT;
-
-	ctrl = (ctrl & 0xFF000000) | ((1 << slave->cs) << 16);
-
-	if (len > 1) {
-		int tmp_len = len - 1;
-		while (tmp_len--) {
-			if (dout != NULL) {
-				if (cfslave->charbit == 16)
-					cfspi_tx(ctrl, *spi_wr16++);
-				else
-					cfspi_tx(ctrl, *spi_wr++);
-				cfspi_rx();
-			}
-
-			if (din != NULL) {
-				cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
-				if (cfslave->charbit == 16)
-					*spi_rd16++ = cfspi_rx();
-				else
-					*spi_rd++ = cfspi_rx();
-			}
-		}
-
-		len = 1;	/* remaining byte */
-	}
-
-	if ((flags & SPI_XFER_END) == SPI_XFER_END)
-		ctrl &= ~DSPI_TFR_CONT;
-
-	if (len) {
-		if (dout != NULL) {
-			if (cfslave->charbit == 16)
-				cfspi_tx(ctrl, *spi_wr16);
-			else
-				cfspi_tx(ctrl, *spi_wr);
-			cfspi_rx();
-		}
-
-		if (din != NULL) {
-			cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
-			if (cfslave->charbit == 16)
-				*spi_rd16 = cfspi_rx();
-			else
-				*spi_rd = cfspi_rx();
-		}
-	} else {
-		/* dummy read */
-		cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
-		cfspi_rx();
-	}
-
-	return 0;
-}
-
-struct spi_slave *cfspi_setup_slave(struct cf_spi_slave *cfslave, uint mode)
-{
-	/*
-	 * bit definition for mode:
-	 * bit 31 - 28: Transfer size 3 to 16 bits
-	 *     27 - 26: PCS to SCK delay prescaler
-	 *     25 - 24: After SCK delay prescaler
-	 *     23 - 22: Delay after transfer prescaler
-	 *     21     : Allow overwrite for bit 31-22 and bit 20-8
-	 *     20     : Double baud rate
-	 *     19 - 16: PCS to SCK delay scaler
-	 *     15 - 12: After SCK delay scaler
-	 *     11 -  8: Delay after transfer scaler
-	 *      7 -  0: SPI_CPHA, SPI_CPOL, SPI_LSB_FIRST
-	 */
-	volatile dspi_t *dspi = (dspi_t *) MMAP_DSPI;
-	int prescaler[] = { 2, 3, 5, 7 };
-	int scaler[] = {
-		2, 4, 6, 8,
-		16, 32, 64, 128,
-		256, 512, 1024, 2048,
-		4096, 8192, 16384, 32768
-	};
-	int i, j, pbrcnt, brcnt, diff, tmp, dbr = 0;
-	int best_i, best_j, bestmatch = 0x7FFFFFFF, baud_speed;
-	u32 bus_setup = 0;
-
-	tmp = (prescaler[3] * scaler[15]);
-	/* Maximum and minimum baudrate it can handle */
-	if ((cfslave->baudrate > (gd->bus_clk >> 1)) ||
-	    (cfslave->baudrate < (gd->bus_clk / tmp))) {
-		printf("Exceed baudrate limitation: Max %d - Min %d\n",
-		       (int)(gd->bus_clk >> 1), (int)(gd->bus_clk / tmp));
-		return NULL;
-	}
-
-	/* Activate Double Baud when it exceed 1/4 the bus clk */
-	if ((CONFIG_SYS_DSPI_CTAR0 & DSPI_CTAR_DBR) ||
-	    (cfslave->baudrate > (gd->bus_clk / (prescaler[0] * scaler[0])))) {
-		bus_setup |= DSPI_CTAR_DBR;
-		dbr = 1;
-	}
-
-	if (mode & SPI_CPOL)
-		bus_setup |= DSPI_CTAR_CPOL;
-	if (mode & SPI_CPHA)
-		bus_setup |= DSPI_CTAR_CPHA;
-	if (mode & SPI_LSB_FIRST)
-		bus_setup |= DSPI_CTAR_LSBFE;
-
-	/* Overwrite default value set in platform configuration file */
-	if (mode & SPI_MODE_MOD) {
-
-		if ((mode & 0xF0000000) == 0)
-			bus_setup |=
-			    dspi->ctar[cfslave->slave.bus] & 0x78000000;
-		else
-			bus_setup |= ((mode & 0xF0000000) >> 1);
-
-		/*
-		 * Check to see if it is enabled by default in platform
-		 * config, or manual setting passed by mode parameter
-		 */
-		if (mode & SPI_DBLRATE) {
-			bus_setup |= DSPI_CTAR_DBR;
-			dbr = 1;
-		}
-		bus_setup |= (mode & 0x0FC00000) >> 4;	/* PSCSCK, PASC, PDT */
-		bus_setup |= (mode & 0x000FFF00) >> 4;	/* CSSCK, ASC, DT */
-	} else
-		bus_setup |= (dspi->ctar[cfslave->slave.bus] & 0x78FCFFF0);
-
-	cfslave->charbit =
-	    ((dspi->ctar[cfslave->slave.bus] & 0x78000000) ==
-	     0x78000000) ? 16 : 8;
-
-	pbrcnt = sizeof(prescaler) / sizeof(int);
-	brcnt = sizeof(scaler) / sizeof(int);
-
-	/* baudrate calculation - to closer value, may not be exact match */
-	for (best_i = 0, best_j = 0, i = 0; i < pbrcnt; i++) {
-		baud_speed = gd->bus_clk / prescaler[i];
-		for (j = 0; j < brcnt; j++) {
-			tmp = (baud_speed / scaler[j]) * (1 + dbr);
-
-			if (tmp > cfslave->baudrate)
-				diff = tmp - cfslave->baudrate;
-			else
-				diff = cfslave->baudrate - tmp;
-
-			if (diff < bestmatch) {
-				bestmatch = diff;
-				best_i = i;
-				best_j = j;
-			}
-		}
-	}
-	bus_setup |= (DSPI_CTAR_PBR(best_i) | DSPI_CTAR_BR(best_j));
-	dspi->ctar[cfslave->slave.bus] = bus_setup;
-
-	return &cfslave->slave;
-}
-#endif				/* CONFIG_CF_DSPI */
-
-#ifdef CONFIG_CF_QSPI
-/* 52xx, 53xx */
-#endif				/* CONFIG_CF_QSPI */
-
-#ifdef CONFIG_CMD_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;
-}
-
-void spi_init_f(void)
-{
-}
-
-void spi_init_r(void)
-{
-}
-
-void spi_init(void)
-{
-	cfspi_init();
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-				  unsigned int max_hz, unsigned int mode)
-{
-	struct cf_spi_slave *cfslave;
-
-	if (!spi_cs_is_valid(bus, cs))
-		return NULL;
-
-	cfslave = spi_alloc_slave(struct cf_spi_slave, bus, cs);
-	if (!cfslave)
-		return NULL;
-
-	cfslave->baudrate = max_hz;
-
-	/* specific setup */
-	return cfspi_setup_slave(cfslave, mode);
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
-	free(slave);
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-	return cfspi_claim_bus(slave->bus, slave->cs);
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
-	cfspi_release_bus(slave->bus, slave->cs);
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
-	     void *din, unsigned long flags)
-{
-	return cfspi_xfer(slave, bitlen, dout, din, flags);
-}
-#endif				/* CONFIG_CMD_SPI */
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
new file mode 100644
index 0000000..16d85ff
--- /dev/null
+++ b/drivers/spi/fsl_dspi.c
@@ -0,0 +1,352 @@
+/*
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * Copyright (C) 2004-2009, 2013 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew at freescale.com)
+ * Chao Fu (B44548 at freescale.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <fsl_dspi.h>
+
+#ifdef CONFIG_VF610
+#include <asm/arch/clock.h>
+#endif
+
+#ifndef CONFIG_VF610
+#include <asm/immap.h>
+#endif
+
+struct dspi_slave {
+	struct spi_slave slave;
+	struct dspi *regs;
+	uint baudrate;
+	int charbit;
+};
+
+static inline struct dspi_slave *to_dspi_spi(struct spi_slave *slave)
+{
+	return container_of(slave, struct dspi_slave, slave);
+}
+
+#ifndef CONFIG_SPI_IDLE_VAL
+#if defined(CONFIG_SPI_MMC)
+#define CONFIG_SPI_IDLE_VAL	0xFFFF
+#else
+#define CONFIG_SPI_IDLE_VAL	0x0
+#endif
+#endif
+
+#if defined(CONFIG_FSL_DSPI)
+/* DSPI specific mode */
+#define SPI_MODE_MOD	0x00200000
+#define SPI_DBLRATE	0x00100000
+
+static void dspi_tx(struct dspi_slave *dspislave, u32 ctrl, u16 data)
+{
+	while ((readl(&dspislave->regs->sr) & 0x0000F000) >= 4)
+		;
+
+	writel((ctrl | data), &dspislave->regs->tfr);
+}
+
+static u16 dspi_rx(struct dspi_slave *dspislave)
+{
+	while ((readl(&dspislave->regs->sr) & 0x000000F0) == 0)
+		;
+
+	return (u16)(readl(&dspislave->regs->rfr) & 0xFFFF);
+}
+
+int dspi_xfer(struct spi_slave *slave, uint bitlen, const void *dout,
+	       void *din, ulong flags)
+{
+	struct dspi_slave *dspislave = to_dspi_spi(slave);
+	u16 *spi_rd16 = NULL, *spi_wr16 = NULL;
+	u8 *spi_rd = NULL, *spi_wr = NULL;
+	static u32 ctrl = 0;
+	uint len = bitlen >> 3;
+
+	if (dspislave->charbit == 16) {
+		bitlen >>= 1;
+		spi_wr16 = (u16 *) dout;
+		spi_rd16 = (u16 *) din;
+	} else {
+		spi_wr = (u8 *) dout;
+		spi_rd = (u8 *) din;
+	}
+
+	if ((flags & SPI_XFER_BEGIN) == SPI_XFER_BEGIN)
+		ctrl |= DSPI_TFR_CONT;
+
+	ctrl = (ctrl & 0xFF000000) | ((1 << slave->cs) << 16);
+
+	if (len > 1) {
+		int tmp_len = len - 1;
+		while (tmp_len--) {
+			if (dout != NULL) {
+				if (dspislave->charbit == 16)
+					dspi_tx(dspislave, ctrl, *spi_wr16++);
+				else
+					dspi_tx(dspislave, ctrl, *spi_wr++);
+				dspi_rx(dspislave);
+			}
+
+			if (din != NULL) {
+				dspi_tx(dspislave, ctrl, CONFIG_SPI_IDLE_VAL);
+				if (dspislave->charbit == 16)
+					*spi_rd16++ = dspi_rx(dspislave);
+				else
+					*spi_rd++ = dspi_rx(dspislave);
+			}
+		}
+
+		len = 1;	/* remaining byte */
+	}
+
+	if ((flags & SPI_XFER_END) == SPI_XFER_END)
+		ctrl &= ~DSPI_TFR_CONT;
+
+	if (len) {
+		if (dout != NULL) {
+			if (dspislave->charbit == 16)
+				dspi_tx(dspislave, ctrl, *spi_wr16);
+			else
+				dspi_tx(dspislave, ctrl, *spi_wr);
+			dspi_rx(dspislave);
+		}
+
+		if (din != NULL) {
+			dspi_tx(dspislave, ctrl, CONFIG_SPI_IDLE_VAL);
+			if (dspislave->charbit == 16)
+				*spi_rd16 = dspi_rx(dspislave);
+			else
+				*spi_rd = dspi_rx(dspislave);
+		}
+	} else {
+		/* dummy read */
+		dspi_tx(dspislave, ctrl, CONFIG_SPI_IDLE_VAL);
+		dspi_rx(dspislave);
+	}
+
+	return 0;
+}
+
+struct spi_slave *dspi_setup_slave(struct dspi_slave *dspislave, uint mode)
+{
+	/*
+	 * bit definition for mode:
+	 * bit 31 - 28: Transfer size 3 to 16 bits
+	 *     27 - 26: PCS to SCK delay prescaler
+	 *     25 - 24: After SCK delay prescaler
+	 *     23 - 22: Delay after transfer prescaler
+	 *     21     : Allow overwrite for bit 31-22 and bit 20-8
+	 *     20     : Double baud rate
+	 *     19 - 16: PCS to SCK delay scaler
+	 *     15 - 12: After SCK delay scaler
+	 *     11 -  8: Delay after transfer scaler
+	 *      7 -  0: SPI_CPHA, SPI_CPOL, SPI_LSB_FIRST
+	 */
+	int prescaler[] = { 2, 3, 5, 7 };
+	int scaler[] = {
+		2, 4, 6, 8,
+		16, 32, 64, 128,
+		256, 512, 1024, 2048,
+		4096, 8192, 16384, 32768
+	};
+	int i, j, pbrcnt, brcnt, diff, tmp, dbr = 0;
+	int best_i, best_j, bestmatch = 0x7FFFFFFF, baud_speed, bus_clk;
+	u32 bus_setup = 0;
+
+	dspislave->regs = (dspi_t *) MMAP_DSPI;
+
+#ifndef CONFIG_VF610
+	cfspi_port_conf();	/* port configuration */
+#endif
+
+	writel(DSPI_MCR_MSTR | DSPI_MCR_CSIS7 | DSPI_MCR_CSIS6 |
+		DSPI_MCR_CSIS5 | DSPI_MCR_CSIS4 | DSPI_MCR_CSIS3 |
+		DSPI_MCR_CSIS2 | DSPI_MCR_CSIS1 | DSPI_MCR_CSIS0 |
+		DSPI_MCR_CRXF | DSPI_MCR_CTXF,
+		&dspislave->regs->mcr);
+	/* Default setting in platform configuration */
+#ifdef CONFIG_SYS_DSPI_CTAR0
+	writel(CONFIG_SYS_DSPI_CTAR0, &dspislave->regs->ctar[0]);
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR1
+	writel(CONFIG_SYS_DSPI_CTAR1, &dspislave->regs->ctar[1]);
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR2
+	writel(CONFIG_SYS_DSPI_CTAR2, &dspislave->regs->ctar[2]);
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR3
+	writel(CONFIG_SYS_DSPI_CTAR3, &dspislave->regs->ctar[3]);
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR4
+	writel(CONFIG_SYS_DSPI_CTAR4, &dspislave->regs->ctar[4]);
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR5
+	writel(CONFIG_SYS_DSPI_CTAR5, &dspislave->regs->ctar[5]);
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR6
+	writel(CONFIG_SYS_DSPI_CTAR6, &dspislave->regs->ctar[6]);
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR7
+	writel(CONFIG_SYS_DSPI_CTAR7, &dspislave->regs->ctar[7]);
+#endif
+
+	tmp = (prescaler[3] * scaler[15]);
+#ifdef CONFIG_VF610
+	bus_clk = mxc_get_clock(MXC_DSPI_CLK);
+#else
+	bus_clk = get_dspi_clk();
+#endif
+	/* Maximum and minimum baudrate it can handle */
+	if ((dspislave->baudrate > (bus_clk >> 1)) ||
+	    (dspislave->baudrate < (bus_clk / tmp))) {
+		printf("Exceed baudrate limitation: Max %d - Min %d\n",
+		       (int)(bus_clk >> 1), (int)(bus_clk / tmp));
+		return NULL;
+	}
+
+	/* Activate Double Baud when it exceed 1/4 the bus clk */
+	if ((CONFIG_SYS_DSPI_CTAR0 & DSPI_CTAR_DBR) ||
+	    (dspislave->baudrate > (bus_clk / (prescaler[0] * scaler[0])))) {
+		bus_setup |= DSPI_CTAR_DBR;
+		dbr = 1;
+	}
+
+
+	if (mode & SPI_CPOL)
+		bus_setup |= DSPI_CTAR_CPOL;
+	if (mode & SPI_CPHA)
+		bus_setup |= DSPI_CTAR_CPHA;
+	if (mode & SPI_LSB_FIRST)
+		bus_setup |= DSPI_CTAR_LSBFE;
+
+	/* Overwrite default value set in platform configuration file */
+	if (mode & SPI_MODE_MOD) {
+
+		if ((mode & 0xF0000000) == 0)
+			bus_setup |=
+			    readl(&dspislave->regs->ctar[dspislave->slave.bus])
+			    & 0x78000000;
+		else
+			bus_setup |= ((mode & 0xF0000000) >> 1);
+
+		/*
+		 * Check to see if it is enabled by default in platform
+		 * config, or manual setting passed by mode parameter
+		 */
+		if (mode & SPI_DBLRATE) {
+			bus_setup |= DSPI_CTAR_DBR;
+			dbr = 1;
+		}
+		bus_setup |= (mode & 0x0FC00000) >> 4;	/* PSCSCK, PASC, PDT */
+		bus_setup |= (mode & 0x000FFF00) >> 4;	/* CSSCK, ASC, DT */
+	} else
+		bus_setup |= readl(&dspislave->regs->ctar[dspislave->slave.bus])
+				& 0x78FCFFF0;
+
+	dspislave->charbit =
+	    ((readl(&dspislave->regs->ctar[dspislave->slave.bus]) & 0x78000000)
+	     == 0x78000000) ? 16 : 8;
+
+	pbrcnt = sizeof(prescaler) / sizeof(int);
+	brcnt = sizeof(scaler) / sizeof(int);
+
+	/* baudrate calculation - to closer value, may not be exact match */
+	for (best_i = 0, best_j = 0, i = 0; i < pbrcnt; i++) {
+		baud_speed = bus_clk / prescaler[i];
+		for (j = 0; j < brcnt; j++) {
+			tmp = (baud_speed / scaler[j]) * (1 + dbr);
+
+			if (tmp > dspislave->baudrate)
+				diff = tmp - dspislave->baudrate;
+			else
+				diff = dspislave->baudrate - tmp;
+
+			if (diff < bestmatch) {
+				bestmatch = diff;
+				best_i = i;
+				best_j = j;
+			}
+		}
+	}
+
+	bus_setup |= (DSPI_CTAR_PBR(best_i) | DSPI_CTAR_BR(best_j));
+	writel(bus_setup, &dspislave->regs->ctar[dspislave->slave.bus]) ;
+	return &dspislave->slave;
+}
+#endif				/* CONFIG_FSL_DSPI */
+
+#ifdef CONFIG_CMD_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;
+}
+
+void spi_init_f(void)
+{
+}
+
+void spi_init_r(void)
+{
+}
+
+void spi_init(void)
+{
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+				  unsigned int max_hz, unsigned int mode)
+{
+	struct dspi_slave *dspislave;
+
+	if (!spi_cs_is_valid(bus, cs))
+		return NULL;
+	dspislave = spi_alloc_slave(struct dspi_slave, bus, cs);
+	if (!dspislave)
+		return NULL;
+
+	dspislave->baudrate = max_hz;
+	/* specific setup */
+	return dspi_setup_slave(dspislave, mode);
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+#ifdef CONFIG_VF610
+	return 0;
+#else
+	return cfspi_claim_bus(slave->bus, slave->cs);
+#endif
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+#ifndef CONFIG_VF610
+	cfspi_release_bus(slave->bus, slave->cs);
+#endif
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+	     void *din, unsigned long flags)
+{
+	return dspi_xfer(slave, bitlen, dout, din, flags);
+}
+#endif				/* CONFIG_CMD_SPI */
diff --git a/include/fsl_dspi.h b/include/fsl_dspi.h
new file mode 100644
index 0000000..861404e
--- /dev/null
+++ b/include/fsl_dspi.h
@@ -0,0 +1,147 @@
+/*
+ * MCF5227x Internal Memory Map
+ * MCF54418 Internal Memory Map
+ * MCF5445x Internal Memory Map
+ * VF610    Internal Memory Map
+ *
+ * Copyright (C) 2004-2007, 2013 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew at freescale.com)
+ * Chao Fu (B44548 at freesacle.com)
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __DSPI_H__
+#define __DSPI_H__
+
+
+/* DMA Serial Peripheral Interface (DSPI) */
+typedef struct dspi {
+	u32 mcr;	/* 0x00 */
+	u32 resv0;	/* 0x04 */
+	u32 tcr;	/* 0x08 */
+	u32 ctar[8];	/* 0x0C - 0x28 */
+	u32 sr;		/* 0x2C */
+	u32 irsr;	/* 0x30 */
+	u32 tfr;	/* 0x34 - PUSHR */
+	u16 rfr;	/* 0x38 - POPR */
+	u16 resv1;	/* 0x3A - POPR resv*/
+#ifdef CONFIG_MCF547x_8x
+	u32 tfdr[4];	/* 0x3C */
+	u8 resv2[0x30];	/* 0x40 */
+	u32 rfdr[4];	/* 0x7C */
+#else
+	u32 tfdr[16];	/* 0x3C */
+	u32 rfdr[16];	/* 0x7C */
+#endif
+} dspi_t;
+
+/* Module configuration */
+#define DSPI_MCR_MSTR			(0x80000000)
+#define DSPI_MCR_CSCK			(0x40000000)
+#define DSPI_MCR_DCONF(x)		(((x)&0x03)<<28)
+#define DSPI_MCR_FRZ			(0x08000000)
+#define DSPI_MCR_MTFE			(0x04000000)
+#define DSPI_MCR_PCSSE			(0x02000000)
+#define DSPI_MCR_ROOE			(0x01000000)
+#define DSPI_MCR_CSIS7			(0x00800000)
+#define DSPI_MCR_CSIS6			(0x00400000)
+#define DSPI_MCR_CSIS5			(0x00200000)
+#define DSPI_MCR_CSIS4			(0x00100000)
+#define DSPI_MCR_CSIS3			(0x00080000)
+#define DSPI_MCR_CSIS2			(0x00040000)
+#define DSPI_MCR_CSIS1			(0x00020000)
+#define DSPI_MCR_CSIS0			(0x00010000)
+#define DSPI_MCR_MDIS			(0x00004000)
+#define DSPI_MCR_DTXF			(0x00002000)
+#define DSPI_MCR_DRXF			(0x00001000)
+#define DSPI_MCR_CTXF			(0x00000800)
+#define DSPI_MCR_CRXF			(0x00000400)
+#define DSPI_MCR_SMPL_PT(x)		(((x)&0x03)<<8)
+#define DSPI_MCR_HALT			(0x00000001)
+
+/* Transfer count */
+#define DSPI_TCR_SPI_TCNT(x)		(((x)&0x0000FFFF)<<16)
+
+/* Clock and transfer attributes */
+#define DSPI_CTAR_DBR			(0x80000000)
+#define DSPI_CTAR_TRSZ(x)		(((x)&0x0F)<<27)
+#define DSPI_CTAR_CPOL			(0x04000000)
+#define DSPI_CTAR_CPHA			(0x02000000)
+#define DSPI_CTAR_LSBFE			(0x01000000)
+#define DSPI_CTAR_PCSSCK(x)		(((x)&0x03)<<22)
+#define DSPI_CTAR_PCSSCK_7CLK		(0x00A00000)
+#define DSPI_CTAR_PCSSCK_5CLK		(0x00800000)
+#define DSPI_CTAR_PCSSCK_3CLK		(0x00400000)
+#define DSPI_CTAR_PCSSCK_1CLK		(0x00000000)
+#define DSPI_CTAR_PASC(x)		(((x)&0x03)<<20)
+#define DSPI_CTAR_PASC_7CLK		(0x00300000)
+#define DSPI_CTAR_PASC_5CLK		(0x00200000)
+#define DSPI_CTAR_PASC_3CLK		(0x00100000)
+#define DSPI_CTAR_PASC_1CLK		(0x00000000)
+#define DSPI_CTAR_PDT(x)		(((x)&0x03)<<18)
+#define DSPI_CTAR_PDT_7CLK		(0x000A0000)
+#define DSPI_CTAR_PDT_5CLK		(0x00080000)
+#define DSPI_CTAR_PDT_3CLK		(0x00040000)
+#define DSPI_CTAR_PDT_1CLK		(0x00000000)
+#define DSPI_CTAR_PBR(x)		(((x)&0x03)<<16)
+#define DSPI_CTAR_PBR_7CLK		(0x00030000)
+#define DSPI_CTAR_PBR_5CLK		(0x00020000)
+#define DSPI_CTAR_PBR_3CLK		(0x00010000)
+#define DSPI_CTAR_PBR_1CLK		(0x00000000)
+#define DSPI_CTAR_CSSCK(x)		(((x)&0x0F)<<12)
+#define DSPI_CTAR_ASC(x)		(((x)&0x0F)<<8)
+#define DSPI_CTAR_DT(x)			(((x)&0x0F)<<4)
+#define DSPI_CTAR_BR(x)			(((x)&0x0F))
+
+/* Status */
+#define DSPI_SR_TCF			(0x80000000)
+#define DSPI_SR_TXRXS			(0x40000000)
+#define DSPI_SR_EOQF			(0x10000000)
+#define DSPI_SR_TFUF			(0x08000000)
+#define DSPI_SR_TFFF			(0x02000000)
+#define DSPI_SR_RFOF			(0x00080000)
+#define DSPI_SR_RFDF			(0x00020000)
+#define DSPI_SR_TXCTR(x)		(((x)&0x0F)<<12)
+#define DSPI_SR_TXPTR(x)		(((x)&0x0F)<<8)
+#define DSPI_SR_RXCTR(x)		(((x)&0x0F)<<4)
+#define DSPI_SR_RXPTR(x)		(((x)&0x0F))
+
+/* DMA/interrupt request selct and enable */
+#define DSPI_IRSR_TCFE			(0x80000000)
+#define DSPI_IRSR_EOQFE			(0x10000000)
+#define DSPI_IRSR_TFUFE			(0x08000000)
+#define DSPI_IRSR_TFFFE			(0x02000000)
+#define DSPI_IRSR_TFFFS			(0x01000000)
+#define DSPI_IRSR_RFOFE			(0x00080000)
+#define DSPI_IRSR_RFDFE			(0x00020000)
+#define DSPI_IRSR_RFDFS			(0x00010000)
+
+/* Transfer control - 32-bit access */
+#define DSPI_TFR_CONT			(0x80000000)
+#define DSPI_TFR_CTAS(x)		(((x)&0x07)<<12)
+#define DSPI_TFR_EOQ			(0x08000000)
+#define DSPI_TFR_CTCNT			(0x04000000)
+#define DSPI_TFR_CS7			(0x00800000)
+#define DSPI_TFR_CS6			(0x00400000)
+#define DSPI_TFR_CS5			(0x00200000)
+#define DSPI_TFR_CS4			(0x00100000)
+#define DSPI_TFR_CS3			(0x00080000)
+#define DSPI_TFR_CS2			(0x00040000)
+#define DSPI_TFR_CS1			(0x00020000)
+#define DSPI_TFR_CS0			(0x00010000)
+
+/* Transfer Fifo */
+#define DSPI_TFR_TXDATA(x)		(((x)&0xFFFF))
+
+/* Bit definitions and macros for DRFR */
+#define DSPI_RFR_RXDATA(x)		(((x)&0xFFFF))
+
+/* Bit definitions and macros for DTFDR group */
+#define DSPI_TFDR_TXDATA(x)		(((x)&0x0000FFFF))
+#define DSPI_TFDR_TXCMD(x)		(((x)&0x0000FFFF)<<16)
+
+/* Bit definitions and macros for DRFDR group */
+#define DSPI_RFDR_RXDATA(x)		(((x)&0x0000FFFF))
+
+#endif				/* __DSPI_H__ */
-- 
1.8.4




More information about the U-Boot mailing list