--- /dev/null
+/*
+ * 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";
+ };
+
+};
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>;
#include "rk3188.dtsi"
#include "rk3188-clocks.dtsi"
#include "lcd-b101ew05.dtsi"
+#include "rk3188-mmc.dtsi"
/ {
memory {
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
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
--- /dev/null
+/*
+ * 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");
}
}
+#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) {
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
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;
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 */
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)
#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 */