]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
293eb33f | 2 | /* |
d9ae52c8 | 3 | * (C) Copyright 2013 - 2015 Xilinx, Inc. |
293eb33f MS |
4 | * |
5 | * Xilinx Zynq SD Host Controller Interface | |
293eb33f MS |
6 | */ |
7 | ||
e0f4de1a | 8 | #include <clk.h> |
293eb33f | 9 | #include <common.h> |
d9ae52c8 | 10 | #include <dm.h> |
345d3c0f | 11 | #include <fdtdec.h> |
c05ed00a | 12 | #include <linux/delay.h> |
d1f4e39d | 13 | #include "mmc_private.h" |
f7ae49fc | 14 | #include <log.h> |
336d4615 | 15 | #include <dm/device_compat.h> |
61b29b82 | 16 | #include <linux/err.h> |
b08c8c48 | 17 | #include <linux/libfdt.h> |
293eb33f MS |
18 | #include <malloc.h> |
19 | #include <sdhci.h> | |
d1f4e39d | 20 | #include <zynqmp_tap_delay.h> |
293eb33f | 21 | |
2e819a77 ARS |
22 | #define SDHCI_ARASAN_ITAPDLY_REGISTER 0xF0F8 |
23 | #define SDHCI_ARASAN_OTAPDLY_REGISTER 0xF0FC | |
24 | #define SDHCI_ITAPDLY_CHGWIN 0x200 | |
25 | #define SDHCI_ITAPDLY_ENABLE 0x100 | |
26 | #define SDHCI_OTAPDLY_ENABLE 0x40 | |
27 | ||
9851f50d | 28 | #define SDHCI_TUNING_LOOP_COUNT 40 |
80355ae4 MS |
29 | #define MMC_BANK2 0x2 |
30 | ||
31 | struct arasan_sdhci_clk_data { | |
32 | int clk_phase_in[MMC_TIMING_MMC_HS400 + 1]; | |
33 | int clk_phase_out[MMC_TIMING_MMC_HS400 + 1]; | |
34 | }; | |
9851f50d | 35 | |
329a449f SG |
36 | struct arasan_sdhci_plat { |
37 | struct mmc_config cfg; | |
38 | struct mmc mmc; | |
39 | }; | |
40 | ||
d1f4e39d SDPP |
41 | struct arasan_sdhci_priv { |
42 | struct sdhci_host *host; | |
80355ae4 | 43 | struct arasan_sdhci_clk_data clk_data; |
d1f4e39d SDPP |
44 | u8 deviceid; |
45 | u8 bank; | |
7a49a16e | 46 | u8 no_1p8; |
d1f4e39d SDPP |
47 | }; |
48 | ||
2e819a77 | 49 | #if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) |
80355ae4 MS |
50 | /* Default settings for ZynqMP Clock Phases */ |
51 | const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63, 0, 0, 183, 54, 0, 0}; | |
52 | const u32 zynqmp_oclk_phases[] = {0, 72, 60, 0, 60, 72, 135, 48, 72, 135, 0}; | |
53 | ||
2e819a77 ARS |
54 | /* Default settings for Versal Clock Phases */ |
55 | const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132, 0, 0, 162, 90, 0, 0}; | |
56 | const u32 versal_oclk_phases[] = {0, 60, 48, 0, 48, 72, 90, 36, 60, 90, 0}; | |
57 | ||
d1f4e39d | 58 | static const u8 mode2timing[] = { |
17a42abb ARS |
59 | [MMC_LEGACY] = MMC_TIMING_LEGACY, |
60 | [MMC_HS] = MMC_TIMING_MMC_HS, | |
61 | [SD_HS] = MMC_TIMING_SD_HS, | |
62 | [MMC_HS_52] = MMC_TIMING_UHS_SDR50, | |
63 | [MMC_DDR_52] = MMC_TIMING_UHS_DDR50, | |
64 | [UHS_SDR12] = MMC_TIMING_UHS_SDR12, | |
65 | [UHS_SDR25] = MMC_TIMING_UHS_SDR25, | |
66 | [UHS_SDR50] = MMC_TIMING_UHS_SDR50, | |
67 | [UHS_DDR50] = MMC_TIMING_UHS_DDR50, | |
68 | [UHS_SDR104] = MMC_TIMING_UHS_SDR104, | |
69 | [MMC_HS_200] = MMC_TIMING_MMC_HS200, | |
d1f4e39d SDPP |
70 | }; |
71 | ||
d1f4e39d SDPP |
72 | static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid) |
73 | { | |
74 | u16 clk; | |
75 | unsigned long timeout; | |
76 | ||
77 | clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); | |
78 | clk &= ~(SDHCI_CLOCK_CARD_EN); | |
79 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | |
80 | ||
81 | /* Issue DLL Reset */ | |
82 | zynqmp_dll_reset(deviceid); | |
83 | ||
84 | /* Wait max 20 ms */ | |
85 | timeout = 100; | |
86 | while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) | |
87 | & SDHCI_CLOCK_INT_STABLE)) { | |
88 | if (timeout == 0) { | |
89 | dev_err(mmc_dev(host->mmc), | |
90 | ": Internal clock never stabilised.\n"); | |
91 | return; | |
92 | } | |
93 | timeout--; | |
94 | udelay(1000); | |
95 | } | |
96 | ||
97 | clk |= SDHCI_CLOCK_CARD_EN; | |
98 | sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); | |
99 | } | |
100 | ||
101 | static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode) | |
102 | { | |
103 | struct mmc_cmd cmd; | |
104 | struct mmc_data data; | |
105 | u32 ctrl; | |
106 | struct sdhci_host *host; | |
107 | struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev); | |
b6911780 | 108 | char tuning_loop_counter = SDHCI_TUNING_LOOP_COUNT; |
d1f4e39d SDPP |
109 | u8 deviceid; |
110 | ||
111 | debug("%s\n", __func__); | |
112 | ||
113 | host = priv->host; | |
114 | deviceid = priv->deviceid; | |
115 | ||
d1c0a220 | 116 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
d1f4e39d | 117 | ctrl |= SDHCI_CTRL_EXEC_TUNING; |
d1c0a220 | 118 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); |
d1f4e39d SDPP |
119 | |
120 | mdelay(1); | |
121 | ||
122 | arasan_zynqmp_dll_reset(host, deviceid); | |
123 | ||
124 | sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE); | |
125 | sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE); | |
126 | ||
127 | do { | |
128 | cmd.cmdidx = opcode; | |
129 | cmd.resp_type = MMC_RSP_R1; | |
130 | cmd.cmdarg = 0; | |
131 | ||
132 | data.blocksize = 64; | |
133 | data.blocks = 1; | |
134 | data.flags = MMC_DATA_READ; | |
135 | ||
136 | if (tuning_loop_counter-- == 0) | |
137 | break; | |
138 | ||
139 | if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200 && | |
140 | mmc->bus_width == 8) | |
141 | data.blocksize = 128; | |
142 | ||
143 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, | |
144 | data.blocksize), | |
145 | SDHCI_BLOCK_SIZE); | |
146 | sdhci_writew(host, data.blocks, SDHCI_BLOCK_COUNT); | |
147 | sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE); | |
148 | ||
149 | mmc_send_cmd(mmc, &cmd, NULL); | |
d1c0a220 | 150 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
d1f4e39d SDPP |
151 | |
152 | if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK) | |
153 | udelay(1); | |
154 | ||
155 | } while (ctrl & SDHCI_CTRL_EXEC_TUNING); | |
156 | ||
157 | if (tuning_loop_counter < 0) { | |
158 | ctrl &= ~SDHCI_CTRL_TUNED_CLK; | |
d1c0a220 | 159 | sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL2); |
d1f4e39d SDPP |
160 | } |
161 | ||
162 | if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) { | |
163 | printf("%s:Tuning failed\n", __func__); | |
164 | return -1; | |
165 | } | |
166 | ||
167 | udelay(1); | |
168 | arasan_zynqmp_dll_reset(host, deviceid); | |
169 | ||
170 | /* Enable only interrupts served by the SD controller */ | |
171 | sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK, | |
172 | SDHCI_INT_ENABLE); | |
173 | /* Mask all sdhci interrupt sources */ | |
174 | sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE); | |
175 | ||
176 | return 0; | |
177 | } | |
178 | ||
f4b297bb ARS |
179 | /** |
180 | * sdhci_zynqmp_sdcardclk_set_phase - Set the SD Output Clock Tap Delays | |
181 | * | |
182 | * Set the SD Output Clock Tap Delays for Output path | |
183 | * | |
184 | * @host: Pointer to the sdhci_host structure. | |
185 | * @degrees: The clock phase shift between 0 - 359. | |
8e34aa00 | 186 | * Return: 0 |
f4b297bb ARS |
187 | */ |
188 | static int sdhci_zynqmp_sdcardclk_set_phase(struct sdhci_host *host, | |
189 | int degrees) | |
190 | { | |
191 | struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev); | |
192 | struct mmc *mmc = (struct mmc *)host->mmc; | |
193 | u8 tap_delay, tap_max = 0; | |
f4b297bb ARS |
194 | int timing = mode2timing[mmc->selected_mode]; |
195 | ||
196 | /* | |
197 | * This is applicable for SDHCI_SPEC_300 and above | |
198 | * ZynqMP does not set phase for <=25MHz clock. | |
199 | * If degrees is zero, no need to do anything. | |
200 | */ | |
affcba72 | 201 | if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) |
f4b297bb ARS |
202 | return 0; |
203 | ||
204 | switch (timing) { | |
205 | case MMC_TIMING_MMC_HS: | |
206 | case MMC_TIMING_SD_HS: | |
207 | case MMC_TIMING_UHS_SDR25: | |
208 | case MMC_TIMING_UHS_DDR50: | |
209 | case MMC_TIMING_MMC_DDR52: | |
210 | /* For 50MHz clock, 30 Taps are available */ | |
211 | tap_max = 30; | |
212 | break; | |
213 | case MMC_TIMING_UHS_SDR50: | |
214 | /* For 100MHz clock, 15 Taps are available */ | |
215 | tap_max = 15; | |
216 | break; | |
217 | case MMC_TIMING_UHS_SDR104: | |
218 | case MMC_TIMING_MMC_HS200: | |
219 | /* For 200MHz clock, 8 Taps are available */ | |
220 | tap_max = 8; | |
221 | default: | |
222 | break; | |
223 | } | |
224 | ||
225 | tap_delay = (degrees * tap_max) / 360; | |
226 | ||
227 | arasan_zynqmp_set_tapdelay(priv->deviceid, 0, tap_delay); | |
228 | ||
8e34aa00 | 229 | return 0; |
f4b297bb ARS |
230 | } |
231 | ||
232 | /** | |
233 | * sdhci_zynqmp_sampleclk_set_phase - Set the SD Input Clock Tap Delays | |
234 | * | |
235 | * Set the SD Input Clock Tap Delays for Input path | |
236 | * | |
237 | * @host: Pointer to the sdhci_host structure. | |
238 | * @degrees: The clock phase shift between 0 - 359. | |
8e34aa00 | 239 | * Return: 0 |
f4b297bb ARS |
240 | */ |
241 | static int sdhci_zynqmp_sampleclk_set_phase(struct sdhci_host *host, | |
242 | int degrees) | |
243 | { | |
244 | struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev); | |
245 | struct mmc *mmc = (struct mmc *)host->mmc; | |
246 | u8 tap_delay, tap_max = 0; | |
f4b297bb ARS |
247 | int timing = mode2timing[mmc->selected_mode]; |
248 | ||
249 | /* | |
250 | * This is applicable for SDHCI_SPEC_300 and above | |
251 | * ZynqMP does not set phase for <=25MHz clock. | |
252 | * If degrees is zero, no need to do anything. | |
253 | */ | |
affcba72 | 254 | if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) |
f4b297bb ARS |
255 | return 0; |
256 | ||
257 | switch (timing) { | |
258 | case MMC_TIMING_MMC_HS: | |
259 | case MMC_TIMING_SD_HS: | |
260 | case MMC_TIMING_UHS_SDR25: | |
261 | case MMC_TIMING_UHS_DDR50: | |
262 | case MMC_TIMING_MMC_DDR52: | |
263 | /* For 50MHz clock, 120 Taps are available */ | |
264 | tap_max = 120; | |
265 | break; | |
266 | case MMC_TIMING_UHS_SDR50: | |
267 | /* For 100MHz clock, 60 Taps are available */ | |
268 | tap_max = 60; | |
269 | break; | |
270 | case MMC_TIMING_UHS_SDR104: | |
271 | case MMC_TIMING_MMC_HS200: | |
272 | /* For 200MHz clock, 30 Taps are available */ | |
273 | tap_max = 30; | |
274 | default: | |
275 | break; | |
276 | } | |
277 | ||
278 | tap_delay = (degrees * tap_max) / 360; | |
279 | ||
280 | arasan_zynqmp_set_tapdelay(priv->deviceid, tap_delay, 0); | |
281 | ||
8e34aa00 | 282 | return 0; |
f4b297bb ARS |
283 | } |
284 | ||
2e819a77 ARS |
285 | /** |
286 | * sdhci_versal_sdcardclk_set_phase - Set the SD Output Clock Tap Delays | |
287 | * | |
288 | * Set the SD Output Clock Tap Delays for Output path | |
289 | * | |
290 | * @host: Pointer to the sdhci_host structure. | |
291 | * @degrees The clock phase shift between 0 - 359. | |
8e34aa00 | 292 | * Return: 0 |
2e819a77 ARS |
293 | */ |
294 | static int sdhci_versal_sdcardclk_set_phase(struct sdhci_host *host, | |
295 | int degrees) | |
296 | { | |
297 | struct mmc *mmc = (struct mmc *)host->mmc; | |
298 | u8 tap_delay, tap_max = 0; | |
2e819a77 ARS |
299 | int timing = mode2timing[mmc->selected_mode]; |
300 | ||
301 | /* | |
302 | * This is applicable for SDHCI_SPEC_300 and above | |
303 | * Versal does not set phase for <=25MHz clock. | |
304 | * If degrees is zero, no need to do anything. | |
305 | */ | |
affcba72 | 306 | if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) |
2e819a77 ARS |
307 | return 0; |
308 | ||
309 | switch (timing) { | |
310 | case MMC_TIMING_MMC_HS: | |
311 | case MMC_TIMING_SD_HS: | |
312 | case MMC_TIMING_UHS_SDR25: | |
313 | case MMC_TIMING_UHS_DDR50: | |
314 | case MMC_TIMING_MMC_DDR52: | |
315 | /* For 50MHz clock, 30 Taps are available */ | |
316 | tap_max = 30; | |
317 | break; | |
318 | case MMC_TIMING_UHS_SDR50: | |
319 | /* For 100MHz clock, 15 Taps are available */ | |
320 | tap_max = 15; | |
321 | break; | |
322 | case MMC_TIMING_UHS_SDR104: | |
323 | case MMC_TIMING_MMC_HS200: | |
324 | /* For 200MHz clock, 8 Taps are available */ | |
325 | tap_max = 8; | |
326 | default: | |
327 | break; | |
328 | } | |
329 | ||
330 | tap_delay = (degrees * tap_max) / 360; | |
331 | ||
332 | /* Set the Clock Phase */ | |
333 | if (tap_delay) { | |
334 | u32 regval; | |
335 | ||
336 | regval = sdhci_readl(host, SDHCI_ARASAN_OTAPDLY_REGISTER); | |
337 | regval |= SDHCI_OTAPDLY_ENABLE; | |
338 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); | |
339 | regval |= tap_delay; | |
340 | sdhci_writel(host, regval, SDHCI_ARASAN_OTAPDLY_REGISTER); | |
341 | } | |
342 | ||
8e34aa00 | 343 | return 0; |
2e819a77 ARS |
344 | } |
345 | ||
346 | /** | |
347 | * sdhci_versal_sampleclk_set_phase - Set the SD Input Clock Tap Delays | |
348 | * | |
349 | * Set the SD Input Clock Tap Delays for Input path | |
350 | * | |
351 | * @host: Pointer to the sdhci_host structure. | |
352 | * @degrees The clock phase shift between 0 - 359. | |
8e34aa00 | 353 | * Return: 0 |
2e819a77 ARS |
354 | */ |
355 | static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host, | |
356 | int degrees) | |
357 | { | |
358 | struct mmc *mmc = (struct mmc *)host->mmc; | |
359 | u8 tap_delay, tap_max = 0; | |
2e819a77 ARS |
360 | int timing = mode2timing[mmc->selected_mode]; |
361 | ||
362 | /* | |
363 | * This is applicable for SDHCI_SPEC_300 and above | |
364 | * Versal does not set phase for <=25MHz clock. | |
365 | * If degrees is zero, no need to do anything. | |
366 | */ | |
affcba72 | 367 | if (SDHCI_GET_VERSION(host) < SDHCI_SPEC_300) |
2e819a77 ARS |
368 | return 0; |
369 | ||
370 | switch (timing) { | |
371 | case MMC_TIMING_MMC_HS: | |
372 | case MMC_TIMING_SD_HS: | |
373 | case MMC_TIMING_UHS_SDR25: | |
374 | case MMC_TIMING_UHS_DDR50: | |
375 | case MMC_TIMING_MMC_DDR52: | |
376 | /* For 50MHz clock, 120 Taps are available */ | |
377 | tap_max = 120; | |
378 | break; | |
379 | case MMC_TIMING_UHS_SDR50: | |
380 | /* For 100MHz clock, 60 Taps are available */ | |
381 | tap_max = 60; | |
382 | break; | |
383 | case MMC_TIMING_UHS_SDR104: | |
384 | case MMC_TIMING_MMC_HS200: | |
385 | /* For 200MHz clock, 30 Taps are available */ | |
386 | tap_max = 30; | |
387 | default: | |
388 | break; | |
389 | } | |
390 | ||
391 | tap_delay = (degrees * tap_max) / 360; | |
392 | ||
393 | /* Set the Clock Phase */ | |
394 | if (tap_delay) { | |
395 | u32 regval; | |
396 | ||
397 | regval = sdhci_readl(host, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
398 | regval |= SDHCI_ITAPDLY_CHGWIN; | |
399 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
400 | regval |= SDHCI_ITAPDLY_ENABLE; | |
401 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
402 | regval |= tap_delay; | |
403 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
404 | regval &= ~SDHCI_ITAPDLY_CHGWIN; | |
405 | sdhci_writel(host, regval, SDHCI_ARASAN_ITAPDLY_REGISTER); | |
406 | } | |
407 | ||
8e34aa00 | 408 | return 0; |
2e819a77 ARS |
409 | } |
410 | ||
d1f4e39d SDPP |
411 | static void arasan_sdhci_set_tapdelay(struct sdhci_host *host) |
412 | { | |
413 | struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev); | |
f4b297bb | 414 | struct arasan_sdhci_clk_data *clk_data = &priv->clk_data; |
d1f4e39d | 415 | struct mmc *mmc = (struct mmc *)host->mmc; |
f4b297bb ARS |
416 | struct udevice *dev = mmc->dev; |
417 | u8 timing = mode2timing[mmc->selected_mode]; | |
418 | u32 iclk_phase = clk_data->clk_phase_in[timing]; | |
419 | u32 oclk_phase = clk_data->clk_phase_out[timing]; | |
d1f4e39d | 420 | |
f4b297bb | 421 | dev_dbg(dev, "%s, host:%s, mode:%d\n", __func__, host->name, timing); |
d1f4e39d | 422 | |
f4b297bb ARS |
423 | if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) && |
424 | device_is_compatible(dev, "xlnx,zynqmp-8.9a")) { | |
425 | sdhci_zynqmp_sampleclk_set_phase(host, iclk_phase); | |
426 | sdhci_zynqmp_sdcardclk_set_phase(host, oclk_phase); | |
2e819a77 ARS |
427 | } else if (IS_ENABLED(CONFIG_ARCH_VERSAL) && |
428 | device_is_compatible(dev, "xlnx,versal-8.9a")) { | |
429 | sdhci_versal_sampleclk_set_phase(host, iclk_phase); | |
430 | sdhci_versal_sdcardclk_set_phase(host, oclk_phase); | |
f4b297bb | 431 | } |
d1f4e39d SDPP |
432 | } |
433 | ||
80355ae4 MS |
434 | static void arasan_dt_read_clk_phase(struct udevice *dev, unsigned char timing, |
435 | const char *prop) | |
436 | { | |
437 | struct arasan_sdhci_priv *priv = dev_get_priv(dev); | |
438 | struct arasan_sdhci_clk_data *clk_data = &priv->clk_data; | |
439 | u32 clk_phase[2] = {0}; | |
440 | ||
441 | /* | |
442 | * Read Tap Delay values from DT, if the DT does not contain the | |
443 | * Tap Values then use the pre-defined values | |
444 | */ | |
445 | if (dev_read_u32_array(dev, prop, &clk_phase[0], 2)) { | |
446 | dev_dbg(dev, "Using predefined clock phase for %s = %d %d\n", | |
447 | prop, clk_data->clk_phase_in[timing], | |
448 | clk_data->clk_phase_out[timing]); | |
449 | return; | |
450 | } | |
451 | ||
452 | /* The values read are Input and Output Clock Delays in order */ | |
453 | clk_data->clk_phase_in[timing] = clk_phase[0]; | |
454 | clk_data->clk_phase_out[timing] = clk_phase[1]; | |
455 | } | |
456 | ||
457 | /** | |
458 | * arasan_dt_parse_clk_phases - Read Tap Delay values from DT | |
459 | * | |
460 | * Called at initialization to parse the values of Tap Delays. | |
461 | * | |
462 | * @dev: Pointer to our struct udevice. | |
463 | */ | |
464 | static void arasan_dt_parse_clk_phases(struct udevice *dev) | |
465 | { | |
466 | struct arasan_sdhci_priv *priv = dev_get_priv(dev); | |
467 | struct arasan_sdhci_clk_data *clk_data = &priv->clk_data; | |
468 | int i; | |
469 | ||
470 | if (IS_ENABLED(CONFIG_ARCH_ZYNQMP) && | |
471 | device_is_compatible(dev, "xlnx,zynqmp-8.9a")) { | |
472 | for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) { | |
473 | clk_data->clk_phase_in[i] = zynqmp_iclk_phases[i]; | |
474 | clk_data->clk_phase_out[i] = zynqmp_oclk_phases[i]; | |
475 | } | |
476 | ||
477 | if (priv->bank == MMC_BANK2) { | |
478 | clk_data->clk_phase_out[MMC_TIMING_UHS_SDR104] = 90; | |
479 | clk_data->clk_phase_out[MMC_TIMING_MMC_HS200] = 90; | |
480 | } | |
481 | } | |
482 | ||
2e819a77 ARS |
483 | if (IS_ENABLED(CONFIG_ARCH_VERSAL) && |
484 | device_is_compatible(dev, "xlnx,versal-8.9a")) { | |
485 | for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) { | |
486 | clk_data->clk_phase_in[i] = versal_iclk_phases[i]; | |
487 | clk_data->clk_phase_out[i] = versal_oclk_phases[i]; | |
488 | } | |
489 | } | |
490 | ||
80355ae4 MS |
491 | arasan_dt_read_clk_phase(dev, MMC_TIMING_LEGACY, |
492 | "clk-phase-legacy"); | |
493 | arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS, | |
494 | "clk-phase-mmc-hs"); | |
495 | arasan_dt_read_clk_phase(dev, MMC_TIMING_SD_HS, | |
496 | "clk-phase-sd-hs"); | |
497 | arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR12, | |
498 | "clk-phase-uhs-sdr12"); | |
499 | arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR25, | |
500 | "clk-phase-uhs-sdr25"); | |
501 | arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR50, | |
502 | "clk-phase-uhs-sdr50"); | |
503 | arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_SDR104, | |
504 | "clk-phase-uhs-sdr104"); | |
505 | arasan_dt_read_clk_phase(dev, MMC_TIMING_UHS_DDR50, | |
506 | "clk-phase-uhs-ddr50"); | |
507 | arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_DDR52, | |
508 | "clk-phase-mmc-ddr52"); | |
509 | arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS200, | |
510 | "clk-phase-mmc-hs200"); | |
511 | arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS400, | |
512 | "clk-phase-mmc-hs400"); | |
513 | } | |
514 | ||
d1f4e39d SDPP |
515 | static void arasan_sdhci_set_control_reg(struct sdhci_host *host) |
516 | { | |
517 | struct mmc *mmc = (struct mmc *)host->mmc; | |
518 | u32 reg; | |
519 | ||
84333708 SDPP |
520 | if (!IS_SD(mmc)) |
521 | return; | |
522 | ||
d1f4e39d | 523 | if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { |
d1c0a220 FA |
524 | reg = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
525 | reg |= SDHCI_CTRL_VDD_180; | |
526 | sdhci_writew(host, reg, SDHCI_HOST_CONTROL2); | |
d1f4e39d SDPP |
527 | } |
528 | ||
529 | if (mmc->selected_mode > SD_HS && | |
d3d880b4 | 530 | mmc->selected_mode <= MMC_HS_200) |
d1c0a220 | 531 | sdhci_set_uhs_timing(host); |
d1f4e39d | 532 | } |
d1f4e39d | 533 | |
d1f4e39d | 534 | const struct sdhci_ops arasan_ops = { |
0981ef71 | 535 | .platform_execute_tuning = &arasan_sdhci_execute_tuning, |
d1f4e39d SDPP |
536 | .set_delay = &arasan_sdhci_set_tapdelay, |
537 | .set_control_reg = &arasan_sdhci_set_control_reg, | |
538 | }; | |
539 | #endif | |
540 | ||
d9ae52c8 | 541 | static int arasan_sdhci_probe(struct udevice *dev) |
293eb33f | 542 | { |
c69cda25 | 543 | struct arasan_sdhci_plat *plat = dev_get_plat(dev); |
d9ae52c8 | 544 | struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); |
d1f4e39d SDPP |
545 | struct arasan_sdhci_priv *priv = dev_get_priv(dev); |
546 | struct sdhci_host *host; | |
e0f4de1a SH |
547 | struct clk clk; |
548 | unsigned long clock; | |
329a449f | 549 | int ret; |
293eb33f | 550 | |
d1f4e39d SDPP |
551 | host = priv->host; |
552 | ||
e0f4de1a SH |
553 | ret = clk_get_by_index(dev, 0, &clk); |
554 | if (ret < 0) { | |
555 | dev_err(dev, "failed to get clock\n"); | |
556 | return ret; | |
557 | } | |
558 | ||
559 | clock = clk_get_rate(&clk); | |
560 | if (IS_ERR_VALUE(clock)) { | |
561 | dev_err(dev, "failed to get rate\n"); | |
562 | return clock; | |
563 | } | |
d1f4e39d | 564 | |
e0f4de1a SH |
565 | debug("%s: CLK %ld\n", __func__, clock); |
566 | ||
567 | ret = clk_enable(&clk); | |
9b7aac75 | 568 | if (ret) { |
e0f4de1a SH |
569 | dev_err(dev, "failed to enable clock\n"); |
570 | return ret; | |
571 | } | |
572 | ||
eddabd16 | 573 | host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | |
f9ec45d1 | 574 | SDHCI_QUIRK_BROKEN_R1B; |
b2156146 SDPP |
575 | |
576 | #ifdef CONFIG_ZYNQ_HISPD_BROKEN | |
47819216 | 577 | host->quirks |= SDHCI_QUIRK_BROKEN_HISPD_MODE; |
b2156146 SDPP |
578 | #endif |
579 | ||
7a49a16e ARS |
580 | if (priv->no_1p8) |
581 | host->quirks |= SDHCI_QUIRK_NO_1_8_V; | |
582 | ||
942b5fc0 BG |
583 | plat->cfg.f_max = CONFIG_ZYNQ_SDHCI_MAX_FREQ; |
584 | ||
585 | ret = mmc_of_parse(dev, &plat->cfg); | |
586 | if (ret) | |
587 | return ret; | |
d1f4e39d | 588 | |
e0f4de1a | 589 | host->max_clk = clock; |
6d0e34bf | 590 | |
3148a3c2 MK |
591 | host->mmc = &plat->mmc; |
592 | host->mmc->dev = dev; | |
593 | host->mmc->priv = host; | |
594 | ||
942b5fc0 | 595 | ret = sdhci_setup_cfg(&plat->cfg, host, plat->cfg.f_max, |
14bed52d | 596 | CONFIG_ZYNQ_SDHCI_MIN_FREQ); |
329a449f SG |
597 | if (ret) |
598 | return ret; | |
329a449f | 599 | upriv->mmc = host->mmc; |
d9ae52c8 | 600 | |
329a449f | 601 | return sdhci_probe(dev); |
293eb33f | 602 | } |
d9ae52c8 | 603 | |
d1998a9f | 604 | static int arasan_sdhci_of_to_plat(struct udevice *dev) |
d9ae52c8 | 605 | { |
d1f4e39d SDPP |
606 | struct arasan_sdhci_priv *priv = dev_get_priv(dev); |
607 | ||
608 | priv->host = calloc(1, sizeof(struct sdhci_host)); | |
609 | if (!priv->host) | |
610 | return -1; | |
d9ae52c8 | 611 | |
d1f4e39d | 612 | priv->host->name = dev->name; |
d1f4e39d | 613 | |
2e819a77 | 614 | #if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) |
d1f4e39d | 615 | priv->host->ops = &arasan_ops; |
80355ae4 | 616 | arasan_dt_parse_clk_phases(dev); |
d1f4e39d | 617 | #endif |
d9ae52c8 | 618 | |
458e8d80 MS |
619 | priv->host->ioaddr = (void *)dev_read_addr(dev); |
620 | if (IS_ERR(priv->host->ioaddr)) | |
621 | return PTR_ERR(priv->host->ioaddr); | |
61e745d1 | 622 | |
458e8d80 | 623 | priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1); |
e8deb221 | 624 | priv->bank = dev_read_u32_default(dev, "xlnx,mio-bank", 0); |
7a49a16e | 625 | priv->no_1p8 = dev_read_bool(dev, "no-1-8-v"); |
458e8d80 | 626 | |
d9ae52c8 MS |
627 | return 0; |
628 | } | |
629 | ||
329a449f SG |
630 | static int arasan_sdhci_bind(struct udevice *dev) |
631 | { | |
c69cda25 | 632 | struct arasan_sdhci_plat *plat = dev_get_plat(dev); |
329a449f | 633 | |
24f5aec3 | 634 | return sdhci_bind(dev, &plat->mmc, &plat->cfg); |
329a449f SG |
635 | } |
636 | ||
d9ae52c8 MS |
637 | static const struct udevice_id arasan_sdhci_ids[] = { |
638 | { .compatible = "arasan,sdhci-8.9a" }, | |
639 | { } | |
640 | }; | |
641 | ||
642 | U_BOOT_DRIVER(arasan_sdhci_drv) = { | |
643 | .name = "arasan_sdhci", | |
644 | .id = UCLASS_MMC, | |
645 | .of_match = arasan_sdhci_ids, | |
d1998a9f | 646 | .of_to_plat = arasan_sdhci_of_to_plat, |
329a449f SG |
647 | .ops = &sdhci_ops, |
648 | .bind = arasan_sdhci_bind, | |
d9ae52c8 | 649 | .probe = arasan_sdhci_probe, |
41575d8e | 650 | .priv_auto = sizeof(struct arasan_sdhci_priv), |
caa4daa2 | 651 | .plat_auto = sizeof(struct arasan_sdhci_plat), |
d9ae52c8 | 652 | }; |