Hi Shawn,
On 6 August 2015 at 08:44, Shawn Lin <shawn.lin@xxxxxxxxxxxxxx> wrote:
DesignWare MMC Controller can supports two types of DMA
mode: external dma and internal dma. We get a RK312x platform
integrated dw_mmc and ARM pl330 dma controller. This patch add
edmac ops to support these platforms. I've tested it on RK312x
platform with edmac mode and RK3288 platform with idmac mode.
Signed-off-by: Shawn Lin <shawn.lin@xxxxxxxxxxxxxx>
@@ -2256,26 +2373,30 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
}
-#ifdef CONFIG_MMC_DW_IDMAC
- /* Handle DMA interrupts */
- if (host->dma_64bit_address == 1) {
- pending = mci_readl(host, IDSTS64);
- if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
- mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
- SDMMC_IDMAC_INT_RI);
- mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
- host->dma_ops->complete(host);
- }
- } else {
- pending = mci_readl(host, IDSTS);
- if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
- mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
- SDMMC_IDMAC_INT_RI);
- mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
- host->dma_ops->complete(host);
+ if (host->use_dma == TRANS_MODE_IDMAC) {
Doing:
if (host->use_dma != TRANS_MODE_IDMAC)
return IRQ_HANDLED;
Could save you the extra level of identation you add below.
+ /* Handle DMA interrupts */
+ if (host->dma_64bit_address == 1) {
+ pending = mci_readl(host, IDSTS64);
+ if (pending & (SDMMC_IDMAC_INT_TI |
+ SDMMC_IDMAC_INT_RI)) {
+ mci_writel(host, IDSTS64,
+ SDMMC_IDMAC_INT_TI |
+ SDMMC_IDMAC_INT_RI);
+ mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
+ host->dma_ops->complete((void *)host);
+ }
+ } else {
+ pending = mci_readl(host, IDSTS);
+ if (pending & (SDMMC_IDMAC_INT_TI |
+ SDMMC_IDMAC_INT_RI)) {
+ mci_writel(host, IDSTS,
+ SDMMC_IDMAC_INT_TI |
+ SDMMC_IDMAC_INT_RI);
+ mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
+ host->dma_ops->complete((void *)host);
+ }
}
}
-#endif
return IRQ_HANDLED;
}
@@ -2437,6 +2567,21 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
static void dw_mci_init_dma(struct dw_mci *host)
{
int addr_config;
+ int trans_mode;
+ struct device *dev = host->dev;
+ struct device_node *np = dev->of_node;
+
+ /* Check tansfer mode */
+ trans_mode = (mci_readl(host, HCON) >> 16) & 0x3;
I think it would be nice if you could add some defines for 16 and 0x03
or add a macro like SDMMC_GET_FCNT() that is in dw_mmc.h.
+ if (trans_mode == 0) {
+ trans_mode = TRANS_MODE_IDMAC;
+ } else if (trans_mode == 1 || trans_mode == 2) {
+ trans_mode = TRANS_MODE_EDMAC;
+ } else {
+ trans_mode = TRANS_MODE_PIO;
+ goto no_dma;
+ }
+
/* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
I'll try to get this patch tested on my lpc18xx platform soon.
btw, the HCON reg on lpc18xx reads as 0x00e42cc1 (address 0x40004070).
regard,
Joachim Eastwood