From: xbw Date: Tue, 29 Jan 2013 09:16:17 +0000 (+0800) Subject: SDMMC: X-Git-Tag: firefly_0821_release~7706 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3c48a4ad61e86039483e7e776853c342c01fd50c;p=firefly-linux-kernel-4.4.55.git SDMMC: add the function to adjust Io-voltage according to specific projects. --- diff --git a/arch/arm/plat-rk/rk-sdmmc-ops.c b/arch/arm/plat-rk/rk-sdmmc-ops.c index 9e99e6d95ca5..6c55ce44daa5 100644 --- a/arch/arm/plat-rk/rk-sdmmc-ops.c +++ b/arch/arm/plat-rk/rk-sdmmc-ops.c @@ -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) @@ -21,8 +21,14 @@ #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) @@ -38,6 +43,14 @@ #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) @@ -48,6 +61,22 @@ #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)); diff --git a/drivers/mmc/host/rk29_sdmmc.c b/drivers/mmc/host/rk29_sdmmc.c index a06db99de93b..871a2f49ed1d 100755 --- a/drivers/mmc/host/rk29_sdmmc.c +++ b/drivers/mmc/host/rk29_sdmmc.c @@ -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.