Skip to contentSkip to conversation

Add pdc feature to atmel-mci

RFC PATCH Superseded ludovic.desroches at atmel.com 3 participants 23 messages Jul 28, 2011 – Aug 11, 2011

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

cover Add pdc feature to atmel-mci

The purpose of these patches is to merge at91_mci and atmel atmel-mci drivers. The first one is used only for old atmel mci core and provides the PDC feature. The second one works with the old core but doesn't provide the PDC feature so the goal is to implement this feature in order to remove at91_mci.

This new version of the atmel-mci driver detects mci core version at runtime. Then it knows if we have to use pio, pdc or dma for transfers.

These patches are based on "mmc: atmel-mci: add suspend/resume support" from Nicolas.

arch/arm/mach-at91/at91sam9260_devices.c |    2 +-
drivers/mmc/host/atmel-mci-regs.h        |  220 +++++----
drivers/mmc/host/atmel-mci.c             |  824 ++++++++++++++++++++----------
include/linux/atmel-mci.h                |    4 +-
include/linux/atmel_pdc.h                |    2 +
5 files changed, 681 insertions(+), 371 deletions(-)
#1 lore raw

RFC PATCH 1/9 mmc: atmel-mci: change namespace

From: Ludovic Desroches <[email protected]>

Homogenize namespace to atmci.

---
 arch/arm/mach-at91/at91sam9260_devices.c |    2 +-
 drivers/mmc/host/atmel-mci-regs.h        |  206 ++++++++++----------
 drivers/mmc/host/atmel-mci.c             |  301 +++++++++++++++---------------
 include/linux/atmel-mci.h                |    4 +-
 4 files changed, 257 insertions(+), 256 deletions(-)
arch/arm/mach-at91/at91sam9260_devices.c +1 -1
index 39f81f4..c49e84a 100644
@@ -319,7 +319,7 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
 	if (!data)
 		return;
 
