aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhangfei Gao <zhangfei.gao@linaro.org>2014-01-09 09:35:11 -0500
committerChris Ball <chris@printf.net>2014-01-13 12:48:33 -0500
commit036f29d554e84fa288411d950c2f0ae797be9146 (patch)
tree6ac874f5ae34b97855a2e602275818108169fc9b
parentbf626e5550f24aec24975a0e85ad8e572ca76a6b (diff)
mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org> Signed-off-by: Zhigang Wang <brooke.wangzhigang@huawei.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Chris Ball <chris@printf.net>
-rw-r--r--Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt60
-rw-r--r--drivers/mmc/host/Kconfig10
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/dw_mmc-k3.c132
4 files changed, 203 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
new file mode 100644
index 000000000000..d7e2d7f159bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
@@ -0,0 +1,60 @@
1* Hisilicon specific extensions to the Synopsys Designware Mobile
2 Storage Host Controller
3
4Read synopsys-dw-mshc.txt for more details
5
6The Synopsys designware mobile storage host controller is used to interface
7a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
8differences between the core Synopsys dw mshc controller properties described
9by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific
10extensions to the Synopsys Designware Mobile Storage Host Controller.
11
12Required Properties:
13
14* compatible: should be one of the following.
15 - "hisilicon,hi4511-dw-mshc": for controllers with hi4511 specific extentions.
16
17* clock-freq-table: should be the frequency (in Hz) array of the ciu clock
18 in each supported mode.
19 0. CIU clock rate in Hz for DS mode
20 1. CIU clock rate in Hz for MMC HS mode
21 2. CIU clock rate in Hz for SD HS mode
22 3. CIU clock rate in Hz for SDR12 mode
23 4. CIU clock rate in Hz for SDR25 mode
24 5. CIU clock rate in Hz for SDR50 mode
25 6. CIU clock rate in Hz for SDR104 mode
26 7. CIU clock rate in Hz for DDR50 mode
27 8. CIU clock rate in Hz for HS200 mode
28
29Example:
30
31 /* for Hi3620 */
32
33 /* SoC portion */
34 dwmmc_0: dwmmc0@fcd03000 {
35 compatible = "hisilicon,hi4511-dw-mshc";
36 reg = <0xfcd03000 0x1000>;
37 interrupts = <0 16 4>;
38 #address-cells = <1>;
39 #size-cells = <0>;
40 clocks = <&mmc_clock HI3620_SD_CIUCLK>, <&clock HI3620_DDRC_PER_CLK>;
41 clock-names = "ciu", "biu";
42 clock-freq-table =
43 <25000000 0 50000000 25000000 50000000 100000000 0 50000000>;
44 };
45
46 /* Board portion */
47 dwmmc0@fcd03000 {
48 num-slots = <1>;
49 vmmc-supply = <&ldo12>;
50 fifo-depth = <0x100>;
51 supports-highspeed;
52 pinctrl-names = "default";
53 pinctrl-0 = <&sd_pmx_pins &sd_cfg_func1 &sd_cfg_func2>;
54 slot@0 {
55 reg = <0>;
56 bus-width = <4>;
57 disable-wp;
58 cd-gpios = <&gpio10 3 0>;
59 };
60 };
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 265ba4800134..6da5a085f5f8 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -576,6 +576,16 @@ config MMC_DW_SOCFPGA
576 This selects support for Altera SoCFPGA specific extensions to the 576 This selects support for Altera SoCFPGA specific extensions to the
577 Synopsys DesignWare Memory Card Interface driver. 577 Synopsys DesignWare Memory Card Interface driver.
578 578
579config MMC_DW_K3
580 tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
581 depends on MMC_DW
582 select MMC_DW_PLTFM
583 select MMC_DW_IDMAC
584 help
585 This selects support for Hisilicon K3 SoC specific extensions to the
586 Synopsys DesignWare Memory Card Interface driver. Select this option
587 for platforms based on Hisilicon K3 SoC's.
588
579config MMC_DW_PCI 589config MMC_DW_PCI
580 tristate "Synopsys Designware MCI support on PCI bus" 590 tristate "Synopsys Designware MCI support on PCI bus"
581 depends on MMC_DW && PCI 591 depends on MMC_DW && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 5dd3de9b2677..a69fd640698d 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o
44obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o 44obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
45obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o 45obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o
46obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o 46obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o
47obj-$(CONFIG_MMC_DW_K3) += dw_mmc-k3.o
47obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o 48obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
48obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o 49obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
49obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o 50obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c
new file mode 100644
index 000000000000..68e5e428e8f6
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-k3.c
@@ -0,0 +1,132 @@
1/*
2 * Copyright (c) 2013 Linaro Ltd.
3 * Copyright (c) 2013 Hisilicon Limited.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/clk.h>
14#include <linux/mmc/host.h>
15#include <linux/mmc/dw_mmc.h>
16#include <linux/of_address.h>
17
18#include "dw_mmc.h"
19#include "dw_mmc-pltfm.h"
20
21#define MAX_NUMS 10
22struct dw_mci_k3_priv_data {
23 u32 clk_table[MAX_NUMS];
24};
25
26static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios)
27{
28 struct dw_mci_k3_priv_data *priv = host->priv;
29 u32 rate = priv->clk_table[ios->timing];
30 int ret;
31
32 if (!rate) {
33 dev_warn(host->dev,
34 "no specified rate in timing %u\n", ios->timing);
35 return;
36 }
37
38 ret = clk_set_rate(host->ciu_clk, rate);
39 if (ret)
40 dev_warn(host->dev, "failed to set clock rate %uHz\n", rate);
41
42 host->bus_hz = clk_get_rate(host->ciu_clk);
43}
44
45static int dw_mci_k3_parse_dt(struct dw_mci *host)
46{
47 struct dw_mci_k3_priv_data *priv;
48 struct device_node *node = host->dev->of_node;
49 struct property *prop;
50 const __be32 *cur;
51 u32 val, num = 0;
52
53 priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
54 if (!priv) {
55 dev_err(host->dev, "mem alloc failed for private data\n");
56 return -ENOMEM;
57 }
58 host->priv = priv;
59
60 of_property_for_each_u32(node, "clock-freq-table", prop, cur, val) {
61 if (num >= MAX_NUMS)
62 break;
63 priv->clk_table[num++] = val;
64 }
65 return 0;
66}
67
68static const struct dw_mci_drv_data k3_drv_data = {
69 .set_ios = dw_mci_k3_set_ios,
70 .parse_dt = dw_mci_k3_parse_dt,
71};
72
73static const struct of_device_id dw_mci_k3_match[] = {
74 { .compatible = "hisilicon,hi4511-dw-mshc", .data = &k3_drv_data, },
75 {},
76};
77MODULE_DEVICE_TABLE(of, dw_mci_k3_match);
78
79static int dw_mci_k3_probe(struct platform_device *pdev)
80{
81 const struct dw_mci_drv_data *drv_data;
82 const struct of_device_id *match;
83
84 match = of_match_node(dw_mci_k3_match, pdev->dev.of_node);
85 drv_data = match->data;
86
87 return dw_mci_pltfm_register(pdev, drv_data);
88}
89
90static int dw_mci_k3_suspend(struct device *dev)
91{
92 struct dw_mci *host = dev_get_drvdata(dev);
93 int ret;
94
95 ret = dw_mci_suspend(host);
96 if (!ret)
97 clk_disable_unprepare(host->ciu_clk);
98
99 return ret;
100}
101
102static int dw_mci_k3_resume(struct device *dev)
103{
104 struct dw_mci *host = dev_get_drvdata(dev);
105 int ret;
106
107 ret = clk_prepare_enable(host->ciu_clk);
108 if (ret) {
109 dev_err(host->dev, "failed to enable ciu clock\n");
110 return ret;
111 }
112
113 return dw_mci_resume(host);
114}
115
116SIMPLE_DEV_PM_OPS(dw_mci_k3_pmops, dw_mci_k3_suspend, dw_mci_k3_resume);
117
118static struct platform_driver dw_mci_k3_pltfm_driver = {
119 .probe = dw_mci_k3_probe,
120 .remove = dw_mci_pltfm_remove,
121 .driver = {
122 .name = "dwmmc_k3",
123 .of_match_table = dw_mci_k3_match,
124 .pm = &dw_mci_k3_pmops,
125 },
126};
127
128module_platform_driver(dw_mci_k3_pltfm_driver);
129
130MODULE_DESCRIPTION("K3 Specific DW-MSHC Driver Extension");
131MODULE_LICENSE("GPL v2");
132MODULE_ALIAS("platform:dwmmc-k3");