2005-04-17 02:20:36 +04:00
/*
2007-07-11 22:04:50 +04:00
* linux / drivers / mmc / host / mmci . h - ARM PrimeCell MMCI PL180 / 1 driver
2005-04-17 02:20:36 +04:00
*
* Copyright ( C ) 2003 Deep Blue Solutions , Ltd , All Rights Reserved .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# define MMCIPOWER 0x000
# define MCI_PWR_OFF 0x00
# define MCI_PWR_UP 0x02
# define MCI_PWR_ON 0x03
# define MCI_OD (1 << 6)
# define MCI_ROD (1 << 7)
2014-03-21 13:13:05 +04:00
/*
* The ST Micro version does not have ROD and reuse the voltage registers for
* direction settings .
*/
# define MCI_ST_DATA2DIREN (1 << 2)
# define MCI_ST_CMDDIREN (1 << 3)
# define MCI_ST_DATA0DIREN (1 << 4)
# define MCI_ST_DATA31DIREN (1 << 5)
# define MCI_ST_FBCLKEN (1 << 7)
# define MCI_ST_DATA74DIREN (1 << 8)
2018-10-08 15:08:53 +03:00
/*
* The STM32 sdmmc does not have PWR_UP / OD / ROD
* and uses the power register for
*/
# define MCI_STM32_PWR_CYC 0x02
# define MCI_STM32_VSWITCH BIT(2)
# define MCI_STM32_VSWITCHEN BIT(3)
# define MCI_STM32_DIRPOL BIT(4)
2005-04-17 02:20:36 +04:00
# define MMCICLOCK 0x004
# define MCI_CLK_ENABLE (1 << 8)
# define MCI_CLK_PWRSAVE (1 << 9)
# define MCI_CLK_BYPASS (1 << 10)
2010-04-08 10:38:52 +04:00
# define MCI_4BIT_BUS (1 << 11)
2011-03-04 16:54:16 +03:00
/*
* 8 bit wide buses , hardware flow contronl , negative edges and clock inversion
* supported in ST Micro U300 and Ux500 versions
*/
2010-04-08 10:38:52 +04:00
# define MCI_ST_8BIT_BUS (1 << 12)
2011-03-04 16:54:16 +03:00
# define MCI_ST_U300_HWFCEN (1 << 13)
# define MCI_ST_UX500_NEG_EDGE (1 << 13)
# define MCI_ST_UX500_HWFCEN (1 << 14)
# define MCI_ST_UX500_CLK_INV (1 << 15)
2013-01-24 17:12:45 +04:00
/* Modified PL180 on Versatile Express platform */
# define MCI_ARM_HWFCEN (1 << 12)
2005-04-17 02:20:36 +04:00
2014-06-02 13:08:48 +04:00
/* Modified on Qualcomm Integrations */
# define MCI_QCOM_CLK_WIDEBUS_8 (BIT(10) | BIT(11))
# define MCI_QCOM_CLK_FLOWENA BIT(12)
# define MCI_QCOM_CLK_INVERTOUT BIT(13)
/* select in latch data and command in */
# define MCI_QCOM_CLK_SELECT_IN_FBCLK BIT(15)
# define MCI_QCOM_CLK_SELECT_IN_DDR_MODE (BIT(14) | BIT(15))
2018-10-08 15:08:53 +03:00
/* Modified on STM32 sdmmc */
# define MCI_STM32_CLK_CLKDIV_MSK GENMASK(9, 0)
# define MCI_STM32_CLK_WIDEBUS_4 BIT(14)
# define MCI_STM32_CLK_WIDEBUS_8 BIT(15)
# define MCI_STM32_CLK_NEGEDGE BIT(16)
# define MCI_STM32_CLK_HWFCEN BIT(17)
# define MCI_STM32_CLK_DDR BIT(18)
# define MCI_STM32_CLK_BUSSPEED BIT(19)
# define MCI_STM32_CLK_SEL_MSK GENMASK(21, 20)
# define MCI_STM32_CLK_SELCK (0 << 20)
# define MCI_STM32_CLK_SELCKIN (1 << 20)
# define MCI_STM32_CLK_SELFBCK (2 << 20)
2005-04-17 02:20:36 +04:00
# define MMCIARGUMENT 0x008
2016-10-25 12:06:05 +03:00
/* The command register controls the Command Path State Machine (CPSM) */
# define MMCICOMMAND 0x00c
# define MCI_CPSM_RESPONSE BIT(6)
# define MCI_CPSM_LONGRSP BIT(7)
# define MCI_CPSM_INTERRUPT BIT(8)
# define MCI_CPSM_PENDING BIT(9)
# define MCI_CPSM_ENABLE BIT(10)
/* Command register flag extenstions in the ST Micro versions */
# define MCI_CPSM_ST_SDIO_SUSP BIT(11)
# define MCI_CPSM_ST_ENCMD_COMPL BIT(12)
# define MCI_CPSM_ST_NIEN BIT(13)
# define MCI_CPSM_ST_CE_ATACMD BIT(14)
/* Command register flag extensions in the Qualcomm versions */
# define MCI_CPSM_QCOM_PROGENA BIT(11)
# define MCI_CPSM_QCOM_DATCMD BIT(12)
# define MCI_CPSM_QCOM_MCIABORT BIT(13)
# define MCI_CPSM_QCOM_CCSENABLE BIT(14)
# define MCI_CPSM_QCOM_CCSDISABLE BIT(15)
# define MCI_CPSM_QCOM_AUTO_CMD19 BIT(16)
# define MCI_CPSM_QCOM_AUTO_CMD21 BIT(21)
2018-10-08 15:08:53 +03:00
/* Command register in STM32 sdmmc versions */
# define MCI_CPSM_STM32_CMDTRANS BIT(6)
# define MCI_CPSM_STM32_CMDSTOP BIT(7)
# define MCI_CPSM_STM32_WAITRESP_MASK GENMASK(9, 8)
# define MCI_CPSM_STM32_NORSP (0 << 8)
# define MCI_CPSM_STM32_SRSP_CRC (1 << 8)
# define MCI_CPSM_STM32_SRSP (2 << 8)
# define MCI_CPSM_STM32_LRSP_CRC (3 << 8)
# define MCI_CPSM_STM32_ENABLE BIT(12)
2014-06-02 13:08:48 +04:00
2005-04-17 02:20:36 +04:00
# define MMCIRESPCMD 0x010
# define MMCIRESPONSE0 0x014
# define MMCIRESPONSE1 0x018
# define MMCIRESPONSE2 0x01c
# define MMCIRESPONSE3 0x020
# define MMCIDATATIMER 0x024
# define MMCIDATALENGTH 0x028
2016-10-25 12:06:05 +03:00
/* The data control register controls the Data Path State Machine (DPSM) */
2005-04-17 02:20:36 +04:00
# define MMCIDATACTRL 0x02c
2016-10-25 12:06:05 +03:00
# define MCI_DPSM_ENABLE BIT(0)
# define MCI_DPSM_DIRECTION BIT(1)
# define MCI_DPSM_MODE BIT(2)
# define MCI_DPSM_DMAENABLE BIT(3)
# define MCI_DPSM_BLOCKSIZE BIT(4)
2010-10-09 16:43:21 +04:00
/* Control register extensions in the ST Micro U300 and Ux500 versions */
2016-10-25 12:06:05 +03:00
# define MCI_DPSM_ST_RWSTART BIT(8)
# define MCI_DPSM_ST_RWSTOP BIT(9)
# define MCI_DPSM_ST_RWMOD BIT(10)
# define MCI_DPSM_ST_SDIOEN BIT(11)
2010-10-09 16:43:21 +04:00
/* Control register extensions in the ST Micro Ux500 versions */
2016-10-25 12:06:05 +03:00
# define MCI_DPSM_ST_DMAREQCTL BIT(12)
# define MCI_DPSM_ST_DBOOTMODEEN BIT(13)
# define MCI_DPSM_ST_BUSYMODE BIT(14)
# define MCI_DPSM_ST_DDRMODE BIT(15)
/* Control register extensions in the Qualcomm versions */
# define MCI_DPSM_QCOM_DATA_PEND BIT(17)
# define MCI_DPSM_QCOM_RX_DATA_PEND BIT(20)
2005-04-17 02:20:36 +04:00
# define MMCIDATACNT 0x030
# define MMCISTATUS 0x034
# define MCI_CMDCRCFAIL (1 << 0)
# define MCI_DATACRCFAIL (1 << 1)
# define MCI_CMDTIMEOUT (1 << 2)
# define MCI_DATATIMEOUT (1 << 3)
# define MCI_TXUNDERRUN (1 << 4)
# define MCI_RXOVERRUN (1 << 5)
# define MCI_CMDRESPEND (1 << 6)
# define MCI_CMDSENT (1 << 7)
# define MCI_DATAEND (1 << 8)
2011-06-30 18:10:21 +04:00
# define MCI_STARTBITERR (1 << 9)
2005-04-17 02:20:36 +04:00
# define MCI_DATABLOCKEND (1 << 10)
# define MCI_CMDACTIVE (1 << 11)
# define MCI_TXACTIVE (1 << 12)
# define MCI_RXACTIVE (1 << 13)
# define MCI_TXFIFOHALFEMPTY (1 << 14)
# define MCI_RXFIFOHALFFULL (1 << 15)
# define MCI_TXFIFOFULL (1 << 16)
# define MCI_RXFIFOFULL (1 << 17)
# define MCI_TXFIFOEMPTY (1 << 18)
# define MCI_RXFIFOEMPTY (1 << 19)
# define MCI_TXDATAAVLBL (1 << 20)
# define MCI_RXDATAAVLBL (1 << 21)
2011-03-04 16:54:16 +03:00
/* Extended status bits for the ST Micro variants */
# define MCI_ST_SDIOIT (1 << 22)
# define MCI_ST_CEATAEND (1 << 23)
2013-05-15 23:53:22 +04:00
# define MCI_ST_CARDBUSY (1 << 24)
2018-10-08 15:08:53 +03:00
/* Extended status bits for the STM32 variants */
# define MCI_STM32_BUSYD0 BIT(20)
2005-04-17 02:20:36 +04:00
# define MMCICLEAR 0x038
# define MCI_CMDCRCFAILCLR (1 << 0)
# define MCI_DATACRCFAILCLR (1 << 1)
# define MCI_CMDTIMEOUTCLR (1 << 2)
# define MCI_DATATIMEOUTCLR (1 << 3)
# define MCI_TXUNDERRUNCLR (1 << 4)
# define MCI_RXOVERRUNCLR (1 << 5)
# define MCI_CMDRESPENDCLR (1 << 6)
# define MCI_CMDSENTCLR (1 << 7)
# define MCI_DATAENDCLR (1 << 8)
2011-06-30 18:10:21 +04:00
# define MCI_STARTBITERRCLR (1 << 9)
2005-04-17 02:20:36 +04:00
# define MCI_DATABLOCKENDCLR (1 << 10)
2011-03-04 16:54:16 +03:00
/* Extended status bits for the ST Micro variants */
# define MCI_ST_SDIOITC (1 << 22)
# define MCI_ST_CEATAENDC (1 << 23)
2013-05-15 23:53:22 +04:00
# define MCI_ST_BUSYENDC (1 << 24)
2005-04-17 02:20:36 +04:00
# define MMCIMASK0 0x03c
# define MCI_CMDCRCFAILMASK (1 << 0)
# define MCI_DATACRCFAILMASK (1 << 1)
# define MCI_CMDTIMEOUTMASK (1 << 2)
# define MCI_DATATIMEOUTMASK (1 << 3)
# define MCI_TXUNDERRUNMASK (1 << 4)
# define MCI_RXOVERRUNMASK (1 << 5)
# define MCI_CMDRESPENDMASK (1 << 6)
# define MCI_CMDSENTMASK (1 << 7)
# define MCI_DATAENDMASK (1 << 8)
2011-06-30 18:10:21 +04:00
# define MCI_STARTBITERRMASK (1 << 9)
2005-04-17 02:20:36 +04:00
# define MCI_DATABLOCKENDMASK (1 << 10)
# define MCI_CMDACTIVEMASK (1 << 11)
# define MCI_TXACTIVEMASK (1 << 12)
# define MCI_RXACTIVEMASK (1 << 13)
# define MCI_TXFIFOHALFEMPTYMASK (1 << 14)
# define MCI_RXFIFOHALFFULLMASK (1 << 15)
# define MCI_TXFIFOFULLMASK (1 << 16)
# define MCI_RXFIFOFULLMASK (1 << 17)
# define MCI_TXFIFOEMPTYMASK (1 << 18)
# define MCI_RXFIFOEMPTYMASK (1 << 19)
# define MCI_TXDATAAVLBLMASK (1 << 20)
# define MCI_RXDATAAVLBLMASK (1 << 21)
2011-03-04 16:54:16 +03:00
/* Extended status bits for the ST Micro variants */
# define MCI_ST_SDIOITMASK (1 << 22)
# define MCI_ST_CEATAENDMASK (1 << 23)
2016-10-25 12:06:06 +03:00
# define MCI_ST_BUSYENDMASK (1 << 24)
2018-10-08 15:08:53 +03:00
/* Extended status bits for the STM32 variants */
# define MCI_STM32_BUSYD0ENDMASK BIT(21)
2005-04-17 02:20:36 +04:00
# define MMCIMASK1 0x040
# define MMCIFIFOCNT 0x048
# define MMCIFIFO 0x080 /* to 0x0bc */
2018-10-08 15:08:53 +03:00
/* STM32 sdmmc registers for IDMA (Internal DMA) */
# define MMCI_STM32_IDMACTRLR 0x050
# define MMCI_STM32_IDMAEN BIT(0)
# define MMCI_STM32_IDMALLIEN BIT(1)
# define MMCI_STM32_IDMABSIZER 0x054
# define MMCI_STM32_IDMABNDT_SHIFT 5
# define MMCI_STM32_IDMABNDT_MASK GENMASK(12, 5)
# define MMCI_STM32_IDMABASE0R 0x058
# define MMCI_STM32_IDMALAR 0x64
# define MMCI_STM32_IDMALA_MASK GENMASK(13, 0)
# define MMCI_STM32_ABR BIT(29)
# define MMCI_STM32_ULS BIT(30)
# define MMCI_STM32_ULA BIT(31)
# define MMCI_STM32_IDMABAR 0x68
2005-04-17 02:20:36 +04:00
# define MCI_IRQENABLE \
2018-10-08 15:08:44 +03:00
( MCI_CMDCRCFAILMASK | MCI_DATACRCFAILMASK | MCI_CMDTIMEOUTMASK | \
MCI_DATATIMEOUTMASK | MCI_TXUNDERRUNMASK | MCI_RXOVERRUNMASK | \
MCI_CMDRESPENDMASK | MCI_CMDSENTMASK )
2005-04-17 02:20:36 +04:00
2010-10-19 15:39:48 +04:00
/* These interrupts are directed to IRQ1 when two IRQ lines are available */
2018-10-08 15:08:47 +03:00
# define MCI_IRQ_PIO_MASK \
2010-10-19 15:39:48 +04:00
( MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \
MCI_TXFIFOHALFEMPTYMASK )
2018-10-08 15:08:53 +03:00
# define MCI_IRQ_PIO_STM32_MASK \
( MCI_RXFIFOHALFFULLMASK | MCI_TXFIFOHALFEMPTYMASK )
2011-12-13 19:52:00 +04:00
# define NR_SG 128
2005-04-17 02:20:36 +04:00
2018-01-18 17:34:20 +03:00
# define MMCI_PINCTRL_STATE_OPENDRAIN "opendrain"
2005-04-17 02:20:36 +04:00
struct clk ;
ARM: mmci: add dmaengine-based DMA support
Based on a patch from Linus Walleij.
Add dmaengine based support for DMA to the MMCI driver, using the
Primecell DMA engine interface. The changes over Linus' driver are:
- rename txsize_threshold to dmasize_threshold, as this reflects the
purpose more.
- use 'mmci_dma_' as the function prefix rather than 'dma_mmci_'.
- clean up requesting of dma channels.
- don't release a single channel twice when it's shared between tx and rx.
- get rid of 'dma_enable' bool - instead check whether the channel is NULL.
- detect incomplete DMA at the end of a transfer. Some DMA controllers
(eg, PL08x) are unable to be configured for scatter DMA and also listen
to all four DMA request signals [BREQ,SREQ,LBREQ,LSREQ] from the MMCI.
They can do one or other but not both. As MMCI uses LBREQ/LSREQ for the
final burst/words, PL08x does not transfer the last few words.
- map and unmap DMA buffers using the DMA engine struct device, not the
MMCI struct device - the DMA engine is doing the DMA transfer, not us.
- avoid double-unmapping of the DMA buffers on MMCI data errors.
- don't check for negative values from the dmaengine tx submission
function - Dan says this must never fail.
- use new dmaengine helper functions rather than using the ugly function
pointers directly.
- allow DMA code to be fully optimized away using dma_inprogress() which
is defined to constant 0 if DMA engine support is disabled.
- request maximum segment size from the DMA engine struct device and
set this appropriately.
- removed checking of buffer alignment - the DMA engine should deal with
its own restrictions on buffer alignment, not the individual DMA engine
users.
- removed setting DMAREQCTL - this confuses some DMA controllers as it
causes LBREQ to be asserted for the last seven transfers, rather than
six SREQ and one LSREQ.
- removed burst setting - the DMA controller should not burst past the
transfer size required to complete the DMA operation.
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2011-01-11 22:35:53 +03:00
struct dma_chan ;
2018-07-13 14:15:23 +03:00
struct mmci_host ;
/**
* struct variant_data - MMCI variant - specific quirks
* @ clkreg : default value for MCICLOCK register
* @ clkreg_enable : enable value for MMCICLOCK register
* @ clkreg_8bit_bus_enable : enable value for 8 bit bus
* @ clkreg_neg_edge_enable : enable value for inverted data / cmd output
2018-10-08 15:08:45 +03:00
* @ cmdreg_cpsm_enable : enable value for CPSM
* @ cmdreg_lrsp_crc : enable value for long response with crc
* @ cmdreg_srsp_crc : enable value for short response with crc
* @ cmdreg_srsp : enable value for short response without crc
2018-07-13 14:15:23 +03:00
* @ datalength_bits : number of bits in the MMCIDATALENGTH register
* @ fifosize : number of bytes that can be written when MMCI_TXFIFOEMPTY
* is asserted ( likewise for RX )
* @ fifohalfsize : number of bytes that can be written when MCI_TXFIFOHALFEMPTY
* is asserted ( likewise for RX )
* @ data_cmd_enable : enable value for data commands .
* @ st_sdio : enable ST specific SDIO logic
* @ st_clkdiv : true if using a ST - specific clock divider algorithm
2018-10-08 15:08:52 +03:00
* @ stm32_clkdiv : true if using a STM32 - specific clock divider algorithm
2018-07-13 14:15:23 +03:00
* @ datactrl_mask_ddrmode : ddr mode mask in datactrl register .
* @ blksz_datactrl16 : true if Block size is at b16 . . b30 position in datactrl register
* @ blksz_datactrl4 : true if Block size is at b4 . . b16 position in datactrl
* register
* @ datactrl_mask_sdio : SDIO enable mask in datactrl register
2018-10-08 15:08:43 +03:00
* @ datactrl_blksz : block size in power of two
2018-10-08 15:08:46 +03:00
* @ datactrl_dpsm_enable : enable value for DPSM
2018-10-08 15:08:48 +03:00
* @ datactrl_first : true if data must be setup before send command
2018-10-08 15:08:49 +03:00
* @ datacnt_useless : true if you could not use datacnt register to read
* remaining data
2018-07-13 14:15:23 +03:00
* @ pwrreg_powerup : power up value for MMCIPOWER register
* @ f_max : maximum clk frequency supported by the controller .
* @ signal_direction : input / out direction of bus signals can be indicated
* @ pwrreg_clkgate : MMCIPOWER register must be used to gate the clock
* @ busy_detect : true if the variant supports busy detection on DAT0 .
* @ busy_dpsm_flag : bitmask enabling busy detection in the DPSM
* @ busy_detect_flag : bitmask identifying the bit in the MMCISTATUS register
* indicating that the card is busy
* @ busy_detect_mask : bitmask identifying the bit in the MMCIMASK0 to mask for
* getting busy end detection interrupts
* @ pwrreg_nopower : bits in MMCIPOWER don ' t controls ext . power supply
* @ explicit_mclk_control : enable explicit mclk control in driver .
* @ qcom_fifo : enables qcom specific fifo pio read logic .
* @ qcom_dml : enables qcom specific dma glue for dma transfers .
* @ reversed_irq_handling : handle data irq before cmd irq .
* @ mmcimask1 : true if variant have a MMCIMASK1 register .
2018-10-08 15:08:47 +03:00
* @ irq_pio_mask : bitmask used to manage interrupt pio transfert in mmcimask
* register
2018-07-13 14:15:23 +03:00
* @ start_err : bitmask identifying the STARTBITERR bit inside MMCISTATUS
* register .
* @ opendrain : bitmask identifying the OPENDRAIN bit inside MMCIPOWER register
2018-10-08 15:08:55 +03:00
* @ dma_lli : true if variant has dma link list feature .
* @ stm32_idmabsize_mask : stm32 sdmmc idma buffer size .
2018-07-13 14:15:23 +03:00
*/
struct variant_data {
unsigned int clkreg ;
unsigned int clkreg_enable ;
unsigned int clkreg_8bit_bus_enable ;
unsigned int clkreg_neg_edge_enable ;
2018-10-08 15:08:45 +03:00
unsigned int cmdreg_cpsm_enable ;
unsigned int cmdreg_lrsp_crc ;
unsigned int cmdreg_srsp_crc ;
unsigned int cmdreg_srsp ;
2018-07-13 14:15:23 +03:00
unsigned int datalength_bits ;
unsigned int fifosize ;
unsigned int fifohalfsize ;
unsigned int data_cmd_enable ;
unsigned int datactrl_mask_ddrmode ;
unsigned int datactrl_mask_sdio ;
2018-10-08 15:08:43 +03:00
unsigned int datactrl_blocksz ;
2018-10-08 15:08:46 +03:00
unsigned int datactrl_dpsm_enable ;
2018-10-08 15:08:48 +03:00
u8 datactrl_first : 1 ;
2018-10-08 15:08:49 +03:00
u8 datacnt_useless : 1 ;
2018-10-02 15:09:03 +03:00
u8 st_sdio : 1 ;
u8 st_clkdiv : 1 ;
2018-10-08 15:08:52 +03:00
u8 stm32_clkdiv : 1 ;
2018-10-02 15:09:03 +03:00
u8 blksz_datactrl16 : 1 ;
u8 blksz_datactrl4 : 1 ;
2018-07-13 14:15:23 +03:00
u32 pwrreg_powerup ;
u32 f_max ;
2018-10-02 15:09:03 +03:00
u8 signal_direction : 1 ;
u8 pwrreg_clkgate : 1 ;
u8 busy_detect : 1 ;
2018-07-13 14:15:23 +03:00
u32 busy_dpsm_flag ;
u32 busy_detect_flag ;
u32 busy_detect_mask ;
2018-10-02 15:09:03 +03:00
u8 pwrreg_nopower : 1 ;
u8 explicit_mclk_control : 1 ;
u8 qcom_fifo : 1 ;
u8 qcom_dml : 1 ;
u8 reversed_irq_handling : 1 ;
u8 mmcimask1 : 1 ;
2018-10-08 15:08:47 +03:00
unsigned int irq_pio_mask ;
2018-07-13 14:15:23 +03:00
u32 start_err ;
u32 opendrain ;
2018-10-08 15:08:55 +03:00
u8 dma_lli : 1 ;
u32 stm32_idmabsize_mask ;
2018-07-13 14:15:23 +03:00
void ( * init ) ( struct mmci_host * host ) ;
} ;
/* mmci variant callbacks */
struct mmci_host_ops {
2018-10-08 15:08:41 +03:00
int ( * validate_data ) ( struct mmci_host * host , struct mmc_data * data ) ;
2018-10-08 15:08:36 +03:00
int ( * prep_data ) ( struct mmci_host * host , struct mmc_data * data ,
bool next ) ;
void ( * unprep_data ) ( struct mmci_host * host , struct mmc_data * data ,
int err ) ;
2018-10-08 15:08:37 +03:00
void ( * get_next_data ) ( struct mmci_host * host , struct mmc_data * data ) ;
2018-10-08 15:08:33 +03:00
int ( * dma_setup ) ( struct mmci_host * host ) ;
void ( * dma_release ) ( struct mmci_host * host ) ;
2018-10-08 15:08:38 +03:00
int ( * dma_start ) ( struct mmci_host * host , unsigned int * datactrl ) ;
2018-10-08 15:08:39 +03:00
void ( * dma_finalize ) ( struct mmci_host * host , struct mmc_data * data ) ;
2018-10-08 15:08:40 +03:00
void ( * dma_error ) ( struct mmci_host * host ) ;
2018-10-08 15:08:42 +03:00
void ( * set_clkreg ) ( struct mmci_host * host , unsigned int desired ) ;
void ( * set_pwrreg ) ( struct mmci_host * host , unsigned int pwr ) ;
2018-07-13 14:15:23 +03:00
} ;
2005-04-17 02:20:36 +04:00
struct mmci_host {
ARM: mmci: add dmaengine-based DMA support
Based on a patch from Linus Walleij.
Add dmaengine based support for DMA to the MMCI driver, using the
Primecell DMA engine interface. The changes over Linus' driver are:
- rename txsize_threshold to dmasize_threshold, as this reflects the
purpose more.
- use 'mmci_dma_' as the function prefix rather than 'dma_mmci_'.
- clean up requesting of dma channels.
- don't release a single channel twice when it's shared between tx and rx.
- get rid of 'dma_enable' bool - instead check whether the channel is NULL.
- detect incomplete DMA at the end of a transfer. Some DMA controllers
(eg, PL08x) are unable to be configured for scatter DMA and also listen
to all four DMA request signals [BREQ,SREQ,LBREQ,LSREQ] from the MMCI.
They can do one or other but not both. As MMCI uses LBREQ/LSREQ for the
final burst/words, PL08x does not transfer the last few words.
- map and unmap DMA buffers using the DMA engine struct device, not the
MMCI struct device - the DMA engine is doing the DMA transfer, not us.
- avoid double-unmapping of the DMA buffers on MMCI data errors.
- don't check for negative values from the dmaengine tx submission
function - Dan says this must never fail.
- use new dmaengine helper functions rather than using the ugly function
pointers directly.
- allow DMA code to be fully optimized away using dma_inprogress() which
is defined to constant 0 if DMA engine support is disabled.
- request maximum segment size from the DMA engine struct device and
set this appropriately.
- removed checking of buffer alignment - the DMA engine should deal with
its own restrictions on buffer alignment, not the individual DMA engine
users.
- removed setting DMAREQCTL - this confuses some DMA controllers as it
causes LBREQ to be asserted for the last seven transfers, rather than
six SREQ and one LSREQ.
- removed burst setting - the DMA controller should not burst past the
transfer size required to complete the DMA operation.
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2011-01-11 22:35:53 +03:00
phys_addr_t phybase ;
2005-04-17 02:20:36 +04:00
void __iomem * base ;
struct mmc_request * mrq ;
struct mmc_command * cmd ;
struct mmc_data * data ;
struct mmc_host * mmc ;
struct clk * clk ;
2018-10-02 15:09:03 +03:00
u8 singleirq : 1 ;
2005-04-17 02:20:36 +04:00
2018-10-08 15:08:51 +03:00
struct reset_control * rst ;
2005-04-17 02:20:36 +04:00
spinlock_t lock ;
unsigned int mclk ;
2014-06-02 13:09:55 +04:00
/* cached value of requested clk in set_ios */
unsigned int clock_cache ;
2005-04-17 02:20:36 +04:00
unsigned int cclk ;
2012-01-18 12:17:27 +04:00
u32 pwr_reg ;
2014-03-21 13:13:05 +04:00
u32 pwr_reg_add ;
2012-01-18 12:17:27 +04:00
u32 clk_reg ;
2018-10-08 15:08:55 +03:00
u32 clk_reg_add ;
2013-05-15 23:48:23 +04:00
u32 datactrl_reg ;
2014-01-13 19:49:31 +04:00
u32 busy_status ;
2018-01-18 17:34:17 +03:00
u32 mask1_reg ;
2018-10-02 15:09:03 +03:00
u8 vqmmc_enabled : 1 ;
2009-09-22 17:29:36 +04:00
struct mmci_platform_data * plat ;
2018-07-13 14:15:23 +03:00
struct mmci_host_ops * ops ;
2010-07-21 15:54:40 +04:00
struct variant_data * variant ;
2018-01-18 17:34:20 +03:00
struct pinctrl * pinctrl ;
struct pinctrl_state * pins_default ;
struct pinctrl_state * pins_opendrain ;
2005-04-17 02:20:36 +04:00
2009-01-04 17:18:54 +03:00
u8 hw_designer ;
u8 hw_revision : 4 ;
2005-04-17 02:20:36 +04:00
struct timer_list timer ;
unsigned int oldstat ;
/* pio stuff */
2010-07-21 15:44:58 +04:00
struct sg_mapping_iter sg_miter ;
2005-04-17 02:20:36 +04:00
unsigned int size ;
2014-06-02 13:10:04 +04:00
int ( * get_rx_fifocnt ) ( struct mmci_host * h , u32 status , int remain ) ;
ARM: mmci: add dmaengine-based DMA support
Based on a patch from Linus Walleij.
Add dmaengine based support for DMA to the MMCI driver, using the
Primecell DMA engine interface. The changes over Linus' driver are:
- rename txsize_threshold to dmasize_threshold, as this reflects the
purpose more.
- use 'mmci_dma_' as the function prefix rather than 'dma_mmci_'.
- clean up requesting of dma channels.
- don't release a single channel twice when it's shared between tx and rx.
- get rid of 'dma_enable' bool - instead check whether the channel is NULL.
- detect incomplete DMA at the end of a transfer. Some DMA controllers
(eg, PL08x) are unable to be configured for scatter DMA and also listen
to all four DMA request signals [BREQ,SREQ,LBREQ,LSREQ] from the MMCI.
They can do one or other but not both. As MMCI uses LBREQ/LSREQ for the
final burst/words, PL08x does not transfer the last few words.
- map and unmap DMA buffers using the DMA engine struct device, not the
MMCI struct device - the DMA engine is doing the DMA transfer, not us.
- avoid double-unmapping of the DMA buffers on MMCI data errors.
- don't check for negative values from the dmaengine tx submission
function - Dan says this must never fail.
- use new dmaengine helper functions rather than using the ugly function
pointers directly.
- allow DMA code to be fully optimized away using dma_inprogress() which
is defined to constant 0 if DMA engine support is disabled.
- request maximum segment size from the DMA engine struct device and
set this appropriately.
- removed checking of buffer alignment - the DMA engine should deal with
its own restrictions on buffer alignment, not the individual DMA engine
users.
- removed setting DMAREQCTL - this confuses some DMA controllers as it
causes LBREQ to be asserted for the last seven transfers, rather than
six SREQ and one LSREQ.
- removed burst setting - the DMA controller should not burst past the
transfer size required to complete the DMA operation.
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2011-01-11 22:35:53 +03:00
2018-10-08 15:08:33 +03:00
u8 use_dma : 1 ;
2018-10-02 15:09:03 +03:00
u8 dma_in_progress : 1 ;
2018-10-08 15:08:34 +03:00
void * dma_priv ;
ARM: mmci: add dmaengine-based DMA support
Based on a patch from Linus Walleij.
Add dmaengine based support for DMA to the MMCI driver, using the
Primecell DMA engine interface. The changes over Linus' driver are:
- rename txsize_threshold to dmasize_threshold, as this reflects the
purpose more.
- use 'mmci_dma_' as the function prefix rather than 'dma_mmci_'.
- clean up requesting of dma channels.
- don't release a single channel twice when it's shared between tx and rx.
- get rid of 'dma_enable' bool - instead check whether the channel is NULL.
- detect incomplete DMA at the end of a transfer. Some DMA controllers
(eg, PL08x) are unable to be configured for scatter DMA and also listen
to all four DMA request signals [BREQ,SREQ,LBREQ,LSREQ] from the MMCI.
They can do one or other but not both. As MMCI uses LBREQ/LSREQ for the
final burst/words, PL08x does not transfer the last few words.
- map and unmap DMA buffers using the DMA engine struct device, not the
MMCI struct device - the DMA engine is doing the DMA transfer, not us.
- avoid double-unmapping of the DMA buffers on MMCI data errors.
- don't check for negative values from the dmaengine tx submission
function - Dan says this must never fail.
- use new dmaengine helper functions rather than using the ugly function
pointers directly.
- allow DMA code to be fully optimized away using dma_inprogress() which
is defined to constant 0 if DMA engine support is disabled.
- request maximum segment size from the DMA engine struct device and
set this appropriately.
- removed checking of buffer alignment - the DMA engine should deal with
its own restrictions on buffer alignment, not the individual DMA engine
users.
- removed setting DMAREQCTL - this confuses some DMA controllers as it
causes LBREQ to be asserted for the last seven transfers, rather than
six SREQ and one LSREQ.
- removed burst setting - the DMA controller should not burst past the
transfer size required to complete the DMA operation.
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2011-01-11 22:35:53 +03:00
2018-10-08 15:08:34 +03:00
s32 next_cookie ;
2005-04-17 02:20:36 +04:00
} ;
2018-10-08 15:08:34 +03:00
# define dma_inprogress(host) ((host)->dma_in_progress)
2018-10-08 15:08:42 +03:00
void mmci_write_clkreg ( struct mmci_host * host , u32 clk ) ;
void mmci_write_pwrreg ( struct mmci_host * host , u32 pwr ) ;
2018-10-08 15:08:36 +03:00
int mmci_dmae_prep_data ( struct mmci_host * host , struct mmc_data * data ,
bool next ) ;
void mmci_dmae_unprep_data ( struct mmci_host * host , struct mmc_data * data ,
int err ) ;
2018-10-08 15:08:37 +03:00
void mmci_dmae_get_next_data ( struct mmci_host * host , struct mmc_data * data ) ;
2018-10-08 15:08:33 +03:00
int mmci_dmae_setup ( struct mmci_host * host ) ;
void mmci_dmae_release ( struct mmci_host * host ) ;
2018-10-08 15:08:38 +03:00
int mmci_dmae_start ( struct mmci_host * host , unsigned int * datactrl ) ;
2018-10-08 15:08:39 +03:00
void mmci_dmae_finalize ( struct mmci_host * host , struct mmc_data * data ) ;
2018-10-08 15:08:40 +03:00
void mmci_dmae_error ( struct mmci_host * host ) ;