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/mmc/slot-gpio.h>
15 #include "sdhci-pltfm.h"
17 #define SDHCI_CLK_DELAY_SETTING 0x4C
18 #define SDHCI_SIRF_8BITBUS BIT(3)
19 #define SIRF_TUNING_COUNT 16384
21 static void sdhci_sirf_set_bus_width(struct sdhci_host
*host
, int width
)
25 ctrl
= sdhci_readb(host
, SDHCI_HOST_CONTROL
);
26 ctrl
&= ~(SDHCI_CTRL_4BITBUS
| SDHCI_SIRF_8BITBUS
);
29 * CSR atlas7 and prima2 SD host version is not 3.0
30 * 8bit-width enable bit of CSR SD hosts is 3,
31 * while stardard hosts use bit 5
33 if (width
== MMC_BUS_WIDTH_8
)
34 ctrl
|= SDHCI_SIRF_8BITBUS
;
35 else if (width
== MMC_BUS_WIDTH_4
)
36 ctrl
|= SDHCI_CTRL_4BITBUS
;
38 sdhci_writeb(host
, ctrl
, SDHCI_HOST_CONTROL
);
41 static u32
sdhci_sirf_readl_le(struct sdhci_host
*host
, int reg
)
43 u32 val
= readl(host
->ioaddr
+ reg
);
45 if (unlikely((reg
== SDHCI_CAPABILITIES_1
) &&
46 (host
->mmc
->caps
& MMC_CAP_UHS_SDR50
))) {
47 /* fake CAP_1 register */
48 val
= SDHCI_SUPPORT_DDR50
|
49 SDHCI_SUPPORT_SDR50
| SDHCI_USE_SDR50_TUNING
;
52 if (unlikely(reg
== SDHCI_SLOT_INT_STATUS
)) {
54 /* fake chips as V3.0 host conreoller */
55 prss
&= ~(0xFF << 16);
56 val
= prss
| (SDHCI_SPEC_300
<< 16);
61 static u16
sdhci_sirf_readw_le(struct sdhci_host
*host
, int reg
)
65 ret
= readw(host
->ioaddr
+ reg
);
67 if (unlikely(reg
== SDHCI_HOST_VERSION
)) {
68 ret
= readw(host
->ioaddr
+ SDHCI_HOST_VERSION
);
69 ret
|= SDHCI_SPEC_300
;
75 static int sdhci_sirf_execute_tuning(struct sdhci_host
*host
, u32 opcode
)
77 int tuning_seq_cnt
= 3;
79 u8 tuned_phase_cnt
= 0;
80 int rc
= 0, longest_range
= 0;
81 int start
= -1, end
= 0, tuning_value
= -1, range
= 0;
83 struct mmc_host
*mmc
= host
->mmc
;
85 clock_setting
= sdhci_readw(host
, SDHCI_CLK_DELAY_SETTING
);
86 clock_setting
&= ~0x3fff;
93 clock_setting
| phase
,
94 SDHCI_CLK_DELAY_SETTING
);
96 if (!mmc_send_tuning(mmc
, opcode
, NULL
)) {
97 /* Tuning is successful at this tuning point */
99 dev_dbg(mmc_dev(mmc
), "%s: Found good phase = %d\n",
100 mmc_hostname(mmc
), phase
);
105 if (phase
== (SIRF_TUNING_COUNT
- 1)
106 && range
> longest_range
)
107 tuning_value
= (start
+ end
) / 2;
109 dev_dbg(mmc_dev(mmc
), "%s: Found bad phase = %d\n",
110 mmc_hostname(mmc
), phase
);
111 if (range
> longest_range
) {
112 tuning_value
= (start
+ end
) / 2;
113 longest_range
= range
;
118 } while (++phase
< SIRF_TUNING_COUNT
);
120 if (tuned_phase_cnt
&& tuning_value
> 0) {
122 * Finally set the selected phase in delay
125 phase
= tuning_value
;
127 clock_setting
| phase
,
128 SDHCI_CLK_DELAY_SETTING
);
130 dev_dbg(mmc_dev(mmc
), "%s: Setting the tuning phase to %d\n",
131 mmc_hostname(mmc
), phase
);
133 if (--tuning_seq_cnt
)
136 dev_dbg(mmc_dev(mmc
), "%s: No tuning point found\n",
144 static const struct sdhci_ops sdhci_sirf_ops
= {
145 .read_l
= sdhci_sirf_readl_le
,
146 .read_w
= sdhci_sirf_readw_le
,
147 .platform_execute_tuning
= sdhci_sirf_execute_tuning
,
148 .set_clock
= sdhci_set_clock
,
149 .get_max_clock
= sdhci_pltfm_clk_get_max_clock
,
150 .set_bus_width
= sdhci_sirf_set_bus_width
,
151 .reset
= sdhci_reset
,
152 .set_uhs_signaling
= sdhci_set_uhs_signaling
,
155 static const struct sdhci_pltfm_data sdhci_sirf_pdata
= {
156 .ops
= &sdhci_sirf_ops
,
157 .quirks
= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
|
158 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
|
159 SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN
|
160 SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS
,
161 .quirks2
= SDHCI_QUIRK2_PRESET_VALUE_BROKEN
,
164 static int sdhci_sirf_probe(struct platform_device
*pdev
)
166 struct sdhci_host
*host
;
167 struct sdhci_pltfm_host
*pltfm_host
;
171 clk
= devm_clk_get(&pdev
->dev
, NULL
);
173 dev_err(&pdev
->dev
, "unable to get clock");
177 host
= sdhci_pltfm_init(pdev
, &sdhci_sirf_pdata
, 0);
179 return PTR_ERR(host
);
181 pltfm_host
= sdhci_priv(host
);
182 pltfm_host
->clk
= clk
;
184 sdhci_get_of_property(pdev
);
186 ret
= clk_prepare_enable(pltfm_host
->clk
);
188 goto err_clk_prepare
;
190 ret
= sdhci_add_host(host
);
195 * We must request the IRQ after sdhci_add_host(), as the tasklet only
196 * gets setup in sdhci_add_host() and we oops.
198 ret
= mmc_gpiod_request_cd(host
->mmc
, "cd", 0, false, 0, NULL
);
199 if (ret
== -EPROBE_DEFER
)
202 mmc_gpiod_request_cd_irq(host
->mmc
);
207 sdhci_remove_host(host
, 0);
209 clk_disable_unprepare(pltfm_host
->clk
);
211 sdhci_pltfm_free(pdev
);
215 static const struct of_device_id sdhci_sirf_of_match
[] = {
216 { .compatible
= "sirf,prima2-sdhc" },
219 MODULE_DEVICE_TABLE(of
, sdhci_sirf_of_match
);
221 static struct platform_driver sdhci_sirf_driver
= {
223 .name
= "sdhci-sirf",
224 .of_match_table
= sdhci_sirf_of_match
,
225 .pm
= &sdhci_pltfm_pmops
,
227 .probe
= sdhci_sirf_probe
,
228 .remove
= sdhci_pltfm_unregister
,
231 module_platform_driver(sdhci_sirf_driver
);
233 MODULE_DESCRIPTION("SDHCI driver for SiRFprimaII/SiRFmarco");
234 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
235 MODULE_LICENSE("GPL v2");