SDMMC: add the sdmmc driver to kernel_3.10
authorxbw <xbw@rock-chips.com>
Sat, 22 Feb 2014 08:03:46 +0000 (16:03 +0800)
committerxbw <xbw@rock-chips.com>
Sat, 22 Feb 2014 08:03:46 +0000 (16:03 +0800)
12 files changed:
arch/arm/boot/dts/rk3188-mmc.dtsi [new file with mode: 0755]
arch/arm/boot/dts/rk3188-pinctrl.dtsi
arch/arm/boot/dts/rk3188-tb.dts [changed mode: 0644->0755]
drivers/mmc/host/Kconfig [changed mode: 0644->0755]
drivers/mmc/host/Makefile [changed mode: 0644->0755]
drivers/mmc/host/dw_mmc-rockchip.c [new file with mode: 0755]
drivers/mmc/host/dw_mmc.c [changed mode: 0644->0755]
drivers/mmc/host/rk_sdmmc_of.c [new file with mode: 0755]
drivers/mmc/host/rk_sdmmc_of.h [new file with mode: 0755]
include/dt-bindings/mmc/rockchip-sdmmc.h [new file with mode: 0755]
include/linux/mmc/host.h [changed mode: 0644->0755]
include/linux/mmc/mmc.h [changed mode: 0644->0755]

