2 * SDHCI support for SiRF primaII and marco SoCs
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
6 * Licensed under GPLv2 or later.
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/mmc/host.h>
12 #include <linux/module.h>
14 #include <linux/of_gpio.h>
15 #include <linux/mmc/slot-gpio.h>
16 #include "sdhci-pltfm.h"
18 #define SDHCI_CLK_DELAY_SETTING 0x4C
19 #define SDHCI_SIRF_8BITBUS BIT(3)
20 #define SIRF_TUNING_COUNT 128
22 struct sdhci_sirf_priv {
26 static void sdhci_sirf_set_bus_width(struct sdhci_host *host, int width)
30 ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
31 ctrl &= ~(SDHCI_CTRL_4BITBUS | SDHCI_SIRF_8BITBUS);
34 * CSR atlas7 and prima2 SD host version is not 3.0
35 * 8bit-width enable bit of CSR SD hosts is 3,
36 * while stardard hosts use bit 5
38 if (width == MMC_BUS_WIDTH_8)
39 ctrl |= SDHCI_SIRF_8BITBUS;
40 else if (width == MMC_BUS_WIDTH_4)
41 ctrl |= SDHCI_CTRL_4BITBUS;
43 sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
46 static int sdhci_sirf_execute_tuning(struct sdhci_host *host, u32 opcode)
48 int tuning_seq_cnt = 3;
49 u8 phase, tuned_phases[SIRF_TUNING_COUNT];
50 u8 tuned_phase_cnt = 0;
51 int rc = 0, longest_range = 0;
52 int start = -1, end = 0, tuning_value = -1, range = 0;
54 struct mmc_host *mmc = host->mmc;
56 clock_setting = sdhci_readw(host, SDHCI_CLK_DELAY_SETTING);
57 clock_setting &= ~0x3fff;
63 clock_setting | phase,
64 SDHCI_CLK_DELAY_SETTING);
66 if (!mmc_send_tuning(mmc)) {
67 /* Tuning is successful at this tuning point */
68 tuned_phases[tuned_phase_cnt++] = phase;
69 dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n",
70 mmc_hostname(mmc), phase);
75 if (phase == (SIRF_TUNING_COUNT - 1)
76 && range > longest_range)
77 tuning_value = (start + end) / 2;
79 dev_dbg(mmc_dev(mmc), "%s: Found bad phase = %d\n",
80 mmc_hostname(mmc), phase);
81 if (range > longest_range) {
82 tuning_value = (start + end) / 2;
83 longest_range = range;
88 } while (++phase < ARRAY_SIZE(tuned_phases));
90 if (tuned_phase_cnt && tuning_value > 0) {
92 * Finally set the selected phase in delay
97 clock_setting | phase,
98 SDHCI_CLK_DELAY_SETTING);
100 dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n",
101 mmc_hostname(mmc), phase);
103 if (--tuning_seq_cnt)
106 dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n",
114 static struct sdhci_ops sdhci_sirf_ops = {
115 .platform_execute_tuning = sdhci_sirf_execute_tuning,
116 .set_clock = sdhci_set_clock,
117 .get_max_clock = sdhci_pltfm_clk_get_max_clock,
118 .set_bus_width = sdhci_sirf_set_bus_width,
119 .reset = sdhci_reset,
120 .set_uhs_signaling = sdhci_set_uhs_signaling,
123 static struct sdhci_pltfm_data sdhci_sirf_pdata = {
124 .ops = &sdhci_sirf_ops,
125 .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
126 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
127 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
128 SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
129 SDHCI_QUIRK_DELAY_AFTER_POWER,
132 static int sdhci_sirf_probe(struct platform_device *pdev)
134 struct sdhci_host *host;
135 struct sdhci_pltfm_host *pltfm_host;
136 struct sdhci_sirf_priv *priv;
141 clk = devm_clk_get(&pdev->dev, NULL);
143 dev_err(&pdev->dev, "unable to get clock");
147 if (pdev->dev.of_node)
148 gpio_cd = of_get_named_gpio(pdev->dev.of_node, "cd-gpios", 0);
152 host = sdhci_pltfm_init(pdev, &sdhci_sirf_pdata, sizeof(struct sdhci_sirf_priv));
154 return PTR_ERR(host);
156 pltfm_host = sdhci_priv(host);
157 pltfm_host->clk = clk;
158 priv = sdhci_pltfm_priv(pltfm_host);
159 priv->gpio_cd = gpio_cd;
161 sdhci_get_of_property(pdev);
163 ret = clk_prepare_enable(pltfm_host->clk);
165 goto err_clk_prepare;
167 ret = sdhci_add_host(host);
172 * We must request the IRQ after sdhci_add_host(), as the tasklet only
173 * gets setup in sdhci_add_host() and we oops.
175 if (gpio_is_valid(priv->gpio_cd)) {
176 ret = mmc_gpio_request_cd(host->mmc, priv->gpio_cd, 0);
178 dev_err(&pdev->dev, "card detect irq request failed: %d\n",
182 mmc_gpiod_request_cd_irq(host->mmc);
188 sdhci_remove_host(host, 0);
190 clk_disable_unprepare(pltfm_host->clk);
192 sdhci_pltfm_free(pdev);
196 #ifdef CONFIG_PM_SLEEP
197 static int sdhci_sirf_suspend(struct device *dev)
199 struct sdhci_host *host = dev_get_drvdata(dev);
200 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
203 ret = sdhci_suspend_host(host);
207 clk_disable(pltfm_host->clk);
212 static int sdhci_sirf_resume(struct device *dev)
214 struct sdhci_host *host = dev_get_drvdata(dev);
215 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
218 ret = clk_enable(pltfm_host->clk);
220 dev_dbg(dev, "Resume: Error enabling clock\n");
224 return sdhci_resume_host(host);
227 static SIMPLE_DEV_PM_OPS(sdhci_sirf_pm_ops, sdhci_sirf_suspend, sdhci_sirf_resume);
230 static const struct of_device_id sdhci_sirf_of_match[] = {
231 { .compatible = "sirf,prima2-sdhc" },
234 MODULE_DEVICE_TABLE(of, sdhci_sirf_of_match);
236 static struct platform_driver sdhci_sirf_driver = {
238 .name = "sdhci-sirf",
239 .of_match_table = sdhci_sirf_of_match,
240 #ifdef CONFIG_PM_SLEEP
241 .pm = &sdhci_sirf_pm_ops,
244 .probe = sdhci_sirf_probe,
245 .remove = sdhci_pltfm_unregister,
248 module_platform_driver(sdhci_sirf_driver);
250 MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco");
251 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
252 MODULE_LICENSE("GPL v2");