diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 14:16:11 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-28 14:16:11 -0700 |
| commit | 46b51ea2099fa2082342e52b8284aa828429b80b (patch) | |
| tree | 0a0d7bfe1aff036c86a2e7beacbd91398008bfb6 /drivers/mmc/host | |
| parent | 1fdb24e969110fafea36d3b393bea438f702c87f (diff) | |
| parent | a6029e1f75bb484c1f5bc68b6a8572e4024795bc (diff) | |
| download | linux-46b51ea2099fa2082342e52b8284aa828429b80b.tar.gz linux-46b51ea2099fa2082342e52b8284aa828429b80b.tar.bz2 linux-46b51ea2099fa2082342e52b8284aa828429b80b.zip | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (83 commits)
mmc: fix compile error when CONFIG_BLOCK is not enabled
mmc: core: Cleanup eMMC4.5 conditionals
mmc: omap_hsmmc: if multiblock reads are broken, disable them
mmc: core: add workaround for controllers with broken multiblock reads
mmc: core: Prevent too long response times for suspend
mmc: recognise SDIO cards with SDIO_CCCR_REV 3.00
mmc: sd: Handle SD3.0 cards not supporting UHS-I bus speed mode
mmc: core: support HPI send command
mmc: core: Add cache control for eMMC4.5 device
mmc: core: Modify the timeout value for writing power class
mmc: core: new discard feature support at eMMC v4.5
mmc: core: mmc sanitize feature support for v4.5
mmc: dw_mmc: modify DATA register offset
mmc: sdhci-pci: add flag for devices that can support runtime PM
mmc: omap_hsmmc: ensure pbias configuration is always done
mmc: core: Add Power Off Notify Feature eMMC 4.5
mmc: sdhci-s3c: fix potential NULL dereference
mmc: replace printk with appropriate display macro
mmc: core: Add default timeout value for CMD6
mmc: sdhci-pci: add runtime pm support
...
Diffstat (limited to 'drivers/mmc/host')
39 files changed, 1800 insertions, 707 deletions
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 8c87096531e9..87d5067ba629 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -130,13 +130,13 @@ config MMC_SDHCI_CNS3XXX If unsure, say N. config MMC_SDHCI_ESDHC_IMX - tristate "SDHCI platform support for the Freescale eSDHC i.MX controller" - depends on ARCH_MX25 || ARCH_MX35 || ARCH_MX5 + tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller" + depends on ARCH_MXC depends on MMC_SDHCI_PLTFM select MMC_SDHCI_IO_ACCESSORS help - This selects the Freescale eSDHC controller support on the platform - bus, found on platforms like mx35/51. + This selects the Freescale eSDHC/uSDHC controller support + found on i.MX25, i.MX35 i.MX5x and i.MX6x. If you have a controller with this interface, say Y or M here. @@ -326,11 +326,11 @@ config MMC_MSM support for SDIO devices. config MMC_MXC - tristate "Freescale i.MX2/3 Multimedia Card Interface support" - depends on MACH_MX21 || MACH_MX27 || ARCH_MX31 + tristate "Freescale i.MX21/27/31 Multimedia Card Interface support" + depends on ARCH_MXC help - This selects the Freescale i.MX2/3 Multimedia card Interface. - If you have a i.MX platform with a Multimedia Card slot, + This selects the Freescale i.MX21, i.MX27 and i.MX31 Multimedia card + Interface. If you have a i.MX platform with a Multimedia Card slot, say Y or M here. If unsure, say N. diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index a4aa3af86fed..a8b4d2aa18e5 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c @@ -869,7 +869,11 @@ static irqreturn_t at91_mci_irq(int irq, void *devid) static irqreturn_t at91_mmc_det_irq(int irq, void *_host) { struct at91mci_host *host = _host; - int present = !gpio_get_value(irq_to_gpio(irq)); + int present; + + /* entering this ISR means that we have configured det_pin: + * we can use its value in board structure */ + present = !gpio_get_value(host->board->det_pin); /* * we expect this irq on both insert and remove, diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h index fc8a0fe7c5c5..000b3ad0f5ca 100644 --- a/drivers/mmc/host/atmel-mci-regs.h +++ b/drivers/mmc/host/atmel-mci-regs.h @@ -17,112 +17,126 @@ #define __DRIVERS_MMC_ATMEL_MCI_H__ /* MCI Register Definitions */ -#define MCI_CR 0x0000 /* Control */ -# define MCI_CR_MCIEN ( 1 << 0) /* MCI Enable */ -# define MCI_CR_MCIDIS ( 1 << 1) /* MCI Disable */ -# define MCI_CR_PWSEN ( 1 << 2) /* Power Save Enable */ -# define MCI_CR_PWSDIS ( 1 << 3) /* Power Save Disable */ -# define MCI_CR_SWRST ( 1 << 7) /* Software Reset */ -#define MCI_MR 0x0004 /* Mode */ -# define MCI_MR_CLKDIV(x) ((x) << 0) /* Clock Divider */ -# define MCI_MR_PWSDIV(x) ((x) << 8) /* Power Saving Divider */ -# define MCI_MR_RDPROOF ( 1 << 11) /* Read Proof */ -# define MCI_MR_WRPROOF ( 1 << 12) /* Write Proof */ -# define MCI_MR_PDCFBYTE ( 1 << 13) /* Force Byte Transfer */ -# define MCI_MR_PDCPADV ( 1 << 14) /* Padding Value */ -# define MCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ -#define MCI_DTOR 0x0008 /* Data Timeout */ -# define MCI_DTOCYC(x) ((x) << 0) /* Data Timeout Cycles */ -# define MCI_DTOMUL(x) ((x) << 4) /* Data Timeout Multiplier */ -#define MCI_SDCR 0x000c /* SD Card / SDIO */ -# define MCI_SDCSEL_SLOT_A ( 0 << 0) /* Select SD slot A */ -# define MCI_SDCSEL_SLOT_B ( 1 << 0) /* Select SD slot A */ -# define MCI_SDCSEL_MASK ( 3 << 0) -# define MCI_SDCBUS_1BIT ( 0 << 6) /* 1-bit data bus */ -# define MCI_SDCBUS_4BIT ( 2 << 6) /* 4-bit data bus */ -# define MCI_SDCBUS_8BIT ( 3 << 6) /* 8-bit data bus[2] */ -# define MCI_SDCBUS_MASK ( 3 << 6) -#define MCI_ARGR 0x0010 /* Command Argument */ -#define MCI_CMDR 0x0014 /* Command */ -# define MCI_CMDR_CMDNB(x) ((x) << 0) /* Command Opcode */ -# define MCI_CMDR_RSPTYP_NONE ( 0 << 6) /* No response */ -# define MCI_CMDR_RSPTYP_48BIT ( 1 << 6) /* 48-bit response */ -# define MCI_CMDR_RSPTYP_136BIT ( 2 << 6) /* 136-bit response */ -# define MCI_CMDR_SPCMD_INIT ( 1 << 8) /* Initialization command */ -# define MCI_CMDR_SPCMD_SYNC ( 2 << 8) /* Synchronized command */ -# define MCI_CMDR_SPCMD_INT ( 4 << 8) /* Interrupt command */ -# define MCI_CMDR_SPCMD_INTRESP ( 5 << 8) /* Interrupt response */ -# define MCI_CMDR_OPDCMD ( 1 << 11) /* Open Drain */ -# define MCI_CMDR_MAXLAT_5CYC ( 0 << 12) /* Max latency 5 cycles */ -# define MCI_CMDR_MAXLAT_64CYC ( 1 << 12) /* Max latency 64 cycles */ -# define MCI_CMDR_START_XFER ( 1 << 16) /* Start data transfer */ -# define MCI_CMDR_STOP_XFER ( 2 << 16) /* Stop data transfer */ -# define MCI_CMDR_TRDIR_WRITE ( 0 << 18) /* Write data */ -# define MCI_CMDR_TRDIR_READ ( 1 << 18) /* Read data */ -# define MCI_CMDR_BLOCK ( 0 << 19) /* Single-block transfer */ -# define MCI_CMDR_MULTI_BLOCK ( 1 << 19) /* Multi-block transfer */ -# define MCI_CMDR_STREAM ( 2 << 19) /* MMC Stream transfer */ -# define MCI_CMDR_SDIO_BYTE ( 4 << 19) /* SDIO Byte transfer */ -# define MCI_CMDR_SDIO_BLOCK ( 5 << 19) /* SDIO Block transfer */ -# define MCI_CMDR_SDIO_SUSPEND ( 1 << 24) /* SDIO Suspend Command */ -# define MCI_CMDR_SDIO_RESUME ( 2 << 24) /* SDIO Resume Command */ -#define MCI_BLKR 0x0018 /* Block */ -# define MCI_BCNT(x) ((x) << 0) /* Data Block Count */ -# define MCI_BLKLEN(x) ((x) << 16) /* Data Block Length */ -#define MCI_CSTOR 0x001c /* Completion Signal Timeout[2] */ -# define MCI_CSTOCYC(x) ((x) << 0) /* CST cycles */ -# define MCI_CSTOMUL(x) ((x) << 4) /* CST multiplier */ -#define MCI_RSPR 0x0020 /* Response 0 */ -#define MCI_RSPR1 0x0024 /* Response 1 */ -#define MCI_RSPR2 0x0028 /* Response 2 */ -#define MCI_RSPR3 0x002c /* Response 3 */ -#define MCI_RDR 0x0030 /* Receive Data */ -#define MCI_TDR 0x0034 /* Transmit Data */ -#define MCI_SR 0x0040 /* Status */ -#define MCI_IER 0x0044 /* Interrupt Enable */ -#define MCI_IDR 0x0048 /* Interrupt Disable */ -#define MCI_IMR 0x004c /* Interrupt Mask */ -# define MCI_CMDRDY ( 1 << 0) /* Command Ready */ -# define MCI_RXRDY ( 1 << 1) /* Receiver Ready */ -# define MCI_TXRDY ( 1 << 2) /* Transmitter Ready */ -# define MCI_BLKE ( 1 << 3) /* Data Block Ended */ -# define MCI_DTIP ( 1 << 4) /* Data Transfer In Progress */ -# define MCI_NOTBUSY ( 1 << 5) /* Data Not Busy */ -# define MCI_SDIOIRQA ( 1 << 8) /* SDIO IRQ in slot A */ -# define MCI_SDIOIRQB ( 1 << 9) /* SDIO IRQ in slot B */ -# define MCI_RINDE ( 1 << 16) /* Response Index Error */ -# define MCI_RDIRE ( 1 << 17) /* Response Direction Error */ -# define MCI_RCRCE ( 1 << 18) /* Response CRC Error */ -# define MCI_RENDE ( 1 << 19) /* Response End Bit Error */ -# define MCI_RTOE ( 1 << 20) /* Response Time-Out Error */ -# define MCI_DCRCE ( 1 << 21) /* Data CRC Error */ -# define MCI_DTOE ( 1 << 22) /* Data Time-Out Error */ -# define MCI_OVRE ( 1 << 30) /* RX Overrun Error */ -# define MCI_UNRE ( 1 << 31) /* TX Underrun Error */ -#define MCI_DMA 0x0050 /* DMA Configuration[2] */ -# define MCI_DMA_OFFSET(x) ((x) << 0) /* DMA Write Buffer Offset */ -# define MCI_DMA_CHKSIZE(x) ((x) << 4) /* DMA Channel Read and Write Chunk Size */ -# define MCI_DMAEN ( 1 << 8) /* DMA Hardware Handshaking Enable */ -#define MCI_CFG 0x0054 /* Configuration[2] */ -# define MCI_CFG_FIFOMODE_1DATA ( 1 << 0) /* MCI Internal FIFO control mode */ -# define MCI_CFG_FERRCTRL_COR ( 1 << 4) /* Flow Error flag reset control mode */ -# define MCI_CFG_HSMODE ( 1 << 8) /* High Speed Mode */ -# define MCI_CFG_LSYNC ( 1 << 12) /* Synchronize on the last block */ -#define MCI_WPMR 0x00e4 /* Write Protection Mode[2] */ -# define MCI_WP_EN ( 1 << 0) /* WP Enable */ -# define MCI_WP_KEY (0x4d4349 << 8) /* WP Key */ -#define MCI_WPSR 0x00e8 /* Write Protection Status[2] */ -# define MCI_GET_WP_VS(x) ((x) & 0x0f) -# define MCI_GET_WP_VSRC(x) (((x) >> 8) & 0xffff) -#define MCI_FIFO_APERTURE 0x0200 /* FIFO Aperture[2] */ +#define ATMCI_CR 0x0000 /* Control */ +# 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_PWSDIS ( 1 << 3) /* Power Save Disable */ +# 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_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_PDCPADV ( 1 << 14) /* Padding Value */ +# define ATMCI_MR_PDCMODE ( 1 << 15) /* PDC-oriented Mode */ +#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_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_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_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_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_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_BLKLEN(x) ((x) << 16) /* Data Block Length */ +#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_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_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 */ +# 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_CSTOE ( 1 << 23) /* Completion Signal 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] */ +# 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_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_VERSION 0x00FC /* Version */ +#define ATMCI_FIFO_APERTURE 0x0200 /* FIFO Aperture[2] */ /* This is not including the FIFO Aperture on MCI2 */ -#define MCI_REGS_SIZE 0x100 +#define ATMCI_REGS_SIZE 0x100 /* Register access macros */ -#define mci_readl(port,reg) \ - __raw_readl((port)->regs + MCI_##reg) -#define mci_writel(port,reg,value) \ - __raw_writel((value), (port)->regs + MCI_##reg) +#define atmci_readl(port,reg) \ + __raw_readl((port)->regs + reg) +#define atmci_writel(port,reg,value) \ + __raw_writel((value), (port)->regs + reg) #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index fa8cae1d7005..a7ee50271465 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -30,6 +30,7 @@ #include <mach/atmel-mci.h> #include <linux/atmel-mci.h> +#include <linux/atmel_pdc.h> #include <asm/io.h> #include <asm/unaligned.h> @@ -39,7 +40,7 @@ #include "atmel-mci-regs.h" -#define ATMCI_DATA_ERROR_FLAGS (MCI_DCRCE | MCI_DTOE | MCI_OVRE | MCI_UNRE) +#define ATMCI_DATA_ERROR_FLAGS (ATMCI_DCRCE | ATMCI_DTOE | ATMCI_OVRE | ATMCI_UNRE) #define ATMCI_DMA_THRESHOLD 16 enum { @@ -58,18 +59,35 @@ enum atmel_mci_state { STATE_DATA_ERROR, }; +enum atmci_xfer_dir { + XFER_RECEIVE = 0, + XFER_TRANSMIT, +}; + +enum atmci_pdc_buf { + PDC_FIRST_BUF = 0, + PDC_SECOND_BUF, +}; + +struct atmel_mci_caps { + bool has_dma; + bool has_pdc; + bool has_cfg_reg; + bool has_cstor_reg; + bool has_highspeed; + bool has_rwproof; +}; + struct atmel_mci_dma { -#ifdef CONFIG_MMC_ATMELMCI_DMA struct dma_chan *chan; struct dma_async_tx_descriptor *data_desc; -#endif }; /** * struct atmel_mci - MMC controller state shared between all slots * @lock: Spinlock protecting the queue and associated data. * @regs: Pointer to MMIO registers. - * @sg: Scatterlist entry currently being processed by PIO code, if any. + * @sg: Scatterlist entry currently being processed by PIO or PDC code. * @pio_offset: Offset into the current scatterlist entry. * @cur_slot: The slot which is currently using the controller. * @mrq: The request currently being processed on @cur_slot, @@ -77,6 +95,7 @@ struct atmel_mci_dma { * @cmd: The command currently being sent to the card, or NULL. * @data: The data currently being transferred, or NULL if no data * transfer is in progress. + * @data_size: just data->blocks * data->blksz. * @dma: DMA client state. * @data_chan: DMA channel being used for the current data transfer. * @cmd_status: Snapshot of SR taken upon completion of the current @@ -103,6 +122,13 @@ struct atmel_mci_dma { * @mck: The peripheral bus clock hooked up to the MMC controller. * @pdev: Platform device associated with the MMC controller. * @slot: Slots sharing this MMC controller. + * @caps: MCI capabilities depending on MCI version. + * @prepare_data: function to setup MCI before data transfer which + * depends on MCI capabilities. + * @submit_data: function to start data transfer which depends on MCI + * capabilities. + * @stop_transfer: function to stop data transfer which depends on MCI + * capabilities. * * Locking * ======= @@ -143,6 +169,7 @@ struct atmel_mci { struct mmc_request *mrq; struct mmc_command *cmd; struct mmc_data *data; + unsigned int data_size; struct atmel_mci_dma dma; struct dma_chan *data_chan; @@ -166,7 +193,13 @@ struct atmel_mci { struct clk *mck; struct platform_device *pdev; - struct atmel_mci_slot *slot[ATMEL_MCI_MAX_NR_SLOTS]; + struct atmel_mci_slot *slot[ATMCI_MAX_NR_SLOTS]; + + struct atmel_mci_caps caps; + + u32 (*prepare_data)(struct atmel_mci *host, struct mmc_data *data); + void (*submit_data)(struct atmel_mci *host, struct mmc_data *data); + void (*stop_transfer)(struct atmel_mci *host); }; /** @@ -220,31 +253,6 @@ struct atmel_mci_slot { set_bit(event, &host->pending_events) /* - * Enable or disable features/registers based on - * whether the processor supports them - */ -static bool mci_has_rwproof(void) -{ - if (cpu_is_at91sam9261() || cpu_is_at91rm9200()) - return false; - else - return true; -} - -/* - * The new MCI2 module isn't 100% compatible with the old MCI module, - * and it has a few nice features which we want to use... - */ -static inline bool atmci_is_mci2(void) -{ - if (cpu_is_at91sam9g45()) - return true; - - return false; -} - - -/* * The debugfs stuff below is mostly optimized away when * CONFIG_DEBUG_FS is not set. */ @@ -352,7 +360,7 @@ static int atmci_regs_show(struct seq_file *s, void *v) struct atmel_mci *host = s->private; u32 *buf; - buf = kmalloc(MCI_REGS_SIZE, GFP_KERNEL); + buf = kmalloc(ATMCI_REGS_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -363,47 +371,50 @@ static int atmci_regs_show(struct seq_file *s, void *v) */ spin_lock_bh(&host->lock); clk_enable(host->mck); - memcpy_fromio(buf, host->regs, MCI_REGS_SIZE); + memcpy_fromio(buf, host->regs, ATMCI_REGS_SIZE); clk_disable(host->mck); spin_unlock_bh(&host->lock); seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n", - buf[MCI_MR / 4], - buf[MCI_MR / 4] & MCI_MR_RDPROOF ? " RDPROOF" : "", - buf[MCI_MR / 4] & MCI_MR_WRPROOF ? " WRPROOF" : "", - buf[MCI_MR / 4] & 0xff); - seq_printf(s, "DTOR:\t0x%08x\n", buf[MCI_DTOR / 4]); - seq_printf(s, "SDCR:\t0x%08x\n", buf[MCI_SDCR / 4]); - seq_printf(s, "ARGR:\t0x%08x\n", buf[MCI_ARGR / 4]); + buf[ATMCI_MR / 4], + buf[ATMCI_MR / 4] & ATMCI_MR_RDPROOF ? " RDPROOF" : "", + buf[ATMCI_MR / 4] & ATMCI_MR_WRPROOF ? " WRPROOF" : "", + buf[ATMCI_MR / 4] & 0xff); + seq_printf(s, "DTOR:\t0x%08x\n", buf[ATMCI_DTOR / 4]); + seq_printf(s, "SDCR:\t0x%08x\n", buf[ATMCI_SDCR / 4]); + seq_printf(s, "ARGR:\t0x%08x\n", buf[ATMCI_ARGR / 4]); seq_printf(s, "BLKR:\t0x%08x BCNT=%u BLKLEN=%u\n", - buf[MCI_BLKR / 4], - buf[MCI_BLKR / 4] & 0xffff, - (buf[MCI_BLKR / 4] >> 16) & 0xffff); - if (atmci_is_mci2()) - seq_printf(s, "CSTOR:\t0x%08x\n", buf[MCI_CSTOR / 4]); + buf[ATMCI_BLKR / 4], + buf[ATMCI_BLKR / 4] & 0xffff, + (buf[ATMCI_BLKR / 4] >> 16) & 0xffff); + if (host->caps.has_cstor_reg) + seq_printf(s, "CSTOR:\t0x%08x\n", buf[ATMCI_CSTOR / 4]); /* Don't read RSPR and RDR; it will consume the data there */ - atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); - atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); + atmci_show_status_reg(s, "SR", buf[ATMCI_SR / 4]); + atmci_show_status_reg(s, "IMR", buf[ATMCI_IMR / 4]); - if (atmci_is_mci2()) { + if (host->caps.has_dma) { u32 val; - val = buf[MCI_DMA / 4]; + val = buf[ATMCI_DMA / 4]; seq_printf(s, "DMA:\t0x%08x OFFSET=%u CHKSIZE=%u%s\n", val, val & 3, ((val >> 4) & 3) ? 1 << (((val >> 4) & 3) + 1) : 1, - val & MCI_DMAEN ? " DMAEN" : ""); + val & ATMCI_DMAEN ? " DMAEN" : ""); + } + if (host->caps.has_cfg_reg) { + u32 val; - val = buf[MCI_CFG / 4]; + val = buf[ATMCI_CFG / 4]; seq_printf(s, "CFG:\t0x%08x%s%s%s%s\n", val, - val & MCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "", - val & MCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "", - val & MCI_CFG_HSMODE ? " HSMODE" : "", - val & MCI_CFG_LSYNC ? " LSYNC" : ""); + val & ATMCI_CFG_FIFOMODE_1DATA ? " FIFOMODE_ONE_DATA" : "", + val & ATMCI_CFG_FERRCTRL_COR ? " FERRCTRL_CLEAR_ON_READ" : "", + val & ATMCI_CFG_HSMODE ? " HSMODE" : "", + val & ATMCI_CFG_LSYNC ? " LSYNC" : ""); } kfree(buf); @@ -466,7 +477,7 @@ err: dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n"); } -static inline unsigned int ns_to_clocks(struct atmel_mci *host, +static inline unsigned int atmci_ns_to_clocks(struct atmel_mci *host, unsigned int ns) { return (ns * (host->bus_hz / 1000000) + 999) / 1000; @@ -482,7 +493,8 @@ static void atmci_set_timeout(struct atmel_mci *host, unsigned dtocyc; unsigned dtomul; - timeout = ns_to_clocks(host, data->timeout_ns) + data->timeout_clks; + timeout = atmci_ns_to_clocks(host, data->timeout_ns) + + data->timeout_clks; for (dtomul = 0; dtomul < 8; dtomul++) { unsigned shift = dtomul_to_shift[dtomul]; @@ -498,7 +510,7 @@ static void atmci_set_timeout(struct atmel_mci *host, dev_vdbg(&slot->mmc->class_dev, "setting timeout to %u cycles\n", dtocyc << dtomul_to_shift[dtomul]); - mci_writel(host, DTOR, (MCI_DTOMUL(dtomul) | MCI_DTOCYC(dtocyc))); + atmci_writel(host, ATMCI_DTOR, (ATMCI_DTOMUL(dtomul) | ATMCI_DTOCYC(dtocyc))); } /* @@ -512,13 +524,13 @@ static u32 atmci_prepare_command(struct mmc_host *mmc, cmd->error = -EINPROGRESS; - cmdr = MCI_CMDR_CMDNB(cmd->opcode); + cmdr = ATMCI_CMDR_CMDNB(cmd->opcode); if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) - cmdr |= MCI_CMDR_RSPTYP_136BIT; + cmdr |= ATMCI_CMDR_RSPTYP_136BIT; else - cmdr |= MCI_CMDR_RSPTYP_48BIT; + cmdr |= ATMCI_CMDR_RSPTYP_48BIT; } /* @@ -526,34 +538,34 @@ static u32 atmci_prepare_command(struct mmc_host *mmc, * it's too difficult to determine whether this is an ACMD or * not. Better make it 64. */ - cmdr |= MCI_CMDR_MAXLAT_64CYC; + cmdr |= ATMCI_CMDR_MAXLAT_64CYC; if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN) - cmdr |= MCI_CMDR_OPDCMD; + cmdr |= ATMCI_CMDR_OPDCMD; data = cmd->data; if (data) { - cmdr |= MCI_CMDR_START_XFER; + cmdr |= ATMCI_CMDR_START_XFER; if (cmd->opcode == SD_IO_RW_EXTENDED) { - cmdr |= MCI_CMDR_SDIO_BLOCK; + cmdr |= ATMCI_CMDR_SDIO_BLOCK; } else { if (data->flags & MMC_DATA_STREAM) - cmdr |= MCI_CMDR_STREAM; + cmdr |= ATMCI_CMDR_STREAM; else if (data->blocks > 1) - cmdr |= MCI_CMDR_MULTI_BLOCK; + cmdr |= ATMCI_CMDR_MULTI_BLOCK; else - cmdr |= MCI_CMDR_BLOCK; + cmdr |= ATMCI_CMDR_BLOCK; } if (data->flags & MMC_DATA_READ) - cmdr |= MCI_CMDR_TRDIR_READ; + cmdr |= ATMCI_CMDR_TRDIR_READ; } return cmdr; } -static void atmci_start_command(struct atmel_m |
