SDMMC:
authorxbw <xbw@rock-chips.com>
Fri, 2 Aug 2013 07:58:43 +0000 (15:58 +0800)
committerxbw <xbw@rock-chips.com>
Fri, 2 Aug 2013 07:58:43 +0000 (15:58 +0800)
1、add the support for SD Spec V3.0.
2、add the support for UHS-I
3. add the support for IDMA(Internal DMA)
4. eliminate the small flaw about some machines may crash because of sdio-interrupt.

drivers/mmc/core/sd.c
drivers/mmc/host/rk29_sdmmc.c
drivers/mmc/host/rk29_sdmmc.h

index 2e636377b15687e96e5f427b189a3f053ff0a107..8d99c7fd1adc557d771eb304f4097e460f7578df 100755 (executable)
@@ -243,7 +243,8 @@ static int mmc_read_ssr(struct mmc_card *card)
         * bitfield positions accordingly.
         */
        au = UNSTUFF_BITS(ssr, 428 - 384, 4);
-       if (au > 0 || au <= 9) {
+    //if (au > 0 || au <= 9) {  //Modifyed by xbw at 2013-02-28
+       if (au > 0 && au <= 9) {
                card->ssr.au = 1 << (au + 4);
                es = UNSTUFF_BITS(ssr, 408 - 384, 16);
                et = UNSTUFF_BITS(ssr, 402 - 384, 6);
@@ -290,7 +291,8 @@ static int mmc_read_switch(struct mmc_card *card)
        }
 
        /* Find out the supported Bus Speed Modes. */
-       err = mmc_sd_switch(card, 0, 0, 1, status);
+    //err = mmc_sd_switch(card, 0, 0, 1, status);
+    err = mmc_sd_switch(card, 0, 0, 0, status);  //Modifyed by xbw at 2013-02-28
        if (err) {
                /*
                 * If the host or the card can't do the switch,
index 3f4e7cc08b69b914c842900165c9dc97732d4ade..0059e0220b92215891c4a62594fa953703d689b8 100755 (executable)
@@ -106,7 +106,7 @@ int debug_level = 5;
 #define RK29_SDMMC_WAIT_DTO_INTERNVAL   4500  //The time interval from the CMD_DONE_INT to DTO_INT
 #define RK29_SDMMC_REMOVAL_DELAY        2000  //The time interval from the CD_INT to detect_timer react.
 
-#define RK29_SDMMC_VERSION "Ver.5.05 The last modify date is 2013-05-08"
+#define RK29_SDMMC_VERSION "Ver.6.00 The last modify date is 2013-08-02"
 
 #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) 
 #define RK29_CTRL_SDMMC_ID   0  //mainly used by SDMMC
@@ -137,6 +137,16 @@ int debug_level = 5;
 #define DRIVER_SDMMC_USE_NEW_IOMUX_API 0
 #endif
 
+//support Internal DMA 
+#if 0 //Sometime in the future to enable
+#define DRIVER_SDMMC_USE_IDMA 1
+#else
+#define DRIVER_SDMMC_USE_IDMA 0
+#endif
+
+#define SWITCH_VOLTAGE_18_33            0 //RK30_PIN2_PD7 //Temporary experiment
+#define SWITCH_VOLTAGE_ENABLE_VALUE_33  GPIO_LOW
+
 enum {
        EVENT_CMD_COMPLETE = 0,
        EVENT_DATA_COMPLETE,
@@ -728,6 +738,28 @@ err:
 }
 #endif
 
+
+
+/**
+**  This function checks whether the core supports the IDMAC.
+**  return Returns 1 if HW supports IDMAC, else returns 0.
+*/
+u32 rk_sdmmc_check_idma_support(struct rk29_sdmmc *host)
+{
+     u32 retval = 0;
+     u32 ctrl_reg;
+        ctrl_reg = rk29_sdmmc_read(host->regs, SDMMC_CTRL);
+     if(ctrl_reg & SDMMC_CTRL_USE_IDMAC)
+        retval = 1;//Return "true", indicating the hardware supports IDMAC
+     else
+        retval = 0;// Hardware doesnot support IDMAC
+
+       return retval;
+}
+
+
+
+
 static u32 rk29_sdmmc_prepare_command(struct mmc_command *cmd)
 {
        u32             cmdr = cmd->opcode;
@@ -855,6 +887,7 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command
     }
                        
        rk29_sdmmc_write(host->regs, SDMMC_CMDARG, cmd->arg); // write to SDMMC_CMDARG register
+       
 #if defined(CONFIG_ARCH_RK29)  
        rk29_sdmmc_write(host->regs, SDMMC_CMD, cmd_flags | SDMMC_CMD_START); // write to SDMMC_CMD register
 #else
@@ -890,7 +923,7 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command
                return SDM_WAIT_FOR_CMDSTART_TIMEOUT;
        }
     host->errorstep = 0xfe;
+
        return SDM_SUCCESS;
 }
 
@@ -1644,6 +1677,90 @@ static int rk29_sdmmc_get_cd(struct mmc_host *mmc)
 }
 
 