-	for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+	for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
 		if (data->slot[i].bus_width) {
 			/* input/irq */
 			if (data->slot[i].detect_pin) {
drivers/mmc/host/atmel-mci-regs.h +103 -103

215 lines not on this page · raw message

drivers/mmc/host/atmel-mci.c +151 -150

775 lines not on this page · raw message

include/linux/atmel-mci.h +2 -2
index 3e09b34..4c7a4b2 100644
@@ -1,7 +1,7 @@
 #ifndef __LINUX_ATMEL_MCI_H
 #define __LINUX_ATMEL_MCI_H
 
-#define ATMEL_MCI_MAX_NR_SLOTS	2
+#define ATMCI_MAX_NR_SLOTS	2
 
 /**
  * struct mci_slot_pdata - board-specific per-slot configuration
@@ -33,7 +33,7 @@ struct mci_slot_pdata {
  */
 struct mci_platform_data {
 	struct mci_dma_data	*dma_slave;
-	struct mci_slot_pdata	slot[ATMEL_MCI_MAX_NR_SLOTS];
+	struct mci_slot_pdata	slot[ATMCI_MAX_NR_SLOTS];
 };
 
 #endif /* __LINUX_ATMEL_MCI_H */
Signature · 1 line
1.7.0.4
#3 lore raw

RFC PATCH 1/9 mmc: atmel-mci: change namespace

Quoted 9 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 5 lines · ludovic.desroches at atmel.com

From: Ludovic Desroches<[email protected]>

Homogenize namespace to atmci.

prefer ATMEL_MCI

ATMCI is not clear

Well it is used all over the place in the driver code. It is shorter and in coherence with what is existing already: I will take ATMCI_ naming by Ludovic.

Best regards,

Signature · 1 line
Nicolas Ferre
#4 lore raw

RFC PATCH 2/9 mmc: atmel-mci: change atmci_readl and atmci_writel macros

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Change atmci_readl and atmci_writel macros: remove string concatenation. We can use these macros with registers which are not prefix by ATMCI_. It's the case if we want to write PDC registers which are common to several devices so they are not prefixed with ATMCI_.

---
 drivers/mmc/host/atmel-mci-regs.h |    4 +-
 drivers/mmc/host/atmel-mci.c      |  126 ++++++++++++++++++------------------
 2 files changed, 65 insertions(+), 65 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +2 -2
index 29331ab..8574e91 100644
@@ -121,8 +121,8 @@
 
 /* Register access macros */
 #define atmci_readl(port,reg)				\
-	__raw_readl((port)->regs + ATMCI_##reg)
+	__raw_readl((port)->regs + reg)
 #define atmci_writel(port,reg,value)			\
-	__raw_writel((value), (port)->regs + ATMCI_##reg)
+	__raw_writel((value), (port)->regs + reg)
 
 #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */
drivers/mmc/host/atmel-mci.c +63 -63

350 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#5 lore raw

RFC PATCH 3/9 mmc: atmel-mci: indentation

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

---
 drivers/mmc/host/atmel-mci-regs.h |  136 ++++++++++++++++++------------------
 1 files changed, 68 insertions(+), 68 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +68 -68
index 8574e91..7310b20 100644
@@ -18,103 +18,103 @@
 
 /* MCI Register Definitions */
 #define ATMCI_CR			0x0000	/* Control */
-# define ATMCI_CR_MCIEN		(  1 <<  0)	/* MCI Enable */
+# define ATMCI_CR_MCIEN			(  1 <<  0)	/* MCI Enable */
 # define ATMCI_CR_MCIDIS		(  1 <<  1)	/* MCI Disable */
-# define ATMCI_CR_PWSEN		(  1 <<  2)	/* Power Save Enable */
+# define ATMCI_CR_PWSEN			(  1 <<  2)	/* Power Save Enable */
 # define ATMCI_CR_PWSDIS		(  1 <<  3)	/* Power Save Disable */
-# define ATMCI_CR_SWRST		(  1 <<  7)	/* Software Reset */
+# define ATMCI_CR_SWRST			(  1 <<  7)	/* Software Reset */
 #define ATMCI_MR			0x0004	/* Mode */
-# define ATMCI_MR_CLKDIV(x)	((x) <<  0)	/* Clock Divider */
-# define ATMCI_MR_PWSDIV(x)	((x) <<  8)	/* Power Saving Divider */
+# define ATMCI_MR_CLKDIV(x)		((x) <<  0)	/* Clock Divider */
+# define ATMCI_MR_PWSDIV(x)		((x) <<  8)	/* Power Saving Divider */
 # define ATMCI_MR_RDPROOF		(  1 << 11)	/* Read Proof */
 # define ATMCI_MR_WRPROOF		(  1 << 12)	/* Write Proof */
-# define ATMCI_MR_PDCFBYTE	(  1 << 13)	/* Force Byte Transfer */
+# define ATMCI_MR_PDCFBYTE		(  1 << 13)	/* Force Byte Transfer */
 # define ATMCI_MR_PDCPADV		(  1 << 14)	/* Padding Value */
 # define ATMCI_MR_PDCMODE		(  1 << 15)	/* PDC-oriented Mode */
-#define ATMCI_DTOR		0x0008	/* Data Timeout */
+#define ATMCI_DTOR			0x0008	/* Data Timeout */
 # define ATMCI_DTOCYC(x)		((x) <<  0)	/* Data Timeout Cycles */
 # define ATMCI_DTOMUL(x)		((x) <<  4)	/* Data Timeout Multiplier */
-#define ATMCI_SDCR		0x000c	/* SD Card / SDIO */
-# define ATMCI_SDCSEL_SLOT_A	(  0 <<  0)	/* Select SD slot A */
-# define ATMCI_SDCSEL_SLOT_B	(  1 <<  0)	/* Select SD slot A */
-# define ATMCI_SDCSEL_MASK	(  3 <<  0)
-# define ATMCI_SDCBUS_1BIT	(  0 <<  6)	/* 1-bit data bus */
-# define ATMCI_SDCBUS_4BIT	(  2 <<  6)	/* 4-bit data bus */
-# define ATMCI_SDCBUS_8BIT	(  3 <<  6)	/* 8-bit data bus[2] */
-# define ATMCI_SDCBUS_MASK	(  3 <<  6)
-#define ATMCI_ARGR		0x0010	/* Command Argument */
-#define ATMCI_CMDR		0x0014	/* Command */
-# define ATMCI_CMDR_CMDNB(x)	((x) <<  0)	/* Command Opcode */
-# define ATMCI_CMDR_RSPTYP_NONE	(  0 <<  6)	/* No response */
+#define ATMCI_SDCR			0x000c	/* SD Card / SDIO */
+# define ATMCI_SDCSEL_SLOT_A		(  0 <<  0)	/* Select SD slot A */
+# define ATMCI_SDCSEL_SLOT_B		(  1 <<  0)	/* Select SD slot A */
+# define ATMCI_SDCSEL_MASK		(  3 <<  0)
+# define ATMCI_SDCBUS_1BIT		(  0 <<  6)	/* 1-bit data bus */
+# define ATMCI_SDCBUS_4BIT		(  2 <<  6)	/* 4-bit data bus */
+# define ATMCI_SDCBUS_8BIT		(  3 <<  6)	/* 8-bit data bus[2] */
+# define ATMCI_SDCBUS_MASK		(  3 <<  6)
+#define ATMCI_ARGR			0x0010	/* Command Argument */
+#define ATMCI_CMDR			0x0014	/* Command */
+# define ATMCI_CMDR_CMDNB(x)		((x) <<  0)	/* Command Opcode */
+# define ATMCI_CMDR_RSPTYP_NONE		(  0 <<  6)	/* No response */
 # define ATMCI_CMDR_RSPTYP_48BIT	(  1 <<  6)	/* 48-bit response */
 # define ATMCI_CMDR_RSPTYP_136BIT	(  2 <<  6)	/* 136-bit response */
-# define ATMCI_CMDR_SPCMD_INIT	(  1 <<  8)	/* Initialization command */
-# define ATMCI_CMDR_SPCMD_SYNC	(  2 <<  8)	/* Synchronized command */
-# define ATMCI_CMDR_SPCMD_INT	(  4 <<  8)	/* Interrupt command */
+# define ATMCI_CMDR_SPCMD_INIT		(  1 <<  8)	/* Initialization command */
+# define ATMCI_CMDR_SPCMD_SYNC		(  2 <<  8)	/* Synchronized command */
+# define ATMCI_CMDR_SPCMD_INT		(  4 <<  8)	/* Interrupt command */
 # define ATMCI_CMDR_SPCMD_INTRESP	(  5 <<  8)	/* Interrupt response */
-# define ATMCI_CMDR_OPDCMD	(  1 << 11)	/* Open Drain */
-# define ATMCI_CMDR_MAXLAT_5CYC	(  0 << 12)	/* Max latency 5 cycles */
+# define ATMCI_CMDR_OPDCMD		(  1 << 11)	/* Open Drain */
+# define ATMCI_CMDR_MAXLAT_5CYC		(  0 << 12)	/* Max latency 5 cycles */
 # define ATMCI_CMDR_MAXLAT_64CYC	(  1 << 12)	/* Max latency 64 cycles */
-# define ATMCI_CMDR_START_XFER	(  1 << 16)	/* Start data transfer */
-# define ATMCI_CMDR_STOP_XFER	(  2 << 16)	/* Stop data transfer */
-# define ATMCI_CMDR_TRDIR_WRITE	(  0 << 18)	/* Write data */
-# define ATMCI_CMDR_TRDIR_READ	(  1 << 18)	/* Read data */
+# define ATMCI_CMDR_START_XFER		(  1 << 16)	/* Start data transfer */
+# define ATMCI_CMDR_STOP_XFER		(  2 << 16)	/* Stop data transfer */
+# define ATMCI_CMDR_TRDIR_WRITE		(  0 << 18)	/* Write data */
+# define ATMCI_CMDR_TRDIR_READ		(  1 << 18)	/* Read data */
 # define ATMCI_CMDR_BLOCK		(  0 << 19)	/* Single-block transfer */
-# define ATMCI_CMDR_MULTI_BLOCK	(  1 << 19)	/* Multi-block transfer */
-# define ATMCI_CMDR_STREAM	(  2 << 19)	/* MMC Stream transfer */
-# define ATMCI_CMDR_SDIO_BYTE	(  4 << 19)	/* SDIO Byte transfer */
-# define ATMCI_CMDR_SDIO_BLOCK	(  5 << 19)	/* SDIO Block transfer */
+# define ATMCI_CMDR_MULTI_BLOCK		(  1 << 19)	/* Multi-block transfer */
+# define ATMCI_CMDR_STREAM		(  2 << 19)	/* MMC Stream transfer */
+# define ATMCI_CMDR_SDIO_BYTE		(  4 << 19)	/* SDIO Byte transfer */
+# define ATMCI_CMDR_SDIO_BLOCK		(  5 << 19)	/* SDIO Block transfer */
 # define ATMCI_CMDR_SDIO_SUSPEND	(  1 << 24)	/* SDIO Suspend Command */
-# define ATMCI_CMDR_SDIO_RESUME	(  2 << 24)	/* SDIO Resume Command */
-#define ATMCI_BLKR		0x0018	/* Block */
-# define ATMCI_BCNT(x)		((x) <<  0)	/* Data Block Count */
+# define ATMCI_CMDR_SDIO_RESUME		(  2 << 24)	/* SDIO Resume Command */
+#define ATMCI_BLKR			0x0018	/* Block */
+# define ATMCI_BCNT(x)			((x) <<  0)	/* Data Block Count */
 # define ATMCI_BLKLEN(x)		((x) << 16)	/* Data Block Length */
-#define ATMCI_CSTOR		0x001c	/* Completion Signal Timeout[2] */
+#define ATMCI_CSTOR			0x001c	/* Completion Signal Timeout[2] */
 # define ATMCI_CSTOCYC(x)		((x) <<  0)	/* CST cycles */
 # define ATMCI_CSTOMUL(x)		((x) <<  4)	/* CST multiplier */
-#define ATMCI_RSPR		0x0020	/* Response 0 */
-#define ATMCI_RSPR1		0x0024	/* Response 1 */
-#define ATMCI_RSPR2		0x0028	/* Response 2 */
-#define ATMCI_RSPR3		0x002c	/* Response 3 */
+#define ATMCI_RSPR			0x0020	/* Response 0 */
+#define ATMCI_RSPR1			0x0024	/* Response 1 */
+#define ATMCI_RSPR2			0x0028	/* Response 2 */
+#define ATMCI_RSPR3			0x002c	/* Response 3 */
 #define ATMCI_RDR			0x0030	/* Receive Data */
 #define ATMCI_TDR			0x0034	/* Transmit Data */
 #define ATMCI_SR			0x0040	/* Status */
 #define ATMCI_IER			0x0044	/* Interrupt Enable */
 #define ATMCI_IDR			0x0048	/* Interrupt Disable */
 #define ATMCI_IMR			0x004c	/* Interrupt Mask */
-# define ATMCI_CMDRDY		(  1 <<   0)	/* Command Ready */
-# define ATMCI_RXRDY		(  1 <<   1)	/* Receiver Ready */
-# define ATMCI_TXRDY		(  1 <<   2)	/* Transmitter Ready */
-# define ATMCI_BLKE		(  1 <<   3)	/* Data Block Ended */
-# define ATMCI_DTIP		(  1 <<   4)	/* Data Transfer In Progress */
-# define ATMCI_NOTBUSY		(  1 <<   5)	/* Data Not Busy */
-# define ATMCI_SDIOIRQA		(  1 <<   8)	/* SDIO IRQ in slot A */
-# define ATMCI_SDIOIRQB		(  1 <<   9)	/* SDIO IRQ in slot B */
-# define ATMCI_RINDE		(  1 <<  16)	/* Response Index Error */
-# define ATMCI_RDIRE		(  1 <<  17)	/* Response Direction Error */
-# define ATMCI_RCRCE		(  1 <<  18)	/* Response CRC Error */
-# define ATMCI_RENDE		(  1 <<  19)	/* Response End Bit Error */
-# define ATMCI_RTOE		(  1 <<  20)	/* Response Time-Out Error */
-# define ATMCI_DCRCE		(  1 <<  21)	/* Data CRC Error */
-# define ATMCI_DTOE		(  1 <<  22)	/* Data Time-Out Error */
-# define ATMCI_OVRE		(  1 <<  30)	/* RX Overrun Error */
-# define ATMCI_UNRE		(  1 <<  31)	/* TX Underrun Error */
+# define ATMCI_CMDRDY			(  1 <<   0)	/* Command Ready */
+# define ATMCI_RXRDY			(  1 <<   1)	/* Receiver Ready */
+# define ATMCI_TXRDY			(  1 <<   2)	/* Transmitter Ready */
+# define ATMCI_BLKE			(  1 <<   3)	/* Data Block Ended */
+# define ATMCI_DTIP			(  1 <<   4)	/* Data Transfer In Progress */
+# define ATMCI_NOTBUSY			(  1 <<   5)	/* Data Not Busy */
+# define ATMCI_SDIOIRQA			(  1 <<   8)	/* SDIO IRQ in slot A */
+# define ATMCI_SDIOIRQB			(  1 <<   9)	/* SDIO IRQ in slot B */
+# define ATMCI_RINDE			(  1 <<  16)	/* Response Index Error */
+# define ATMCI_RDIRE			(  1 <<  17)	/* Response Direction Error */
+# define ATMCI_RCRCE			(  1 <<  18)	/* Response CRC Error */
+# define ATMCI_RENDE			(  1 <<  19)	/* Response End Bit Error */
+# define ATMCI_RTOE			(  1 <<  20)	/* Response Time-Out Error */
+# define ATMCI_DCRCE			(  1 <<  21)	/* Data CRC Error */
+# define ATMCI_DTOE			(  1 <<  22)	/* Data Time-Out Error */
+# define ATMCI_OVRE			(  1 <<  30)	/* RX Overrun Error */
+# define ATMCI_UNRE			(  1 <<  31)	/* TX Underrun Error */
 #define ATMCI_DMA			0x0050	/* DMA Configuration[2] */
-# define ATMCI_DMA_OFFSET(x)	((x) <<  0)	/* DMA Write Buffer Offset */
-# define ATMCI_DMA_CHKSIZE(x)	((x) <<  4)	/* DMA Channel Read and Write Chunk Size */
-# define ATMCI_DMAEN		(  1 <<  8)	/* DMA Hardware Handshaking Enable */
+# define ATMCI_DMA_OFFSET(x)		((x) <<  0)	/* DMA Write Buffer Offset */
+# define ATMCI_DMA_CHKSIZE(x)		((x) <<  4)	/* DMA Channel Read and Write Chunk Size */
+# define ATMCI_DMAEN			(  1 <<  8)	/* DMA Hardware Handshaking Enable */
 #define ATMCI_CFG			0x0054	/* Configuration[2] */
 # define ATMCI_CFG_FIFOMODE_1DATA	(  1 <<  0)	/* MCI Internal FIFO control mode */
-# define ATMCI_CFG_FERRCTRL_COR	(  1 <<  4)	/* Flow Error flag reset control mode */
+# define ATMCI_CFG_FERRCTRL_COR		(  1 <<  4)	/* Flow Error flag reset control mode */
 # define ATMCI_CFG_HSMODE		(  1 <<  8)	/* High Speed Mode */
 # define ATMCI_CFG_LSYNC		(  1 << 12)	/* Synchronize on the last block */
-#define ATMCI_WPMR		0x00e4	/* Write Protection Mode[2] */
-# define ATMCI_WP_EN		(  1 <<  0)	/* WP Enable */
-# define ATMCI_WP_KEY		(0x4d4349 << 8)	/* WP Key */
-#define ATMCI_WPSR		0x00e8	/* Write Protection Status[2] */
-# define ATMCI_GET_WP_VS(x)	((x) & 0x0f)
-# define ATMCI_GET_WP_VSRC(x)	(((x) >> 8) & 0xffff)
-#define ATMCI_FIFO_APERTURE	0x0200	/* FIFO Aperture[2] */
+#define ATMCI_WPMR			0x00e4	/* Write Protection Mode[2] */
+# define ATMCI_WP_EN			(  1 <<  0)	/* WP Enable */
+# define ATMCI_WP_KEY			(0x4d4349 << 8)	/* WP Key */
+#define ATMCI_WPSR			0x00e8	/* Write Protection Status[2] */
+# define ATMCI_GET_WP_VS(x)		((x) & 0x0f)
+# define ATMCI_GET_WP_VSRC(x)		(((x) >> 8) & 0xffff)
+#define ATMCI_FIFO_APERTURE		0x0200	/* FIFO Aperture[2] */
 
 /* This is not including the FIFO Aperture on MCI2 */
 #define ATMCI_REGS_SIZE		0x100
Signature · 1 line
1.7.0.4
#6 lore raw

RFC PATCH 4/9 mmc: atmel-mci: add pdc support and runtime capabilities detection

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Add the pdc support for atmel-mci. It makes at91-mci driver useless because it was only used for the old atmel MCI core which has pdc but no dma support. To allow removing at91-mci, the capabilites of the MCI core is detected at runtime, then the driver will use pio, pdc or dma transfers.
Warning: at91rm9200 is not supported, to support it we need to use swab32 on data but I have no board to test it.

---
 drivers/mmc/host/atmel-mci-regs.h |   14 +
 drivers/mmc/host/atmel-mci.c      |  528 ++++++++++++++++++++++++++++--------
 2 files changed, 424 insertions(+), 118 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +14 -0
index 7310b20..6dd2826 100644
@@ -88,8 +88,14 @@
 # define ATMCI_BLKE			(  1 <<   3)	/* Data Block Ended */
 # define ATMCI_DTIP			(  1 <<   4)	/* Data Transfer In Progress */
 # define ATMCI_NOTBUSY			(  1 <<   5)	/* Data Not Busy */
+# define ATMCI_ENDRX			(  1 <<   6)    /* End of RX Buffer */
+# define ATMCI_ENDTX			(  1 <<   7)    /* End of TX Buffer */
 # define ATMCI_SDIOIRQA			(  1 <<   8)	/* SDIO IRQ in slot A */
 # define ATMCI_SDIOIRQB			(  1 <<   9)	/* SDIO IRQ in slot B */
+# define ATMCI_SDIOWAIT			(  1 <<  12)    /* SDIO Read Wait Operation Status */
+# define ATMCI_CSRCV			(  1 <<  13)    /* CE-ATA Completion Signal Received */
+# define ATMCI_RXBUFF			(  1 <<  14)    /* RX Buffer Full */
+# define ATMCI_TXBUFE			(  1 <<  15)    /* TX Buffer Empty */
 # define ATMCI_RINDE			(  1 <<  16)	/* Response Index Error */
 # define ATMCI_RDIRE			(  1 <<  17)	/* Response Direction Error */
 # define ATMCI_RCRCE			(  1 <<  18)	/* Response CRC Error */
@@ -97,6 +103,13 @@
 # define ATMCI_RTOE			(  1 <<  20)	/* Response Time-Out Error */
 # define ATMCI_DCRCE			(  1 <<  21)	/* Data CRC Error */
 # define ATMCI_DTOE			(  1 <<  22)	/* Data Time-Out Error */
+# define ATMCI_CSTOE			(  1 <<  23)    /* Completion Signql Time-out Error */
+# define ATMCI_BLKOVRE			(  1 <<  24)    /* DMA Block Overrun Error */
+# define ATMCI_DMADONE			(  1 <<  25)    /* DMA Transfer Done */
+# define ATMCI_FIFOEMPTY		(  1 <<  26)    /* FIFO Empty Flag */
+# define ATMCI_XFRDONE			(  1 <<  27)    /* Transfer Done Flag */
+# define ATMCI_ACKRCV			(  1 <<  28)    /* Boot Operation Acknowledge Received */
+# define ATMCI_ACKRCVE			(  1 <<  29)    /* Boot Operation Acknowledge Error */
 # define ATMCI_OVRE			(  1 <<  30)	/* RX Overrun Error */
 # define ATMCI_UNRE			(  1 <<  31)	/* TX Underrun Error */
 #define ATMCI_DMA			0x0050	/* DMA Configuration[2] */
@@ -114,6 +127,7 @@
 #define ATMCI_WPSR			0x00e8	/* Write Protection Status[2] */
 # define ATMCI_GET_WP_VS(x)		((x) & 0x0f)
 # define ATMCI_GET_WP_VSRC(x)		(((x) >> 8) & 0xffff)
+#define ATMCI_VERSION			0x00FC  /* Version */
 #define ATMCI_FIFO_APERTURE		0x0200	/* FIFO Aperture[2] */
 
 /* This is not including the FIFO Aperture on MCI2 */
drivers/mmc/host/atmel-mci.c +410 -118

793 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#7 lore raw

RFC PATCH 5/9 mmc: atmel-mci: change atmci_start_command to atmci_send_command

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Change atmci_start_command function name to atmci_send_command which is more appropriate to no think we are sending a start command.

---
 drivers/mmc/host/atmel-mci.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/mmc/host/atmel-mci.c +3 -3
index efbee87..7955697 100644
@@ -565,7 +565,7 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
 	return cmdr;
 }
 
-static void atmci_start_command(struct atmel_mci *host,
+static void atmci_send_command(struct atmel_mci *host,
 		struct mmc_command *cmd, u32 cmd_flags)
 {
 	WARN_ON(host->cmd);
@@ -581,7 +581,7 @@ static void atmci_start_command(struct atmel_mci *host,
 
 static void atmci_send_stop_cmd(struct atmel_mci *host, struct mmc_data *data)
 {
-	atmci_start_command(host, data->stop, host->stop_cmdr);
+	atmci_send_command(host, data->stop, host->stop_cmdr);
 	atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
 }
 
@@ -1003,7 +1003,7 @@ static void atmci_start_request(struct atmel_mci *host,
 	iflags |= ATMCI_CMDRDY;
 	cmd = mrq->cmd;
 	cmdflags = atmci_prepare_command(slot->mmc, cmd);
-	atmci_start_command(host, cmd, cmdflags);
+	atmci_send_command(host, cmd, cmdflags);
 
 	if (data)
 		host->submit_data(host, data);
Signature · 1 line
1.7.0.4
#8 lore raw

RFC PATCH 6/9 atmel_pdc: add ATMEL_PDC_SCND_BUF_OFF

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Add define for the offset value between first and second buffer registers.

---
 include/linux/atmel_pdc.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
include/linux/atmel_pdc.h +2 -0
index 5058a31..63499ce 100644
@@ -33,4 +33,6 @@
 
 #define ATMEL_PDC_PTSR		0x124	/* Transfer Status Register */
 
+#define ATMEL_PDC_SCND_BUF_OFF	0x10	/* Offset between first and second buffer registers */
+
 #endif
Signature · 1 line
1.7.0.4
#9 lore raw

RFC PATCH 6/9 atmel_pdc: add ATMEL_PDC_SCND_BUF_OFF

Quoted 3 lines · ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Add define for the offset value between first and second buffer registers.

patch 6 & 7 can be joined

Best Regards,
J.

#10 lore raw

RFC PATCH 6/9 atmel_pdc: add ATMEL_PDC_SCND_BUF_OFF

Quoted 5 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 3 lines · ludovic.desroches at atmel.com

From: Ludovic Desroches<[email protected]>

Add define for the offset value between first and second buffer registers.

patch 6& 7 can be joined

Yes, true.

Bye,

Signature · 1 line
Nicolas Ferre
#11 lore raw

RFC PATCH 7/9 mmc: atmel-mci: use ATMEL_PDC_SCND_BUF_OFF instead of a literal value

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

---
 drivers/mmc/host/atmel-mci.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/mmc/host/atmel-mci.c +2 -2
index 7955697..c415322 100644
@@ -603,8 +603,8 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
 	}
 
 	if (buf_nb == PDC_SECOND_BUF) {
-		pointer_reg += 0x10;
-		counter_reg += 0x10;
+		pointer_reg += ATMEL_PDC_SCND_BUF_OFF;
+		counter_reg += ATMEL_PDC_SCND_BUF_OFF;
 	}
 
 	atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
Signature · 1 line
1.7.0.4
#12 lore raw

RFC PATCH 8/9 mmc: atmel-mci: correct sg buffer size evaluation

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Assuming that a sg buffer size is a page size is false so use sg_dma_len. A 4096 bytes can be required with two 2048-bytes sg buffer.

---
 drivers/mmc/host/atmel-mci.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)
drivers/mmc/host/atmel-mci.c +3 -4
index c415322..963e320 100644
@@ -608,7 +608,7 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
 	}
 
 	atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
-	if (host->data_size <= PAGE_SIZE) {
+	if (host->data_size <= sg_dma_len(host->sg)) {
 		if (host->data_size & 0x3) {
 			/* If size is different from modulo 4, transfer bytes */
 			atmci_writel(host, counter_reg, host->data_size);
@@ -620,8 +620,8 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
 		host->data_size = 0;
 	} else {
 		/* We assume the size of a page is 32-bits aligned */
-		atmci_writel(host, counter_reg, PAGE_SIZE / 4);
-		host->data_size -= PAGE_SIZE;
+		atmci_writel(host, counter_reg, sg_dma_len(host->sg) / 4);
+		host->data_size -= sg_dma_len(host->sg);
 		if (host->data_size)
 			host->sg = sg_next(host->sg);
 	}
@@ -808,7 +808,6 @@ atmci_prepare_data_pdc(struct atmel_mci *host, struct mmc_data *data)
 	/* Configure PDC */
 	host->data_size = data->blocks * data->blksz;
 	sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, dir);
-	BUG_ON(sg_len < host->data_size / PAGE_SIZE);
 	if (host->data_size)
 		atmci_pdc_set_both_buf(host,
 			((dir == DMA_FROM_DEVICE)?XFER_RECEIVE:XFER_TRANSMIT));
Signature · 1 line
1.7.0.4
#13 lore raw

RFC PATCH 9/9 mmc: atmel-mci: fix a potential issue about pending PDC interrupts

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

This patch fixes a potential issue about PDC interrupts. For example we have a ENDRX pending interrupt and a RXBUFF pending interrupt. We have received the RXBUFF interrupt but the transfer is not finished (so we didn't have time to give a new buffer to the PDC controller). Then we will compute ENDRX interrupt and we will give a new buffer to the PDC controller, just after we will compute the RXBUFF interrupt and give one or two new buffers to the PDC controller but we are not sure that the first buffer given has been filled. So in this situation we may "lost" one sg buffer. It's the same for transmission.

---
 drivers/mmc/host/atmel-mci.c |   32 +++++++++++++++++---------------
 1 files changed, 17 insertions(+), 15 deletions(-)
drivers/mmc/host/atmel-mci.c +17 -15
index 963e320..7108f64 100644
@@ -1729,17 +1729,9 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
 			tasklet_schedule(&host->tasklet);
 		}
 
-		if (pending & ATMCI_ENDTX) {
-			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
-			if (host->data_size) {
-				atmci_pdc_set_single_buf(host,
-						XFER_TRANSMIT, PDC_SECOND_BUF);
-				atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
-			}
-		}
-
 		if (pending & ATMCI_TXBUFE) {
 			atmci_writel(host, ATMCI_IDR, ATMCI_TXBUFE);
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
 			/*
 			 * We can receive this interruption before having configured
 			 * the second pdc buffer, so we need to reconfigure first and
@@ -1747,24 +1739,24 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
 			 */
 			if (host->data_size) {
 				atmci_pdc_set_both_buf(host, XFER_TRANSMIT);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
 				atmci_writel(host, ATMCI_IER, ATMCI_TXBUFE);
 			} else {
 				atmci_pdc_complete(host);
 			}
-		}
-
-		if (pending & ATMCI_ENDRX) {
-			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
+		} else if (pending & ATMCI_ENDTX) {
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
 
 			if (host->data_size) {
 				atmci_pdc_set_single_buf(host,
-						XFER_RECEIVE, PDC_SECOND_BUF);
-				atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
+						XFER_TRANSMIT, PDC_SECOND_BUF);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
 			}
 		}
 
 		if (pending & ATMCI_RXBUFF) {
 			atmci_writel(host, ATMCI_IDR, ATMCI_RXBUFF);
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
 			/*
 			 * We can receive this interruption before having configured
 			 * the second pdc buffer, so we need to reconfigure first and
@@ -1772,12 +1764,22 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
 			 */
 			if (host->data_size) {
 				atmci_pdc_set_both_buf(host, XFER_RECEIVE);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
 				atmci_writel(host, ATMCI_IER, ATMCI_RXBUFF);
 			} else {
 				atmci_pdc_complete(host);
 			}
+		} else if (pending & ATMCI_ENDRX) {
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
+
+			if (host->data_size) {
+				atmci_pdc_set_single_buf(host,
+						XFER_RECEIVE, PDC_SECOND_BUF);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
+			}
 		}
 
+
 		if (pending & ATMCI_NOTBUSY) {
 			atmci_writel(host, ATMCI_IDR,
 					ATMCI_DATA_ERROR_FLAGS | ATMCI_NOTBUSY);
Signature · 1 line
1.7.0.4
#14 lore raw

v2 cover Add pdc feature to atmel-mci

In reply to ludovic.desroches at atmel.com

Changes since v1:
* merge patch 6 and 7.

The purpose of these patches is to merge at91_mci and atmel atmel-mci drivers. The first one is used only for old atmel mci core and provides the PDC feature. The second one works with the old core but doesn't provide the PDC feature so the goal is to implement this feature in order to remove at91_mci.

This new version of the atmel-mci driver detects mci core version at runtime. Then it knows if we have to use pio, pdc or dma for transfers.

These patches are based on "mmc: atmel-mci: add suspend/resume support" from Nicolas.

arch/arm/mach-at91/at91sam9260_devices.c |    2 +-
drivers/mmc/host/atmel-mci-regs.h        |  220 +++++----
drivers/mmc/host/atmel-mci.c             |  824 ++++++++++++++++++++----------
include/linux/atmel-mci.h                |    4 +-
include/linux/atmel_pdc.h                |    2 +
5 files changed, 681 insertions(+), 371 deletions(-)
#15 lore raw

PATCH v2 1/8 mmc: atmel-mci: change namespace

From: Ludovic Desroches <[email protected]>

Homogenize namespace to atmci.

---
 arch/arm/mach-at91/at91sam9260_devices.c |    2 +-
 drivers/mmc/host/atmel-mci-regs.h        |  206 ++++++++++----------
 drivers/mmc/host/atmel-mci.c             |  301 +++++++++++++++---------------
 include/linux/atmel-mci.h                |    4 +-
 4 files changed, 257 insertions(+), 256 deletions(-)
arch/arm/mach-at91/at91sam9260_devices.c +1 -1
index 39f81f4..c49e84a 100644
@@ -319,7 +319,7 @@ void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
 	if (!data)
 		return;
 
-	for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+	for (i = 0; i < ATMCI_MAX_NR_SLOTS; i++) {
 		if (data->slot[i].bus_width) {
 			/* input/irq */
 			if (data->slot[i].detect_pin) {
drivers/mmc/host/atmel-mci-regs.h +103 -103

215 lines not on this page · raw message

drivers/mmc/host/atmel-mci.c +151 -150

775 lines not on this page · raw message

include/linux/atmel-mci.h +2 -2
index 3e09b34..4c7a4b2 100644
@@ -1,7 +1,7 @@
 #ifndef __LINUX_ATMEL_MCI_H
 #define __LINUX_ATMEL_MCI_H
 
-#define ATMEL_MCI_MAX_NR_SLOTS	2
+#define ATMCI_MAX_NR_SLOTS	2
 
 /**
  * struct mci_slot_pdata - board-specific per-slot configuration
@@ -33,7 +33,7 @@ struct mci_slot_pdata {
  */
 struct mci_platform_data {
 	struct mci_dma_data	*dma_slave;
-	struct mci_slot_pdata	slot[ATMEL_MCI_MAX_NR_SLOTS];
+	struct mci_slot_pdata	slot[ATMCI_MAX_NR_SLOTS];
 };
 
 #endif /* __LINUX_ATMEL_MCI_H */
Signature · 1 line
1.7.0.4
#16 lore raw

PATCH v2 2/8 mmc: atmel-mci: change atmci_readl and atmci_writel macros

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Change atmci_readl and atmci_writel macros: remove string concatenation. We can use these macros with registers which are not prefix by ATMCI_. It's the case if we want to write PDC registers which are common to several devices so they are not prefixed with ATMCI_.

---
 drivers/mmc/host/atmel-mci-regs.h |    4 +-
 drivers/mmc/host/atmel-mci.c      |  126 ++++++++++++++++++------------------
 2 files changed, 65 insertions(+), 65 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +2 -2
index 29331ab..8574e91 100644
@@ -121,8 +121,8 @@
 
 /* Register access macros */
 #define atmci_readl(port,reg)				\
-	__raw_readl((port)->regs + ATMCI_##reg)
+	__raw_readl((port)->regs + reg)
 #define atmci_writel(port,reg,value)			\
-	__raw_writel((value), (port)->regs + ATMCI_##reg)
+	__raw_writel((value), (port)->regs + reg)
 
 #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */
drivers/mmc/host/atmel-mci.c +63 -63

350 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#17 lore raw

PATCH v2 3/8 mmc: atmel-mci: indentation

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

---
 drivers/mmc/host/atmel-mci-regs.h |  136 ++++++++++++++++++------------------
 1 files changed, 68 insertions(+), 68 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +68 -68
index 8574e91..7310b20 100644
@@ -18,103 +18,103 @@
 
 /* MCI Register Definitions */
 #define ATMCI_CR			0x0000	/* Control */
-# define ATMCI_CR_MCIEN		(  1 <<  0)	/* MCI Enable */
+# define ATMCI_CR_MCIEN			(  1 <<  0)	/* MCI Enable */
 # define ATMCI_CR_MCIDIS		(  1 <<  1)	/* MCI Disable */
-# define ATMCI_CR_PWSEN		(  1 <<  2)	/* Power Save Enable */
+# define ATMCI_CR_PWSEN			(  1 <<  2)	/* Power Save Enable */
 # define ATMCI_CR_PWSDIS		(  1 <<  3)	/* Power Save Disable */
-# define ATMCI_CR_SWRST		(  1 <<  7)	/* Software Reset */
+# define ATMCI_CR_SWRST			(  1 <<  7)	/* Software Reset */
 #define ATMCI_MR			0x0004	/* Mode */
-# define ATMCI_MR_CLKDIV(x)	((x) <<  0)	/* Clock Divider */
-# define ATMCI_MR_PWSDIV(x)	((x) <<  8)	/* Power Saving Divider */
+# define ATMCI_MR_CLKDIV(x)		((x) <<  0)	/* Clock Divider */
+# define ATMCI_MR_PWSDIV(x)		((x) <<  8)	/* Power Saving Divider */
 # define ATMCI_MR_RDPROOF		(  1 << 11)	/* Read Proof */
 # define ATMCI_MR_WRPROOF		(  1 << 12)	/* Write Proof */
-# define ATMCI_MR_PDCFBYTE	(  1 << 13)	/* Force Byte Transfer */
+# define ATMCI_MR_PDCFBYTE		(  1 << 13)	/* Force Byte Transfer */
 # define ATMCI_MR_PDCPADV		(  1 << 14)	/* Padding Value */
 # define ATMCI_MR_PDCMODE		(  1 << 15)	/* PDC-oriented Mode */
-#define ATMCI_DTOR		0x0008	/* Data Timeout */
+#define ATMCI_DTOR			0x0008	/* Data Timeout */
 # define ATMCI_DTOCYC(x)		((x) <<  0)	/* Data Timeout Cycles */
 # define ATMCI_DTOMUL(x)		((x) <<  4)	/* Data Timeout Multiplier */
-#define ATMCI_SDCR		0x000c	/* SD Card / SDIO */
-# define ATMCI_SDCSEL_SLOT_A	(  0 <<  0)	/* Select SD slot A */
-# define ATMCI_SDCSEL_SLOT_B	(  1 <<  0)	/* Select SD slot A */
-# define ATMCI_SDCSEL_MASK	(  3 <<  0)
-# define ATMCI_SDCBUS_1BIT	(  0 <<  6)	/* 1-bit data bus */
-# define ATMCI_SDCBUS_4BIT	(  2 <<  6)	/* 4-bit data bus */
-# define ATMCI_SDCBUS_8BIT	(  3 <<  6)	/* 8-bit data bus[2] */
-# define ATMCI_SDCBUS_MASK	(  3 <<  6)
-#define ATMCI_ARGR		0x0010	/* Command Argument */
-#define ATMCI_CMDR		0x0014	/* Command */
-# define ATMCI_CMDR_CMDNB(x)	((x) <<  0)	/* Command Opcode */
-# define ATMCI_CMDR_RSPTYP_NONE	(  0 <<  6)	/* No response */
+#define ATMCI_SDCR			0x000c	/* SD Card / SDIO */
+# define ATMCI_SDCSEL_SLOT_A		(  0 <<  0)	/* Select SD slot A */
+# define ATMCI_SDCSEL_SLOT_B		(  1 <<  0)	/* Select SD slot A */
+# define ATMCI_SDCSEL_MASK		(  3 <<  0)
+# define ATMCI_SDCBUS_1BIT		(  0 <<  6)	/* 1-bit data bus */
+# define ATMCI_SDCBUS_4BIT		(  2 <<  6)	/* 4-bit data bus */
+# define ATMCI_SDCBUS_8BIT		(  3 <<  6)	/* 8-bit data bus[2] */
+# define ATMCI_SDCBUS_MASK		(  3 <<  6)
+#define ATMCI_ARGR			0x0010	/* Command Argument */
+#define ATMCI_CMDR			0x0014	/* Command */
+# define ATMCI_CMDR_CMDNB(x)		((x) <<  0)	/* Command Opcode */
+# define ATMCI_CMDR_RSPTYP_NONE		(  0 <<  6)	/* No response */
 # define ATMCI_CMDR_RSPTYP_48BIT	(  1 <<  6)	/* 48-bit response */
 # define ATMCI_CMDR_RSPTYP_136BIT	(  2 <<  6)	/* 136-bit response */
-# define ATMCI_CMDR_SPCMD_INIT	(  1 <<  8)	/* Initialization command */
-# define ATMCI_CMDR_SPCMD_SYNC	(  2 <<  8)	/* Synchronized command */
-# define ATMCI_CMDR_SPCMD_INT	(  4 <<  8)	/* Interrupt command */
+# define ATMCI_CMDR_SPCMD_INIT		(  1 <<  8)	/* Initialization command */
+# define ATMCI_CMDR_SPCMD_SYNC		(  2 <<  8)	/* Synchronized command */
+# define ATMCI_CMDR_SPCMD_INT		(  4 <<  8)	/* Interrupt command */
 # define ATMCI_CMDR_SPCMD_INTRESP	(  5 <<  8)	/* Interrupt response */
-# define ATMCI_CMDR_OPDCMD	(  1 << 11)	/* Open Drain */
-# define ATMCI_CMDR_MAXLAT_5CYC	(  0 << 12)	/* Max latency 5 cycles */
+# define ATMCI_CMDR_OPDCMD		(  1 << 11)	/* Open Drain */
+# define ATMCI_CMDR_MAXLAT_5CYC		(  0 << 12)	/* Max latency 5 cycles */
 # define ATMCI_CMDR_MAXLAT_64CYC	(  1 << 12)	/* Max latency 64 cycles */
-# define ATMCI_CMDR_START_XFER	(  1 << 16)	/* Start data transfer */
-# define ATMCI_CMDR_STOP_XFER	(  2 << 16)	/* Stop data transfer */
-# define ATMCI_CMDR_TRDIR_WRITE	(  0 << 18)	/* Write data */
-# define ATMCI_CMDR_TRDIR_READ	(  1 << 18)	/* Read data */
+# define ATMCI_CMDR_START_XFER		(  1 << 16)	/* Start data transfer */
+# define ATMCI_CMDR_STOP_XFER		(  2 << 16)	/* Stop data transfer */
+# define ATMCI_CMDR_TRDIR_WRITE		(  0 << 18)	/* Write data */
+# define ATMCI_CMDR_TRDIR_READ		(  1 << 18)	/* Read data */
 # define ATMCI_CMDR_BLOCK		(  0 << 19)	/* Single-block transfer */
-# define ATMCI_CMDR_MULTI_BLOCK	(  1 << 19)	/* Multi-block transfer */
-# define ATMCI_CMDR_STREAM	(  2 << 19)	/* MMC Stream transfer */
-# define ATMCI_CMDR_SDIO_BYTE	(  4 << 19)	/* SDIO Byte transfer */
-# define ATMCI_CMDR_SDIO_BLOCK	(  5 << 19)	/* SDIO Block transfer */
+# define ATMCI_CMDR_MULTI_BLOCK		(  1 << 19)	/* Multi-block transfer */
+# define ATMCI_CMDR_STREAM		(  2 << 19)	/* MMC Stream transfer */
+# define ATMCI_CMDR_SDIO_BYTE		(  4 << 19)	/* SDIO Byte transfer */
+# define ATMCI_CMDR_SDIO_BLOCK		(  5 << 19)	/* SDIO Block transfer */
 # define ATMCI_CMDR_SDIO_SUSPEND	(  1 << 24)	/* SDIO Suspend Command */
-# define ATMCI_CMDR_SDIO_RESUME	(  2 << 24)	/* SDIO Resume Command */
-#define ATMCI_BLKR		0x0018	/* Block */
-# define ATMCI_BCNT(x)		((x) <<  0)	/* Data Block Count */
+# define ATMCI_CMDR_SDIO_RESUME		(  2 << 24)	/* SDIO Resume Command */
+#define ATMCI_BLKR			0x0018	/* Block */
+# define ATMCI_BCNT(x)			((x) <<  0)	/* Data Block Count */
 # define ATMCI_BLKLEN(x)		((x) << 16)	/* Data Block Length */
-#define ATMCI_CSTOR		0x001c	/* Completion Signal Timeout[2] */
+#define ATMCI_CSTOR			0x001c	/* Completion Signal Timeout[2] */
 # define ATMCI_CSTOCYC(x)		((x) <<  0)	/* CST cycles */
 # define ATMCI_CSTOMUL(x)		((x) <<  4)	/* CST multiplier */
-#define ATMCI_RSPR		0x0020	/* Response 0 */
-#define ATMCI_RSPR1		0x0024	/* Response 1 */
-#define ATMCI_RSPR2		0x0028	/* Response 2 */
-#define ATMCI_RSPR3		0x002c	/* Response 3 */
+#define ATMCI_RSPR			0x0020	/* Response 0 */
+#define ATMCI_RSPR1			0x0024	/* Response 1 */
+#define ATMCI_RSPR2			0x0028	/* Response 2 */
+#define ATMCI_RSPR3			0x002c	/* Response 3 */
 #define ATMCI_RDR			0x0030	/* Receive Data */
 #define ATMCI_TDR			0x0034	/* Transmit Data */
 #define ATMCI_SR			0x0040	/* Status */
 #define ATMCI_IER			0x0044	/* Interrupt Enable */
 #define ATMCI_IDR			0x0048	/* Interrupt Disable */
 #define ATMCI_IMR			0x004c	/* Interrupt Mask */
-# define ATMCI_CMDRDY		(  1 <<   0)	/* Command Ready */
-# define ATMCI_RXRDY		(  1 <<   1)	/* Receiver Ready */
-# define ATMCI_TXRDY		(  1 <<   2)	/* Transmitter Ready */
-# define ATMCI_BLKE		(  1 <<   3)	/* Data Block Ended */
-# define ATMCI_DTIP		(  1 <<   4)	/* Data Transfer In Progress */
-# define ATMCI_NOTBUSY		(  1 <<   5)	/* Data Not Busy */
-# define ATMCI_SDIOIRQA		(  1 <<   8)	/* SDIO IRQ in slot A */
-# define ATMCI_SDIOIRQB		(  1 <<   9)	/* SDIO IRQ in slot B */
-# define ATMCI_RINDE		(  1 <<  16)	/* Response Index Error */
-# define ATMCI_RDIRE		(  1 <<  17)	/* Response Direction Error */
-# define ATMCI_RCRCE		(  1 <<  18)	/* Response CRC Error */
-# define ATMCI_RENDE		(  1 <<  19)	/* Response End Bit Error */
-# define ATMCI_RTOE		(  1 <<  20)	/* Response Time-Out Error */
-# define ATMCI_DCRCE		(  1 <<  21)	/* Data CRC Error */
-# define ATMCI_DTOE		(  1 <<  22)	/* Data Time-Out Error */
-# define ATMCI_OVRE		(  1 <<  30)	/* RX Overrun Error */
-# define ATMCI_UNRE		(  1 <<  31)	/* TX Underrun Error */
+# define ATMCI_CMDRDY			(  1 <<   0)	/* Command Ready */
+# define ATMCI_RXRDY			(  1 <<   1)	/* Receiver Ready */
+# define ATMCI_TXRDY			(  1 <<   2)	/* Transmitter Ready */
+# define ATMCI_BLKE			(  1 <<   3)	/* Data Block Ended */
+# define ATMCI_DTIP			(  1 <<   4)	/* Data Transfer In Progress */
+# define ATMCI_NOTBUSY			(  1 <<   5)	/* Data Not Busy */
+# define ATMCI_SDIOIRQA			(  1 <<   8)	/* SDIO IRQ in slot A */
+# define ATMCI_SDIOIRQB			(  1 <<   9)	/* SDIO IRQ in slot B */
+# define ATMCI_RINDE			(  1 <<  16)	/* Response Index Error */
+# define ATMCI_RDIRE			(  1 <<  17)	/* Response Direction Error */
+# define ATMCI_RCRCE			(  1 <<  18)	/* Response CRC Error */
+# define ATMCI_RENDE			(  1 <<  19)	/* Response End Bit Error */
+# define ATMCI_RTOE			(  1 <<  20)	/* Response Time-Out Error */
+# define ATMCI_DCRCE			(  1 <<  21)	/* Data CRC Error */
+# define ATMCI_DTOE			(  1 <<  22)	/* Data Time-Out Error */
+# define ATMCI_OVRE			(  1 <<  30)	/* RX Overrun Error */
+# define ATMCI_UNRE			(  1 <<  31)	/* TX Underrun Error */
 #define ATMCI_DMA			0x0050	/* DMA Configuration[2] */
-# define ATMCI_DMA_OFFSET(x)	((x) <<  0)	/* DMA Write Buffer Offset */
-# define ATMCI_DMA_CHKSIZE(x)	((x) <<  4)	/* DMA Channel Read and Write Chunk Size */
-# define ATMCI_DMAEN		(  1 <<  8)	/* DMA Hardware Handshaking Enable */
+# define ATMCI_DMA_OFFSET(x)		((x) <<  0)	/* DMA Write Buffer Offset */
+# define ATMCI_DMA_CHKSIZE(x)		((x) <<  4)	/* DMA Channel Read and Write Chunk Size */
+# define ATMCI_DMAEN			(  1 <<  8)	/* DMA Hardware Handshaking Enable */
 #define ATMCI_CFG			0x0054	/* Configuration[2] */
 # define ATMCI_CFG_FIFOMODE_1DATA	(  1 <<  0)	/* MCI Internal FIFO control mode */
-# define ATMCI_CFG_FERRCTRL_COR	(  1 <<  4)	/* Flow Error flag reset control mode */
+# define ATMCI_CFG_FERRCTRL_COR		(  1 <<  4)	/* Flow Error flag reset control mode */
 # define ATMCI_CFG_HSMODE		(  1 <<  8)	/* High Speed Mode */
 # define ATMCI_CFG_LSYNC		(  1 << 12)	/* Synchronize on the last block */
-#define ATMCI_WPMR		0x00e4	/* Write Protection Mode[2] */
-# define ATMCI_WP_EN		(  1 <<  0)	/* WP Enable */
-# define ATMCI_WP_KEY		(0x4d4349 << 8)	/* WP Key */
-#define ATMCI_WPSR		0x00e8	/* Write Protection Status[2] */
-# define ATMCI_GET_WP_VS(x)	((x) & 0x0f)
-# define ATMCI_GET_WP_VSRC(x)	(((x) >> 8) & 0xffff)
-#define ATMCI_FIFO_APERTURE	0x0200	/* FIFO Aperture[2] */
+#define ATMCI_WPMR			0x00e4	/* Write Protection Mode[2] */
+# define ATMCI_WP_EN			(  1 <<  0)	/* WP Enable */
+# define ATMCI_WP_KEY			(0x4d4349 << 8)	/* WP Key */
+#define ATMCI_WPSR			0x00e8	/* Write Protection Status[2] */
+# define ATMCI_GET_WP_VS(x)		((x) & 0x0f)
+# define ATMCI_GET_WP_VSRC(x)		(((x) >> 8) & 0xffff)
+#define ATMCI_FIFO_APERTURE		0x0200	/* FIFO Aperture[2] */
 
 /* This is not including the FIFO Aperture on MCI2 */
 #define ATMCI_REGS_SIZE		0x100
Signature · 1 line
1.7.0.4
#18 lore raw

PATCH v2 4/8 mmc: atmel-mci: add pdc support and runtime capabilities detection

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Add the pdc support for atmel-mci. It makes at91-mci driver useless because it was only used for the old atmel MCI core which has pdc but no dma support. To allow removing at91-mci, the capabilites of the MCI core is detected at runtime, then the driver will use pio, pdc or dma transfers.
Warning: at91rm9200 is not supported, to support it we need to use swab32 on data but I have no board to test it.

---
 drivers/mmc/host/atmel-mci-regs.h |   14 +
 drivers/mmc/host/atmel-mci.c      |  528 ++++++++++++++++++++++++++++--------
 2 files changed, 424 insertions(+), 118 deletions(-)
drivers/mmc/host/atmel-mci-regs.h +14 -0
index 7310b20..6dd2826 100644
@@ -88,8 +88,14 @@
 # define ATMCI_BLKE			(  1 <<   3)	/* Data Block Ended */
 # define ATMCI_DTIP			(  1 <<   4)	/* Data Transfer In Progress */
 # define ATMCI_NOTBUSY			(  1 <<   5)	/* Data Not Busy */
+# define ATMCI_ENDRX			(  1 <<   6)    /* End of RX Buffer */
+# define ATMCI_ENDTX			(  1 <<   7)    /* End of TX Buffer */
 # define ATMCI_SDIOIRQA			(  1 <<   8)	/* SDIO IRQ in slot A */
 # define ATMCI_SDIOIRQB			(  1 <<   9)	/* SDIO IRQ in slot B */
+# define ATMCI_SDIOWAIT			(  1 <<  12)    /* SDIO Read Wait Operation Status */
+# define ATMCI_CSRCV			(  1 <<  13)    /* CE-ATA Completion Signal Received */
+# define ATMCI_RXBUFF			(  1 <<  14)    /* RX Buffer Full */
+# define ATMCI_TXBUFE			(  1 <<  15)    /* TX Buffer Empty */
 # define ATMCI_RINDE			(  1 <<  16)	/* Response Index Error */
 # define ATMCI_RDIRE			(  1 <<  17)	/* Response Direction Error */
 # define ATMCI_RCRCE			(  1 <<  18)	/* Response CRC Error */
@@ -97,6 +103,13 @@
 # define ATMCI_RTOE			(  1 <<  20)	/* Response Time-Out Error */
 # define ATMCI_DCRCE			(  1 <<  21)	/* Data CRC Error */
 # define ATMCI_DTOE			(  1 <<  22)	/* Data Time-Out Error */
+# define ATMCI_CSTOE			(  1 <<  23)    /* Completion Signql Time-out Error */
+# define ATMCI_BLKOVRE			(  1 <<  24)    /* DMA Block Overrun Error */
+# define ATMCI_DMADONE			(  1 <<  25)    /* DMA Transfer Done */
+# define ATMCI_FIFOEMPTY		(  1 <<  26)    /* FIFO Empty Flag */
+# define ATMCI_XFRDONE			(  1 <<  27)    /* Transfer Done Flag */
+# define ATMCI_ACKRCV			(  1 <<  28)    /* Boot Operation Acknowledge Received */
+# define ATMCI_ACKRCVE			(  1 <<  29)    /* Boot Operation Acknowledge Error */
 # define ATMCI_OVRE			(  1 <<  30)	/* RX Overrun Error */
 # define ATMCI_UNRE			(  1 <<  31)	/* TX Underrun Error */
 #define ATMCI_DMA			0x0050	/* DMA Configuration[2] */
@@ -114,6 +127,7 @@
 #define ATMCI_WPSR			0x00e8	/* Write Protection Status[2] */
 # define ATMCI_GET_WP_VS(x)		((x) & 0x0f)
 # define ATMCI_GET_WP_VSRC(x)		(((x) >> 8) & 0xffff)
+#define ATMCI_VERSION			0x00FC  /* Version */
 #define ATMCI_FIFO_APERTURE		0x0200	/* FIFO Aperture[2] */
 
 /* This is not including the FIFO Aperture on MCI2 */
drivers/mmc/host/atmel-mci.c +410 -118

793 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#19 lore raw

PATCH v2 5/8 mmc: atmel-mci: change atmci_start_command to atmci_send_command

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Change atmci_start_command function name to atmci_send_command which is more appropriate to no think we are sending a start command.

---
 drivers/mmc/host/atmel-mci.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/mmc/host/atmel-mci.c +3 -3
index efbee87..7955697 100644
@@ -565,7 +565,7 @@ static u32 atmci_prepare_command(struct mmc_host *mmc,
 	return cmdr;
 }
 
-static void atmci_start_command(struct atmel_mci *host,
+static void atmci_send_command(struct atmel_mci *host,
 		struct mmc_command *cmd, u32 cmd_flags)
 {
 	WARN_ON(host->cmd);
@@ -581,7 +581,7 @@ static void atmci_start_command(struct atmel_mci *host,
 
 static void atmci_send_stop_cmd(struct atmel_mci *host, struct mmc_data *data)
 {
-	atmci_start_command(host, data->stop, host->stop_cmdr);
+	atmci_send_command(host, data->stop, host->stop_cmdr);
 	atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY);
 }
 
@@ -1003,7 +1003,7 @@ static void atmci_start_request(struct atmel_mci *host,
 	iflags |= ATMCI_CMDRDY;
 	cmd = mrq->cmd;
 	cmdflags = atmci_prepare_command(slot->mmc, cmd);
-	atmci_start_command(host, cmd, cmdflags);
+	atmci_send_command(host, cmd, cmdflags);
 
 	if (data)
 		host->submit_data(host, data);
Signature · 1 line
1.7.0.4
#20 lore raw

PATCH v2 6/8 mmc: atmel-mci: use ATMEL_PDC_SCND_BUF_OFF instead of a literal value

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

---
 drivers/mmc/host/atmel-mci.c |    4 ++--
 include/linux/atmel_pdc.h    |    2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/mmc/host/atmel-mci.c +2 -2
index 7955697..c415322 100644
@@ -603,8 +603,8 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
 	}
 
 	if (buf_nb == PDC_SECOND_BUF) {
-		pointer_reg += 0x10;
-		counter_reg += 0x10;
+		pointer_reg += ATMEL_PDC_SCND_BUF_OFF;
+		counter_reg += ATMEL_PDC_SCND_BUF_OFF;
 	}
 
 	atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
include/linux/atmel_pdc.h +2 -0
index 5058a31..63499ce 100644
@@ -33,4 +33,6 @@
 
 #define ATMEL_PDC_PTSR		0x124	/* Transfer Status Register */
 
+#define ATMEL_PDC_SCND_BUF_OFF	0x10	/* Offset between first and second buffer registers */
+
 #endif
Signature · 1 line
1.7.0.4
#21 lore raw

PATCH v2 7/8 mmc: atmel-mci: correct sg buffer size evaluation

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

Assuming that a sg buffer size is a page size is false so use sg_dma_len. A 4096 bytes can be required with two 2048-bytes sg buffer.

---
 drivers/mmc/host/atmel-mci.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)
drivers/mmc/host/atmel-mci.c +3 -4
index c415322..963e320 100644
@@ -608,7 +608,7 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
 	}
 
 	atmci_writel(host, pointer_reg, sg_dma_address(host->sg));
-	if (host->data_size <= PAGE_SIZE) {
+	if (host->data_size <= sg_dma_len(host->sg)) {
 		if (host->data_size & 0x3) {
 			/* If size is different from modulo 4, transfer bytes */
 			atmci_writel(host, counter_reg, host->data_size);
@@ -620,8 +620,8 @@ static void atmci_pdc_set_single_buf(struct atmel_mci *host,
 		host->data_size = 0;
 	} else {
 		/* We assume the size of a page is 32-bits aligned */
-		atmci_writel(host, counter_reg, PAGE_SIZE / 4);
-		host->data_size -= PAGE_SIZE;
+		atmci_writel(host, counter_reg, sg_dma_len(host->sg) / 4);
+		host->data_size -= sg_dma_len(host->sg);
 		if (host->data_size)
 			host->sg = sg_next(host->sg);
 	}
@@ -808,7 +808,6 @@ atmci_prepare_data_pdc(struct atmel_mci *host, struct mmc_data *data)
 	/* Configure PDC */
 	host->data_size = data->blocks * data->blksz;
 	sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, dir);
-	BUG_ON(sg_len < host->data_size / PAGE_SIZE);
 	if (host->data_size)
 		atmci_pdc_set_both_buf(host,
 			((dir == DMA_FROM_DEVICE)?XFER_RECEIVE:XFER_TRANSMIT));
Signature · 1 line
1.7.0.4
#22 lore raw

PATCH v2 8/8 mmc: atmel-mci: fix a potential issue about pending PDC interrupts

In reply to ludovic.desroches at atmel.com

From: Ludovic Desroches <[email protected]>

This patch fixes a potential issue about PDC interrupts. For example we have a ENDRX pending interrupt and a RXBUFF pending interrupt. We have received the RXBUFF interrupt but the transfer is not finished (so we didn't have time to give a new buffer to the PDC controller). Then we will compute ENDRX interrupt and we will give a new buffer to the PDC controller, just after we will compute the RXBUFF interrupt and give one or two new buffers to the PDC controller but we are not sure that the first buffer given has been filled. So in this situation we may "lost" one sg buffer. It's the same for transmission.

---
 drivers/mmc/host/atmel-mci.c |   32 +++++++++++++++++---------------
 1 files changed, 17 insertions(+), 15 deletions(-)
drivers/mmc/host/atmel-mci.c +17 -15
index 963e320..7108f64 100644
@@ -1729,17 +1729,9 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
 			tasklet_schedule(&host->tasklet);
 		}
 
-		if (pending & ATMCI_ENDTX) {
-			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
-			if (host->data_size) {
-				atmci_pdc_set_single_buf(host,
-						XFER_TRANSMIT, PDC_SECOND_BUF);
-				atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
-			}
-		}
-
 		if (pending & ATMCI_TXBUFE) {
 			atmci_writel(host, ATMCI_IDR, ATMCI_TXBUFE);
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
 			/*
 			 * We can receive this interruption before having configured
 			 * the second pdc buffer, so we need to reconfigure first and
@@ -1747,24 +1739,24 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
 			 */
 			if (host->data_size) {
 				atmci_pdc_set_both_buf(host, XFER_TRANSMIT);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
 				atmci_writel(host, ATMCI_IER, ATMCI_TXBUFE);
 			} else {
 				atmci_pdc_complete(host);
 			}
-		}
-
-		if (pending & ATMCI_ENDRX) {
-			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
+		} else if (pending & ATMCI_ENDTX) {
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDTX);
 
 			if (host->data_size) {
 				atmci_pdc_set_single_buf(host,
-						XFER_RECEIVE, PDC_SECOND_BUF);
-				atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
+						XFER_TRANSMIT, PDC_SECOND_BUF);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDTX);
 			}
 		}
 
 		if (pending & ATMCI_RXBUFF) {
 			atmci_writel(host, ATMCI_IDR, ATMCI_RXBUFF);
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
 			/*
 			 * We can receive this interruption before having configured
 			 * the second pdc buffer, so we need to reconfigure first and
@@ -1772,12 +1764,22 @@ static irqreturn_t atmci_interrupt(int irq, void *dev_id)
 			 */
 			if (host->data_size) {
 				atmci_pdc_set_both_buf(host, XFER_RECEIVE);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
 				atmci_writel(host, ATMCI_IER, ATMCI_RXBUFF);
 			} else {
 				atmci_pdc_complete(host);
 			}
+		} else if (pending & ATMCI_ENDRX) {
+			atmci_writel(host, ATMCI_IDR, ATMCI_ENDRX);
+
+			if (host->data_size) {
+				atmci_pdc_set_single_buf(host,
+						XFER_RECEIVE, PDC_SECOND_BUF);
+				atmci_writel(host, ATMCI_IER, ATMCI_ENDRX);
+			}
 		}
 
+
 		if (pending & ATMCI_NOTBUSY) {
 			atmci_writel(host, ATMCI_IDR,
 					ATMCI_DATA_ERROR_FLAGS | ATMCI_NOTBUSY);
Signature · 1 line
1.7.0.4