SDMMC:
authorxbw <xbw@rock-chips.com>
Tue, 29 Jan 2013 09:16:17 +0000 (17:16 +0800)
committerxbw <xbw@rock-chips.com>
Tue, 29 Jan 2013 09:16:17 +0000 (17:16 +0800)
add the function to adjust Io-voltage according to specific projects.

arch/arm/plat-rk/rk-sdmmc-ops.c
drivers/mmc/host/rk29_sdmmc.c

index 9e99e6d95ca582a89854381d7ef4ba9a7ce00cda..6c55ce44daa5e9cd9f5cb42fb7e1c1ae07ff05c3 100644 (file)
@@ -1,4 +1,4 @@
-/*****************************************************************************************
+/***************************************************************************************************
  * arch/arm/palt-rk/rk-sdmmc-ops.c
  *
  * Copyright (C) 2013 ROCKCHIP, Inc.
@@ -10,9 +10,9 @@
  *
  * History:
  *     ver1.0 Unified function interface for new imoux-API, created at 2013-01-15
+ *     ver1.1 add drive strength control and the setting of IO-voltage, created at 2013-01-29
  *
- ******************************************************************************************/
-
+ **************************************************************************************************/
 
 //use the new iomux-API
 #if defined(CONFIG_ARCH_RK3066B)||defined(CONFIG_ARCH_RK3168)||defined(CONFIG_ARCH_RK3188)
 #define SDMMC_USE_NEW_IOMUX_API 0
 #endif
 
+//define IO volatga
+#if defined(CONFIG_ARCH_RK3066B)||defined(CONFIG_ARCH_RK3168)||defined(CONFIG_ARCH_RK3188)
+#define SDMMC_SET_IO_VOLTAGE    1
+#else
+#define SDMMC_SET_IO_VOLTAGE    0
+#endif
 
-#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
+#if SDMMC_SET_IO_VOLTAGE
 //GRF_IO_CON2                        0x0FC
 #define SDMMC0_DRIVER_STRENGTH_2MA            (0x00 << 6)
 #define SDMMC0_DRIVER_STRENGTH_4MA            (0x01 << 6)
@@ -30,7 +36,6 @@
 #define SDMMC0_DRIVER_STRENGTH_12MA           (0x03 << 6)
 #define SDMMC0_DRIVER_STRENGTH_MASK           (0x03 << 22)
 
-
 //GRF_IO_CON3                        0x100
 #define SDMMC1_DRIVER_STRENGTH_2MA            (0x00 << 2)
 #define SDMMC1_DRIVER_STRENGTH_4MA            (0x01 << 2)
 #define SDMMC1_DRIVER_STRENGTH_12MA           (0x03 << 2)
 #define SDMMC1_DRIVER_STRENGTH_MASK           (0x03 << 18)
 
+//GRF_IO_CON4       0x104
+#define SDMMC0_IO_VOLTAGE_33            (0x00 << 12)
+#define SDMMC0_IO_VOLTAGE_18            (0x01 << 12)
+#define SDMMC0_IO_VOLTAGE_MASK          (0x01 << 28)
+
+#define SDMMC1_IO_VOLTAGE_33            (0x00 << 8)
+#define SDMMC1_IO_VOLTAGE_18            (0x01 << 8)
+#define SDMMC1_IO_VOLTAGE_MASK          (0x01 << 24)
 
 #define SDMMC_write_grf_reg(addr, val)  __raw_writel(val, addr+RK30_GRF_BASE)
 #define SDMMC_read_grf_reg(addr) __raw_readl(addr+RK30_GRF_BASE)
 #define SDMMC_mask_grf_reg(addr, msk, val)     
 #endif
 
+int rk31sdk_wifi_voltage_select(void)
+{
+    double voltage;
+    int voltage_flag = 0;
+
+    voltage = rk31sdk_get_sdio_wifi_voltage();
+   
+     if(voltage >= 2.7)
+        voltage_flag = 0;
+     else if(voltage <= 2.0)
+        voltage_flag = 1;
+     else
+        voltage_flag = 1;
+
+    return voltage_flag;
+}
 
 
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
@@ -777,10 +806,10 @@ static void rk29_sdmmc_set_iomux_mmc0(unsigned int bus_width)
                #endif
 
             //IO voltage(vccio);sdcard must set the voltage to 3.3v
-            writel_relaxed(0x10000000, RK30_GRF_BASE + GRF_IO_CON4);
-            
+            SDMMC_write_grf_reg(GRF_IO_CON4, (SDMMC0_IO_VOLTAGE_MASK |SDMMC0_IO_VOLTAGE_33));
+    
             //sdmmc drive strength control
-            SDMMC_write_grf_reg(GRF_IO_CON2, (SDMMC0_DRIVER_STRENGTH_MASK |SDMMC0_DRIVER_STRENGTH_12MA));
+            SDMMC_write_grf_reg(GRF_IO_CON2, (SDMMC0_DRIVER_STRENGTH_MASK |SDMMC0_DRIVER_STRENGTH_8MA));
             
             #if !(!!SDMMC_USE_NEW_IOMUX_API)
             rk30_mux_api_set(rksdmmc0_gpio_init.data1_gpio.iomux.name, rksdmmc0_gpio_init.data1_gpio.iomux.fgpio);
