Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
e3ec3a3d SB |
2 | /* |
3 | * Arasan Secure Digital Host Controller Interface. | |
4 | * Copyright (C) 2011 - 2012 Michal Simek <monstr@monstr.eu> | |
5 | * Copyright (c) 2012 Wind River Systems, Inc. | |
6 | * Copyright (C) 2013 Pengutronix e.K. | |
7 | * Copyright (C) 2013 Xilinx Inc. | |
8 | * | |
9 | * Based on sdhci-of-esdhc.c | |
10 | * | |
11 | * Copyright (c) 2007 Freescale Semiconductor, Inc. | |
12 | * Copyright (c) 2009 MontaVista Software, Inc. | |
13 | * | |
14 | * Authors: Xiaobo Xie <X.Xie@freescale.com> | |
15 | * Anton Vorontsov <avorontsov@ru.mvista.com> | |
e3ec3a3d SB |
16 | */ |
17 | ||
c390f211 | 18 | #include <linux/clk-provider.h> |
3ea4666e | 19 | #include <linux/mfd/syscon.h> |
e3ec3a3d | 20 | #include <linux/module.h> |
308f3f8d | 21 | #include <linux/of_device.h> |
91aa3661 | 22 | #include <linux/phy/phy.h> |
3ea4666e | 23 | #include <linux/regmap.h> |
0614b0ae | 24 | #include <linux/reset.h> |
3794c542 | 25 | #include <linux/of.h> |
a5c8b2ae | 26 | #include <linux/firmware/xlnx-zynqmp.h> |
e3ec3a3d | 27 | |
84362d79 | 28 | #include "cqhci.h" |
5d249ac3 | 29 | #include "sdhci-cqhci.h" |
84362d79 | 30 | #include "sdhci-pltfm.h" |
e3ec3a3d | 31 | |
84362d79 | 32 | #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 |
1a470721 MN |
33 | |
34 | #define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 | |
d338c6d0 MN |
35 | #define SDHCI_ARASAN_ITAPDLY_SEL_MASK 0xFF |
36 | ||
1a470721 | 37 | #define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC |
d338c6d0 | 38 | #define SDHCI_ARASAN_OTAPDLY_SEL_MASK 0x3F |
1a470721 | 39 | |
84362d79 | 40 | #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 |
a05c8465 | 41 | #define VENDOR_ENHANCED_STROBE BIT(0) |
e3ec3a3d | 42 | |
b2db9c67 DA |
43 | #define PHY_CLK_TOO_SLOW_HZ 400000 |
44 | ||
1a470721 MN |
45 | #define SDHCI_ITAPDLY_CHGWIN 0x200 |
46 | #define SDHCI_ITAPDLY_ENABLE 0x100 | |
47 | #define SDHCI_OTAPDLY_ENABLE 0x40 | |
48 | ||
a5c8b2ae MN |
49 | /* Default settings for ZynqMP Clock Phases */ |
50 | #define ZYNQMP_ICLK_PHASE {0, 63, 63, 0, 63, 0, 0, 183, 54, 0, 0} | |
51 | #define ZYNQMP_OCLK_PHASE {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0} | |
52 | ||
1a470721 MN |
53 | #define VERSAL_ICLK_PHASE {0, 132, 132, 0, 132, 0, 0, 162, 90, 0, 0} |
54 | #define VERSAL_OCLK_PHASE {0, 60, 48, 0, 48, 72, 90, 36, 60, 90, 0} | |
55 | ||
3ea4666e DA |
56 | /* |
57 | * On some SoCs the syscon area has a feature where the upper 16-bits of | |
58 | * each 32-bit register act as a write mask for the lower 16-bits. This allows | |
59 | * atomic updates of the register without locking. This macro is used on SoCs | |
60 | * that have that feature. | |
61 | */ | |
62 | #define HIWORD_UPDATE(val, mask, shift) \ | |
63 | ((val) << (shift) | (mask) << ((shift) + 16)) | |
64 | ||
65 | /** | |
66 | * struct sdhci_arasan_soc_ctl_field - Field used in sdhci_arasan_soc_ctl_map | |
67 | * | |
68 | * @reg: Offset within the syscon of the register containing this field | |
69 | * @width: Number of bits for this field | |
70 | * @shift: Bit offset within @reg of this field (or -1 if not avail) | |
71 | */ | |
72 | struct sdhci_arasan_soc_ctl_field { | |
73 | u32 reg; | |
74 | u16 width; | |
75 | s16 shift; | |
76 | }; | |
77 | ||
78 | /** | |
79 | * struct sdhci_arasan_soc_ctl_map - Map in syscon to corecfg registers | |
80 | * | |
3ea4666e | 81 | * @baseclkfreq: Where to find corecfg_baseclkfreq |
b2ca77c9 | 82 | * @clockmultiplier: Where to find corecfg_clockmultiplier |
36c6aada | 83 | * @support64b: Where to find SUPPORT64B bit |
3ea4666e | 84 | * @hiword_update: If true, use HIWORD_UPDATE to access the syscon |
4908460e MN |
85 | * |
86 | * It's up to the licensee of the Arsan IP block to make these available | |
87 | * somewhere if needed. Presumably these will be scattered somewhere that's | |
88 | * accessible via the syscon API. | |
3ea4666e DA |
89 | */ |
90 | struct sdhci_arasan_soc_ctl_map { | |
91 | struct sdhci_arasan_soc_ctl_field baseclkfreq; | |
b2ca77c9 | 92 | struct sdhci_arasan_soc_ctl_field clockmultiplier; |
36c6aada | 93 | struct sdhci_arasan_soc_ctl_field support64b; |
3ea4666e DA |
94 | bool hiword_update; |
95 | }; | |
96 | ||
16ada730 MN |
97 | /** |
98 | * struct sdhci_arasan_clk_ops - Clock Operations for Arasan SD controller | |
99 | * | |
100 | * @sdcardclk_ops: The output clock related operations | |
101 | * @sampleclk_ops: The sample clock related operations | |
102 | */ | |
103 | struct sdhci_arasan_clk_ops { | |
104 | const struct clk_ops *sdcardclk_ops; | |
105 | const struct clk_ops *sampleclk_ops; | |
106 | }; | |
107 | ||
e1463618 | 108 | /** |
4908460e MN |
109 | * struct sdhci_arasan_clk_data - Arasan Controller Clock Data. |
110 | * | |
e1463618 MN |
111 | * @sdcardclk_hw: Struct for the clock we might provide to a PHY. |
112 | * @sdcardclk: Pointer to normal 'struct clock' for sdcardclk_hw. | |
07a14d1d MN |
113 | * @sampleclk_hw: Struct for the clock we might provide to a PHY. |
114 | * @sampleclk: Pointer to normal 'struct clock' for sampleclk_hw. | |
f3dafc37 MN |
115 | * @clk_phase_in: Array of Input Clock Phase Delays for all speed modes |
116 | * @clk_phase_out: Array of Output Clock Phase Delays for all speed modes | |
117 | * @set_clk_delays: Function pointer for setting Clock Delays | |
a5c8b2ae | 118 | * @clk_of_data: Platform specific runtime clock data storage pointer |
e1463618 MN |
119 | */ |
120 | struct sdhci_arasan_clk_data { | |
121 | struct clk_hw sdcardclk_hw; | |
122 | struct clk *sdcardclk; | |
07a14d1d MN |
123 | struct clk_hw sampleclk_hw; |
124 | struct clk *sampleclk; | |
f3dafc37 MN |
125 | int clk_phase_in[MMC_TIMING_MMC_HS400 + 1]; |
126 | int clk_phase_out[MMC_TIMING_MMC_HS400 + 1]; | |
127 | void (*set_clk_delays)(struct sdhci_host *host); | |
a5c8b2ae MN |
128 | void *clk_of_data; |
129 | }; | |
130 | ||
e3ec3a3d | 131 | /** |
4908460e MN |
132 | * struct sdhci_arasan_data - Arasan Controller Data |
133 | * | |
c390f211 | 134 | * @host: Pointer to the main SDHCI host structure. |
3ea4666e DA |
135 | * @clk_ahb: Pointer to the AHB clock |
136 | * @phy: Pointer to the generic phy | |
b2db9c67 | 137 | * @is_phy_on: True if the PHY is on; false if not. |
4908460e | 138 | * @has_cqe: True if controller has command queuing engine. |
e1463618 | 139 | * @clk_data: Struct for the Arasan Controller Clock Data. |
16ada730 | 140 | * @clk_ops: Struct for the Arasan Controller Clock Operations. |
3ea4666e DA |
141 | * @soc_ctl_base: Pointer to regmap for syscon for soc_ctl registers. |
142 | * @soc_ctl_map: Map to get offsets into soc_ctl registers. | |
4908460e | 143 | * @quirks: Arasan deviations from spec. |
e3ec3a3d SB |
144 | */ |
145 | struct sdhci_arasan_data { | |
c390f211 | 146 | struct sdhci_host *host; |
e3ec3a3d | 147 | struct clk *clk_ahb; |
91aa3661 | 148 | struct phy *phy; |
b2db9c67 | 149 | bool is_phy_on; |
3ea4666e | 150 | |
84362d79 | 151 | bool has_cqe; |
e1463618 | 152 | struct sdhci_arasan_clk_data clk_data; |
16ada730 | 153 | const struct sdhci_arasan_clk_ops *clk_ops; |
c390f211 | 154 | |
3ea4666e DA |
155 | struct regmap *soc_ctl_base; |
156 | const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; | |
4908460e | 157 | unsigned int quirks; |
3794c542 ZB |
158 | |
159 | /* Controller does not have CD wired and will not function normally without */ | |
160 | #define SDHCI_ARASAN_QUIRK_FORCE_CDTEST BIT(0) | |
3f2c7d5d HG |
161 | /* Controller immediately reports SDHCI_CLOCK_INT_STABLE after enabling the |
162 | * internal clock even when the clock isn't stable */ | |
163 | #define SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE BIT(1) | |
c0b4e411 MN |
164 | /* |
165 | * Some of the Arasan variations might not have timing requirements | |
166 | * met at 25MHz for Default Speed mode, those controllers work at | |
167 | * 19MHz instead | |
168 | */ | |
169 | #define SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN BIT(2) | |
3ea4666e DA |
170 | }; |
171 | ||
06b23ca0 FA |
172 | struct sdhci_arasan_of_data { |
173 | const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; | |
174 | const struct sdhci_pltfm_data *pdata; | |
16ada730 | 175 | const struct sdhci_arasan_clk_ops *clk_ops; |
06b23ca0 FA |
176 | }; |
177 | ||
3ea4666e DA |
178 | static const struct sdhci_arasan_soc_ctl_map rk3399_soc_ctl_map = { |
179 | .baseclkfreq = { .reg = 0xf000, .width = 8, .shift = 8 }, | |
b2ca77c9 | 180 | .clockmultiplier = { .reg = 0xf02c, .width = 8, .shift = 0}, |
3ea4666e | 181 | .hiword_update = true, |
e3ec3a3d SB |
182 | }; |
183 | ||
5c1a4f40 RVM |
184 | static const struct sdhci_arasan_soc_ctl_map intel_lgm_emmc_soc_ctl_map = { |
185 | .baseclkfreq = { .reg = 0xa0, .width = 8, .shift = 2 }, | |
186 | .clockmultiplier = { .reg = 0, .width = -1, .shift = -1 }, | |
187 | .hiword_update = false, | |
188 | }; | |
189 | ||
d1807ad6 RVM |
190 | static const struct sdhci_arasan_soc_ctl_map intel_lgm_sdxc_soc_ctl_map = { |
191 | .baseclkfreq = { .reg = 0x80, .width = 8, .shift = 2 }, | |
192 | .clockmultiplier = { .reg = 0, .width = -1, .shift = -1 }, | |
193 | .hiword_update = false, | |
194 | }; | |
195 | ||
39013f09 R |
196 | static const struct sdhci_arasan_soc_ctl_map thunderbay_soc_ctl_map = { |
197 | .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 }, | |
198 | .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, | |
199 | .support64b = { .reg = 0x4, .width = 1, .shift = 24 }, | |
200 | .hiword_update = false, | |
201 | }; | |
202 | ||
36c6aada WAZ |
203 | static const struct sdhci_arasan_soc_ctl_map intel_keembay_soc_ctl_map = { |
204 | .baseclkfreq = { .reg = 0x0, .width = 8, .shift = 14 }, | |
205 | .clockmultiplier = { .reg = 0x4, .width = 8, .shift = 14 }, | |
206 | .support64b = { .reg = 0x4, .width = 1, .shift = 24 }, | |
207 | .hiword_update = false, | |
208 | }; | |
209 | ||
3ea4666e DA |
210 | /** |
211 | * sdhci_arasan_syscon_write - Write to a field in soc_ctl registers | |
212 | * | |
4908460e MN |
213 | * @host: The sdhci_host |
214 | * @fld: The field to write to | |
215 | * @val: The value to write | |
216 | * | |
3ea4666e DA |
217 | * This function allows writing to fields in sdhci_arasan_soc_ctl_map. |
218 | * Note that if a field is specified as not available (shift < 0) then | |
219 | * this function will silently return an error code. It will be noisy | |
220 | * and print errors for any other (unexpected) errors. | |
221 | * | |
4908460e | 222 | * Return: 0 on success and error value on error |
3ea4666e DA |
223 | */ |
224 | static int sdhci_arasan_syscon_write(struct sdhci_host *host, | |
225 | const struct sdhci_arasan_soc_ctl_field *fld, | |
226 | u32 val) | |
227 | { | |
228 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
229 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
230 | struct regmap *soc_ctl_base = sdhci_arasan->soc_ctl_base; | |
231 | u32 reg = fld->reg; | |
232 | u16 width = fld->width; | |
233 | s16 shift = fld->shift; | |
234 | int ret; | |
235 | ||
236 | /* | |
237 | * Silently return errors for shift < 0 so caller doesn't have | |
238 | * to check for fields which are optional. For fields that | |
239 | * are required then caller needs to do something special | |
240 | * anyway. | |
241 | */ | |
242 | if (shift < 0) | |
243 | return -EINVAL; | |
244 | ||
245 | if (sdhci_arasan->soc_ctl_map->hiword_update) | |
246 | ret = regmap_write(soc_ctl_base, reg, | |
247 | HIWORD_UPDATE(val, GENMASK(width, 0), | |
248 | shift)); | |
249 | else | |
250 | ret = regmap_update_bits(soc_ctl_base, reg, | |
251 | GENMASK(shift + width, shift), | |
252 | val << shift); | |
253 | ||
254 | /* Yell about (unexpected) regmap errors */ | |
255 | if (ret) | |
256 | pr_warn("%s: Regmap write fail: %d\n", | |
257 | mmc_hostname(host->mmc), ret); | |
258 | ||
259 | return ret; | |
260 | } | |
261 | ||
802ac39a SL |
262 | static void sdhci_arasan_set_clock(struct sdhci_host *host, unsigned int clock) |
263 | { | |
264 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
265 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
f3dafc37 | 266 | struct sdhci_arasan_clk_data *clk_data = &sdhci_arasan->clk_data; |
6fc09244 | 267 | bool ctrl_phy = false; |
802ac39a | 268 | |
b2db9c67 DA |
269 | if (!IS_ERR(sdhci_arasan->phy)) { |
270 | if (!sdhci_arasan->is_phy_on && clock <= PHY_CLK_TOO_SLOW_HZ) { | |
271 | /* | |
272 | * If PHY off, set clock to max speed and power PHY on. | |
273 | * | |
274 | * Although PHY docs apparently suggest power cycling | |
275 | * when changing the clock the PHY doesn't like to be | |
276 | * powered on while at low speeds like those used in ID | |
277 | * mode. Even worse is powering the PHY on while the | |
278 | * clock is off. | |
279 | * | |
280 | * To workaround the PHY limitations, the best we can | |
281 | * do is to power it on at a faster speed and then slam | |
282 | * through low speeds without power cycling. | |
283 | */ | |
284 | sdhci_set_clock(host, host->max_clk); | |
66bad6ed MN |
285 | if (phy_power_on(sdhci_arasan->phy)) { |
286 | pr_err("%s: Cannot power on phy.\n", | |
287 | mmc_hostname(host->mmc)); | |
288 | return; | |
289 | } | |
290 | ||
b2db9c67 DA |
291 | sdhci_arasan->is_phy_on = true; |
292 | ||
293 | /* | |
294 | * We'll now fall through to the below case with | |
295 | * ctrl_phy = false (so we won't turn off/on). The | |
296 | * sdhci_set_clock() will set the real clock. | |
297 | */ | |
298 | } else if (clock > PHY_CLK_TOO_SLOW_HZ) { | |
299 | /* | |
300 | * At higher clock speeds the PHY is fine being power | |
301 | * cycled and docs say you _should_ power cycle when | |
302 | * changing clock speeds. | |
303 | */ | |
304 | ctrl_phy = true; | |
305 | } | |
306 | } | |
802ac39a | 307 | |
b2db9c67 | 308 | if (ctrl_phy && sdhci_arasan->is_phy_on) { |
802ac39a | 309 | phy_power_off(sdhci_arasan->phy); |
b2db9c67 | 310 | sdhci_arasan->is_phy_on = false; |
802ac39a SL |
311 | } |
312 | ||
c0b4e411 MN |
313 | if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN) { |
314 | /* | |
315 | * Some of the Arasan variations might not have timing | |
316 | * requirements met at 25MHz for Default Speed mode, | |
317 | * those controllers work at 19MHz instead. | |
318 | */ | |
319 | if (clock == DEFAULT_SPEED_MAX_DTR) | |
320 | clock = (DEFAULT_SPEED_MAX_DTR * 19) / 25; | |
321 | } | |
322 | ||
f3dafc37 MN |
323 | /* Set the Input and Output Clock Phase Delays */ |
324 | if (clk_data->set_clk_delays) | |
325 | clk_data->set_clk_delays(host); | |
326 | ||
802ac39a SL |
327 | sdhci_set_clock(host, clock); |
328 | ||
3f2c7d5d HG |
329 | if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE) |
330 | /* | |
331 | * Some controllers immediately report SDHCI_CLOCK_INT_STABLE | |
332 | * after enabling the clock even though the clock is not | |
333 | * stable. Trying to use a clock without waiting here results | |
334 | * in EILSEQ while detecting some older/slower cards. The | |
335 | * chosen delay is the maximum delay from sdhci_set_clock. | |
336 | */ | |
337 | msleep(20); | |
338 | ||
6fc09244 | 339 | if (ctrl_phy) { |
66bad6ed MN |
340 | if (phy_power_on(sdhci_arasan->phy)) { |
341 | pr_err("%s: Cannot power on phy.\n", | |
342 | mmc_hostname(host->mmc)); | |
343 | return; | |
344 | } | |
345 | ||
b2db9c67 | 346 | sdhci_arasan->is_phy_on = true; |
802ac39a SL |
347 | } |
348 | } | |
349 | ||
a05c8465 SL |
350 | static void sdhci_arasan_hs400_enhanced_strobe(struct mmc_host *mmc, |
351 | struct mmc_ios *ios) | |
352 | { | |
353 | u32 vendor; | |
354 | struct sdhci_host *host = mmc_priv(mmc); | |
355 | ||
0daf72fe | 356 | vendor = sdhci_readl(host, SDHCI_ARASAN_VENDOR_REGISTER); |
a05c8465 SL |
357 | if (ios->enhanced_strobe) |
358 | vendor |= VENDOR_ENHANCED_STROBE; | |
359 | else | |
360 | vendor &= ~VENDOR_ENHANCED_STROBE; | |
361 | ||
0daf72fe | 362 | sdhci_writel(host, vendor, SDHCI_ARASAN_VENDOR_REGISTER); |
a05c8465 SL |
363 | } |
364 | ||
13d62fd2 | 365 | static void sdhci_arasan_reset(struct sdhci_host *host, u8 mask) |
3794c542 ZB |
366 | { |
367 | u8 ctrl; | |
368 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
369 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
370 | ||
5d249ac3 | 371 | sdhci_and_cqhci_reset(host, mask); |
3794c542 ZB |
372 | |
373 | if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) { | |
374 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); | |
375 | ctrl |= SDHCI_CTRL_CDTEST_INS | SDHCI_CTRL_CDTEST_EN; | |
376 | sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); | |
377 | } | |
378 | } | |
379 | ||
8a3bee9b SL |
380 | static int sdhci_arasan_voltage_switch(struct mmc_host *mmc, |
381 | struct mmc_ios *ios) | |
382 | { | |
383 | switch (ios->signal_voltage) { | |
384 | case MMC_SIGNAL_VOLTAGE_180: | |
385 | /* | |
386 | * Plese don't switch to 1V8 as arasan,5.1 doesn't | |
387 | * actually refer to this setting to indicate the | |
388 | * signal voltage and the state machine will be broken | |
389 | * actually if we force to enable 1V8. That's something | |
390 | * like broken quirk but we could work around here. | |
391 | */ | |
392 | return 0; | |
393 | case MMC_SIGNAL_VOLTAGE_330: | |
394 | case MMC_SIGNAL_VOLTAGE_120: | |
395 | /* We don't support 3V3 and 1V2 */ | |
396 | break; | |
397 | } | |
398 | ||
399 | return -EINVAL; | |
400 | } | |
401 | ||
a81dae3a | 402 | static const struct sdhci_ops sdhci_arasan_ops = { |
802ac39a | 403 | .set_clock = sdhci_arasan_set_clock, |
e3ec3a3d | 404 | .get_max_clock = sdhci_pltfm_clk_get_max_clock, |
8cc35289 | 405 | .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, |
2317f56c | 406 | .set_bus_width = sdhci_set_bus_width, |
3794c542 | 407 | .reset = sdhci_arasan_reset, |
96d7b78c | 408 | .set_uhs_signaling = sdhci_set_uhs_signaling, |
c2c5252c | 409 | .set_power = sdhci_set_power_and_bus_voltage, |
e3ec3a3d SB |
410 | }; |
411 | ||
84362d79 SL |
412 | static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask) |
413 | { | |
414 | int cmd_error = 0; | |
415 | int data_error = 0; | |
416 | ||
417 | if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error)) | |
418 | return intmask; | |
419 | ||
420 | cqhci_irq(host->mmc, intmask, cmd_error, data_error); | |
421 | ||
422 | return 0; | |
423 | } | |
424 | ||
425 | static void sdhci_arasan_dumpregs(struct mmc_host *mmc) | |
426 | { | |
427 | sdhci_dumpregs(mmc_priv(mmc)); | |
428 | } | |
429 | ||
430 | static void sdhci_arasan_cqe_enable(struct mmc_host *mmc) | |
431 | { | |
432 | struct sdhci_host *host = mmc_priv(mmc); | |
433 | u32 reg; | |
434 | ||
435 | reg = sdhci_readl(host, SDHCI_PRESENT_STATE); | |
436 | while (reg & SDHCI_DATA_AVAILABLE) { | |
437 | sdhci_readl(host, SDHCI_BUFFER); | |
438 | reg = sdhci_readl(host, SDHCI_PRESENT_STATE); | |
439 | } | |
440 | ||
441 | sdhci_cqe_enable(mmc); | |
442 | } | |
443 | ||
444 | static const struct cqhci_host_ops sdhci_arasan_cqhci_ops = { | |
445 | .enable = sdhci_arasan_cqe_enable, | |
446 | .disable = sdhci_cqe_disable, | |
447 | .dumpregs = sdhci_arasan_dumpregs, | |
448 | }; | |
449 | ||
450 | static const struct sdhci_ops sdhci_arasan_cqe_ops = { | |
451 | .set_clock = sdhci_arasan_set_clock, | |
452 | .get_max_clock = sdhci_pltfm_clk_get_max_clock, | |
453 | .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, | |
454 | .set_bus_width = sdhci_set_bus_width, | |
455 | .reset = sdhci_arasan_reset, | |
456 | .set_uhs_signaling = sdhci_set_uhs_signaling, | |
c2c5252c | 457 | .set_power = sdhci_set_power_and_bus_voltage, |
84362d79 SL |
458 | .irq = sdhci_arasan_cqhci_irq, |
459 | }; | |
460 | ||
461 | static const struct sdhci_pltfm_data sdhci_arasan_cqe_pdata = { | |
462 | .ops = &sdhci_arasan_cqe_ops, | |
463 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | |
464 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | |
465 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, | |
466 | }; | |
467 | ||
39013f09 R |
468 | static const struct sdhci_pltfm_data sdhci_arasan_thunderbay_pdata = { |
469 | .ops = &sdhci_arasan_cqe_ops, | |
470 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | |
471 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | |
472 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | | |
473 | SDHCI_QUIRK2_STOP_WITH_TC | | |
474 | SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400, | |
475 | }; | |
476 | ||
e3ec3a3d SB |
477 | #ifdef CONFIG_PM_SLEEP |
478 | /** | |
479 | * sdhci_arasan_suspend - Suspend method for the driver | |
480 | * @dev: Address of the device structure | |
e3ec3a3d SB |
481 | * |
482 | * Put the device in a low power state. | |
4908460e MN |
483 | * |
484 | * Return: 0 on success and error value on error | |
e3ec3a3d SB |
485 | */ |
486 | static int sdhci_arasan_suspend(struct device *dev) | |
487 | { | |
970f2d90 | 488 | struct sdhci_host *host = dev_get_drvdata(dev); |
e3ec3a3d | 489 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
89211418 | 490 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
e3ec3a3d SB |
491 | int ret; |
492 | ||
d38dcad4 AH |
493 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
494 | mmc_retune_needed(host->mmc); | |
495 | ||
84362d79 SL |
496 | if (sdhci_arasan->has_cqe) { |
497 | ret = cqhci_suspend(host->mmc); | |
498 | if (ret) | |
499 | return ret; | |
500 | } | |
501 | ||
e3ec3a3d SB |
502 | ret = sdhci_suspend_host(host); |
503 | if (ret) | |
504 | return ret; | |
505 | ||
b2db9c67 | 506 | if (!IS_ERR(sdhci_arasan->phy) && sdhci_arasan->is_phy_on) { |
91aa3661 SL |
507 | ret = phy_power_off(sdhci_arasan->phy); |
508 | if (ret) { | |
509 | dev_err(dev, "Cannot power off phy.\n"); | |
66bad6ed MN |
510 | if (sdhci_resume_host(host)) |
511 | dev_err(dev, "Cannot resume host.\n"); | |
512 | ||
91aa3661 SL |
513 | return ret; |
514 | } | |
b2db9c67 | 515 | sdhci_arasan->is_phy_on = false; |
91aa3661 SL |
516 | } |
517 | ||
e3ec3a3d SB |
518 | clk_disable(pltfm_host->clk); |
519 | clk_disable(sdhci_arasan->clk_ahb); | |
520 | ||
521 | return 0; | |
522 | } | |
523 | ||
524 | /** | |
525 | * sdhci_arasan_resume - Resume method for the driver | |
526 | * @dev: Address of the device structure | |
e3ec3a3d SB |
527 | * |
528 | * Resume operation after suspend | |
4908460e MN |
529 | * |
530 | * Return: 0 on success and error value on error | |
e3ec3a3d SB |
531 | */ |
532 | static int sdhci_arasan_resume(struct device *dev) | |
533 | { | |
970f2d90 | 534 | struct sdhci_host *host = dev_get_drvdata(dev); |
e3ec3a3d | 535 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
89211418 | 536 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
e3ec3a3d SB |
537 | int ret; |
538 | ||
539 | ret = clk_enable(sdhci_arasan->clk_ahb); | |
540 | if (ret) { | |
541 | dev_err(dev, "Cannot enable AHB clock.\n"); | |
542 | return ret; | |
543 | } | |
544 | ||
545 | ret = clk_enable(pltfm_host->clk); | |
546 | if (ret) { | |
547 | dev_err(dev, "Cannot enable SD clock.\n"); | |
e3ec3a3d SB |
548 | return ret; |
549 | } | |
550 | ||
b2db9c67 | 551 | if (!IS_ERR(sdhci_arasan->phy) && host->mmc->actual_clock) { |
91aa3661 SL |
552 | ret = phy_power_on(sdhci_arasan->phy); |
553 | if (ret) { | |
554 | dev_err(dev, "Cannot power on phy.\n"); | |
555 | return ret; | |
556 | } | |
b2db9c67 | 557 | sdhci_arasan->is_phy_on = true; |
91aa3661 SL |
558 | } |
559 | ||
84362d79 SL |
560 | ret = sdhci_resume_host(host); |
561 | if (ret) { | |
562 | dev_err(dev, "Cannot resume host.\n"); | |
563 | return ret; | |
564 | } | |
565 | ||
566 | if (sdhci_arasan->has_cqe) | |
567 | return cqhci_resume(host->mmc); | |
568 | ||
569 | return 0; | |
e3ec3a3d SB |
570 | } |
571 | #endif /* ! CONFIG_PM_SLEEP */ | |
572 | ||
573 | static SIMPLE_DEV_PM_OPS(sdhci_arasan_dev_pm_ops, sdhci_arasan_suspend, | |
574 | sdhci_arasan_resume); | |
575 | ||
c390f211 DA |
576 | /** |
577 | * sdhci_arasan_sdcardclk_recalc_rate - Return the card clock rate | |
578 | * | |
4908460e MN |
579 | * @hw: Pointer to the hardware clock structure. |
580 | * @parent_rate: The parent rate (should be rate of clk_xin). | |
581 | * | |
c390f211 DA |
582 | * Return the current actual rate of the SD card clock. This can be used |
583 | * to communicate with out PHY. | |
584 | * | |
4908460e | 585 | * Return: The card clock rate. |
c390f211 DA |
586 | */ |
587 | static unsigned long sdhci_arasan_sdcardclk_recalc_rate(struct clk_hw *hw, | |
588 | unsigned long parent_rate) | |
c390f211 | 589 | { |
e1463618 MN |
590 | struct sdhci_arasan_clk_data *clk_data = |
591 | container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); | |
c390f211 | 592 | struct sdhci_arasan_data *sdhci_arasan = |
e1463618 | 593 | container_of(clk_data, struct sdhci_arasan_data, clk_data); |
c390f211 DA |
594 | struct sdhci_host *host = sdhci_arasan->host; |
595 | ||
596 | return host->mmc->actual_clock; | |
597 | } | |
598 | ||
599 | static const struct clk_ops arasan_sdcardclk_ops = { | |
600 | .recalc_rate = sdhci_arasan_sdcardclk_recalc_rate, | |
601 | }; | |
602 | ||
07a14d1d MN |
603 | /** |
604 | * sdhci_arasan_sampleclk_recalc_rate - Return the sampling clock rate | |
605 | * | |
4908460e MN |
606 | * @hw: Pointer to the hardware clock structure. |
607 | * @parent_rate: The parent rate (should be rate of clk_xin). | |
608 | * | |
07a14d1d MN |
609 | * Return the current actual rate of the sampling clock. This can be used |
610 | * to communicate with out PHY. | |
611 | * | |
4908460e | 612 | * Return: The sample clock rate. |
07a14d1d MN |
613 | */ |
614 | static unsigned long sdhci_arasan_sampleclk_recalc_rate(struct clk_hw *hw, | |
615 | unsigned long parent_rate) | |
07a14d1d MN |
616 | { |
617 | struct sdhci_arasan_clk_data *clk_data = | |
618 | container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw); | |
619 | struct sdhci_arasan_data *sdhci_arasan = | |
620 | container_of(clk_data, struct sdhci_arasan_data, clk_data); | |
621 | struct sdhci_host *host = sdhci_arasan->host; | |
622 | ||
623 | return host->mmc->actual_clock; | |
624 | } | |
625 | ||
626 | static const struct clk_ops arasan_sampleclk_ops = { | |
627 | .recalc_rate = sdhci_arasan_sampleclk_recalc_rate, | |
628 | }; | |
629 | ||
a5c8b2ae MN |
630 | /** |
631 | * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays | |
632 | * | |
4908460e MN |
633 | * @hw: Pointer to the hardware clock structure. |
634 | * @degrees: The clock phase shift between 0 - 359. | |
635 | * | |
a5c8b2ae MN |
636 | * Set the SD Output Clock Tap Delays for Output path |
637 | * | |
a5c8b2ae MN |
638 | * Return: 0 on success and error value on error |
639 | */ | |
640 | static int sdhci_zynqmp_sdcardclk_set_phase(struct clk_hw *hw, int degrees) | |
a5c8b2ae MN |
641 | { |
642 | struct sdhci_arasan_clk_data *clk_data = | |
643 | container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); | |
644 | struct sdhci_arasan_data *sdhci_arasan = | |
645 | container_of(clk_data, struct sdhci_arasan_data, clk_data); | |
646 | struct sdhci_host *host = sdhci_arasan->host; | |
a5c8b2ae MN |
647 | const char *clk_name = clk_hw_get_name(hw); |
648 | u32 node_id = !strcmp(clk_name, "clk_out_sd0") ? NODE_SD_0 : NODE_SD_1; | |
649 | u8 tap_delay, tap_max = 0; | |
650 | int ret; | |
651 | ||
9e953432 MN |
652 | /* This is applicable for SDHCI_SPEC_300 and above */ |
653 | if (host->version < SDHCI_SPEC_300) | |
a5c8b2ae MN |
654 | return 0; |
655 | ||
656 | switch (host->timing) { | |
657 | case MMC_TIMING_MMC_HS: | |
658 | case MMC_TIMING_SD_HS: | |
659 | case MMC_TIMING_UHS_SDR25: | |
660 | case MMC_TIMING_UHS_DDR50: | |
661 | case MMC_TIMING_MMC_DDR52: | |
662 | /* For 50MHz clock, 30 Taps are available */ | |
663 | tap_max = 30; | |
664 | break; | |
665 | case MMC_TIMING_UHS_SDR50: | |
666 | /* For 100MHz clock, 15 Taps are available */ | |
667 | tap_max = 15; | |
668 | break; | |
669 | case MMC_TIMING_UHS_SDR104: | |
670 | case MMC_TIMING_MMC_HS200: | |
671 | /* For 200MHz clock, 8 Taps are available */ | |
672 | tap_max = 8; | |
a3096ec6 | 673 | break; |
a5c8b2ae MN |
674 | default: |
675 | break; | |
676 | } | |
677 | ||
678 | tap_delay = (degrees * tap_max) / 360; | |
679 | ||
680 | /* Set the Clock Phase */ | |
426c8d85 | 681 | ret = zynqmp_pm_set_sd_tapdelay(node_id, PM_TAPDELAY_OUTPUT, tap_delay); |
a5c8b2ae MN |
682 | if (ret) |
683 | pr_err("Error setting Output Tap Delay\n"); | |
684 | ||
d06d60d5 MN |
685 | /* Release DLL Reset */ |
686 | zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_RELEASE); | |
687 | ||
a5c8b2ae MN |
688 | return ret; |
689 | } | |
690 | ||
691 | static const struct clk_ops zynqmp_sdcardclk_ops = { | |
692 | .recalc_rate = sdhci_arasan_sdcardclk_recalc_rate, | |
693 | .set_phase = sdhci_zynqmp_sdcardclk_set_phase, | |
694 | }; | |
695 | ||
696 | /** | |
697 | * sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Clock Tap Delays | |
698 | * | |
4908460e MN |
699 | * @hw: Pointer to the hardware clock structure. |
700 | * @degrees: The clock phase shift between 0 - 359. | |
701 | * | |
a5c8b2ae MN |
702 | * Set the SD Input Clock Tap Delays for Input path |
703 | * | |
a5c8b2ae MN |
704 | * Return: 0 on success and error value on error |
705 | */ | |
706 | static int sdhci_zynqmp_sampleclk_set_phase(struct clk_hw *hw, int degrees) | |
a5c8b2ae MN |
707 | { |
708 | struct sdhci_arasan_clk_data *clk_data = | |
709 | container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw); | |
710 | struct sdhci_arasan_data *sdhci_arasan = | |
711 | container_of(clk_data, struct sdhci_arasan_data, clk_data); | |
712 | struct sdhci_host *host = sdhci_arasan->host; | |
a5c8b2ae MN |
713 | const char *clk_name = clk_hw_get_name(hw); |
714 | u32 node_id = !strcmp(clk_name, "clk_in_sd0") ? NODE_SD_0 : NODE_SD_1; | |
715 | u8 tap_delay, tap_max = 0; | |
716 | int ret; | |
717 | ||
9e953432 MN |
718 | /* This is applicable for SDHCI_SPEC_300 and above */ |
719 | if (host->version < SDHCI_SPEC_300) | |
a5c8b2ae MN |
720 | return 0; |
721 | ||
d06d60d5 MN |
722 | /* Assert DLL Reset */ |
723 | zynqmp_pm_sd_dll_reset(node_id, PM_DLL_RESET_ASSERT); | |
724 | ||
a5c8b2ae MN |
725 | switch (host->timing) { |
726 | case MMC_TIMING_MMC_HS: | |
727 | case MMC_TIMING_SD_HS: | |
728 | case MMC_TIMING_UHS_SDR25: | |
729 | case MMC_TIMING_UHS_DDR50: | |
730 | case MMC_TIMING_MMC_DDR52: | |
731 | /* For 50MHz clock, 120 Taps are available */ | |
732 | tap_max = 120; | |
733 | break; | |
734 | case MMC_TIMING_UHS_SDR50: | |
735 | /* For 100MHz clock, 60 Taps are available */ | |
736 | tap_max = 60; | |
737 | break; | |
738 | case MMC_TIMING_UHS_SDR104: | |
739 | case MMC_TIMING_MMC_HS200: | |
740 | /* For 200MHz clock, 30 Taps are available */ | |
741 | tap_max = 30; | |
a3096ec6 | 742 | break; |
a5c8b2ae MN |
743 | default: |
744 | break; | |
745 | } | |
746 | ||
747 | tap_delay = (degrees * tap_max) / 360; | |
748 | ||
749 | /* Set the Clock Phase */ | |
426c8d85 | 750 | ret = zynqmp_pm_set_sd_tapdelay(node_id, PM_TAPDELAY_INPUT, tap_delay); |
a5c8b2ae MN |
751 | if (ret) |
752 | pr_err("Error setting Input Tap Delay\n"); | |
753 | ||
754 | return ret; | |
755 | } | |
756 | ||
757 | static const struct clk_ops zynqmp_sampleclk_ops = { | |
758 | .recalc_rate = sdhci_arasan_sampleclk_recalc_rate, | |
759 | .set_phase = sdhci_zynqmp_sampleclk_set_phase, | |
760 | }; | |
761 | ||
1a470721 MN |
762 | /** |
763 | * sdhci_versal_sdcardclk_set_phase - Set the SD Output Clock Tap Delays | |
764 | * | |
4908460e MN |
765 | * @hw: Pointer to the hardware clock structure. |
766 | * @degrees: The clock phase shift between 0 - 359. | |
767 | * | |
1a470721 MN |
768 | * Set the SD Output Clock Tap Delays for Output path |
769 | * | |
1a470721 MN |
770 | * Return: 0 on success and error value on error |
771 | */ | |
772 | static int sdhci_versal_sdcardclk_set_phase(struct clk_hw *hw, int degrees) | |
773 | { | |
774 | struct sdhci_arasan_clk_data *clk_data = | |
775 | container_of(hw, struct sdhci_arasan_clk_data, sdcardclk_hw); | |
776 | struct sdhci_arasan_data *sdhci_arasan = | |
777 | container_of(clk_data, struct sdhci_arasan_data, clk_data); | |
778 | struct sdhci_host *host = sdhci_arasan->host; | |
779 | u8 tap_delay, tap_max = 0; | |
1a470721 | 780 | |
9e953432 MN |
781 | /* This is applicable for SDHCI_SPEC_300 and above */ |
782 | if (host->version < SDHCI_SPEC_300) | |
1a470721 MN |
783 | return 0; |
784 | ||
785 | switch (host->timing) { | |
786 | case MMC_TIMING_MMC_HS: | |
787 | case MMC_TIMING_SD_HS: | |
788 | case MMC_TIMING_UHS_SDR25: | |
789 | case MMC_TIMING_UHS_DDR50: | |
790 | case MMC_TIMING_MMC_DDR52: | |
791 | /* For 50MHz clock, 30 Taps are available */ | |
792 | tap_max = 30; | |
793 | break; | |
794 | case MMC_TIMING_UHS_SDR50: | |
795 | /* For 100MHz clock, 15 Taps are available */ | |
796 | tap_max = 15; | |
797 | break; | |
798 | case MMC_TIMING_UHS_SDR104: | |
799 | case MMC_TIMING_MMC_HS200: | |
800 | /* For 200MHz clock, 8 Taps are available */ | |
801 | tap_max = 8; | |
a3096ec6 | 802 | break; |
1a470721 MN |
803 | default: |
804 | break; | |
805 | } | |
806 | ||
807 | tap_delay = (degrees * tap_max) / 360; | |
808 | ||
809 | /* Set the Clock Phase */ | |
810 | if (tap_delay) { | |
811 | u32 regval; | |
812 | ||
813 | regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); | |
814 | regval |= SDHCI_OTAPDLY_ENABLE; | |
815 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); | |
d338c6d0 | 816 | regval &= ~SDHCI_ARASAN_OTAPDLY_SEL_MASK; |
1a470721 MN |
817 | regval |= tap_delay; |
818 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); | |
819 | } | |
820 | ||
098c408b | 821 | return 0; |
1a470721 MN |
822 | } |
823 | ||
824 | static const struct clk_ops versal_sdcardclk_ops = { | |
825 | .recalc_rate = sdhci_arasan_sdcardclk_recalc_rate, | |
826 | .set_phase = sdhci_versal_sdcardclk_set_phase, | |
827 | }; | |
828 | ||
829 | /** | |
830 | * sdhci_versal_sampleclk_set_phase - Set the SD Input Clock Tap Delays | |
831 | * | |
4908460e MN |
832 | * @hw: Pointer to the hardware clock structure. |
833 | * @degrees: The clock phase shift between 0 - 359. | |
834 | * | |
1a470721 MN |
835 | * Set the SD Input Clock Tap Delays for Input path |
836 | * | |
1a470721 MN |
837 | * Return: 0 on success and error value on error |
838 | */ | |
839 | static int sdhci_versal_sampleclk_set_phase(struct clk_hw *hw, int degrees) | |
840 | { | |
841 | struct sdhci_arasan_clk_data *clk_data = | |
842 | container_of(hw, struct sdhci_arasan_clk_data, sampleclk_hw); | |
843 | struct sdhci_arasan_data *sdhci_arasan = | |
844 | container_of(clk_data, struct sdhci_arasan_data, clk_data); | |
845 | struct sdhci_host *host = sdhci_arasan->host; | |
846 | u8 tap_delay, tap_max = 0; | |
1a470721 | 847 | |
9e953432 MN |
848 | /* This is applicable for SDHCI_SPEC_300 and above */ |
849 | if (host->version < SDHCI_SPEC_300) | |
1a470721 MN |
850 | return 0; |
851 | ||
852 | switch (host->timing) { | |
853 | case MMC_TIMING_MMC_HS: | |
854 | case MMC_TIMING_SD_HS: | |
855 | case MMC_TIMING_UHS_SDR25: | |
856 | case MMC_TIMING_UHS_DDR50: | |
857 | case MMC_TIMING_MMC_DDR52: | |
858 | /* For 50MHz clock, 120 Taps are available */ | |
859 | tap_max = 120; | |
860 | break; | |
861 | case MMC_TIMING_UHS_SDR50: | |
862 | /* For 100MHz clock, 60 Taps are available */ | |
863 | tap_max = 60; | |
864 | break; | |
865 | case MMC_TIMING_UHS_SDR104: | |
866 | case MMC_TIMING_MMC_HS200: | |
867 | /* For 200MHz clock, 30 Taps are available */ | |
868 | tap_max = 30; | |
a3096ec6 | 869 | break; |
1a470721 MN |
870 | default: |
871 | break; | |
872 | } | |
873 | ||
874 | tap_delay = (degrees * tap_max) / 360; | |
875 | ||
876 | /* Set the Clock Phase */ | |
877 | if (tap_delay) { | |
878 | u32 regval; | |
879 | ||
880 | regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
881 | regval |= SDHCI_ITAPDLY_CHGWIN; | |
882 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
883 | regval |= SDHCI_ITAPDLY_ENABLE; | |
884 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
d338c6d0 | 885 | regval &= ~SDHCI_ARASAN_ITAPDLY_SEL_MASK; |
1a470721 MN |
886 | regval |= tap_delay; |
887 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
888 | regval &= ~SDHCI_ITAPDLY_CHGWIN; | |
889 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
890 | } | |
891 | ||
098c408b | 892 | return 0; |
1a470721 MN |
893 | } |
894 | ||
895 | static const struct clk_ops versal_sampleclk_ops = { | |
896 | .recalc_rate = sdhci_arasan_sampleclk_recalc_rate, | |
897 | .set_phase = sdhci_versal_sampleclk_set_phase, | |
898 | }; | |
899 | ||
8d2e3343 MN |
900 | static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u32 deviceid) |
901 | { | |
8d2e3343 MN |
902 | u16 clk; |
903 | ||
904 | clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); | |
905 | clk &= ~(SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_INT_EN); | |
906 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | |
907 | ||
908 | /* Issue DLL Reset */ | |
426c8d85 | 909 | zynqmp_pm_sd_dll_reset(deviceid, PM_DLL_RESET_PULSE); |
8d2e3343 MN |
910 | |
911 | clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); | |
912 | ||
913 | sdhci_enable_clk(host, clk); | |
914 | } | |
915 | ||
916 | static int arasan_zynqmp_execute_tuning(struct mmc_host *mmc, u32 opcode) | |
917 | { | |
918 | struct sdhci_host *host = mmc_priv(mmc); | |
919 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
920 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
921 | struct clk_hw *hw = &sdhci_arasan->clk_data.sdcardclk_hw; | |
922 | const char *clk_name = clk_hw_get_name(hw); | |
923 | u32 device_id = !strcmp(clk_name, "clk_out_sd0") ? NODE_SD_0 : | |
924 | NODE_SD_1; | |
925 | int err; | |
926 | ||
256e4e4e MN |
927 | /* ZynqMP SD controller does not perform auto tuning in DDR50 mode */ |
928 | if (mmc->ios.timing == MMC_TIMING_UHS_DDR50) | |
929 | return 0; | |
930 | ||
8d2e3343 MN |
931 | arasan_zynqmp_dll_reset(host, device_id); |
932 | ||
933 | err = sdhci_execute_tuning(mmc, opcode); | |
934 | if (err) | |
935 | return err; | |
936 | ||
937 | arasan_zynqmp_dll_reset(host, device_id); | |
938 | ||
939 | return 0; | |
940 | } | |
941 | ||
b2ca77c9 SL |
942 | /** |
943 | * sdhci_arasan_update_clockmultiplier - Set corecfg_clockmultiplier | |
944 | * | |
4908460e MN |
945 | * @host: The sdhci_host |
946 | * @value: The value to write | |
947 | * | |
b2ca77c9 SL |
948 | * The corecfg_clockmultiplier is supposed to contain clock multiplier |
949 | * value of programmable clock generator. | |
950 | * | |
951 | * NOTES: | |
952 | * - Many existing devices don't seem to do this and work fine. To keep | |
953 | * compatibility for old hardware where the device tree doesn't provide a | |
954 | * register map, this function is a noop if a soc_ctl_map hasn't been provided | |
955 | * for this platform. | |
956 | * - The value of corecfg_clockmultiplier should sync with that of corresponding | |
957 | * value reading from sdhci_capability_register. So this function is called | |
958 | * once at probe time and never called again. | |
b2ca77c9 SL |
959 | */ |
960 | static void sdhci_arasan_update_clockmultiplier(struct sdhci_host *host, | |
961 | u32 value) | |
962 | { | |
963 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
964 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
965 | const struct sdhci_arasan_soc_ctl_map *soc_ctl_map = | |
966 | sdhci_arasan->soc_ctl_map; | |
967 | ||
968 | /* Having a map is optional */ | |
969 | if (!soc_ctl_map) | |
970 | return; | |
971 | ||
972 | /* If we have a map, we expect to have a syscon */ | |
973 | if (!sdhci_arasan->soc_ctl_base) { | |
974 | pr_warn("%s: Have regmap, but no soc-ctl-syscon\n", | |
975 | mmc_hostname(host->mmc)); | |
976 | return; | |
977 | } | |
978 | ||
979 | sdhci_arasan_syscon_write(host, &soc_ctl_map->clockmultiplier, value); | |
980 | } | |
981 | ||
3ea4666e DA |
982 | /** |
983 | * sdhci_arasan_update_baseclkfreq - Set corecfg_baseclkfreq | |
984 | * | |
4908460e MN |
985 | * @host: The sdhci_host |
986 | * | |
3ea4666e DA |
987 | * The corecfg_baseclkfreq is supposed to contain the MHz of clk_xin. This |
988 | * function can be used to make that happen. | |
989 | * | |
990 | * NOTES: | |
991 | * - Many existing devices don't seem to do this and work fine. To keep | |
992 | * compatibility for old hardware where the device tree doesn't provide a | |
993 | * register map, this function is a noop if a soc_ctl_map hasn't been provided | |
994 | * for this platform. | |
995 | * - It's assumed that clk_xin is not dynamic and that we use the SDHCI divider | |
996 | * to achieve lower clock rates. That means that this function is called once | |
997 | * at probe time and never called again. | |
3ea4666e DA |
998 | */ |
999 | static void sdhci_arasan_update_baseclkfreq(struct sdhci_host *host) | |
1000 | { | |
1001 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1002 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
1003 | const struct sdhci_arasan_soc_ctl_map *soc_ctl_map = | |
1004 | sdhci_arasan->soc_ctl_map; | |
462f58fd | 1005 | u32 mhz = DIV_ROUND_CLOSEST_ULL(clk_get_rate(pltfm_host->clk), 1000000); |
3ea4666e DA |
1006 | |
1007 | /* Having a map is optional */ | |
1008 | if (!soc_ctl_map) | |
1009 | return; | |
1010 | ||
1011 | /* If we have a map, we expect to have a syscon */ | |
1012 | if (!sdhci_arasan->soc_ctl_base) { | |
1013 | pr_warn("%s: Have regmap, but no soc-ctl-syscon\n", | |
1014 | mmc_hostname(host->mmc)); | |
1015 | return; | |
1016 | } | |
1017 | ||
1018 | sdhci_arasan_syscon_write(host, &soc_ctl_map->baseclkfreq, mhz); | |
1019 | } | |
1020 | ||
f3dafc37 MN |
1021 | static void sdhci_arasan_set_clk_delays(struct sdhci_host *host) |
1022 | { | |
1023 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1024 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
1025 | struct sdhci_arasan_clk_data *clk_data = &sdhci_arasan->clk_data; | |
1026 | ||
1027 | clk_set_phase(clk_data->sampleclk, | |
1028 | clk_data->clk_phase_in[host->timing]); | |
1029 | clk_set_phase(clk_data->sdcardclk, | |
1030 | clk_data->clk_phase_out[host->timing]); | |
1031 | } | |
1032 | ||
1033 | static void arasan_dt_read_clk_phase(struct device *dev, | |
1034 | struct sdhci_arasan_clk_data *clk_data, | |
1035 | unsigned int timing, const char *prop) | |
1036 | { | |
1037 | struct device_node *np = dev->of_node; | |
1038 | ||
4dd7080a | 1039 | u32 clk_phase[2] = {0}; |
5c7e468a | 1040 | int ret; |
f3dafc37 MN |
1041 | |
1042 | /* | |
1043 | * Read Tap Delay values from DT, if the DT does not contain the | |
1044 | * Tap Values then use the pre-defined values. | |
1045 | */ | |
5c7e468a SKP |
1046 | ret = of_property_read_variable_u32_array(np, prop, &clk_phase[0], |
1047 | 2, 0); | |
1048 | if (ret < 0) { | |
f3dafc37 MN |
1049 | dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n", |
1050 | prop, clk_data->clk_phase_in[timing], | |
1051 | clk_data->clk_phase_out[timing]); | |
1052 | return; | |
1053 | } | |
1054 | ||
1055 | /* The values read are Input and Output Clock Delays in order */ | |
1056 | clk_data->clk_phase_in[timing] = clk_phase[0]; | |
1057 | clk_data->clk_phase_out[timing] = clk_phase[1]; | |
1058 | } | |
1059 | ||
1060 | /** | |
1061 | * arasan_dt_parse_clk_phases - Read Clock Delay values from DT | |
1062 | * | |
f3dafc37 MN |
1063 | * @dev: Pointer to our struct device. |
1064 | * @clk_data: Pointer to the Clock Data structure | |
4908460e MN |
1065 | * |
1066 | * Called at initialization to parse the values of Clock Delays. | |
f3dafc37 MN |
1067 | */ |
1068 | static void arasan_dt_parse_clk_phases(struct device *dev, | |
1069 | struct sdhci_arasan_clk_data *clk_data) | |
1070 | { | |
a5c8b2ae MN |
1071 | u32 mio_bank = 0; |
1072 | int i; | |
1073 | ||
f3dafc37 MN |
1074 | /* |
1075 | * This has been kept as a pointer and is assigned a function here. | |
1076 | * So that different controller variants can assign their own handling | |
1077 | * function. | |
1078 | */ | |
1079 | clk_data->set_clk_delays = sdhci_arasan_set_clk_delays; | |
1080 | ||
a5c8b2ae | 1081 | if (of_device_is_compatible(dev->of_node, "xlnx,zynqmp-8.9a")) { |
88e1d0b1 MN |
1082 | u32 zynqmp_iclk_phase[MMC_TIMING_MMC_HS400 + 1] = |
1083 | ZYNQMP_ICLK_PHASE; | |
1084 | u32 zynqmp_oclk_phase[MMC_TIMING_MMC_HS400 + 1] = | |
1085 | ZYNQMP_OCLK_PHASE; | |
a5c8b2ae MN |
1086 | |
1087 | of_property_read_u32(dev->of_node, "xlnx,mio-bank", &mio_bank); | |
1088 | if (mio_bank == 2) { | |
88e1d0b1 MN |
1089 | zynqmp_oclk_phase[MMC_TIMING_UHS_SDR104] = 90; |
1090 | zynqmp_oclk_phase[MMC_TIMING_MMC_HS200] = 90; | |
a5c8b2ae MN |
1091 | } |
1092 | ||
1093 | for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) { | |
88e1d0b1 MN |
1094 | clk_data->clk_phase_in[i] = zynqmp_iclk_phase[i]; |
1095 | clk_data->clk_phase_out[i] = zynqmp_oclk_phase[i]; | |
a5c8b2ae MN |
1096 | } |
1097 | } | |
1098 | ||
1a470721 | 1099 | if (of_device_is_compatible(dev->of_node, "xlnx,versal-8.9a")) { |
88e1d0b1 MN |
1100 | u32 versal_iclk_phase[MMC_TIMING_MMC_HS400 + 1] = |
1101 | VERSAL_ICLK_PHASE; | |
1102 | u32 versal_oclk_phase[MMC_TIMING_MMC_HS400 + 1] = | |
1103 | VERSAL_OCLK_PHASE; | |
1a470721 MN |
1104 | |
1105 | for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) { | |
88e1d0b1 MN |
1106 | clk_data->clk_phase_in[i] = versal_iclk_phase[i]; |
1107 | clk_data->clk_phase_out[i] = versal_oclk_phase[i]; | |
1a470721 MN |
1108 | } |
1109 | } | |
1110 | ||
f3dafc37 MN |
1111 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_LEGACY, |
1112 | "clk-phase-legacy"); | |
1113 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_HS, | |
1114 | "clk-phase-mmc-hs"); | |
1115 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_SD_HS, | |
1116 | "clk-phase-sd-hs"); | |
1117 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_UHS_SDR12, | |
1118 | "clk-phase-uhs-sdr12"); | |
1119 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_UHS_SDR25, | |
1120 | "clk-phase-uhs-sdr25"); | |
1121 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_UHS_SDR50, | |
1122 | "clk-phase-uhs-sdr50"); | |
1123 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_UHS_SDR104, | |
1124 | "clk-phase-uhs-sdr104"); | |
1125 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_UHS_DDR50, | |
1126 | "clk-phase-uhs-ddr50"); | |
1127 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_DDR52, | |
1128 | "clk-phase-mmc-ddr52"); | |
1129 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_HS200, | |
1130 | "clk-phase-mmc-hs200"); | |
1131 | arasan_dt_read_clk_phase(dev, clk_data, MMC_TIMING_MMC_HS400, | |
1132 | "clk-phase-mmc-hs400"); | |
1133 | } | |
1134 | ||
37d3ee7c MN |
1135 | static const struct sdhci_pltfm_data sdhci_arasan_pdata = { |
1136 | .ops = &sdhci_arasan_ops, | |
1137 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | |
1138 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | |
1139 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | | |
1140 | SDHCI_QUIRK2_STOP_WITH_TC, | |
1141 | }; | |
1142 | ||
16ada730 MN |
1143 | static const struct sdhci_arasan_clk_ops arasan_clk_ops = { |
1144 | .sdcardclk_ops = &arasan_sdcardclk_ops, | |
1145 | .sampleclk_ops = &arasan_sampleclk_ops, | |
1146 | }; | |
1147 | ||
37d3ee7c MN |
1148 | static struct sdhci_arasan_of_data sdhci_arasan_generic_data = { |
1149 | .pdata = &sdhci_arasan_pdata, | |
16ada730 | 1150 | .clk_ops = &arasan_clk_ops, |
37d3ee7c MN |
1151 | }; |
1152 | ||
39013f09 R |
1153 | static const struct sdhci_arasan_of_data sdhci_arasan_thunderbay_data = { |
1154 | .soc_ctl_map = &thunderbay_soc_ctl_map, | |
1155 | .pdata = &sdhci_arasan_thunderbay_pdata, | |
1156 | .clk_ops = &arasan_clk_ops, | |
1157 | }; | |
1158 | ||
36c6aada WAZ |
1159 | static const struct sdhci_pltfm_data sdhci_keembay_emmc_pdata = { |
1160 | .ops = &sdhci_arasan_cqe_ops, | |
1161 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | | |
1162 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | |
1163 | SDHCI_QUIRK_NO_LED | | |
1164 | SDHCI_QUIRK_32BIT_DMA_ADDR | | |
1165 | SDHCI_QUIRK_32BIT_DMA_SIZE | | |
1166 | SDHCI_QUIRK_32BIT_ADMA_SIZE, | |
1167 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | |
1168 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | | |
1169 | SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 | | |
1170 | SDHCI_QUIRK2_STOP_WITH_TC | | |
1171 | SDHCI_QUIRK2_BROKEN_64_BIT_DMA, | |
1172 | }; | |
1173 | ||
1174 | static const struct sdhci_pltfm_data sdhci_keembay_sd_pdata = { | |
1175 | .ops = &sdhci_arasan_ops, | |
1176 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | | |
1177 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | |
1178 | SDHCI_QUIRK_NO_LED | | |
1179 | SDHCI_QUIRK_32BIT_DMA_ADDR | | |
1180 | SDHCI_QUIRK_32BIT_DMA_SIZE | | |
1181 | SDHCI_QUIRK_32BIT_ADMA_SIZE, | |
1182 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | |
1183 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | | |
1184 | SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON | | |
1185 | SDHCI_QUIRK2_STOP_WITH_TC | | |
1186 | SDHCI_QUIRK2_BROKEN_64_BIT_DMA, | |
1187 | }; | |
1188 | ||
1189 | static const struct sdhci_pltfm_data sdhci_keembay_sdio_pdata = { | |
1190 | .ops = &sdhci_arasan_ops, | |
1191 | .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | | |
1192 | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | | |
1193 | SDHCI_QUIRK_NO_LED | | |
1194 | SDHCI_QUIRK_32BIT_DMA_ADDR | | |
1195 | SDHCI_QUIRK_32BIT_DMA_SIZE | | |
1196 | SDHCI_QUIRK_32BIT_ADMA_SIZE, | |
1197 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | |
1198 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | | |
1199 | SDHCI_QUIRK2_HOST_OFF_CARD_ON | | |
1200 | SDHCI_QUIRK2_BROKEN_64_BIT_DMA, | |
1201 | }; | |
1202 | ||
37d3ee7c MN |
1203 | static struct sdhci_arasan_of_data sdhci_arasan_rk3399_data = { |
1204 | .soc_ctl_map = &rk3399_soc_ctl_map, | |
1205 | .pdata = &sdhci_arasan_cqe_pdata, | |
16ada730 | 1206 | .clk_ops = &arasan_clk_ops, |
37d3ee7c MN |
1207 | }; |
1208 | ||
1209 | static struct sdhci_arasan_of_data intel_lgm_emmc_data = { | |
1210 | .soc_ctl_map = &intel_lgm_emmc_soc_ctl_map, | |
1211 | .pdata = &sdhci_arasan_cqe_pdata, | |
16ada730 | 1212 | .clk_ops = &arasan_clk_ops, |
37d3ee7c MN |
1213 | }; |
1214 | ||
1215 | static struct sdhci_arasan_of_data intel_lgm_sdxc_data = { | |
1216 | .soc_ctl_map = &intel_lgm_sdxc_soc_ctl_map, | |
1217 | .pdata = &sdhci_arasan_cqe_pdata, | |
16ada730 | 1218 | .clk_ops = &arasan_clk_ops, |
37d3ee7c MN |
1219 | }; |
1220 | ||
1221 | static const struct sdhci_pltfm_data sdhci_arasan_zynqmp_pdata = { | |
1222 | .ops = &sdhci_arasan_ops, | |
1223 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | |
1224 | SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN | | |
1225 | SDHCI_QUIRK2_STOP_WITH_TC, | |
1226 | }; | |
1227 | ||
16ada730 MN |
1228 | static const struct sdhci_arasan_clk_ops zynqmp_clk_ops = { |
1229 | .sdcardclk_ops = &zynqmp_sdcardclk_ops, | |
1230 | .sampleclk_ops = &zynqmp_sampleclk_ops, | |
1231 | }; | |
1232 | ||
37d3ee7c MN |
1233 | static struct sdhci_arasan_of_data sdhci_arasan_zynqmp_data = { |
1234 | .pdata = &sdhci_arasan_zynqmp_pdata, | |
16ada730 MN |
1235 | .clk_ops = &zynqmp_clk_ops, |
1236 | }; | |
1237 | ||
1238 | static const struct sdhci_arasan_clk_ops versal_clk_ops = { | |
1239 | .sdcardclk_ops = &versal_sdcardclk_ops, | |
1240 | .sampleclk_ops = &versal_sampleclk_ops, | |
37d3ee7c MN |
1241 | }; |
1242 | ||
1243 | static struct sdhci_arasan_of_data sdhci_arasan_versal_data = { | |
1244 | .pdata = &sdhci_arasan_zynqmp_pdata, | |
16ada730 | 1245 | .clk_ops = &versal_clk_ops, |
37d3ee7c MN |
1246 | }; |
1247 | ||
36c6aada WAZ |
1248 | static struct sdhci_arasan_of_data intel_keembay_emmc_data = { |
1249 | .soc_ctl_map = &intel_keembay_soc_ctl_map, | |
1250 | .pdata = &sdhci_keembay_emmc_pdata, | |
a42a7ec9 | 1251 | .clk_ops = &arasan_clk_ops, |
36c6aada WAZ |
1252 | }; |
1253 | ||
1254 | static struct sdhci_arasan_of_data intel_keembay_sd_data = { | |
1255 | .soc_ctl_map = &intel_keembay_soc_ctl_map, | |
1256 | .pdata = &sdhci_keembay_sd_pdata, | |
a42a7ec9 | 1257 | .clk_ops = &arasan_clk_ops, |
36c6aada WAZ |
1258 | }; |
1259 | ||
1260 | static struct sdhci_arasan_of_data intel_keembay_sdio_data = { | |
1261 | .soc_ctl_map = &intel_keembay_soc_ctl_map, | |
1262 | .pdata = &sdhci_keembay_sdio_pdata, | |
a42a7ec9 | 1263 | .clk_ops = &arasan_clk_ops, |
36c6aada WAZ |
1264 | }; |
1265 | ||
37d3ee7c MN |
1266 | static const struct of_device_id sdhci_arasan_of_match[] = { |
1267 | /* SoC-specific compatible strings w/ soc_ctl_map */ | |
1268 | { | |
1269 | .compatible = "rockchip,rk3399-sdhci-5.1", | |
1270 | .data = &sdhci_arasan_rk3399_data, | |
1271 | }, | |
1272 | { | |
1273 | .compatible = "intel,lgm-sdhci-5.1-emmc", | |
1274 | .data = &intel_lgm_emmc_data, | |
1275 | }, | |
1276 | { | |
1277 | .compatible = "intel,lgm-sdhci-5.1-sdxc", | |
1278 | .data = &intel_lgm_sdxc_data, | |
1279 | }, | |
36c6aada WAZ |
1280 | { |
1281 | .compatible = "intel,keembay-sdhci-5.1-emmc", | |
1282 | .data = &intel_keembay_emmc_data, | |
1283 | }, | |
1284 | { | |
1285 | .compatible = "intel,keembay-sdhci-5.1-sd", | |
1286 | .data = &intel_keembay_sd_data, | |
1287 | }, | |
1288 | { | |
1289 | .compatible = "intel,keembay-sdhci-5.1-sdio", | |
1290 | .data = &intel_keembay_sdio_data, | |
1291 | }, | |
39013f09 R |
1292 | { |
1293 | .compatible = "intel,thunderbay-sdhci-5.1", | |
1294 | .data = &sdhci_arasan_thunderbay_data, | |
1295 | }, | |
37d3ee7c MN |
1296 | /* Generic compatible below here */ |
1297 | { | |
1298 | .compatible = "arasan,sdhci-8.9a", | |
1299 | .data = &sdhci_arasan_generic_data, | |
1300 | }, | |
1301 | { | |
1302 | .compatible = "arasan,sdhci-5.1", | |
1303 | .data = &sdhci_arasan_generic_data, | |
1304 | }, | |
1305 | { | |
1306 | .compatible = "arasan,sdhci-4.9a", | |
1307 | .data = &sdhci_arasan_generic_data, | |
1308 | }, | |
1309 | { | |
1310 | .compatible = "xlnx,zynqmp-8.9a", | |
1311 | .data = &sdhci_arasan_zynqmp_data, | |
1312 | }, | |
1313 | { | |
1314 | .compatible = "xlnx,versal-8.9a", | |
1315 | .data = &sdhci_arasan_versal_data, | |
1316 | }, | |
1317 | { /* sentinel */ } | |
1318 | }; | |
1319 | MODULE_DEVICE_TABLE(of, sdhci_arasan_of_match); | |
1320 | ||
c390f211 | 1321 | /** |
07a14d1d | 1322 | * sdhci_arasan_register_sdcardclk - Register the sdcardclk for a PHY to use |
c390f211 | 1323 | * |
4908460e MN |
1324 | * @sdhci_arasan: Our private data structure. |
1325 | * @clk_xin: Pointer to the functional clock | |
1326 | * @dev: Pointer to our struct device. | |
1327 | * | |
c390f211 DA |
1328 | * Some PHY devices need to know what the actual card clock is. In order for |
1329 | * them to find out, we'll provide a clock through the common clock framework | |
1330 | * for them to query. | |
1331 | * | |
4908460e | 1332 | * Return: 0 on success and error value on error |
c390f211 | 1333 | */ |
07a14d1d MN |
1334 | static int |
1335 | sdhci_arasan_register_sdcardclk(struct sdhci_arasan_data *sdhci_arasan, | |
1336 | struct clk *clk_xin, | |
1337 | struct device *dev) | |
c390f211 | 1338 | { |
e1463618 | 1339 | struct sdhci_arasan_clk_data *clk_data = &sdhci_arasan->clk_data; |
c390f211 DA |
1340 | struct device_node *np = dev->of_node; |
1341 | struct clk_init_data sdcardclk_init; | |
1342 | const char *parent_clk_name; | |
1343 | int ret; | |
1344 | ||
c390f211 DA |
1345 | ret = of_property_read_string_index(np, "clock-output-names", 0, |
1346 | &sdcardclk_init.name); | |
1347 | if (ret) { | |
1348 | dev_err(dev, "DT has #clock-cells but no clock-output-names\n"); | |
1349 | return ret; | |
1350 | } | |
1351 | ||
1352 | parent_clk_name = __clk_get_name(clk_xin); | |
1353 | sdcardclk_init.parent_names = &parent_clk_name; | |
1354 | sdcardclk_init.num_parents = 1; | |
1355 | sdcardclk_init.flags = CLK_GET_RATE_NOCACHE; | |
16ada730 | 1356 | sdcardclk_init.ops = sdhci_arasan->clk_ops->sdcardclk_ops; |
c390f211 | 1357 | |
e1463618 MN |
1358 | clk_data->sdcardclk_hw.init = &sdcardclk_init; |
1359 | clk_data->sdcardclk = | |
1360 | devm_clk_register(dev, &clk_data->sdcardclk_hw); | |
c99e1d0c CY |
1361 | if (IS_ERR(clk_data->sdcardclk)) |
1362 | return PTR_ERR(clk_data->sdcardclk); | |
e1463618 | 1363 | clk_data->sdcardclk_hw.init = NULL; |
c390f211 DA |
1364 | |
1365 | ret = of_clk_add_provider(np, of_clk_src_simple_get, | |
e1463618 | 1366 | clk_data->sdcardclk); |
c390f211 | 1367 | if (ret) |
07a14d1d MN |
1368 | dev_err(dev, "Failed to add sdcard clock provider\n"); |
1369 | ||
1370 | return ret; | |
1371 | } | |
1372 | ||
1373 | /** | |
1374 | * sdhci_arasan_register_sampleclk - Register the sampleclk for a PHY to use | |
1375 | * | |
4908460e MN |
1376 | * @sdhci_arasan: Our private data structure. |
1377 | * @clk_xin: Pointer to the functional clock | |
1378 | * @dev: Pointer to our struct device. | |
1379 | * | |
07a14d1d MN |
1380 | * Some PHY devices need to know what the actual card clock is. In order for |
1381 | * them to find out, we'll provide a clock through the common clock framework | |
1382 | * for them to query. | |
1383 | * | |
4908460e | 1384 | * Return: 0 on success and error value on error |
07a14d1d MN |
1385 | */ |
1386 | static int | |
1387 | sdhci_arasan_register_sampleclk(struct sdhci_arasan_data *sdhci_arasan, | |
1388 | struct clk *clk_xin, | |
1389 | struct device *dev) | |
1390 | { | |
1391 | struct sdhci_arasan_clk_data *clk_data = &sdhci_arasan->clk_data; | |
1392 | struct device_node *np = dev->of_node; | |
1393 | struct clk_init_data sampleclk_init; | |
1394 | const char *parent_clk_name; | |
1395 | int ret; | |
1396 | ||
1397 | ret = of_property_read_string_index(np, "clock-output-names", 1, | |
1398 | &sampleclk_init.name); | |
1399 | if (ret) { | |
1400 | dev_err(dev, "DT has #clock-cells but no clock-output-names\n"); | |
1401 | return ret; | |
1402 | } | |
1403 | ||
1404 | parent_clk_name = __clk_get_name(clk_xin); | |
1405 | sampleclk_init.parent_names = &parent_clk_name; | |
1406 | sampleclk_init.num_parents = 1; | |
1407 | sampleclk_init.flags = CLK_GET_RATE_NOCACHE; | |
16ada730 | 1408 | sampleclk_init.ops = sdhci_arasan->clk_ops->sampleclk_ops; |
07a14d1d MN |
1409 | |
1410 | clk_data->sampleclk_hw.init = &sampleclk_init; | |
1411 | clk_data->sampleclk = | |
1412 | devm_clk_register(dev, &clk_data->sampleclk_hw); | |
c99e1d0c CY |
1413 | if (IS_ERR(clk_data->sampleclk)) |
1414 | return PTR_ERR(clk_data->sampleclk); | |
07a14d1d MN |
1415 | clk_data->sampleclk_hw.init = NULL; |
1416 | ||
1417 | ret = of_clk_add_provider(np, of_clk_src_simple_get, | |
1418 | clk_data->sampleclk); | |
1419 | if (ret) | |
1420 | dev_err(dev, "Failed to add sample clock provider\n"); | |
c390f211 DA |
1421 | |
1422 | return ret; | |
1423 | } | |
1424 | ||
1425 | /** | |
1426 | * sdhci_arasan_unregister_sdclk - Undoes sdhci_arasan_register_sdclk() | |
1427 | * | |
4908460e MN |
1428 | * @dev: Pointer to our struct device. |
1429 | * | |
c390f211 DA |
1430 | * Should be called any time we're exiting and sdhci_arasan_register_sdclk() |
1431 | * returned success. | |
c390f211 DA |
1432 | */ |
1433 | static void sdhci_arasan_unregister_sdclk(struct device *dev) | |
1434 | { | |
1435 | struct device_node *np = dev->of_node; | |
1436 | ||
1437 | if (!of_find_property(np, "#clock-cells", NULL)) | |
1438 | return; | |
1439 | ||
1440 | of_clk_del_provider(dev->of_node); | |
1441 | } | |
1442 | ||
36c6aada WAZ |
1443 | /** |
1444 | * sdhci_arasan_update_support64b - Set SUPPORT_64B (64-bit System Bus Support) | |
973c7c99 MHZ |
1445 | * @host: The sdhci_host |
1446 | * @value: The value to write | |
36c6aada WAZ |
1447 | * |
1448 | * This should be set based on the System Address Bus. | |
1449 | * 0: the Core supports only 32-bit System Address Bus. | |
1450 | * 1: the Core supports 64-bit System Address Bus. | |
1451 | * | |
973c7c99 MHZ |
1452 | * NOTE: |
1453 | * For Keem Bay, it is required to clear this bit. Its default value is 1'b1. | |
1454 | * Keem Bay does not support 64-bit access. | |
36c6aada WAZ |
1455 | */ |
1456 | static void sdhci_arasan_update_support64b(struct sdhci_host *host, u32 value) | |
1457 | { | |
1458 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1459 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
db845093 | 1460 | const struct sdhci_arasan_soc_ctl_map *soc_ctl_map; |
36c6aada WAZ |
1461 | |
1462 | /* Having a map is optional */ | |
db845093 | 1463 | soc_ctl_map = sdhci_arasan->soc_ctl_map; |
36c6aada WAZ |
1464 | if (!soc_ctl_map) |
1465 | return; | |
1466 | ||
1467 | /* If we have a map, we expect to have a syscon */ | |
1468 | if (!sdhci_arasan->soc_ctl_base) { | |
1469 | pr_warn("%s: Have regmap, but no soc-ctl-syscon\n", | |
1470 | mmc_hostname(host->mmc)); | |
1471 | return; | |
1472 | } | |
1473 | ||
1474 | sdhci_arasan_syscon_write(host, &soc_ctl_map->support64b, value); | |
1475 | } | |
1476 | ||
07a14d1d MN |
1477 | /** |
1478 | * sdhci_arasan_register_sdclk - Register the sdcardclk for a PHY to use | |
1479 | * | |
4908460e MN |
1480 | * @sdhci_arasan: Our private data structure. |
1481 | * @clk_xin: Pointer to the functional clock | |
1482 | * @dev: Pointer to our struct device. | |
1483 | * | |
07a14d1d MN |
1484 | * Some PHY devices need to know what the actual card clock is. In order for |
1485 | * them to find out, we'll provide a clock through the common clock framework | |
1486 | * for them to query. | |
1487 | * | |
1488 | * Note: without seriously re-architecting SDHCI's clock code and testing on | |
1489 | * all platforms, there's no way to create a totally beautiful clock here | |
1490 | * with all clock ops implemented. Instead, we'll just create a clock that can | |
1491 | * be queried and set the CLK_GET_RATE_NOCACHE attribute to tell common clock | |
1492 | * framework that we're doing things behind its back. This should be sufficient | |
1493 | * to create nice clean device tree bindings and later (if needed) we can try | |
1494 | * re-architecting SDHCI if we see some benefit to it. | |
1495 | * | |
4908460e | 1496 | * Return: 0 on success and error value on error |
07a14d1d MN |
1497 | */ |
1498 | static int sdhci_arasan_register_sdclk(struct sdhci_arasan_data *sdhci_arasan, | |
1499 | struct clk *clk_xin, | |
1500 | struct device *dev) | |
1501 | { | |
1502 | struct device_node *np = dev->of_node; | |
1503 | u32 num_clks = 0; | |
1504 | int ret; | |
1505 | ||
1506 | /* Providing a clock to the PHY is optional; no error if missing */ | |
1507 | if (of_property_read_u32(np, "#clock-cells", &num_clks) < 0) | |
1508 | return 0; | |
1509 | ||
1510 | ret = sdhci_arasan_register_sdcardclk(sdhci_arasan, clk_xin, dev); | |
1511 | if (ret) | |
1512 | return ret; | |
1513 | ||
1514 | if (num_clks) { | |
1515 | ret = sdhci_arasan_register_sampleclk(sdhci_arasan, clk_xin, | |
1516 | dev); | |
1517 | if (ret) { | |
1518 | sdhci_arasan_unregister_sdclk(dev); | |
1519 | return ret; | |
1520 | } | |
1521 | } | |
1522 | ||
1523 | return 0; | |
1524 | } | |
1525 | ||
0614b0ae SKP |
1526 | static int sdhci_zynqmp_set_dynamic_config(struct device *dev, |
1527 | struct sdhci_arasan_data *sdhci_arasan) | |
1528 | { | |
1529 | struct sdhci_host *host = sdhci_arasan->host; | |
1530 | struct clk_hw *hw = &sdhci_arasan->clk_data.sdcardclk_hw; | |
1531 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1532 | const char *clk_name = clk_hw_get_name(hw); | |
1533 | u32 mhz, node_id = !strcmp(clk_name, "clk_out_sd0") ? NODE_SD_0 : NODE_SD_1; | |
1534 | struct reset_control *rstc; | |
1535 | int ret; | |
1536 | ||
1537 | /* Obtain SDHC reset control */ | |
1538 | rstc = devm_reset_control_get_optional_exclusive(dev, NULL); | |
1539 | if (IS_ERR(rstc)) { | |
1540 | dev_err(dev, "Cannot get SDHC reset.\n"); | |
1541 | return PTR_ERR(rstc); | |
1542 | } | |
1543 | ||
1544 | ret = reset_control_assert(rstc); | |
1545 | if (ret) | |
1546 | return ret; | |
1547 | ||
1548 | ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_FIXED, 0); | |
1549 | if (ret) | |
1550 | return ret; | |
1551 | ||
1552 | ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_EMMC_SEL, | |
1553 | !!(host->mmc->caps & MMC_CAP_NONREMOVABLE)); | |
1554 | if (ret) | |
1555 | return ret; | |
1556 | ||
1557 | mhz = DIV_ROUND_CLOSEST_ULL(clk_get_rate(pltfm_host->clk), 1000000); | |
1558 | if (mhz > 100 && mhz <= 200) | |
1559 | mhz = 200; | |
1560 | else if (mhz > 50 && mhz <= 100) | |
1561 | mhz = 100; | |
1562 | else if (mhz > 25 && mhz <= 50) | |
1563 | mhz = 50; | |
1564 | else | |
1565 | mhz = 25; | |
1566 | ||
1567 | ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_BASECLK, mhz); | |
1568 | if (ret) | |
1569 | return ret; | |
1570 | ||
1571 | ret = zynqmp_pm_set_sd_config(node_id, SD_CONFIG_8BIT, | |
1572 | !!(host->mmc->caps & MMC_CAP_8_BIT_DATA)); | |
1573 | if (ret) | |
1574 | return ret; | |
1575 | ||
1576 | ret = reset_control_deassert(rstc); | |
1577 | if (ret) | |
1578 | return ret; | |
1579 | ||
1580 | usleep_range(1000, 1500); | |
1581 | ||
1582 | return 0; | |
1583 | } | |
1584 | ||
84362d79 SL |
1585 | static int sdhci_arasan_add_host(struct sdhci_arasan_data *sdhci_arasan) |
1586 | { | |
1587 | struct sdhci_host *host = sdhci_arasan->host; | |
1588 | struct cqhci_host *cq_host; | |
1589 | bool dma64; | |
1590 | int ret; | |
1591 | ||
1592 | if (!sdhci_arasan->has_cqe) | |
1593 | return sdhci_add_host(host); | |
1594 | ||
1595 | ret = sdhci_setup_host(host); | |
1596 | if (ret) | |
1597 | return ret; | |
1598 | ||
1599 | cq_host = devm_kzalloc(host->mmc->parent, | |
1600 | sizeof(*cq_host), GFP_KERNEL); | |
1601 | if (!cq_host) { | |
1602 | ret = -ENOMEM; | |
1603 | goto cleanup; | |
1604 | } | |
1605 | ||
1606 | cq_host->mmio = host->ioaddr + SDHCI_ARASAN_CQE_BASE_ADDR; | |
1607 | cq_host->ops = &sdhci_arasan_cqhci_ops; | |
1608 | ||
1609 | dma64 = host->flags & SDHCI_USE_64_BIT_DMA; | |
1610 | if (dma64) | |
1611 | cq_host->caps |= CQHCI_TASK_DESC_SZ_128; | |
1612 | ||
1613 | ret = cqhci_init(cq_host, host->mmc, dma64); | |
1614 | if (ret) | |
1615 | goto cleanup; | |
1616 | ||
1617 | ret = __sdhci_add_host(host); | |
1618 | if (ret) | |
1619 | goto cleanup; | |
1620 | ||
1621 | return 0; | |
1622 | ||
1623 | cleanup: | |
1624 | sdhci_cleanup_host(host); | |
1625 | return ret; | |
1626 | } | |
1627 | ||
e3ec3a3d SB |
1628 | static int sdhci_arasan_probe(struct platform_device *pdev) |
1629 | { | |
1630 | int ret; | |
3ea4666e | 1631 | struct device_node *node; |
e3ec3a3d SB |
1632 | struct clk *clk_xin; |
1633 | struct sdhci_host *host; | |
1634 | struct sdhci_pltfm_host *pltfm_host; | |
2ff0b85d MHZ |
1635 | struct device *dev = &pdev->dev; |
1636 | struct device_node *np = dev->of_node; | |
e3ec3a3d | 1637 | struct sdhci_arasan_data *sdhci_arasan; |
06b23ca0 | 1638 | const struct sdhci_arasan_of_data *data; |
84362d79 | 1639 | |
2ff0b85d | 1640 | data = of_device_get_match_data(dev); |
ded2c4c3 SKP |
1641 | if (!data) |
1642 | return -EINVAL; | |
1643 | ||
06b23ca0 | 1644 | host = sdhci_pltfm_init(pdev, data->pdata, sizeof(*sdhci_arasan)); |
e3ec3a3d | 1645 | |
89211418 JZ |
1646 | if (IS_ERR(host)) |
1647 | return PTR_ERR(host); | |
1648 | ||
1649 | pltfm_host = sdhci_priv(host); | |
1650 | sdhci_arasan = sdhci_pltfm_priv(pltfm_host); | |
c390f211 | 1651 | sdhci_arasan->host = host; |
e3ec3a3d | 1652 | |
06b23ca0 | 1653 | sdhci_arasan->soc_ctl_map = data->soc_ctl_map; |
16ada730 | 1654 | sdhci_arasan->clk_ops = data->clk_ops; |
3ea4666e | 1655 | |
80d41efe | 1656 | node = of_parse_phandle(np, "arasan,soc-ctl-syscon", 0); |
3ea4666e DA |
1657 | if (node) { |
1658 | sdhci_arasan->soc_ctl_base = syscon_node_to_regmap(node); | |
1659 | of_node_put(node); | |
1660 | ||
1661 | if (IS_ERR(sdhci_arasan->soc_ctl_base)) { | |
2ff0b85d | 1662 | ret = dev_err_probe(dev, |
72ea817d KK |
1663 | PTR_ERR(sdhci_arasan->soc_ctl_base), |
1664 | "Can't get syscon\n"); | |
3ea4666e DA |
1665 | goto err_pltfm_free; |
1666 | } | |
1667 | } | |
1668 | ||
b2af3227 R |
1669 | sdhci_get_of_property(pdev); |
1670 | ||
2ff0b85d | 1671 | sdhci_arasan->clk_ahb = devm_clk_get(dev, "clk_ahb"); |
e3ec3a3d | 1672 | if (IS_ERR(sdhci_arasan->clk_ahb)) { |
ffd68f35 MHZ |
1673 | ret = dev_err_probe(dev, PTR_ERR(sdhci_arasan->clk_ahb), |
1674 | "clk_ahb clock not found.\n"); | |
278d0962 | 1675 | goto err_pltfm_free; |
e3ec3a3d SB |
1676 | } |
1677 | ||
2ff0b85d | 1678 | clk_xin = devm_clk_get(dev, "clk_xin"); |
e3ec3a3d | 1679 | if (IS_ERR(clk_xin)) { |
ffd68f35 | 1680 | ret = dev_err_probe(dev, PTR_ERR(clk_xin), "clk_xin clock not found.\n"); |
278d0962 | 1681 | goto err_pltfm_free; |
e3ec3a3d SB |
1682 | } |
1683 | ||
1684 | ret = clk_prepare_enable(sdhci_arasan->clk_ahb); | |
1685 | if (ret) { | |
2ff0b85d | 1686 | dev_err(dev, "Unable to enable AHB clock.\n"); |
278d0962 | 1687 | goto err_pltfm_free; |
e3ec3a3d SB |
1688 | } |
1689 | ||
b2af3227 R |
1690 | /* If clock-frequency property is set, use the provided value */ |
1691 | if (pltfm_host->clock && | |
1692 | pltfm_host->clock != clk_get_rate(clk_xin)) { | |
1693 | ret = clk_set_rate(clk_xin, pltfm_host->clock); | |
1694 | if (ret) { | |
1695 | dev_err(&pdev->dev, "Failed to set SD clock rate\n"); | |
1696 | goto clk_dis_ahb; | |
1697 | } | |
1698 | } | |
1699 | ||
e3ec3a3d SB |
1700 | ret = clk_prepare_enable(clk_xin); |
1701 | if (ret) { | |
2ff0b85d | 1702 | dev_err(dev, "Unable to enable SD clock.\n"); |
e3ec3a3d SB |
1703 | goto clk_dis_ahb; |
1704 | } | |
1705 | ||
3794c542 ZB |
1706 | if (of_property_read_bool(np, "xlnx,fails-without-test-cd")) |
1707 | sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_FORCE_CDTEST; | |
1708 | ||
3f2c7d5d HG |
1709 | if (of_property_read_bool(np, "xlnx,int-clock-stable-broken")) |
1710 | sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_UNSTABLE; | |
1711 | ||
e3ec3a3d SB |
1712 | pltfm_host->clk = clk_xin; |
1713 | ||
80d41efe | 1714 | if (of_device_is_compatible(np, "rockchip,rk3399-sdhci-5.1")) |
b2ca77c9 SL |
1715 | sdhci_arasan_update_clockmultiplier(host, 0x0); |
1716 | ||
36c6aada WAZ |
1717 | if (of_device_is_compatible(np, "intel,keembay-sdhci-5.1-emmc") || |
1718 | of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sd") || | |
39013f09 R |
1719 | of_device_is_compatible(np, "intel,keembay-sdhci-5.1-sdio") || |
1720 | of_device_is_compatible(np, "intel,thunderbay-sdhci-5.1")) { | |
36c6aada WAZ |
1721 | sdhci_arasan_update_clockmultiplier(host, 0x0); |
1722 | sdhci_arasan_update_support64b(host, 0x0); | |
1723 | ||
1724 | host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; | |
1725 | } | |
1726 | ||
3ea4666e DA |
1727 | sdhci_arasan_update_baseclkfreq(host); |
1728 | ||
2ff0b85d | 1729 | ret = sdhci_arasan_register_sdclk(sdhci_arasan, clk_xin, dev); |
c390f211 DA |
1730 | if (ret) |
1731 | goto clk_disable_all; | |
1732 | ||
a5c8b2ae | 1733 | if (of_device_is_compatible(np, "xlnx,zynqmp-8.9a")) { |
8d2e3343 MN |
1734 | host->mmc_host_ops.execute_tuning = |
1735 | arasan_zynqmp_execute_tuning; | |
c0b4e411 MN |
1736 | |
1737 | sdhci_arasan->quirks |= SDHCI_ARASAN_QUIRK_CLOCK_25_BROKEN; | |
25a91664 | 1738 | host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; |
a5c8b2ae MN |
1739 | } |
1740 | ||
2ff0b85d | 1741 | arasan_dt_parse_clk_phases(dev, &sdhci_arasan->clk_data); |
f3dafc37 | 1742 | |
16b23787 MS |
1743 | ret = mmc_of_parse(host->mmc); |
1744 | if (ret) { | |
ffd68f35 | 1745 | ret = dev_err_probe(dev, ret, "parsing dt failed.\n"); |
c390f211 | 1746 | goto unreg_clk; |
16b23787 MS |
1747 | } |
1748 | ||
0614b0ae SKP |
1749 | if (of_device_is_compatible(np, "xlnx,zynqmp-8.9a")) { |
1750 | ret = zynqmp_pm_is_function_supported(PM_IOCTL, IOCTL_SET_SD_CONFIG); | |
1751 | if (!ret) { | |
1752 | ret = sdhci_zynqmp_set_dynamic_config(dev, sdhci_arasan); | |
1753 | if (ret) | |
1754 | goto unreg_clk; | |
1755 | } | |
1756 | } | |
1757 | ||
91aa3661 | 1758 | sdhci_arasan->phy = ERR_PTR(-ENODEV); |
80d41efe | 1759 | if (of_device_is_compatible(np, "arasan,sdhci-5.1")) { |
2ff0b85d | 1760 | sdhci_arasan->phy = devm_phy_get(dev, "phy_arasan"); |
91aa3661 | 1761 | if (IS_ERR(sdhci_arasan->phy)) { |
ffd68f35 MHZ |
1762 | ret = dev_err_probe(dev, PTR_ERR(sdhci_arasan->phy), |
1763 | "No phy for arasan,sdhci-5.1.\n"); | |
c390f211 | 1764 | goto unreg_clk; |
91aa3661 SL |
1765 | } |
1766 | ||
1767 | ret = phy_init(sdhci_arasan->phy); | |
1768 | if (ret < 0) { | |
2ff0b85d | 1769 | dev_err(dev, "phy_init err.\n"); |
c390f211 | 1770 | goto unreg_clk; |
91aa3661 SL |
1771 | } |
1772 | ||
a05c8465 SL |
1773 | host->mmc_host_ops.hs400_enhanced_strobe = |
1774 | sdhci_arasan_hs400_enhanced_strobe; | |
8a3bee9b SL |
1775 | host->mmc_host_ops.start_signal_voltage_switch = |
1776 | sdhci_arasan_voltage_switch; | |
84362d79 | 1777 | sdhci_arasan->has_cqe = true; |
7bda9482 CM |
1778 | host->mmc->caps2 |= MMC_CAP2_CQE; |
1779 | ||
1780 | if (!of_property_read_bool(np, "disable-cqe-dcmd")) | |
1781 | host->mmc->caps2 |= MMC_CAP2_CQE_DCMD; | |
91aa3661 SL |
1782 | } |
1783 | ||
84362d79 | 1784 | ret = sdhci_arasan_add_host(sdhci_arasan); |
b1df9de7 | 1785 | if (ret) |
91aa3661 | 1786 | goto err_add_host; |
e3ec3a3d SB |
1787 | |
1788 | return 0; | |
1789 | ||
91aa3661 | 1790 | err_add_host: |
91aa3661 SL |
1791 | if (!IS_ERR(sdhci_arasan->phy)) |
1792 | phy_exit(sdhci_arasan->phy); | |
c390f211 | 1793 | unreg_clk: |
2ff0b85d | 1794 | sdhci_arasan_unregister_sdclk(dev); |
e3ec3a3d SB |
1795 | clk_disable_all: |
1796 | clk_disable_unprepare(clk_xin); | |
1797 | clk_dis_ahb: | |
1798 | clk_disable_unprepare(sdhci_arasan->clk_ahb); | |
278d0962 SL |
1799 | err_pltfm_free: |
1800 | sdhci_pltfm_free(pdev); | |
e3ec3a3d SB |
1801 | return ret; |
1802 | } | |
1803 | ||
1804 | static int sdhci_arasan_remove(struct platform_device *pdev) | |
1805 | { | |
1806 | struct sdhci_host *host = platform_get_drvdata(pdev); | |
1807 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
89211418 JZ |
1808 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
1809 | struct clk *clk_ahb = sdhci_arasan->clk_ahb; | |
e3ec3a3d | 1810 | |
91aa3661 | 1811 | if (!IS_ERR(sdhci_arasan->phy)) { |
b2db9c67 DA |
1812 | if (sdhci_arasan->is_phy_on) |
1813 | phy_power_off(sdhci_arasan->phy); | |
91aa3661 SL |
1814 | phy_exit(sdhci_arasan->phy); |
1815 | } | |
1816 | ||
c390f211 DA |
1817 | sdhci_arasan_unregister_sdclk(&pdev->dev); |
1818 | ||
869f9875 | 1819 | sdhci_pltfm_unregister(pdev); |
0c7fe32e | 1820 | |
89211418 | 1821 | clk_disable_unprepare(clk_ahb); |
e3ec3a3d | 1822 | |
869f9875 | 1823 | return 0; |
e3ec3a3d SB |
1824 | } |
1825 | ||
e3ec3a3d SB |
1826 | static struct platform_driver sdhci_arasan_driver = { |
1827 | .driver = { | |
1828 | .name = "sdhci-arasan", | |
21b2cec6 | 1829 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
e3ec3a3d SB |
1830 | .of_match_table = sdhci_arasan_of_match, |
1831 | .pm = &sdhci_arasan_dev_pm_ops, | |
1832 | }, | |
1833 | .probe = sdhci_arasan_probe, | |
1834 | .remove = sdhci_arasan_remove, | |
1835 | }; | |
1836 | ||
1837 | module_platform_driver(sdhci_arasan_driver); | |
1838 | ||
1839 | MODULE_DESCRIPTION("Driver for the Arasan SDHCI Controller"); | |
1840 | MODULE_AUTHOR("Soeren Brinkmann <soren.brinkmann@xilinx.com>"); | |
1841 | MODULE_LICENSE("GPL"); |