+/**
+  * Delay loop.
+  * Very rough microsecond delay loop  for the system.
+  * \param[in] u32 Value in Number of Microseconds.
+  * \return Returns Void
+ **/
+void rk_sdmmc_udelay(u32 value)
+{
+       u32 counter;
+       for (counter = 0; counter < value ; counter++)
+               udelay(1);
+}
+
+int rk_sdmmc_reset_host(struct rk29_sdmmc *host)
+{
+    int ret = SDM_SUCCESS;
+    int timeout;
+    //reset the host cotroller
+    rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_RESET);
+    udelay(10);
+    
+    timeout = 1000;
+    while((rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_RESET)&& timeout--)
+        udelay(1);
+    if(0 == timeout)
+    {
+        ret = SDM_FALSE;
+        printk(KERN_ERR "%d..  reset ctrl_reset fail! [%s]=\n", __LINE__, host->dma_name);
+        goto EXIT_RESET;
+    }
+
+#if !defined(CONFIG_ARCH_RK29)
+    //reset DMA
+    rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_DMA_RESET);
+    udelay(10);
+    
+    timeout = 1000;
+    while((rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_DMA_RESET)&& timeout--)
+        udelay(1);    
+    if(0 == timeout)
+    {
+        ret = SDM_FALSE;
+        printk(KERN_ERR "%d..  reset dma_reset fail! [%s]=\n", __LINE__, host->dma_name);
+        goto EXIT_RESET;
+    }
+#endif
+
+    //reset FIFO
+    rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_FIFO_RESET);
+    udelay(10);
+    
+    timeout = 1000;
+    while((rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_FIFO_RESET)&& timeout--)
+        udelay(1);       
+    if(0 == timeout)
+    {
+        ret = SDM_FALSE;
+        printk(KERN_ERR "%d..  reset fofo_reset fail! [%s]=\n", __LINE__, host->dma_name);
+        goto EXIT_RESET;
+    }
+
+#if DRIVER_SDMMC_USE_IDMA
+    //reset the internal DMA Controller.
+    rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_SWR);
+    udelay(10);
+    
+    timeout = 1000;
+    while((rk29_sdmmc_read(host->regs, SDMMC_BMOD) & BMOD_SWR)&& timeout--)
+        udelay(1);       
+    if(0 == timeout)
+    {
+        ret = SDM_FALSE;
+        printk(KERN_ERR "%d..  reset IDMAC fail! [%s]=\n", __LINE__, host->dma_name);
+        goto EXIT_RESET;
+    }
+
+    // Program the BMOD register for DMA
+    rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_DSL_TWO);
+#endif
+
+EXIT_RESET:
+    return ret;
+}
+
 /****************************************************************/
 //reset the SDMMC controller of the current host
 /****************************************************************/
@@ -1662,38 +1779,22 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host)
             
         value = rk29_sdmmc_read(host->regs, SDMMC_DATA);
     }
-   
-    /* reset */
-#if defined(CONFIG_ARCH_RK29)     
-    rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET ));
-#else
-    rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET));
-#endif
-    timeOut = 1000;
-    value = rk29_sdmmc_read(host->regs, SDMMC_CTRL);
-    while (( value & (SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_RESET)) && (timeOut > 0))
-    {
-        udelay(1);
-        timeOut--;
-        value = rk29_sdmmc_read(host->regs, SDMMC_CTRL);
-    }
 
-    if (timeOut == 0)
-    {
-        printk(KERN_WARNING "%s..%s..%d..  reset controller fail! [%s]=\n",\
-                               __FILE__, __FUNCTION__,__LINE__, host->dma_name);
-
-        host->errorstep = 0x0A;
-        return SDM_WAIT_FOR_FIFORESET_TIMEOUT;
-    }
+    /* reset */
+    value = rk_sdmmc_reset_host(host);
+    if(value)
+        return SDM_FALSE;
 
      /* FIFO threshold settings  */
-       rk29_sdmmc_write(host->regs, SDMMC_FIFOTH, (SD_MSIZE_16 | (RX_WMARK << RX_WMARK_SHIFT) | (TX_WMARK << TX_WMARK_SHIFT)));
+       rk29_sdmmc_write(host->regs, SDMMC_FIFOTH, FIFO_THRESHOLD_WATERMASK);
        
     rk29_sdmmc_write(host->regs, SDMMC_CTYPE, SDMMC_CTYPE_1BIT);
     rk29_sdmmc_write(host->regs, SDMMC_CLKSRC, CLK_DIV_SRC_0);
+
     /* config debounce */
     host->bus_hz = clk_get_rate(host->clk);
+    
+#if 0//Perhaps in some cases, it is necessary to restrict.
     if((host->bus_hz > 52000000) || (host->bus_hz <= 0))
     {
         printk(KERN_WARNING "%s..%s..%d..****Error!!!!!!  Bus clock %d hz is beyond the prescribed limits. [%s]\n",\
@@ -1702,14 +1803,16 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host)
                host->errorstep = 0x0B;            
         return SDM_PARAM_ERROR;            
     }
+#endif
 
-    rk29_sdmmc_write(host->regs, SDMMC_DEBNCE, (DEBOUNCE_TIME*host->bus_hz)&0xFFFFFF);
+    rk29_sdmmc_write(host->regs, SDMMC_DEBNCE, (DEBOUNCE_TIME*host->bus_hz)& SDMMC_DEFAULT_DEBNCE_VAL);
 
     /* config interrupt */
     rk29_sdmmc_write(host->regs, SDMMC_RINTSTS, 0xFFFFFFFF);
 
     if(host->use_dma)
     {
+
         if(RK29_CTRL_SDMMC_ID == host->pdev->id)
         {
                    rk29_sdmmc_write(host->regs, SDMMC_INTMASK,RK29_SDMMC_INTMASK_USEDMA);
@@ -1793,10 +1896,21 @@ int rk29_sdmmc_reset_controller(struct rk29_sdmmc *host)
                }               
     }
 
