From 96bc2cfe02e369a21082eee1274def9a0be8c33c Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 12 May 2016 13:10:11 +0200 Subject: [PATCH] TPL: TM2: mmc: dwmmc: Provide support for 64 bit idma operation Some Exynos7 platforms (e.g. Espresso 7420, Samsung TM2 5433) use 64bit version of dwmmc driver. This patch allows using both 32 bit and 64 bit versions. Signed-off-by: Lukasz Majewski --- drivers/mmc/dw_mmc.c | 46 ++++++++++++++++++++++++++++++++++++++++------ include/dwmmc.h | 11 +++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 7702f4b..7a3ac21 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -36,8 +36,8 @@ static int dwmci_wait_reset(struct dwmci_host *host, u32 value) return 0; } -static void dwmci_set_idma_desc(struct dwmci_idmac *idmac, - u32 desc0, u32 desc1, u32 desc2) +static void dwmci_set_idma_desc_32bit(void *idmac, + u32 desc0, u32 desc1, u32 desc2) { struct dwmci_idmac *desc = idmac; @@ -47,10 +47,29 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac, desc->next_addr = (ulong)desc + sizeof(struct dwmci_idmac); } -static void dwmci_prepare_data(struct dwmci_host *host, +static void dwmci_set_idma_desc_64bit(void *idmac, u32 flags, + u32 cnt, u32 addr) +{ + struct dwmci_idmac_64addr *d = idmac; + memset(d, '\0', sizeof(*d)); + + d->des0 = flags; + d->des2 = cnt; + d->des4 = addr; + d->des6 = (ulong)d + sizeof(struct dwmci_idmac_64addr); +} + +#ifdef CONFIG_TPL_TM2 +void dwmci_prepare_data(struct dwmci_host *host, + struct mmc_data *data, + struct dwmci_idmac_64addr *cur_idmac, + void *bounce_buffer) +#else +void dwmci_prepare_data(struct dwmci_host *host, struct mmc_data *data, struct dwmci_idmac *cur_idmac, void *bounce_buffer) +#endif { unsigned long ctrl; unsigned int i = 0, flags, cnt, blk_cnt; @@ -76,8 +95,15 @@ static void dwmci_prepare_data(struct dwmci_host *host, } else cnt = data->blocksize * 8; - dwmci_set_idma_desc(cur_idmac, flags, cnt, - (ulong)bounce_buffer + (i * PAGE_SIZE)); + if (host->dma_64bit_address) + dwmci_set_idma_desc_64bit(cur_idmac, flags, cnt, + (ulong)bounce_buffer + + (i * PAGE_SIZE)); + else + dwmci_set_idma_desc_32bit(cur_idmac, + flags, cnt, + (ulong)bounce_buffer + + (i * PAGE_SIZE)); cur_idmac++; if (blk_cnt <= 8) @@ -250,8 +276,13 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, { #endif struct dwmci_host *host = mmc->priv; +#ifdef CONFIG_TPL_TM2 + ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac_64addr, cur_idmac, + data ? DIV_ROUND_UP(data->blocks, 8) : 0); +#else ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data ? DIV_ROUND_UP(data->blocks, 8) : 0); +#endif int ret = 0, flags = 0, i; unsigned int timeout = 500; u32 retry = 100000; @@ -538,8 +569,11 @@ static int dwmci_init(struct mmc *mmc) dwmci_writel(host, DWMCI_INTMASK, 0); dwmci_writel(host, DWMCI_TMOUT, 0xFFFFFFFF); - +#ifdef CONFIG_TPL_TM2 + dwmci_writel(host, DWMCI_IDINTEN + 0x4, 0); +#else dwmci_writel(host, DWMCI_IDINTEN, 0); +#endif dwmci_writel(host, DWMCI_BMOD, 1); if (!host->fifoth_val) { diff --git a/include/dwmmc.h b/include/dwmmc.h index 32fedb5..e560f9e 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -209,6 +209,17 @@ struct dwmci_idmac { u32 next_addr; } __aligned(ARCH_DMA_MINALIGN); +struct dwmci_idmac_64addr { + u32 des0; /* Control Descriptor */ + u32 des1; /* Reserved */ + u32 des2; /* Buffer sizes */ + u32 des3; /* Reserved */ + u32 des4; /* Lower 32-bits of Buffer Address Pointer 1*/ + u32 des5; /* Upper 32-bits of Buffer Address Pointer 1*/ + u32 des6; /* Lower 32-bits of Next Descriptor Address */ + u32 des7; /* Upper 32-bits of Next Descriptor Address */ +}; + static inline void dwmci_writel(struct dwmci_host *host, int reg, u32 val) { writel(val, host->ioaddr + reg); -- 2.7.4