@@ -822,14 +851,12 @@ static void rk29_sdmmc_set_iomux_mmc1(unsigned int bus_width)
     rk30_mux_api_set(rksdmmc1_gpio_init.data3_gpio.iomux.name, rksdmmc1_gpio_init.data3_gpio.iomux.fmux);
     #endif
 
-    //IO voltage(vcc-ap0)
- #if defined(CONFIG_BCM4329) || defined(CONFIG_BCM4319) || defined(CONFIG_RK903) || defined(CONFIG_RK901)
-    writel_relaxed(0x01000100, RK30_GRF_BASE + GRF_IO_CON4);
-    
- #elif defined(CONFIG_MT5931_MT6622) || defined(CONFIG_MT5931)|| defined(CONFIG_MT6620)
-    writel_relaxed(0x01000000, RK30_GRF_BASE + GRF_IO_CON4);
-    
- #endif
+     //IO voltage(vcc-ap0)
+    if(rk31sdk_wifi_voltage_select())
+        SDMMC_write_grf_reg(GRF_IO_CON4, (SDMMC1_IO_VOLTAGE_MASK|SDMMC1_IO_VOLTAGE_18));       
+    else
+        SDMMC_write_grf_reg(GRF_IO_CON4, (SDMMC1_IO_VOLTAGE_MASK|SDMMC1_IO_VOLTAGE_33));
+
     //sdmmc1 drive strength control
     SDMMC_write_grf_reg(GRF_IO_CON3, (SDMMC1_DRIVER_STRENGTH_MASK|SDMMC1_DRIVER_STRENGTH_12MA));
     
index a06db99de93b1ed21ede82b42fdce62509466acb..871a2f49ed1dead359ffa9c1d4321d50da88bce6 100755 (executable)
@@ -95,7 +95,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.00 The last modify date is 2012-11-05"
+#define RK29_SDMMC_VERSION "Ver.5.02 The last modify date is 2013-01-29"
 
 #if !defined(CONFIG_USE_SDMMC0_FOR_WIFI_DEVELOP_BOARD) 
 #define RK29_CTRL_SDMMC_ID   0  //mainly used by SDMMC
@@ -2374,30 +2374,6 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
     rk29_sdmmc_enable_irq(host, false);
 
-    if(test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags) || (RK29_CTRL_SDMMC_ID == host->pdev->id))
-    {
-        /*
-         * Waiting SDIO controller to be IDLE.
-        */
-        while (timeout-- > 0)
-       {
-               value = rk29_sdmmc_read(host->regs, SDMMC_STATUS);
-               if ((value & SDMMC_STAUTS_DATA_BUSY) == 0 &&(value & SDMMC_CMD_FSM_MASK) == SDMMC_CMD_FSM_IDLE)
-               {
-                       break;
-               }
-               
-               mdelay(1);
-       }
-       if (timeout <= 0)
-       {
-               printk(KERN_WARNING "%s..%d...Waiting for SDMMC%d controller to be IDLE timeout.[%s]\n", \
-                               __FUNCTION__, __LINE__, host->pdev->id, host->dma_name);
-
-               goto out;
-       }
-       }
-
     //if(host->bus_mode != ios->power_mode)
     {
         switch (ios->power_mode) 
@@ -2424,9 +2400,10 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
               
                 if(RK29_CTRL_SDMMC_ID == host->pdev->id)
                 {
+                    mdelay(5);
                        rk29_sdmmc_control_clock(host, FALSE);
                        rk29_sdmmc_write(host->regs, SDMMC_PWREN, POWER_DISABLE);
-                                       
+                       mdelay(5);                
                        if(5 == host->bus_mode)
                        {
                         mdelay(5);
@@ -2449,6 +2426,31 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        
        }
 
+    if(test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags) || (RK29_CTRL_SDMMC_ID == host->pdev->id))
+    {
+        /*
+         * Waiting SDIO controller to be IDLE.
+        */
+        while (timeout-- > 0)
+       {
+               value = rk29_sdmmc_read(host->regs, SDMMC_STATUS);
+               if ((value & SDMMC_STAUTS_DATA_BUSY) == 0 &&(value & SDMMC_CMD_FSM_MASK) == SDMMC_CMD_FSM_IDLE)
+               {
+                       break;
+               }
+               
+               mdelay(1);
+       }
+       if (timeout <= 0)
+       {
+               printk(KERN_WARNING "%s..%d...Waiting for SDMMC%d controller to be IDLE timeout.[%s]\n", \
+                               __FUNCTION__, __LINE__, host->pdev->id, host->dma_name);
+
+               goto out;
+       }
+       }
+
+
     if(!(test_bit(RK29_SDMMC_CARD_PRESENT, &host->flags) || (RK29_CTRL_SDIO1_ID != host->pdev->id)))
         goto out; //exit the set_ios directly if the SDIO is not present.