Add pdc feature to atmel-mci
Subsystems (6)
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(-)
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
@@ -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
@@ -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
RFC PATCH 1/9 mmc: atmel-mci: change namespace
Quoted 5 lines · ludovic.desroches at atmel.com
From: Ludovic Desroches <[email protected]>
Homogenize namespace to atmci.
Signed-off-by Ludovic Desroches <[email protected]>
prefer ATMEL_MCI
ATMCI is not clear
Best Regards,
J.
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.
Signed-off-by Ludovic Desroches<[email protected]>prefer
ATMEL_MCIATMCI 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
RFC PATCH 2/9 mmc: atmel-mci: change atmci_readl and atmci_writel macros
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
RFC PATCH 3/9 mmc: atmel-mci: indentation
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
RFC PATCH 4/9 mmc: atmel-mci: add pdc support and runtime capabilities detection
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
RFC PATCH 5/9 mmc: atmel-mci: change atmci_start_command to atmci_send_command
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
RFC PATCH 6/9 atmel_pdc: add ATMEL_PDC_SCND_BUF_OFF
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
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.
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
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.comFrom: 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
@@ -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
RFC PATCH 8/9 mmc: atmel-mci: correct sg buffer size evaluation
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
RFC PATCH 9/9 mmc: atmel-mci: fix a potential issue about pending PDC interrupts
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
v2 cover Add pdc feature to atmel-mci
In reply to ludovic.desroches at atmel.comChanges 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(-)
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
@@ -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
@@ -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
PATCH v2 2/8 mmc: atmel-mci: change atmci_readl and atmci_writel macros
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
PATCH v2 3/8 mmc: atmel-mci: indentation
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
PATCH v2 4/8 mmc: atmel-mci: add pdc support and runtime capabilities detection
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
PATCH v2 5/8 mmc: atmel-mci: change atmci_start_command to atmci_send_command
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
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.comFrom: 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
@@ -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
@@ -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
PATCH v2 7/8 mmc: atmel-mci: correct sg buffer size evaluation
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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
PATCH v2 8/8 mmc: atmel-mci: fix a potential issue about pending PDC interrupts
In reply to ludovic.desroches at atmel.comFrom: 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
@@ -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