+    /*
+    **  Some machines may crash because of sdio-interrupt to open too early.
+    **  then, in the initialization phase, close the interruption.
+    **  noted by xbw,at 2013-07-25
+    */
+    rk29_sdmmc_write(host->regs, SDMMC_INTMASK,rk29_sdmmc_read(host->regs, SDMMC_INTMASK) & ~SDMMC_INT_SDIO);
+    
        rk29_sdmmc_write(host->regs, SDMMC_PWREN, POWER_ENABLE);
        
+#if DRIVER_SDMMC_USE_IDMA 
+    rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE | SDMMC_CTRL_USE_IDMAC); //Set the bit  use_internal_dmac.
+#else
        rk29_sdmmc_write(host->regs, SDMMC_CTRL,SDMMC_CTRL_INT_ENABLE); // enable mci interrupt
-
+#endif
     return SDM_SUCCESS;
 }
 
@@ -2251,7 +2365,23 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc )
         goto start_request_Err; 
        }
        host->errorstep = 0xfd;
-
+    
+#if DRIVER_SDMMC_USE_IDMA 
+    /*  Check if it is a data command. If yes, we need to handle only IDMAC interrupts
+    **  So we disable the Slave mode interrupts and enable DMA mode interrupts.
+    **  CTRL and BMOD registers are set up for DMA mode of operation
+    */
+    if(mrq->data)
+    {
+        rk29_sdmmc_write(host->regs, SDMMC_INTMASK, 0x00000000);//Mask all slave interrupts
+        rk29_sdmmc_write(host->regs, SDMMC_IDINTEN, IDMAC_EN_INT_ALL);
+        rk29_sdmmc_write(host->regs, SDMMC_CTRL, SDMMC_CTRL_USE_IDMAC);
+        rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_DE);            
+        rk29_sdmmc_write(host->regs, SDMMC_BMOD, BMOD_DSL_TWO);// Program the BMOD register for DMA
+        rk29_sdmmc_write(host->regs, SDMMC_FIFOTH, FIFO_THRESHOLD_WATERMASK);
+    }
+#endif    
+   
     xbwprintk(7, "%s..%d...  CMD=%d, wait for INT_CMD_DONE, ret=%d , \n  \
         host->state=0x%x, cmdINT=0x%x \n    host->pendingEvent=0x%lu, host->completeEvents=0x%lu [%s]\n\n",\
         __FUNCTION__, __LINE__, host->cmd->opcode,ret, \
@@ -2679,6 +2809,112 @@ static int rk29_sdmmc_clear_fifo(struct rk29_sdmmc *host)
     return ret;
 }
 
