From: xbw Date: Sat, 22 Feb 2014 08:03:46 +0000 (+0800) Subject: SDMMC: add the sdmmc driver to kernel_3.10 X-Git-Tag: firefly_0821_release~6299 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=3510c255c321a9a82960b655f72de0b1078ccfba;p=firefly-linux-kernel-4.4.55.git SDMMC: add the sdmmc driver to kernel_3.10 --- diff --git a/arch/arm/boot/dts/rk3188-mmc.dtsi b/arch/arm/boot/dts/rk3188-mmc.dtsi new file mode 100755 index 000000000000..2b4eb8d9f207 --- /dev/null +++ b/arch/arm/boot/dts/rk3188-mmc.dtsi @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 ROCKCHIP, Inc. + * Author: lintao + * Bangwang Xie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + + +/{ + sdmmc: rksdmmc@10214000 { + compatible = "rockchip,rk_mmc"; + reg = <0x10214000 0x4000>; + interrupts = ; /*irq=55*/ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default","suspend"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_wp &sd0_pwr &sd0_bus1 &sd0_bus4>; + pinctrl-1 = <&sd0_cd_gpio>; //for int gpio? + clocks = <&clk_gates2 11>; + num-slots = <1>; + supports-highspeed; + broken-cd; + fifo-depth = <0x80>; + mmc,caps = <(MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED)>; + mmc,ocr = <(MMC_VDD_25_26 | MMC_VDD_26_27 | 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)>; + mmc,use_dma = ; + mmc,dma_ch = ; + mmc,int = ; + //mmc,int = ; + mmc,emmc_is_selected = <0>; + status = "okay"; + }; + + sdio: rksdmmc@10218000 { + compatible = "rockchip,rk_mmc"; + reg = <0x10218000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_wp &sd1_bus1 &sd1_bus4>; + clocks = <&clk_gates2 14>; + num-slots = <1>; + supports-highspeed; + fifo-depth = <0x100>; + mmc,caps = <(MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED)>; + mmc,ocr = <(MMC_VDD_25_26 | MMC_VDD_26_27 | 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,use_dma = ; + mmc,dma_ch = ; + mmc,int = ; + //mmc,int = ; + //OOB pin? + mmc,emmc_is_selected = <0>; + status = "disabled"; + }; + + emmc: rksdmmc@1021C000 { + compatible = "rockchip,rk_mmc"; + reg = <0x1021C000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + //pinctrl-names = "default"; + //pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_wp &sd0_pwr &sd0_bus1 &sd0_bus4>; + clocks = <&clk_gates2 11>; + num-slots = <1>; + supports-highspeed; + fifo-depth = <0x100>; + mmc,caps = <(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED)>; + mmc,ocr = <(MMC_VDD_25_26 | MMC_VDD_26_27 | 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)>; + mmc,use_dma = ; + mmc,dma_ch = ; + mmc,int = ; + //mmc,int = ; + mmc,emmc_is_selected = <1>; + status = "disabled"; + }; + +}; diff --git a/arch/arm/boot/dts/rk3188-pinctrl.dtsi b/arch/arm/boot/dts/rk3188-pinctrl.dtsi index 6c2945a3b2fd..c5e665b003da 100755 --- a/arch/arm/boot/dts/rk3188-pinctrl.dtsi +++ b/arch/arm/boot/dts/rk3188-pinctrl.dtsi @@ -583,7 +583,7 @@ sd0_cmd: sd0-cmd { rockchip,pins = ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; @@ -591,12 +591,18 @@ sd0_cd: sd0-cd { rockchip,pins = ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; }; + sd0_cd_gpio:sd0_cd_gpio{ + rockchip,pins = ; + rockchip,pull = ; + rockchip,drive = ; + }; + sd0_wp: sd0-wp { rockchip,pins = ; rockchip,pull = ; @@ -615,7 +621,7 @@ sd0_bus1: sd0-bus-width1 { rockchip,pins = ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; @@ -626,7 +632,7 @@ , , ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; @@ -644,7 +650,7 @@ sd1_cmd: sd1-cmd { rockchip,pins = ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; @@ -652,7 +658,7 @@ sd1_cd: sd1-cd { rockchip,pins = ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; @@ -668,7 +674,7 @@ sd1_bus1: sd1-bus-width1 { rockchip,pins = ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; @@ -679,7 +685,7 @@ , , ; - rockchip,pull = ; + rockchip,pull = ; //rockchip,voltage = ; rockchip,drive = ; //rockchip,tristate = ; diff --git a/arch/arm/boot/dts/rk3188-tb.dts b/arch/arm/boot/dts/rk3188-tb.dts old mode 100644 new mode 100755 index d1470dbcbff5..f209141ce324 --- a/arch/arm/boot/dts/rk3188-tb.dts +++ b/arch/arm/boot/dts/rk3188-tb.dts @@ -3,6 +3,7 @@ #include "rk3188.dtsi" #include "rk3188-clocks.dtsi" #include "lcd-b101ew05.dtsi" +#include "rk3188-mmc.dtsi" / { memory { diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig old mode 100644 new mode 100755 index 9ab8f8dee942..0fc7a9eed0be --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -547,6 +547,15 @@ config MMC_DW_PLTFM If unsure, say Y. +config MMC_DW_RK + tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface" + depends on MMC_DW + select MMC_DW_PLTFM + help + This selects support for Rockchip RK32XX SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on RK32XX SoC's. + config MMC_DW_EXYNOS tristate "Exynos specific extensions for Synopsys DW Memory Card Interface" depends on MMC_DW diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile old mode 100644 new mode 100755 index cd3228075553..81cd30728cb5 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -41,6 +41,10 @@ obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o + +# added by XBW to Specific Extensions for Synopsys DW Multimedia Card Interface in Rockchip Soc. +obj-$(CONFIG_MMC_DW_RK) += dw_mmc-rockchip.o rk_sdmmc_of.o + obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c new file mode 100755 index 000000000000..86c12333dba0 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -0,0 +1,228 @@ +/* + * Rockchip Specific Extensions for Synopsys DW Multimedia Card Interface driver + * + * Copyright (C) 2014, Rockchip Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "dw_mmc.h" +#include "dw_mmc-pltfm.h" + +#include "rk_sdmmc_of.h" +u32 mmc_debug_level = MMC_DBG_BOOT | MMC_DBG_ERROR;//|MMC_DBG_WARN|MMC_DBG_ALL; + + +#define NUM_PINS(x) (x + 2) + +/* SDMMC_CLKSEL is not used in Rockchip +#define SDMMC_CLKSEL 0x09C +#define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) +#define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) +#define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) +#define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) +#define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ + SDMMC_CLKSEL_CCLK_DRIVE(y) | \ + SDMMC_CLKSEL_CCLK_DIVIDER(z)) +*/ +#define SDMMC_CMD_USE_HOLD_REG BIT(29) + +//#define EXYNOS4210_FIXED_CIU_CLK_DIV 2 +//#define EXYNOS4412_FIXED_CIU_CLK_DIV 4 + +/* Variations in Rockchip specific dw-mshc controller */ +enum dw_mci_rockchip_type { + DW_MCI_TYPE_RK3288, +}; + +/* Rockchip implementation specific driver private data */ +struct dw_mci_rockchip_priv_data { + enum dw_mci_rockchip_type ctrl_type; + u8 ciu_div; + u32 sdr_timing; + u32 ddr_timing; +}; + +static struct dw_mci_rockchip_compatible { + char *compatible; + enum dw_mci_rockchip_type ctrl_type; +} rockchip_compat[] = { + { + .compatible = "rockchip,rk3288-sdmmc", + .ctrl_type = DW_MCI_TYPE_RK3288, + }, +}; + +static int dw_mci_rockchip_priv_init(struct dw_mci *host) +{ + struct dw_mci_rockchip_priv_data *priv; + int idx; + + priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(host->dev, "mem alloc failed for private data\n"); + return -ENOMEM; + } + + for (idx = 0; idx < ARRAY_SIZE(rockchip_compat); idx++) { + if (of_device_is_compatible(host->dev->of_node, + rockchip_compat[idx].compatible)) + priv->ctrl_type = rockchip_compat[idx].ctrl_type; + } + + host->priv = priv; + return 0; +} + +static int dw_mci_rockchip_setup_clock(struct dw_mci *host) +{ + struct dw_mci_rockchip_priv_data *priv = host->priv; + + if (priv->ctrl_type == DW_MCI_TYPE_RK3288) + host->bus_hz /= (priv->ciu_div + 1); + /*else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) + host->bus_hz /= EXYNOS4412_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) + host->bus_hz /= EXYNOS4210_FIXED_CIU_CLK_DIV; + */ + return 0; +} + +static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr) +{ + /* + * Exynos4412 and Exynos5250 extends the use of CMD register with the + * use of bit 29 (which is reserved on standard MSHC controllers) for + * optionally bypassing the HOLD register for command and data. The + * HOLD register should be bypassed in case there is no phase shift + * applied on CMD/DATA that is sent to the card. + */ +// if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL))) +// *cmdr |= SDMMC_CMD_USE_HOLD_REG; +} + +static void dw_mci_rockchip_set_ios(struct dw_mci *host, struct mmc_ios *ios) +{ + struct dw_mci_rockchip_priv_data *priv = host->priv; +/* + if (ios->timing == MMC_TIMING_UHS_DDR50) + mci_writel(host, CLKSEL, priv->ddr_timing); + else + mci_writel(host, CLKSEL, priv->sdr_timing); +*/ +} + +static int dw_mci_rockchip_parse_dt(struct dw_mci *host) +{ + struct dw_mci_rockchip_priv_data *priv = host->priv; + struct device_node *np = host->dev->of_node; + u32 timing[2]; + u32 div = 0; + int ret; +/*rk set the timing in CRU + of_property_read_u32(np, "samsung,dw-mshc-ciu-div", &div); + priv->ciu_div = div; + + ret = of_property_read_u32_array(np, + "samsung,dw-mshc-sdr-timing", timing, 2); + if (ret) + return ret; + + priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); + + ret = of_property_read_u32_array(np, + "samsung,dw-mshc-ddr-timing", timing, 2); + if (ret) + return ret; + + priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); + */ + return 0; +} + +/* Common capabilities of RK32XX SoC */ +static unsigned long rockchip_dwmmc_caps[4] = { + MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR | + MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, + MMC_CAP_CMD23, + MMC_CAP_CMD23, + MMC_CAP_CMD23, +}; + +static const struct dw_mci_drv_data rockchip_drv_data = { + .caps = rockchip_dwmmc_caps, + .init = dw_mci_rockchip_priv_init, + .setup_clock = dw_mci_rockchip_setup_clock, + .prepare_command = dw_mci_rockchip_prepare_command, + .set_ios = dw_mci_rockchip_set_ios, + .parse_dt = dw_mci_rockchip_parse_dt, +}; + +static const struct of_device_id dw_mci_rockchip_match[] = { + { .compatible = "rockchip,rk_mmc", + .data = &rockchip_drv_data, }, + { /* Sentinel */}, +}; +MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match); + +extern void rockchip_mmc_of_probe(struct device_node *np,struct rk_sdmmc_of *mmc_property); + +static int dw_mci_rockchip_probe(struct platform_device *pdev) +{ + const struct dw_mci_drv_data *drv_data; + const struct of_device_id *match; + struct device_node *np = pdev->dev.of_node; + struct rk_sdmmc_of *rk_mmc_property = NULL; + + + rk_mmc_property = (struct rk_sdmmc_of *)kmalloc(sizeof(struct rk_sdmmc_of),GFP_KERNEL); + if(NULL == rk_mmc_property) + { + + kfree(rk_mmc_property); + rk_mmc_property = NULL; + //mmc_error(""); + printk("rk_mmc_property malloc space failed!\n"); + return 0; + } + + + rockchip_mmc_of_probe(np,rk_mmc_property); + + + + match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node); + drv_data = match->data; + return dw_mci_pltfm_register(pdev, drv_data); +} + +static struct platform_driver dw_mci_rockchip_pltfm_driver = { + .probe = dw_mci_rockchip_probe, + .remove = __exit_p(dw_mci_pltfm_remove), + .driver = { + .name = "dwmmc_rockchip", + .of_match_table = dw_mci_rockchip_match, + .pm = &dw_mci_pltfm_pmops, + }, +}; + +module_platform_driver(dw_mci_rockchip_pltfm_driver); + +MODULE_DESCRIPTION("Rockchip Specific DW-SDMMC Driver Extension"); +MODULE_AUTHOR("Bangwang Xie < xbw@rock-chips.com"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:dwmmc-rockchip"); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c old mode 100644 new mode 100755 index bc3a1bc4940f..9bc18a721f86 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2215,11 +2215,15 @@ int dw_mci_probe(struct dw_mci *host) } } +#if 1 + //test, modify by xbw + host->bus_hz = 50000000; +#else if (IS_ERR(host->ciu_clk)) host->bus_hz = host->pdata->bus_hz; else host->bus_hz = clk_get_rate(host->ciu_clk); - +#endif if (drv_data && drv_data->setup_clock) { ret = drv_data->setup_clock(host); if (ret) { diff --git a/drivers/mmc/host/rk_sdmmc_of.c b/drivers/mmc/host/rk_sdmmc_of.c new file mode 100755 index 000000000000..0ea94619742b --- /dev/null +++ b/drivers/mmc/host/rk_sdmmc_of.c @@ -0,0 +1,58 @@ +#include "rk_sdmmc_of.h" + +static void rockchip_mmc_of_dump(struct rk_sdmmc_of *rk_mmc_property) +{ +printk("%d..%s: =====test====\n", __LINE__, __FUNCTION__); +//dump_stack(); +/* + mmc_debug(MMC_DBG_BOOT,"=========rockchip mmc dts dump info start==============\n"); + mmc_debug(MMC_DBG_BOOT,"mmc,caps: 0x%x\n",rk_mmc_property->mmc_caps); + mmc_debug(MMC_DBG_BOOT,"mmc,ocr: 0x%x\n",rk_mmc_property->mmc_ocr); + mmc_debug(MMC_DBG_BOOT,"mmc,int: 0x%x\n",rk_mmc_property->mmc_int_type); + mmc_debug(MMC_DBG_BOOT,"mmc,emmc_is_selected: 0x%x\n",rk_mmc_property->emmc_is_selected); + mmc_debug(MMC_DBG_BOOT,"mmc,use_dma: %d %d\n",rk_mmc_property->mmc_dma_is_used[0], + rk_mmc_property->mmc_dma_is_used[1]); + mmc_debug(MMC_DBG_BOOT,"mmc,dma_ch: %d\n",rk_mmc_property->mmc_dma_chn); + mmc_debug(MMC_DBG_BOOT,"=========rockchip mmc dts dump info end================\n"); + */ + printk("=========rockchip mmc dts dump info start==============\n"); + printk("mmc,caps: 0x%x\n",rk_mmc_property->mmc_caps); + printk("mmc,ocr: 0x%x\n",rk_mmc_property->mmc_ocr); + printk("mmc,int: 0x%x\n",rk_mmc_property->mmc_int_type); + printk("mmc,emmc_is_selected: 0x%x\n",rk_mmc_property->emmc_is_selected); + printk("mmc,use_dma: %d %d\n",rk_mmc_property->mmc_dma_is_used[0], + rk_mmc_property->mmc_dma_is_used[1]); + printk("mmc,dma_ch: %d\n",rk_mmc_property->mmc_dma_chn); + printk("=========rockchip mmc dts dump info end================\n"); +} + + +void rockchip_mmc_of_probe(struct device_node *np,struct rk_sdmmc_of *rk_mmc_property) +{ + of_property_read_u32(np, "mmc,caps", &rk_mmc_property->mmc_caps); + of_property_read_u32(np, "mmc,ocr", &rk_mmc_property->mmc_ocr); + of_property_read_u32(np, "mmc,int", &rk_mmc_property->mmc_int_type); + of_property_read_u32(np, "mmc,emmc_is_selected", &rk_mmc_property->emmc_is_selected); + of_property_read_u32_array(np, "mmc,use_dma", rk_mmc_property->mmc_dma_is_used,2); + if((&rk_mmc_property->mmc_dma_is_used[0] == MMC_USE_DMA)) + { + if(rk_mmc_property->mmc_dma_is_used[1] == 0) + rk_mmc_property->mmc_dma_name = "dma_mmc0"; + else if(rk_mmc_property->mmc_dma_is_used[1] == 1) + rk_mmc_property->mmc_dma_name = "dma_mmc1"; + else + rk_mmc_property->mmc_dma_name = "dma_mmc2"; + + //of_property_read_string(np, "mmc,dma_name", &(rk_mmc_property->mmc_dma_name)); + of_property_read_u32(np, "mmc,dma_ch", &rk_mmc_property->mmc_dma_chn); + + }else{ + mmc_debug(MMC_DBG_WARN,"Device Tree configure mmc drivers to use pio!\n"); + } + rockchip_mmc_of_dump(rk_mmc_property); + return ; + +} +EXPORT_SYSMBOL(rockchip_mmc_of_probe); + + diff --git a/drivers/mmc/host/rk_sdmmc_of.h b/drivers/mmc/host/rk_sdmmc_of.h new file mode 100755 index 000000000000..923bcc23730e --- /dev/null +++ b/drivers/mmc/host/rk_sdmmc_of.h @@ -0,0 +1,64 @@ +#ifndef __RK_SDMMC_OF_H +#define __RK_SDMMC_OF_H + +#include +#include +#include +#include +#include + + +#define DRIVER_NAME "rk_sdmmc" +#define DRIVER_PREFIX DRIVER_NAME ": " + +enum MMC_DBG_MASK{ + MMC_DBG_NONE = 0, + MMC_DBG_BOOT = BIT(0), + MMC_DBG_INFO = BIT(1), + MMC_DBG_ERROR= BIT(2), + MMC_DBG_WARN = BIT(3), + MMC_DBG_CMD = BIT(4), + MMC_DBG_ALL = ~0, + +}; + +extern u32 mmc_debug_level ;//= MMC_DBG_BOOT | MMC_DBG_ERROR;/* | MMC_DBG_CMD | ...*/ + +#define mmc_error(fmt, arg...) \ + pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg) +#define mmc_warning(fmt, arg...) \ + pr_warning(DRIVER_PREFIX "WARNING " fmt "\n", ##arg) + +#define mmc_cmd(fmt, arg...) \ + pr_info(DRIVER_PREFIX "CMD" fmt "\n", ##arg) + +#define mmc_info(fmt, arg...) \ + pr_info(DRIVER_PREFIX fmt "\n", ##arg) + +#if defined(CONFIG_DYNAMIC_DEBUG) + #define mmc_debug(level, fmt, arg...) \ + do { \ + if (unlikely(level & mmc_debug_level)) \ + dynamic_pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \ + } while (0) +#else + #define mmc_debug(level, fmt, arg...) \ + do { \ + if (unlikely(level & mmc_debug_level)) \ + printk(KERN_DEBUG pr_fmt(DRIVER_PREFIX fmt "\n"), \ + ##arg); \ + } while (0) +#endif + +struct rk_sdmmc_of +{ + u32 mmc_caps; + u32 mmc_int_type; + u32 mmc_ocr; + u32 mmc_dma_is_used[2]; /*Bit 1: use dma or not ; Bit 2:general dma or idma*/ + u32 emmc_is_selected; + u32 mmc_dma_chn; + const char *mmc_dma_name; +}; + +#endif diff --git a/include/dt-bindings/mmc/rockchip-sdmmc.h b/include/dt-bindings/mmc/rockchip-sdmmc.h new file mode 100755 index 000000000000..e03e6d885364 --- /dev/null +++ b/include/dt-bindings/mmc/rockchip-sdmmc.h @@ -0,0 +1,64 @@ +#ifndef _DT_ROCKCHIP_SDMMC_H +#define _DT_ROCKCHIP_SDMMC_H + +#define CONTROLLER_INT_DETECT (0) +#define GPIO_INT_DETECT (1) + +#define MMC_NOT_DMA (0) +#define MMC_USE_DMA (1) + +#define MMC_USE_IDMA (0) +#define MMC_USE_GDMA (1) + +#define SDMMC_DMA_CHN (1) +#define SDIO_DMA_CHN (3) +#define EMMC_DMA_CHN (4) + +#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ +#define MMC_CAP_MMC_HIGHSPEED (1 << 1) /* Can do MMC high-speed timing */ +#define MMC_CAP_SD_HIGHSPEED (1 << 2) /* Can do SD high-speed timing */ +#define MMC_CAP_SDIO_IRQ (1 << 3) /* Can signal pending SDIO IRQs */ +#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */ +#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ +#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ + +#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ +#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ +#define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */ +#define MMC_CAP_1_8V_DDR (1 << 11) /* can support */ + /* DDR mode at 1.8V */ +#define MMC_CAP_1_2V_DDR (1 << 12) /* can support */ + /* DDR mode at 1.2V */ +#define MMC_CAP_POWER_OFF_CARD (1 << 13) /* Can power off after boot */ +#define MMC_CAP_BUS_WIDTH_TEST (1 << 14) /* CMD14/CMD19 bus width ok */ +#define MMC_CAP_UHS_SDR12 (1 << 15) /* Host supports UHS SDR12 mode */ +#define MMC_CAP_UHS_SDR25 (1 << 16) /* Host supports UHS SDR25 mode */ +#define MMC_CAP_UHS_SDR50 (1 << 17) /* Host supports UHS SDR50 mode */ +#define MMC_CAP_UHS_SDR104 (1 << 18) /* Host supports UHS SDR104 mode */ +#define MMC_CAP_UHS_DDR50 (1 << 19) /* Host supports UHS DDR50 mode */ +#define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ +#define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ +#define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */ +#define MMC_CAP_CMD23 (1 << 30) /* CMD23 supported. */ +#define MMC_CAP_HW_RESET (1 << 31) /* Hardware reset */ + +#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ +#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ +#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */ +#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */ +#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */ +#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */ +#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */ +#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */ +#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */ +#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */ +#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */ +#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */ +#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */ +#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */ +#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */ +#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ +#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ + + +#endif diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h old mode 100644 new mode 100755 index 66b465927602..4b8771b78839 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -196,6 +196,10 @@ struct mmc_supply { struct regulator *vqmmc; /* Optional Vccq supply */ }; +#define HOST_IS_EMMC(host) (host->unused) +#define SDMMC_SUPPORT_EMMC(host) (host->rk_sdmmc_emmc_used) + + struct mmc_host { struct device *parent; struct device class_dev; @@ -305,6 +309,8 @@ struct mmc_host { unsigned int max_blk_size; /* maximum size of one mmc block */ unsigned int max_blk_count; /* maximum number of blocks in one req */ unsigned int max_discard_to; /* max. discard timeout in ms */ + unsigned short rk_sdmmc_emmc_used; //rk29_sdmmc driver support emmc + int host_dev_id; /* private data */ spinlock_t lock; /* lock for claim and bus ops */ @@ -336,7 +342,10 @@ struct mmc_host { const struct mmc_bus_ops *bus_ops; /* current bus driver */ unsigned int bus_refs; /* reference counter */ - + + unsigned int re_initialized_flags; //in order to begin the rescan ; added by xbw@2011-04-07 + unsigned int doneflag; //added by xbw at 2011-08-27 + int (*sdmmc_host_hw_init)(void *data); unsigned int bus_resume_flags; #define MMC_BUSRESUME_MANUAL_RESUME (1 << 0) #define MMC_BUSRESUME_NEEDS_RESUME (1 << 1) diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h old mode 100644 new mode 100755 index 50bcde3677ca..8f0131f1231b --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -418,4 +418,12 @@ struct _mmc_csd { #define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ +#define FOD_FREQ (300000) // in the identify stage, unit: hz, max is 400Khz, // the least frequency is FREQ_HCLK_MAX/8 +#define SD_FPP_FREQ (24000000) // normal sd freq, 25Mhz +#define SDHC_FPP_FREQ (49500000) // SDHC in the highspeed. unit is hz, max is 50Mhz. +#define MMC_FPP_FREQ (19000000) // MMC freq, unit is hz, max is 20MHz +#define MMCHS_26_FPP_FREQ (24500000) // highspeed mode support 26M HS-MMC, unit is hz, max is 26Mhz, +#define MMCHS_52_FPP_FREQ (51500000) // highspeed support 52M HS-MMC, unit is hz, max is 52Mhz, + + #endif /* LINUX_MMC_MMC_H */