diff --git a/arch/arm/boot/dts/rk3188-mmc.dtsi b/arch/arm/boot/dts/rk3188-mmc.dtsi
new file mode 100755 (executable)
index 0000000..2b4eb8d
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2013 ROCKCHIP, Inc.
+ * Author: lintao  <lintao@rock-chips.com>
+ *         Bangwang Xie <xbw@rock-chips.com>
+ *
+ * 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<dt-bindings/mmc/rockchip-sdmmc.h>
+
+
+/{
+       sdmmc: rksdmmc@10214000 {
+           compatible = "rockchip,rk_mmc";
+           reg = <0x10214000 0x4000>;
+           interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; /*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_USE_DMA 0>; 
+           mmc,dma_ch = <SDMMC_DMA_CHN>;
+               mmc,int = <CONTROLLER_INT_DETECT>;      
+         //mmc,int = <GPIO_INT_DETECT>;
+           mmc,emmc_is_selected = <0>;
+        status = "okay";
+       };
+
+       sdio: rksdmmc@10218000 {
+               compatible = "rockchip,rk_mmc";
+           reg = <0x10218000 0x4000>;
+           interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+           #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_USE_DMA 1>;
+               mmc,dma_ch = <SDIO_DMA_CHN>;
+               mmc,int = <CONTROLLER_INT_DETECT>;
+         //mmc,int = <GPIO_INT_DETECT>;
+           //OOB pin?
+           mmc,emmc_is_selected = <0>;
+           status = "disabled";
+       };
+
+    emmc: rksdmmc@1021C000 {
+               compatible = "rockchip,rk_mmc";
+               reg = <0x1021C000 0x4000>;
+               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+               #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_USE_DMA 2>;
+               mmc,dma_ch = <EMMC_DMA_CHN>;
+               mmc,int = <CONTROLLER_INT_DETECT>;
+         //mmc,int = <GPIO_INT_DETECT>;
+           mmc,emmc_is_selected = <1>;
+           status = "disabled";
+    };
+                                                                                                                                                                                                                                                                                                                                                                       
+};
index 6c2945a3b2fd1a99bcba28f5aa431cb48fc30ffa..c5e665b003daffe04c6463c496459eba5abcd250 100755 (executable)
 
                        sd0_cmd: sd0-cmd {
                                rockchip,pins = <MMC0_CMD>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
 
                        sd0_cd: sd0-cd {
                                rockchip,pins = <MMC0_DETN>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
                        };
 
+                       sd0_cd_gpio:sd0_cd_gpio{
+                               rockchip,pins = <FUNC_TO_GPIO(MMC0_DETN)>;
+                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,drive = <VALUE_DRV_DEFAULT>;
+                       };
+
                        sd0_wp: sd0-wp {
                                rockchip,pins = <MMC0_WRPRT>;
                                rockchip,pull = <VALUE_PULL_DISABLE>;
 
                        sd0_bus1: sd0-bus-width1 {
                                rockchip,pins = <MMC0_D0>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
                                                <MMC0_D1>,
                                                <MMC0_D2 >,
                                                <MMC0_D3>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
 
                        sd1_cmd: sd1-cmd {
                                rockchip,pins = <MMC1_CMD>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
 
                        sd1_cd: sd1-cd {
                                rockchip,pins = <MMC1_DETN>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
 
                        sd1_bus1: sd1-bus-width1 {
                                rockchip,pins = <MMC1_D0>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
                                                <MMC1_D1>,
                                                <MMC1_D2>,
                                                <MMC1_D3>;
-                               rockchip,pull = <VALUE_PULL_DISABLE>;
+                               rockchip,pull = <VALUE_PULL_UP>;
                                //rockchip,voltage = <VALUE_VOL_DEFAULT>;
                                rockchip,drive = <VALUE_DRV_DEFAULT>;
                                //rockchip,tristate = <VALUE_TRI_DEFAULT>;
old mode 100644 (file)
new mode 100755 (executable)
index d1470db..f209141
@@ -3,6 +3,7 @@
 #include "rk3188.dtsi"
 #include "rk3188-clocks.dtsi"
 #include "lcd-b101ew05.dtsi"
+#include "rk3188-mmc.dtsi"
 
 / {
        memory {
old mode 100644 (file)
new mode 100755 (executable)
index 9ab8f8d..0fc7a9e
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index cd32280..81cd307
@@ -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 (executable)
index 0000000..86c1233
--- /dev/null
@@ -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 <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <linux/slab.h>
+
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
+#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");
old mode 100644 (file)
new mode 100755 (executable)
index bc3a1bc..9bc18a7
@@ -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 (executable)
index 0000000..0ea9461
--- /dev/null
@@ -0,0 +1,58 @@
+#include "rk_sdmmc_of.h"\r
+\r
+static void rockchip_mmc_of_dump(struct rk_sdmmc_of *rk_mmc_property)\r
+{\r
+printk("%d..%s: =====test====\n", __LINE__, __FUNCTION__);\r
+//dump_stack();\r
+/*\r
+    mmc_debug(MMC_DBG_BOOT,"=========rockchip mmc dts dump info start==============\n");\r
+    mmc_debug(MMC_DBG_BOOT,"mmc,caps: 0x%x\n",rk_mmc_property->mmc_caps);\r
+    mmc_debug(MMC_DBG_BOOT,"mmc,ocr:  0x%x\n",rk_mmc_property->mmc_ocr);\r
+    mmc_debug(MMC_DBG_BOOT,"mmc,int:  0x%x\n",rk_mmc_property->mmc_int_type);\r
+    mmc_debug(MMC_DBG_BOOT,"mmc,emmc_is_selected: 0x%x\n",rk_mmc_property->emmc_is_selected);\r
+    mmc_debug(MMC_DBG_BOOT,"mmc,use_dma:  %d %d\n",rk_mmc_property->mmc_dma_is_used[0],\r
+                                                   rk_mmc_property->mmc_dma_is_used[1]);\r
+    mmc_debug(MMC_DBG_BOOT,"mmc,dma_ch: %d\n",rk_mmc_property->mmc_dma_chn);\r
+    mmc_debug(MMC_DBG_BOOT,"=========rockchip mmc dts dump info end================\n");\r
+    */\r
+      printk("=========rockchip mmc dts dump info start==============\n");\r
+    printk("mmc,caps: 0x%x\n",rk_mmc_property->mmc_caps);\r
+    printk("mmc,ocr:  0x%x\n",rk_mmc_property->mmc_ocr);\r
+    printk("mmc,int:  0x%x\n",rk_mmc_property->mmc_int_type);\r
+    printk("mmc,emmc_is_selected: 0x%x\n",rk_mmc_property->emmc_is_selected);\r
+    printk("mmc,use_dma:  %d %d\n",rk_mmc_property->mmc_dma_is_used[0],\r
+                                                   rk_mmc_property->mmc_dma_is_used[1]);\r
+    printk("mmc,dma_ch: %d\n",rk_mmc_property->mmc_dma_chn);\r
+    printk("=========rockchip mmc dts dump info end================\n");  \r
+}\r
+\r
+\r
+void rockchip_mmc_of_probe(struct device_node *np,struct rk_sdmmc_of *rk_mmc_property)\r
+{\r
+    of_property_read_u32(np, "mmc,caps", &rk_mmc_property->mmc_caps);\r
+    of_property_read_u32(np, "mmc,ocr", &rk_mmc_property->mmc_ocr);\r
+    of_property_read_u32(np, "mmc,int", &rk_mmc_property->mmc_int_type);\r
+    of_property_read_u32(np, "mmc,emmc_is_selected", &rk_mmc_property->emmc_is_selected);\r
+    of_property_read_u32_array(np, "mmc,use_dma", rk_mmc_property->mmc_dma_is_used,2);\r
+    if((&rk_mmc_property->mmc_dma_is_used[0] == MMC_USE_DMA))\r
+    {   \r
+           if(rk_mmc_property->mmc_dma_is_used[1] == 0)\r
+                rk_mmc_property->mmc_dma_name = "dma_mmc0";\r
+           else if(rk_mmc_property->mmc_dma_is_used[1] == 1)\r
+                rk_mmc_property->mmc_dma_name = "dma_mmc1";\r
+           else \r
+                rk_mmc_property->mmc_dma_name = "dma_mmc2";\r
+\r
+           //of_property_read_string(np, "mmc,dma_name", &(rk_mmc_property->mmc_dma_name));    \r
+           of_property_read_u32(np, "mmc,dma_ch", &rk_mmc_property->mmc_dma_chn);\r
+        \r
+    }else{\r
+        mmc_debug(MMC_DBG_WARN,"Device Tree configure mmc drivers to use pio!\n");\r
+    }\r
+    rockchip_mmc_of_dump(rk_mmc_property);\r
+    return ;\r
+\r
+}\r
+EXPORT_SYSMBOL(rockchip_mmc_of_probe);\r
+\r
+\r
diff --git a/drivers/mmc/host/rk_sdmmc_of.h b/drivers/mmc/host/rk_sdmmc_of.h
new file mode 100755 (executable)
index 0000000..923bcc2
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef __RK_SDMMC_OF_H\r
+#define __RK_SDMMC_OF_H\r
+\r
+#include <dt-bindings/mmc/rockchip-sdmmc.h>\r
+#include <linux/of_gpio.h>\r
+#include <linux/of_i2c.h>\r
+#include <linux/types.h>\r
+#include <linux/bitops.h>\r
+\r
+\r
+#define DRIVER_NAME "rk_sdmmc"\r
+#define DRIVER_PREFIX DRIVER_NAME ": "\r
+\r
+enum MMC_DBG_MASK{\r
+     MMC_DBG_NONE = 0,\r
+     MMC_DBG_BOOT = BIT(0),\r
+     MMC_DBG_INFO = BIT(1),\r
+     MMC_DBG_ERROR= BIT(2), \r
+     MMC_DBG_WARN = BIT(3),\r
+     MMC_DBG_CMD  = BIT(4),\r
+     MMC_DBG_ALL  = ~0,\r
+     \r
+};\r
+\r
+extern u32 mmc_debug_level ;//= MMC_DBG_BOOT | MMC_DBG_ERROR;/* | MMC_DBG_CMD | ...*/\r
+\r
+#define mmc_error(fmt, arg...) \\r
+        pr_err(DRIVER_PREFIX "ERROR " fmt "\n", ##arg)\r
+#define mmc_warning(fmt, arg...) \\r
+        pr_warning(DRIVER_PREFIX "WARNING " fmt "\n", ##arg)\r
+    \r
+#define mmc_cmd(fmt, arg...) \\r
+        pr_info(DRIVER_PREFIX "CMD" fmt "\n", ##arg)\r
+    \r
+#define mmc_info(fmt, arg...) \\r
+        pr_info(DRIVER_PREFIX fmt "\n", ##arg)\r
+\r
+#if defined(CONFIG_DYNAMIC_DEBUG)\r
+    #define mmc_debug(level, fmt, arg...) \\r
+    do { \\r
+        if (unlikely(level & mmc_debug_level)) \\r
+            dynamic_pr_debug(DRIVER_PREFIX fmt "\n", ##arg); \\r
+    } while (0)\r
+#else\r
+    #define mmc_debug(level, fmt, arg...) \\r
+    do { \\r
+        if (unlikely(level & mmc_debug_level)) \\r
+            printk(KERN_DEBUG pr_fmt(DRIVER_PREFIX fmt "\n"), \\r
+                   ##arg); \\r
+    } while (0)\r
+#endif\r
+\r
+struct rk_sdmmc_of\r
+{\r
+    u32 mmc_caps;            \r
+    u32 mmc_int_type;\r
+    u32 mmc_ocr;\r
+    u32 mmc_dma_is_used[2]; /*Bit 1: use dma or not ; Bit 2:general dma or idma*/\r
+    u32 emmc_is_selected;\r
+    u32 mmc_dma_chn;\r
+    const char *mmc_dma_name;\r
+};\r
+\r
+#endif\r
diff --git a/include/dt-bindings/mmc/rockchip-sdmmc.h b/include/dt-bindings/mmc/rockchip-sdmmc.h
new file mode 100755 (executable)
index 0000000..e03e6d8
--- /dev/null
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index 66b4659..4b8771b
@@ -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)
old mode 100644 (file)
new mode 100755 (executable)
index 50bcde3..8f0131f
@@ -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 */