+static int rk_sdmmc_signal_voltage_switch(struct mmc_host *mmc,
+       struct mmc_ios *ios)
+{
+       struct rk29_sdmmc *host;
+       unsigned int value,uhs_reg;
+
+       host = mmc_priv(mmc);
+
+       /*
+        * We first check whether the request is to set signalling voltage
+        * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
+        */
+       uhs_reg = rk29_sdmmc_read(host->regs, SDMMC_UHS_REG); 
+    if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) 
+    {
+       //set 3.3v
+       #if SWITCH_VOLTAGE_18_33
+       if(NULL != SWITCH_VOLTAGE_18_33)
+           gpio_direction_output(SWITCH_VOLTAGE_18_33, SWITCH_VOLTAGE_ENABLE_VALUE_33);
+        #endif
+       //set High-power mode
+       value = rk29_sdmmc_read(host->regs, SDMMC_CLKENA);
+       rk29_sdmmc_write(host->regs,SDMMC_CLKENA , value& ~SDMMC_CLKEN_LOW_PWR);
+
+       //SDMMC_UHS_REG
+       rk29_sdmmc_write(host->regs,SDMMC_UHS_REG , uhs_reg & ~SDMMC_UHS_VOLT_REG_18);
+
+        /* Wait for 5ms */
+               usleep_range(5000, 5500);
+
+               /* 3.3V regulator output should be stable within 5 ms */
+               uhs_reg = rk29_sdmmc_read(host->regs, SDMMC_UHS_REG);
+        if( !(uhs_reg & SDMMC_UHS_VOLT_REG_18))
+            return 0;
+        else
+        {
+            printk(KERN_INFO  ": Switching to 3.3V "
+                               "signalling voltage failed.  [%s]\n", host->dma_name);
+                       return -EIO;
+        }   
+
+    }
+    else if (!(uhs_reg & SDMMC_UHS_VOLT_REG_18) && (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180))
+    {
+        /* Stop SDCLK */
+        rk29_sdmmc_control_clock(host, FALSE);
+
+               /* Check whether DAT[3:0] is 0000 */
+               value = rk29_sdmmc_read(host->regs, SDMMC_STATUS);
+               if ((value & SDMMC_STAUTS_DATA_BUSY) == 0)
+               {
+                       /*
+                        * Enable 1.8V Signal Enable in the Host register 
+                        */
+                       rk29_sdmmc_write(host->regs,SDMMC_UHS_REG , uhs_reg |SDMMC_UHS_VOLT_REG_18);
+
+                       /* Wait for 5ms */
+                       usleep_range(5000, 5500);
+
+                       uhs_reg = rk29_sdmmc_read(host->regs, SDMMC_UHS_REG);
+            if( uhs_reg & SDMMC_UHS_VOLT_REG_18)
+            {
+
+                /* Provide SDCLK again and wait for 1ms*/
+                               rk29_sdmmc_control_clock(host, TRUE);
+                               usleep_range(1000, 1500);
+
+                               /*
+                                * If DAT[3:0] level is 1111b, then the card
+                                * was successfully switched to 1.8V signaling.
+                                */
+                               value = rk29_sdmmc_read(host->regs, SDMMC_STATUS);
+                       if ((value & SDMMC_STAUTS_DATA_BUSY) == 0)
+                           return 0;
+            }
+               }
+
+       /*
+                * If we are here, that means the switch to 1.8V signaling
+                * failed. We power cycle the card, and retry initialization
+                * sequence by setting S18R to 0.
+                */
+               #if SWITCH_VOLTAGE_18_33
+               if(NULL != SWITCH_VOLTAGE_18_33)
+            gpio_direction_output(SWITCH_VOLTAGE_18_33, !(SWITCH_VOLTAGE_ENABLE_VALUE_33));
+        #endif
+        
+               /* Wait for 1ms as per the spec */
+               usleep_range(1000, 1500);
+
+        #if SWITCH_VOLTAGE_18_33
+        if(NULL != SWITCH_VOLTAGE_18_33)
+                   gpio_direction_output(SWITCH_VOLTAGE_18_33, SWITCH_VOLTAGE_ENABLE_VALUE_33);
+               #endif    
+
+               printk(KERN_INFO ": Switching to 1.8V signalling "
+                       "voltage failed, retrying with S18R set to 0. [%s]\n", host->dma_name);
+               return -EAGAIN;
+
+    }
+    else
+    {
+        /* No signal voltage switch required */
+               return 0;
+    }
+}
 
 
 static const struct mmc_host_ops rk29_sdmmc_ops[] = {
@@ -2687,6 +2923,7 @@ static const struct mmc_host_ops rk29_sdmmc_ops[] = {
                .set_ios        = rk29_sdmmc_set_ios,
                .get_ro         = rk29_sdmmc_get_ro,
                .get_cd         = rk29_sdmmc_get_cd,
+           .start_signal_voltage_switch        = rk_sdmmc_signal_voltage_switch,
        },
        {
                .request        = rk29_sdmmc_request,
@@ -3700,7 +3937,18 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
        //mmc->ocr_avail = pdata->host_ocr_avail;
        mmc->ocr_avail = MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31
                      | MMC_VDD_31_32|MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_34_35| MMC_VDD_35_36;    ///set valid volage 2.7---3.6v
+#if 1
+
+    mmc->ocr_avail = mmc->ocr_avail |MMC_VDD_26_27 |MMC_VDD_25_26 |MMC_VDD_24_25 |MMC_VDD_23_24
+                     |MMC_VDD_22_23 |MMC_VDD_21_22 |MMC_VDD_20_21 |MMC_VDD_165_195;
+#endif
        mmc->caps = pdata->host_caps;
+#if 1  
+    mmc->caps = mmc->caps | MMC_CAP_1_8V_DDR |MMC_CAP_1_2V_DDR /*|MMC_CAP_DRIVER_TYPE_A |MMC_CAP_DRIVER_TYPE_C |MMC_CAP_DRIVER_TYPE_D*/
+                |MMC_CAP_UHS_SDR12 |MMC_CAP_UHS_SDR25 |MMC_CAP_UHS_SDR50 |MMC_CAP_UHS_SDR104 |MMC_CAP_UHS_DDR50
+               /* |MMC_CAP_MAX_CURRENT_200 |MMC_CAP_MAX_CURRENT_400 |MMC_CAP_MAX_CURRENT_600 |MMC_CAP_MAX_CURRENT_800
+                |MMC_CAP_SET_XPC_330*/;
+#endif
        mmc->re_initialized_flags = 1;
        mmc->doneflag = 1;
        mmc->sdmmc_host_hw_init = rk29_sdmmc_hw_init;
@@ -3831,6 +4079,10 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
            goto err_dmaunmap;
        }
 
+       //gpio request for switch_voltage 
+       if(RK29_CTRL_SDMMC_ID == host->pdev->id)
+           gpio_request(SWITCH_VOLTAGE_18_33, "sd_volt_switch");
+
 #if defined(CONFIG_SDMMC0_RK29_SDCARD_DET_FROM_GPIO)
     if((RK29_CTRL_SDMMC_ID == host->pdev->id) && (INVALID_GPIO != host->det_pin.io))
     {
index 33b5999b72699c9b163514473daf32baf2c7e29a..8bcd32491df5ab68092d8084d366f95cb48be220 100755 (executable)
@@ -16,6 +16,8 @@
 #ifndef __RK2918_SDMMC_H
 #define __RK2918_SDMMC_H
 
+#include <linux/bitops.h>
+
 #define MAX_SG_CHN     2
 
 
 #define SDMMC_USRID           (0x068)   //User ID register
 
 #if defined(CONFIG_ARCH_RK29)
-#define SDMMC_DATA            (0x100)
+#define SDMMC_DATA            (0x100)   //FIFO data read write
 #else
 #define SDMMC_VERID           (0x06c)   //Version ID register
 #define SDMMC_UHS_REG         (0x074)   //UHS-I register
 #define SDMMC_RST_n           (0x078)   //Hardware reset register
+#define SDMMC_BMOD                   (0x080)   //Bus mode register, control IMAC
+#define SDMMC_PLDMND             (0x084)   //Poll Demand Register
+#define SDMMC_DBADDR             (0x088)   //Descriptor List Base Address Register for 32-bit.
+#define SDMMC_IDSTS                  (0x08c)   //Internal DMAC Status register
+#define SDMMC_IDINTEN            (0x090)   //Internal DMAC Interrupt Enable Register
+#define SDMMC_DSCADDR            (0x094)   //Current Host Descriptor Address Register for 32-bit
+#define SDMMC_BUFADDR            (0x098)   //Current Buffer Descriptor Address Register for 32-bit
 #define SDMMC_CARDTHRCTL      (0x100)   //Card Read Threshold Enable
 #define SDMMC_BACK_END_POWER  (0x104)   //Back-end Power
-#define SDMMC_FIFO_BASE       (0x200)   //
+#define SDMMC_FIFO_BASE       (0x200)   //FIFO data read write
 
 #define SDMMC_DATA            SDMMC_FIFO_BASE
 #endif
 
-#define RK2818_BIT(n)                          (1<<(n))
+#define BIT(n)                         (1<<(n))
 #define RK_CLEAR_BIT(n)                        (0<<(n))
 
 
 /* Control register defines (base+ 0x00)*/
-#define SDMMC_CTRL_OD_PULLUP     RK2818_BIT(24)
-#define SDMMC_CTRL_DMA_ENABLE     RK2818_BIT(5)
-#define SDMMC_CTRL_INT_ENABLE     RK2818_BIT(4)
-#define SDMMC_CTRL_DMA_RESET      RK2818_BIT(2)
-#define SDMMC_CTRL_FIFO_RESET     RK2818_BIT(1)
-#define SDMMC_CTRL_RESET          RK2818_BIT(0)
+#define SDMMC_CTRL_USE_IDMAC       BIT(25)
+#define SDMMC_CTRL_OD_PULLUP       BIT(24)
+#define SDMMC_CTRL_CEATA_INT_EN            BIT(11)
+#define SDMMC_CTRL_SEND_AS_CCSD            BIT(10)
+#define SDMMC_CTRL_SEND_CCSD           BIT(9)
+#define SDMMC_CTRL_ABRT_READ_DATA      BIT(8)
+#define SDMMC_CTRL_SEND_IRQ_RESP       BIT(7)
+#define SDMMC_CTRL_READ_WAIT           BIT(6)
+#define SDMMC_CTRL_DMA_ENABLE       BIT(5)
+#define SDMMC_CTRL_INT_ENABLE       BIT(4)
+#define SDMMC_CTRL_DMA_RESET        BIT(2)
+#define SDMMC_CTRL_FIFO_RESET       BIT(1)
+#define SDMMC_CTRL_RESET            BIT(0)
 
 /* Power Enable Register(base+ 0x04) */
-#define POWER_ENABLE             RK2818_BIT(0)      //Power enable
+#define POWER_ENABLE             BIT(0)             //Power enable
 #define POWER_DISABLE            RK_CLEAR_BIT(0)    //Power off
 
 /* SDMMC Clock source Register(base+ 0x0C) */
@@ -83,9 +99,9 @@
 
 
 /* Clock Enable register defines(base+0x10) */
-#define SDMMC_CLKEN_LOW_PWR      RK2818_BIT(16)
+#define SDMMC_CLKEN_LOW_PWR      BIT(16)
 #define SDMMC_CLKEN_NO_LOW_PWR   RK_CLEAR_BIT(16)   //low-power mode disabled
-#define SDMMC_CLKEN_ENABLE       RK2818_BIT(0)
+#define SDMMC_CLKEN_ENABLE       BIT(0)
 #define SDMMC_CLKEN_DISABLE      RK_CLEAR_BIT(16)   //clock disabled
 
 /* time-out register defines(base+0x14) */
 #define SDMMC_TMOUT_RESP_MSK     0xFF
 
 /* card-type register defines(base+0x18) */
-#define SDMMC_CTYPE_8BIT         RK2818_BIT(16)
-#define SDMMC_CTYPE_4BIT         RK2818_BIT(0)
+#define SDMMC_CTYPE_8BIT         BIT(16)
+#define SDMMC_CTYPE_4BIT         BIT(0)
 #define SDMMC_CTYPE_1BIT         RK_CLEAR_BIT(0)
 
 /* Interrupt status & mask register defines(base+0x24) */
 #if defined(CONFIG_ARCH_RK29)
-#define SDMMC_INT_SDIO          RK2818_BIT(16)      //SDIO interrupt
+#define SDMMC_INT_SDIO          BIT(16)      //SDIO interrupt
 #else
-#define SDMMC_INT_SDIO          RK2818_BIT(24)      //SDIO interrupt
-#define SDMMC_INT_UNBUSY        RK2818_BIT(16)      //data no busy interrupt
+#define SDMMC_INT_SDIO          BIT(24)      //SDIO interrupt
+#define SDMMC_INT_UNBUSY        BIT(16)      //data no busy interrupt
 #endif
 
-#define SDMMC_INT_EBE           RK2818_BIT(15)      //End Bit Error(read)/Write no CRC
-#define SDMMC_INT_ACD           RK2818_BIT(14)      //Auto Command Done
-#define SDMMC_INT_SBE           RK2818_BIT(13)      //Start Bit Error
-#define SDMMC_INT_HLE           RK2818_BIT(12)      //Hardware Locked Write Error
-#define SDMMC_INT_FRUN          RK2818_BIT(11)      //FIFO Underrun/Overrun Error
-#define SDMMC_INT_HTO           RK2818_BIT(10)      //Data Starvation by Host Timeout
-#define SDMMC_INT_DRTO          RK2818_BIT(9)       //Data Read TimeOut
-#define SDMMC_INT_RTO           RK2818_BIT(8)       //Response TimeOut
-#define SDMMC_INT_DCRC          RK2818_BIT(7)       //Data CRC Error
-#define SDMMC_INT_RCRC          RK2818_BIT(6)       //Response CRC Error
-#define SDMMC_INT_RXDR          RK2818_BIT(5)       //Receive FIFO Data Request
-#define SDMMC_INT_TXDR          RK2818_BIT(4)       //Transmit FIFO Data Request
-#define SDMMC_INT_DTO                  RK2818_BIT(3)       //Data Transfer Over
-#define SDMMC_INT_CMD_DONE             RK2818_BIT(2)       //Command Done
-#define SDMMC_INT_RE           RK2818_BIT(1)       //Response Error
-#define SDMMC_INT_CD            RK2818_BIT(0)       //Card Detect
+#define SDMMC_INT_EBE           BIT(15)      //End Bit Error(read)/Write no CRC
+#define SDMMC_INT_ACD           BIT(14)      //Auto Command Done
+#define SDMMC_INT_SBE           BIT(13)      //Start Bit Error
+#define SDMMC_INT_HLE           BIT(12)      //Hardware Locked Write Error
+#define SDMMC_INT_FRUN          BIT(11)      //FIFO Underrun/Overrun Error
+#define SDMMC_INT_HTO           BIT(10)      //Data Starvation by Host Timeout
+#define SDMMC_INT_VSI           SDMMC_INT_HTO   // VSI => Voltage Switch Interrupt,Volt_Switch_int
+#define SDMMC_INT_DRTO          BIT(9)       //Data Read TimeOut
+#define SDMMC_INT_RTO           BIT(8)       //Response TimeOut
+#define SDMMC_INT_DCRC          BIT(7)       //Data CRC Error
+#define SDMMC_INT_RCRC          BIT(6)       //Response CRC Error
+#define SDMMC_INT_RXDR          BIT(5)       //Receive FIFO Data Request
+#define SDMMC_INT_TXDR          BIT(4)       //Transmit FIFO Data Request
+#define SDMMC_INT_DTO                  BIT(3)       //Data Transfer Over
+#define SDMMC_INT_CMD_DONE             BIT(2)       //Command Done
+#define SDMMC_INT_RE           BIT(1)       //Response Error
+#define SDMMC_INT_CD            BIT(0)       //Card Detect
 
 /* Command register defines(base+0x2C) */
-#define SDMMC_CMD_START         RK2818_BIT(31)      //start command
+#define SDMMC_CMD_START         BIT(31)      //start command
 #if !defined(CONFIG_ARCH_RK29)
-#define SDMMC_CMD_USE_HOLD_REG      RK2818_BIT(29)      //Use hold register.
-#define SDMMC_CMD_VOLT_SWITCH       RK2818_BIT(28)      //Voltage switch bit
-#define SDMMC_CMD_BOOT_MODE         RK2818_BIT(27)      //set boot mode.
-#define SDMMC_CMD_DISABLE_BOOT      RK2818_BIT(26)      //disable boot.
-#define SDMMC_CMD_EXPECT_BOOT_ACK   RK2818_BIT(25)      //Expect Boot Acknowledge.
-#define SDMMC_CMD_ENABLE_BOOT       RK2818_BIT(24)      //be set only for mandatory boot mode.
+#define SDMMC_CMD_USE_HOLD_REG      BIT(29)      //Use hold register.
+#define SDMMC_CMD_VOLT_SWITCH       BIT(28)      //Voltage switch bit
+#define SDMMC_CMD_BOOT_MODE         BIT(27)      //set boot mode.
+#define SDMMC_CMD_DISABLE_BOOT      BIT(26)      //disable boot.
+#define SDMMC_CMD_EXPECT_BOOT_ACK   BIT(25)      //Expect Boot Acknowledge.
+#define SDMMC_CMD_ENABLE_BOOT       BIT(24)      //be set only for mandatory boot mode.
+#define SDMMC_CMD_CCS_EXP                  BIT(23)      //expect Command Completion Signal(CCS) from the CE-ATA device.
+#define SDMMC_CMD_CEATA_RD                 BIT(22)      //software should set this bit to indicate that CE-ATA device
 #endif
-#define SDMMC_CMD_UPD_CLK       RK2818_BIT(21)      //update clock register only
-#define SDMMC_CMD_INIT          RK2818_BIT(15)      //send initialization sequence
-#define SDMMC_CMD_STOP          RK2818_BIT(14)      //stop abort command
-#define SDMMC_CMD_PRV_DAT_NO_WAIT  RK_CLEAR_BIT(13) //not wait previous data transfer complete, send command at once
-#define SDMMC_CMD_PRV_DAT_WAIT  RK2818_BIT(13)      //wait previous data transfer complete
-#define SDMMC_CMD_SEND_STOP     RK2818_BIT(12)      //send auto stop command at end of data transfer
-#define SDMMC_CMD_BLOCK_MODE    RK_CLEAR_BIT(11)    //block data transfer command
-#define SDMMC_CMD_STRM_MODE     RK2818_BIT(11)      //stream data transfer command
-#define SDMMC_CMD_DAT_READ      RK_CLEAR_BIT(10)    //read from card
-#define SDMMC_CMD_DAT_WRITE     RK2818_BIT(10)      //write to card; 
-#define SDMMC_CMD_DAT_WR        RK2818_BIT(10)      //write to card;
-#define SDMMC_CMD_DAT_NO_EXP    RK_CLEAR_BIT(9)     //no data transfer expected
-#define SDMMC_CMD_DAT_EXP       RK2818_BIT(9)       //data transfer expected
-#define SDMMC_CMD_RESP_NO_CRC   RK_CLEAR_BIT(8)     //do not check response crc
-#define SDMMC_CMD_RESP_CRC      RK2818_BIT(8)       //check response crc
+#define SDMMC_CMD_UPD_CLK           BIT(21)             //update clock register only
+#define SDMMC_CMD_INIT              BIT(15)             //send initialization sequence
+#define SDMMC_CMD_STOP              BIT(14)             //stop abort command
+#define SDMMC_CMD_PRV_DAT_NO_WAIT   RK_CLEAR_BIT(13)    //not wait previous data transfer complete, send command at once
+#define SDMMC_CMD_PRV_DAT_WAIT      BIT(13)             //wait previous data transfer complete
+#define SDMMC_CMD_SEND_STOP         BIT(12)             //send auto stop command at end of data transfer
+#define SDMMC_CMD_BLOCK_MODE        RK_CLEAR_BIT(11)    //block data transfer command
+#define SDMMC_CMD_STRM_MODE         BIT(11)             //stream data transfer command
+#define SDMMC_CMD_DAT_READ          RK_CLEAR_BIT(10)    //read from card
+#define SDMMC_CMD_DAT_WRITE         BIT(10)             //write to card; 
+#define SDMMC_CMD_DAT_WR            BIT(10)             //write to card;
+#define SDMMC_CMD_DAT_NO_EXP        RK_CLEAR_BIT(9)     //no data transfer expected
+#define SDMMC_CMD_DAT_EXP           BIT(9)              //data transfer expected
+#define SDMMC_CMD_RESP_NO_CRC       RK_CLEAR_BIT(8)     //do not check response crc
+#define SDMMC_CMD_RESP_CRC          BIT(8)              //check response crc
 #define SDMMC_CMD_RESP_CRC_NOCARE   SDMMC_CMD_RESP_CRC  //not care response crc
-#define SDMMC_CMD_RESP_SHORT    RK_CLEAR_BIT(7)     //short response expected from card
-#define SDMMC_CMD_RESP_LONG     RK2818_BIT(7)       //long response expected from card;
-#define SDMMC_CMD_RESP_NOCARE   SDMMC_CMD_RESP_SHORT    //not care response length
-#define SDMMC_CMD_RESP_NO_EXP   RK_CLEAR_BIT(6)     //no response expected from card
-#define SDMMC_CMD_RESP_EXP      RK2818_BIT(6)       //response expected from card
-#define SDMMC_CMD_INDX(n)       ((n) & 0x1F)
+#define SDMMC_CMD_RESP_SHORT        RK_CLEAR_BIT(7)         //short response expected from card
+#define SDMMC_CMD_RESP_LONG         BIT(7)                  //long response expected from card;
+#define SDMMC_CMD_RESP_NOCARE       SDMMC_CMD_RESP_SHORT    //not care response length
+#define SDMMC_CMD_RESP_NO_EXP       RK_CLEAR_BIT(6)         //no response expected from card
+#define SDMMC_CMD_RESP_EXP          BIT(6)                  //response expected from card
+#define SDMMC_CMD_INDX(n)           ((n) & 0x1F)
 
 
 /* Status register defines (base+0x48)*/
-#define SDMMC_STAUTS_MC_BUSY   RK2818_BIT(10)
-#define SDMMC_STAUTS_DATA_BUSY RK2818_BIT(9)       //Card busy
-#define SDMMC_CMD_FSM_MASK             (0x0F << 4)     //Command FSM status mask
-#define SDMMC_CMD_FSM_IDLE      (0x00)                 //CMD FSM is IDLE
-#define SDMMC_STAUTS_FIFO_FULL RK2818_BIT(3)       //FIFO is full status
-#define SDMMC_STAUTS_FIFO_EMPTY        RK2818_BIT(2)       //FIFO is empty status
+#define SDMMC_STAUTS_MC_BUSY       BIT(10)
+#define SDMMC_STAUTS_DATA_BUSY     BIT(9)          //Card busy
+#define SDMMC_CMD_FSM_MASK                 (0x0F << 4)     //Command FSM status mask
+#define SDMMC_CMD_FSM_IDLE          (0x00)                     //CMD FSM is IDLE
+#define SDMMC_STAUTS_FIFO_FULL     BIT(3)          //FIFO is full status
+#define SDMMC_STAUTS_FIFO_EMPTY            BIT(2)          //FIFO is empty status
 
-#define SDMMC_GET_FCNT(x)       (((x)>>17) & 0x1FF)//fifo_count, numbers of filled locations in FIFO
-#define SDMMC_FIFO_SZ           32
+/* Status register defines */
+#define SDMMC_GET_FCNT(x)           (((x)>>17) & 0x1FF)//fifo_count, numbers of filled locations in FIFO
+#define SDMMC_FIFO_SZ               32
 
 
 /* FIFO Register (base + 0x4c)*/
 #define SD_MSIZE_128      (0x6 << 28)
 #define SD_MSIZE_256      (0x7 << 28)
 
+
 #if defined(CONFIG_ARCH_RK29)
 #define FIFO_DEPTH        (0x20)       //FIFO depth = 32 word
 #define RX_WMARK_SHIFT    (16)
 #define TX_WMARK          (FIFO_DEPTH/2)       //TX watermark level set to  128
 #endif
 
+#define FIFO_THRESHOLD_WATERMASK    (SD_MSIZE_16 |(RX_WMARK << RX_WMARK_SHIFT)|(TX_WMARK << TX_WMARK_SHIFT))
+
 /* CDETECT register defines (base+0x50)*/
-#define SDMMC_CARD_DETECT_N            RK2818_BIT(0)        //0--represents presence of card.
+#define SDMMC_CARD_DETECT_N            BIT(0)      //0--represents presence of card.
 
 /* WRIPRT register defines (base+0x54)*/
-#define SDMMC_WRITE_PROTECT            RK2818_BIT(0)       // 1--represents write protect
-
-
+#define SDMMC_WRITE_PROTECT            BIT(0)      // 1--represents write protect
+
+/* Control SDMMC_UHS_REG defines (base+ 0x74)*/
+#define SDMMC_UHS_DDR_MODE      BIT(16)     // 0--Non DDR Mode; 1--DDR mode 
+#define SDMMC_UHS_VOLT_REG_18   BIT(0)      // 0--3.3v; 1--1.8V
+
+
+// #ifdef IDMAC_SUPPORT
+
+/* Bus Mode Register (base + 0x80) */
+#define  BMOD_SWR                  BIT(0)          // Software Reset: Auto cleared after one clock cycle                                0
+#define  BMOD_FB                   BIT(1)          // Fixed Burst Length: when set SINGLE/INCR/INCR4/INCR8/INCR16 used at the start     1 
+#define  BMOD_DE                   BIT(7)          // Idmac Enable: When set IDMAC is enabled                                           7
+#define         BMOD_DSL_MSK           0x0000007C      // Descriptor Skip length: In Number of Words                                      6:2 
+#define         BMOD_DSL_Shift         2               // Descriptor Skip length Shift value
+#define         BMOD_DSL_ZERO      0x00000000  // No Gap between Descriptors
+#define         BMOD_DSL_TWO       0x00000008  // 2 Words Gap between Descriptors
+#define  BMOD_PBL                  0x00000400  // MSIZE in FIFOTH Register 
+
+/* Internal DMAC Status Register(base + 0x8c)*/
+/* Internal DMAC Interrupt Enable Register Bit Definitions */
+#define  IDMAC_AI                          0x00000200   // Abnormal Interrupt Summary Enable/ Status                                       9
+#define  IDMAC_NI                      0x00000100   // Normal Interrupt Summary Enable/ Status                                         8
+#define  IDMAC_CES                             0x00000020   // Card Error Summary Interrupt Enable/ status                                     5
+#define  IDMAC_DU                              0x00000010   // Descriptor Unavailabe Interrupt Enable /Status                                  4
+#define  IDMAC_FBE                             0x00000004   // Fata Bus Error Enable/ Status                                                   2
+#define  IDMAC_RI                              0x00000002   // Rx Interrupt Enable/ Status                                                     1
+#define  IDMAC_TI                              0x00000001   // Tx Interrupt Enable/ Status                                                     0
+
+#define  IDMAC_EN_INT_ALL      0x00000337   // Enables all interrupts 
+
+#define IDMAC_HOST_ABORT_TX     0x00000400   // Host Abort received during Transmission                                     12:10 
+#define IDMAC_HOST_ABORT_RX     0x00000800   // Host Abort received during Reception                                        12:10 
+
+/* IDMAC FSM States */
+#define IDMAC_DMA_IDLE          0x00000000   // DMA is in IDLE state                                                        
+#define IDMAC_DMA_SUSPEND       0x00002000   // DMA is in SUSPEND state                                                     
+#define IDMAC_DESC_RD           0x00004000   // DMA is in DESC READ or FETCH State                                          
+#define IDMAC_DESC_CHK          0x00006000   // DMA is checking the Descriptor for Correctness                              
+#define IDMAC_DMA_RD_REQ_WAIT   0x00008000   // DMA is in this state till dma_req is asserted (Read operation)              
+#define IDMAC_DMA_WR_REQ_WAIT   0x0000A000   // DMA is in this state till dma_req is asserted (Write operation)             
+#define IDMAC_DMA_RD            0x0000C000   // DMA is in Read mode                                                         
+#define IDMAC_DMA_WR            0x0000E000   // DMA is in Write mode                                                         
+#define IDMAC_DESC_CLOSE        0x00010000   // DMA is closing the Descriptor                                               
+
+#define FIFOTH_MSIZE_1         0x00000000   // Multiple Trans. Size is 1
+#define FIFOTH_MSIZE_4         0x10000000   // Multiple Trans. Size is 4
+#define FIFOTH_MSIZE_8         0x20000000   // Multiple Trans. Size is 8
+#define FIFOTH_MSIZE_16                0x30000000   // Multiple Trans. Size is 16
+#define FIFOTH_MSIZE_32                0x40000000   // Multiple Trans. Size is 32
+#define FIFOTH_MSIZE_64                0x50000000   // Multiple Trans. Size is 64
+#define FIFOTH_MSIZE_128       0x60000000   // Multiple Trans. Size is 128
+#define FIFOTH_MSIZE_256       0x70000000   // Multiple Trans. Size is 256
+// #endif //#endif --#ifdef IDMAC_SUPPORT
+
+
+/**********************************************************************
+**  Misc Defines 
+**********************************************************************/
+#define SDMMC_MAX_BUFF_SIZE_IDMAC       8192
+#define SDMMC_DEFAULT_DEBNCE_VAL        0x0FFFFFF
 
 /* Specifies how often in millisecs to poll for card removal-insertion changes
  * when the timer switch is open */
 #define RK_SDMMC0_SWITCH_POLL_DELAY 35
 
-
-
 /* SDMMC progress  return value */
 #define SDM_SUCCESS              (0)                    
 #define SDM_FALSE                (1)