TPL: TM2: mmc: dwmmc: Provide support for 64 bit idma operation
authorLukasz Majewski <l.majewski@samsung.com>
Thu, 12 May 2016 11:10:11 +0000 (13:10 +0200)
committerJaehoon Chung <jh80.chung@samsung.com>
Wed, 18 May 2016 06:32:12 +0000 (15:32 +0900)
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 <l.majewski@samsung.com>
drivers/mmc/dw_mmc.c
include/dwmmc.h

index 7329f40d345b53560da6d19465b7aab0eed3345f..0acb14342afc9819d785b59ccf91c287d37fc8e9 100644 (file)
@@ -32,8 +32,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;
 
@@ -43,10 +43,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;
@@ -69,8 +88,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));
 
                if (blk_cnt <= 8)
                        break;
@@ -185,8 +211,13 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                struct mmc_data *data)
 {
        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 = 100000;
        u32 retry = 100000;
@@ -428,8 +459,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) {
index 8c99d34028780bdba92dce6b6f02aff679cc1faa..84026733d622b828b60715063e0c182df619c435 100644 (file)
@@ -197,6 +197,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);