1 /* $NetBSD: meson_sdhc.c,v 1.6 2021/11/07 17:11:58 jmcneill Exp $ */
2
3 /*-
4 * Copyright (c) 2015-2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: meson_sdhc.c,v 1.6 2021/11/07 17:11:58 jmcneill Exp $");
31
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/device.h>
35 #include <sys/intr.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/gpio.h>
39
40 #include <dev/sdmmc/sdmmcvar.h>
41 #include <dev/sdmmc/sdmmcchip.h>
42 #include <dev/sdmmc/sdmmc_ioreg.h>
43
44 #include <dev/fdt/fdtvar.h>
45
46 #include <arm/amlogic/meson_sdhcreg.h>
47
48 enum {
49 SDHC_PORT_A = 0,
50 SDHC_PORT_B = 1,
51 SDHC_PORT_C = 2
52 };
53
54 static int meson_sdhc_match(device_t, cfdata_t, void *);
55 static void meson_sdhc_attach(device_t, device_t, void *);
56 static void meson_sdhc_attach_i(device_t);
57
58 static int meson_sdhc_intr(void *);
59
60 struct meson_sdhc_softc {
61 device_t sc_dev;
62 bus_space_tag_t sc_bst;
63 bus_space_handle_t sc_bsh;
64 bus_dma_tag_t sc_dmat;
65 void *sc_ih;
66
67 device_t sc_sdmmc_dev;
68 kmutex_t sc_intr_lock;
69 kcondvar_t sc_intr_cv;
70
71 uint32_t sc_intr_ista;
72
73 bus_dmamap_t sc_dmamap;
74 bus_dma_segment_t sc_segs[1];
75 void *sc_bbuf;
76
77 u_int sc_bus_freq;
78
79 struct fdtbus_gpio_pin *sc_gpio_cd;
80 int sc_gpio_cd_inverted;
81 struct fdtbus_gpio_pin *sc_gpio_wp;
82 int sc_gpio_wp_inverted;
83
84 struct fdtbus_regulator *sc_reg_vmmc;
85 struct fdtbus_regulator *sc_reg_vqmmc;
86
87 bool sc_non_removable;
88 bool sc_broken_cd;
89
90 int sc_port;
91 int sc_slot_phandle;
92 int sc_signal_voltage;
93 };
94
95 CFATTACH_DECL_NEW(meson_sdhc, sizeof(struct meson_sdhc_softc),
96 meson_sdhc_match, meson_sdhc_attach, NULL, NULL);
97
98 static int meson_sdhc_host_reset(sdmmc_chipset_handle_t);
99 static uint32_t meson_sdhc_host_ocr(sdmmc_chipset_handle_t);
100 static int meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t);
101 static int meson_sdhc_card_detect(sdmmc_chipset_handle_t);
102 static int meson_sdhc_write_protect(sdmmc_chipset_handle_t);
103 static int meson_sdhc_bus_power(sdmmc_chipset_handle_t, uint32_t);
104 static int meson_sdhc_bus_clock(sdmmc_chipset_handle_t, int);
105 static int meson_sdhc_bus_width(sdmmc_chipset_handle_t, int);
106 static int meson_sdhc_bus_rod(sdmmc_chipset_handle_t, int);
107 static void meson_sdhc_exec_command(sdmmc_chipset_handle_t,
108 struct sdmmc_command *);
109 static void meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t, int);
110 static void meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t);
111 static int meson_sdhc_signal_voltage(sdmmc_chipset_handle_t, int);
112 static int meson_sdhc_execute_tuning(sdmmc_chipset_handle_t, int);
113
114 static int meson_sdhc_default_rx_phase(struct meson_sdhc_softc *);
115 static int meson_sdhc_set_clock(struct meson_sdhc_softc *, u_int);
116 static int meson_sdhc_wait_idle(struct meson_sdhc_softc *);
117 static int meson_sdhc_wait_ista(struct meson_sdhc_softc *, uint32_t, int);
118
119 static void meson_sdhc_dmainit(struct meson_sdhc_softc *);
120
121 static struct sdmmc_chip_functions meson_sdhc_chip_functions = {
122 .host_reset = meson_sdhc_host_reset,
123 .host_ocr = meson_sdhc_host_ocr,
124 .host_maxblklen = meson_sdhc_host_maxblklen,
125 .card_detect = meson_sdhc_card_detect,
126 .write_protect = meson_sdhc_write_protect,
127 .bus_power = meson_sdhc_bus_power,
128 .bus_clock = meson_sdhc_bus_clock,
129 .bus_width = meson_sdhc_bus_width,
130 .bus_rod = meson_sdhc_bus_rod,
131 .exec_command = meson_sdhc_exec_command,
132 .card_enable_intr = meson_sdhc_card_enable_intr,
133 .card_intr_ack = meson_sdhc_card_intr_ack,
134 .signal_voltage = meson_sdhc_signal_voltage,
135 .execute_tuning = meson_sdhc_execute_tuning,
136 };
137
138 #define SDHC_WRITE(sc, reg, val) \
139 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
140 #define SDHC_READ(sc, reg) \
141 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
142 #define SDHC_SET_CLEAR meson_sdhc_set_clear
143
144 static inline void
meson_sdhc_set_clear(struct meson_sdhc_softc * sc,bus_addr_t reg,uint32_t set,uint32_t clr)145 meson_sdhc_set_clear(struct meson_sdhc_softc *sc, bus_addr_t reg, uint32_t set, uint32_t clr)
146 {
147 const uint32_t old = SDHC_READ(sc, reg);
148 const uint32_t new = set | (old & ~clr);
149 if (old != new)
150 SDHC_WRITE(sc, reg, new);
151 }
152
153 static const struct device_compatible_entry compat_data[] = {
154 { .compat = "amlogic,meson8-sdhc" },
155 { .compat = "amlogic,meson8b-sdhc" }, /* DTCOMPAT */
156 DEVICE_COMPAT_EOL
157 };
158
159 static const struct device_compatible_entry slot_compat_data[] = {
160 { .compat = "mmc-slot" },
161 DEVICE_COMPAT_EOL
162 };
163
164 static int
meson_sdhc_match(device_t parent,cfdata_t cf,void * aux)165 meson_sdhc_match(device_t parent, cfdata_t cf, void *aux)
166 {
167 struct fdt_attach_args * const faa = aux;
168
169 return of_compatible_match(faa->faa_phandle, compat_data);
170 }
171
172 static void
meson_sdhc_attach(device_t parent,device_t self,void * aux)173 meson_sdhc_attach(device_t parent, device_t self, void *aux)
174 {
175 struct meson_sdhc_softc * const sc = device_private(self);
176 struct fdt_attach_args * const faa = aux;
177 const int phandle = faa->faa_phandle;
178 char intrstr[128];
179 struct clk *clk_clkin, *clk_core;
180 bus_addr_t addr, port;
181 bus_size_t size;
182 int child;
183
184 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
185 aprint_error(": couldn't get registers\n");
186 return;
187 }
188
189 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
190 aprint_error(": failed to decode interrupt\n");
191 return;
192 }
193
194 clk_core = fdtbus_clock_get(phandle, "core");
195 if (clk_core == NULL) {
196 clk_core = fdtbus_clock_get(phandle, "pclk");
197 }
198 if (clk_core == NULL || clk_enable(clk_core) != 0) {
199 aprint_error(": failed to enable core/pclk clock\n");
200 return;
201 }
202
203 clk_clkin = fdtbus_clock_get(phandle, "clkin");
204 if (clk_clkin == NULL) {
205 clk_clkin = fdtbus_clock_get(phandle, "clkin2");
206 }
207 if (clk_clkin == NULL || clk_enable(clk_clkin) != 0) {
208 aprint_error(": failed to get clkin/clkin2 clock\n");
209 return;
210 }
211
212 sc->sc_dev = self;
213 sc->sc_bst = faa->faa_bst;
214 sc->sc_dmat = faa->faa_dmat;
215 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
216 aprint_error(": failed to map registers\n");
217 return;
218 }
219 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO);
220 cv_init(&sc->sc_intr_cv, "sdhcintr");
221 sc->sc_signal_voltage = SDMMC_SIGNAL_VOLTAGE_330;
222
223 sc->sc_port = -1;
224 for (child = OF_child(phandle); child; child = OF_peer(child))
225 if (of_compatible_match(child, slot_compat_data)) {
226 if (fdtbus_get_reg(child, 0, &port, NULL) == 0) {
227 sc->sc_slot_phandle = child;
228 sc->sc_port = port;
229 }
230 break;
231 }
232 if (sc->sc_port == -1) {
233 aprint_error(": couldn't get mmc slot\n");
234 return;
235 }
236
237 aprint_naive("\n");
238 aprint_normal(": SDHC controller (port %c)\n", sc->sc_port + 'A');
239
240 sc->sc_reg_vmmc = fdtbus_regulator_acquire(sc->sc_slot_phandle, "vmmc-supply");
241 sc->sc_reg_vqmmc = fdtbus_regulator_acquire(sc->sc_slot_phandle, "vqmmc-supply");
242
243 sc->sc_gpio_cd = fdtbus_gpio_acquire(sc->sc_slot_phandle, "cd-gpios",
244 GPIO_PIN_INPUT);
245 sc->sc_gpio_wp = fdtbus_gpio_acquire(sc->sc_slot_phandle, "wp-gpios",
246 GPIO_PIN_INPUT);
247
248 sc->sc_gpio_cd_inverted = of_hasprop(sc->sc_slot_phandle, "cd-inverted");
249 sc->sc_gpio_wp_inverted = of_hasprop(sc->sc_slot_phandle, "wp-inverted");
250
251 sc->sc_non_removable = of_hasprop(sc->sc_slot_phandle, "non-removable");
252 sc->sc_broken_cd = of_hasprop(sc->sc_slot_phandle, "broken-cd");
253
254 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 0,
255 meson_sdhc_intr, sc, device_xname(self));
256 if (sc->sc_ih == NULL) {
257 aprint_error_dev(self, "couldn't establish interrupt on %s\n",
258 intrstr);
259 return;
260 }
261 aprint_normal_dev(self, "interrupting on %s\n", intrstr);
262
263 sc->sc_bus_freq = clk_get_rate(clk_clkin);
264
265 aprint_normal_dev(self, "core %u Hz, clkin %u Hz\n", clk_get_rate(clk_core), clk_get_rate(clk_clkin));
266
267 meson_sdhc_dmainit(sc);
268
269 config_interrupts(self, meson_sdhc_attach_i);
270 }
271
272 static void
meson_sdhc_attach_i(device_t self)273 meson_sdhc_attach_i(device_t self)
274 {
275 struct meson_sdhc_softc *sc = device_private(self);
276 struct sdmmcbus_attach_args saa;
277 u_int pll_freq;
278
279 pll_freq = sc->sc_bus_freq / 1000;
280
281 meson_sdhc_host_reset(sc);
282 meson_sdhc_bus_width(sc, 1);
283
284 memset(&saa, 0, sizeof(saa));
285 saa.saa_busname = "sdmmc";
286 saa.saa_sct = &meson_sdhc_chip_functions;
287 saa.saa_dmat = sc->sc_dmat;
288 saa.saa_sch = sc;
289 saa.saa_clkmin = 400;
290 saa.saa_clkmax = pll_freq;
291 /* Do not advertise DMA capabilities, we handle DMA ourselves */
292 saa.saa_caps = SMC_CAPS_4BIT_MODE|
293 SMC_CAPS_SD_HIGHSPEED|
294 SMC_CAPS_MMC_HIGHSPEED|
295 SMC_CAPS_UHS_SDR50|
296 SMC_CAPS_UHS_SDR104|
297 SMC_CAPS_AUTO_STOP;
298
299 if (sc->sc_port == SDHC_PORT_C) {
300 saa.saa_caps |= SMC_CAPS_MMC_HS200;
301 saa.saa_caps |= SMC_CAPS_8BIT_MODE;
302 }
303
304 sc->sc_sdmmc_dev = config_found(self, &saa, NULL, CFARGS_NONE);
305 }
306
307 static int
meson_sdhc_intr(void * priv)308 meson_sdhc_intr(void *priv)
309 {
310 struct meson_sdhc_softc *sc = priv;
311 uint32_t ista;
312
313 mutex_enter(&sc->sc_intr_lock);
314 ista = SDHC_READ(sc, SD_ISTA_REG);
315
316 if (!ista) {
317 mutex_exit(&sc->sc_intr_lock);
318 return 0;
319 }
320
321 SDHC_WRITE(sc, SD_ISTA_REG, ista);
322
323 sc->sc_intr_ista |= ista;
324 cv_broadcast(&sc->sc_intr_cv);
325
326 mutex_exit(&sc->sc_intr_lock);
327
328 return 1;
329 }
330
331 static void
meson_sdhc_dmainit(struct meson_sdhc_softc * sc)332 meson_sdhc_dmainit(struct meson_sdhc_softc *sc)
333 {
334 int error, rseg;
335
336 error = bus_dmamem_alloc(sc->sc_dmat, MAXPHYS, PAGE_SIZE, MAXPHYS,
337 sc->sc_segs, 1, &rseg, BUS_DMA_WAITOK);
338 if (error) {
339 device_printf(sc->sc_dev, "bus_dmamem_alloc failed: %d\n", error);
340 return;
341 }
342 KASSERT(rseg == 1);
343
344 error = bus_dmamem_map(sc->sc_dmat, sc->sc_segs, rseg, MAXPHYS,
345 &sc->sc_bbuf, BUS_DMA_WAITOK);
346 if (error) {
347 device_printf(sc->sc_dev, "bus_dmamem_map failed\n");
348 return;
349 }
350
351 error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, 1, MAXPHYS, 0,
352 BUS_DMA_WAITOK, &sc->sc_dmamap);
353 if (error) {
354 device_printf(sc->sc_dev, "bus_dmamap_create failed\n");
355 return;
356 }
357
358 }
359
360 static int
meson_sdhc_default_rx_phase(struct meson_sdhc_softc * sc)361 meson_sdhc_default_rx_phase(struct meson_sdhc_softc *sc)
362 {
363 const u_int pll_freq = sc->sc_bus_freq / 1000;
364 const u_int clkc = SDHC_READ(sc, SD_CLKC_REG);
365 const u_int clk_div = __SHIFTOUT(clkc, SD_CLKC_CLK_DIV);
366 const u_int act_freq = pll_freq / clk_div;
367
368 if (act_freq > 90000) {
369 return 1;
370 } else if (act_freq > 45000) {
371 if (sc->sc_signal_voltage == SDMMC_SIGNAL_VOLTAGE_330) {
372 return 15;
373 } else {
374 return 11;
375 }
376 } else if (act_freq >= 25000) {
377 return 15;
378 } else if (act_freq > 5000) {
379 return 23;
380 } else if (act_freq > 1000) {
381 return 55;
382 } else {
383 return 1061;
384 }
385 }
386
387 static int
meson_sdhc_set_clock(struct meson_sdhc_softc * sc,u_int freq)388 meson_sdhc_set_clock(struct meson_sdhc_softc *sc, u_int freq)
389 {
390 uint32_t clkc;
391 uint32_t clk2;
392 u_int pll_freq, clk_div;
393
394 clkc = SDHC_READ(sc, SD_CLKC_REG);
395 clkc &= ~SD_CLKC_TX_CLK_ENABLE;
396 clkc &= ~SD_CLKC_RX_CLK_ENABLE;
397 clkc &= ~SD_CLKC_SD_CLK_ENABLE;
398 SDHC_WRITE(sc, SD_CLKC_REG, clkc);
399 clkc &= ~SD_CLKC_MOD_CLK_ENABLE;
400 SDHC_WRITE(sc, SD_CLKC_REG, clkc);
401
402 if (freq == 0)
403 return 0;
404
405 clkc &= ~SD_CLKC_CLK_DIV;
406 clkc &= ~SD_CLKC_CLK_IN_SEL;
407
408 clkc |= __SHIFTIN(SD_CLKC_CLK_IN_SEL_FCLK_DIV3,
409 SD_CLKC_CLK_IN_SEL);
410
411 pll_freq = sc->sc_bus_freq / 1000; /* 2.55GHz */
412 clk_div = howmany(pll_freq, freq);
413
414 clkc |= __SHIFTIN(clk_div - 1, SD_CLKC_CLK_DIV);
415
416 SDHC_WRITE(sc, SD_CLKC_REG, clkc);
417
418 clkc |= SD_CLKC_MOD_CLK_ENABLE;
419 SDHC_WRITE(sc, SD_CLKC_REG, clkc);
420
421 clkc |= SD_CLKC_TX_CLK_ENABLE;
422 clkc |= SD_CLKC_RX_CLK_ENABLE;
423 clkc |= SD_CLKC_SD_CLK_ENABLE;
424 SDHC_WRITE(sc, SD_CLKC_REG, clkc);
425
426 clk2 = SDHC_READ(sc, SD_CLK2_REG);
427 clk2 &= ~SD_CLK2_SD_CLK_PHASE;
428 clk2 |= __SHIFTIN(1, SD_CLK2_SD_CLK_PHASE);
429 clk2 &= ~SD_CLK2_RX_CLK_PHASE;
430 clk2 |= __SHIFTIN(meson_sdhc_default_rx_phase(sc),
431 SD_CLK2_RX_CLK_PHASE);
432 SDHC_WRITE(sc, SD_CLK2_REG, clk2);
433
434 return 0;
435 }
436
437 static int
meson_sdhc_wait_idle(struct meson_sdhc_softc * sc)438 meson_sdhc_wait_idle(struct meson_sdhc_softc *sc)
439 {
440 int i;
441
442 for (i = 0; i < 1000000; i++) {
443 const uint32_t stat = SDHC_READ(sc, SD_STAT_REG);
444 const uint32_t esta = SDHC_READ(sc, SD_ESTA_REG);
445 if ((stat & SD_STAT_BUSY) == 0 &&
446 (esta & SD_ESTA_BUSY) == 0)
447 return 0;
448 delay(1);
449 }
450
451 return EBUSY;
452 }
453
454 static int
meson_sdhc_wait_ista(struct meson_sdhc_softc * sc,uint32_t mask,int timeout)455 meson_sdhc_wait_ista(struct meson_sdhc_softc *sc, uint32_t mask, int timeout)
456 {
457 int retry, error;
458
459 KASSERT(mutex_owned(&sc->sc_intr_lock));
460
461 if (sc->sc_intr_ista & mask)
462 return 0;
463
464 retry = timeout / hz;
465
466 while (retry > 0) {
467 error = cv_timedwait(&sc->sc_intr_cv, &sc->sc_intr_lock, hz);
468 if (error && error != EWOULDBLOCK)
469 return error;
470 if (sc->sc_intr_ista & mask)
471 return 0;
472 --retry;
473 }
474
475 return ETIMEDOUT;
476 }
477
478 static int
meson_sdhc_host_reset(sdmmc_chipset_handle_t sch)479 meson_sdhc_host_reset(sdmmc_chipset_handle_t sch)
480 {
481 struct meson_sdhc_softc *sc = sch;
482 uint32_t enhc;
483
484 SDHC_WRITE(sc, SD_SRST_REG,
485 SD_SRST_MAIN_CTRL | SD_SRST_TX_FIFO | SD_SRST_RX_FIFO |
486 SD_SRST_DPHY_TX | SD_SRST_DPHY_RX | SD_SRST_DMA_IF);
487
488 delay(50);
489
490 SDHC_WRITE(sc, SD_SRST_REG, 0);
491
492 delay(10);
493
494 SDHC_WRITE(sc, SD_CNTL_REG,
495 __SHIFTIN(0x7, SD_CNTL_TX_ENDIAN_CTRL) |
496 __SHIFTIN(0x7, SD_CNTL_RX_ENDIAN_CTRL) |
497 __SHIFTIN(0xf, SD_CNTL_RX_PERIOD) |
498 __SHIFTIN(0x7f, SD_CNTL_RX_TIMEOUT));
499
500 SDHC_WRITE(sc, SD_CLKC_REG,
501 SDHC_READ(sc, SD_CLKC_REG) & ~SD_CLKC_MEM_PWR);
502
503 SDHC_WRITE(sc, SD_PDMA_REG,
504 __SHIFTIN(7, SD_PDMA_TX_BURST_LEN) |
505 __SHIFTIN(49, SD_PDMA_TXFIFO_THRESHOLD) |
506 __SHIFTIN(15, SD_PDMA_RX_BURST_LEN) |
507 __SHIFTIN(7, SD_PDMA_RXFIFO_THRESHOLD) |
508 SD_PDMA_DMA_URGENT);
509
510 SDHC_WRITE(sc, SD_MISC_REG,
511 __SHIFTIN(7, SD_MISC_TXSTART_THRESHOLD) |
512 __SHIFTIN(5, SD_MISC_WCRC_ERR_PATTERN) |
513 __SHIFTIN(2, SD_MISC_WCRC_OK_PATTERN));
514
515 enhc = SDHC_READ(sc, SD_ENHC_REG);
516 enhc &= ~SD_ENHC_RXFIFO_THRESHOLD;
517 enhc |= __SHIFTIN(63, SD_ENHC_RXFIFO_THRESHOLD);
518 enhc &= ~SD_ENHC_DMA_RX_RESP;
519 enhc |= SD_ENHC_DMA_TX_RESP;
520 enhc &= ~SD_ENHC_SDIO_IRQ_PERIOD;
521 enhc |= __SHIFTIN(12, SD_ENHC_SDIO_IRQ_PERIOD);
522 enhc &= ~SD_ENHC_RX_TIMEOUT;
523 enhc |= __SHIFTIN(0xff, SD_ENHC_RX_TIMEOUT);
524 SDHC_WRITE(sc, SD_ENHC_REG, enhc);
525
526 SDHC_WRITE(sc, SD_ICTL_REG, 0);
527 SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
528
529 return 0;
530 }
531
532 static uint32_t
meson_sdhc_host_ocr(sdmmc_chipset_handle_t sch)533 meson_sdhc_host_ocr(sdmmc_chipset_handle_t sch)
534 {
535 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V |
536 MMC_OCR_HCS | MMC_OCR_S18A;
537 }
538
539 static int
meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)540 meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)
541 {
542 return 512;
543 }
544
545 static int
meson_sdhc_card_detect(sdmmc_chipset_handle_t sch)546 meson_sdhc_card_detect(sdmmc_chipset_handle_t sch)
547 {
548 struct meson_sdhc_softc *sc = sch;
549 int val;
550
551 if (sc->sc_non_removable || sc->sc_broken_cd) {
552 return 1;
553 } else if (sc->sc_gpio_cd != NULL) {
554 val = fdtbus_gpio_read(sc->sc_gpio_cd);
555 if (sc->sc_gpio_cd_inverted)
556 val = !val;
557 return val;
558 } else {
559 return 1;
560 }
561 }
562
563 static int
meson_sdhc_write_protect(sdmmc_chipset_handle_t sch)564 meson_sdhc_write_protect(sdmmc_chipset_handle_t sch)
565 {
566 struct meson_sdhc_softc *sc = sch;
567 int val;
568
569 if (sc->sc_gpio_wp != NULL) {
570 val = fdtbus_gpio_read(sc->sc_gpio_wp);
571 if (sc->sc_gpio_wp_inverted)
572 val = !val;
573 return val;
574 }
575
576 return 0;
577 }
578
579 static int
meson_sdhc_bus_power(sdmmc_chipset_handle_t sch,uint32_t ocr)580 meson_sdhc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
581 {
582 return 0;
583 }
584
585 static int
meson_sdhc_bus_clock(sdmmc_chipset_handle_t sch,int freq)586 meson_sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
587 {
588 struct meson_sdhc_softc *sc = sch;
589
590 return meson_sdhc_set_clock(sc, freq);
591 }
592
593 static int
meson_sdhc_bus_width(sdmmc_chipset_handle_t sch,int width)594 meson_sdhc_bus_width(sdmmc_chipset_handle_t sch, int width)
595 {
596 struct meson_sdhc_softc *sc = sch;
597 uint32_t cntl;
598
599 cntl = SDHC_READ(sc, SD_CNTL_REG);
600 cntl &= ~SD_CNTL_DAT_TYPE;
601 switch (width) {
602 case 1:
603 cntl |= __SHIFTIN(0, SD_CNTL_DAT_TYPE);
604 break;
605 case 4:
606 cntl |= __SHIFTIN(1, SD_CNTL_DAT_TYPE);
607 break;
608 case 8:
609 cntl |= __SHIFTIN(2, SD_CNTL_DAT_TYPE);
610 break;
611 default:
612 return EINVAL;
613 }
614
615 SDHC_WRITE(sc, SD_CNTL_REG, cntl);
616
617 return 0;
618 }
619
620 static int
meson_sdhc_bus_rod(sdmmc_chipset_handle_t sch,int on)621 meson_sdhc_bus_rod(sdmmc_chipset_handle_t sch, int on)
622 {
623 return ENOTSUP;
624 }
625
626 static void
meson_sdhc_exec_command(sdmmc_chipset_handle_t sch,struct sdmmc_command * cmd)627 meson_sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
628 {
629 struct meson_sdhc_softc *sc = sch;
630 uint32_t cmdval = 0, cntl, srst, pdma, ictl;
631 bool use_bbuf = false;
632 int i;
633
634 KASSERT(cmd->c_blklen <= 512);
635
636 mutex_enter(&sc->sc_intr_lock);
637
638 /* Filter SDIO commands */
639 switch (cmd->c_opcode) {
640 case SD_IO_SEND_OP_COND:
641 case SD_IO_RW_DIRECT:
642 case SD_IO_RW_EXTENDED:
643 cmd->c_error = EINVAL;
644 goto done;
645 }
646
647 if (cmd->c_opcode == MMC_STOP_TRANSMISSION)
648 cmdval |= SD_SEND_DATA_STOP;
649 if (cmd->c_flags & SCF_RSP_PRESENT)
650 cmdval |= SD_SEND_COMMAND_HAS_RESP;
651 if (cmd->c_flags & SCF_RSP_136) {
652 cmdval |= SD_SEND_RESPONSE_LENGTH;
653 cmdval |= SD_SEND_RESPONSE_NO_CRC;
654 }
655 if ((cmd->c_flags & SCF_RSP_CRC) == 0)
656 cmdval |= SD_SEND_RESPONSE_NO_CRC;
657
658 SDHC_WRITE(sc, SD_ICTL_REG, 0);
659 SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
660 sc->sc_intr_ista = 0;
661
662 ictl = SD_INT_ERROR;
663
664 cntl = SDHC_READ(sc, SD_CNTL_REG);
665 cntl &= ~SD_CNTL_PACK_LEN;
666 if (cmd->c_datalen > 0) {
667 unsigned int nblks;
668
669 cmdval |= SD_SEND_COMMAND_HAS_DATA;
670 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) {
671 cmdval |= SD_SEND_DATA_DIRECTION;
672 }
673
674 nblks = cmd->c_datalen / cmd->c_blklen;
675 if (nblks == 0 || (cmd->c_datalen % cmd->c_blklen) != 0)
676 ++nblks;
677
678 cntl |= __SHIFTIN(cmd->c_blklen & 0x1ff, SD_CNTL_PACK_LEN);
679
680 cmdval |= __SHIFTIN(nblks - 1, SD_SEND_TOTAL_PACK);
681
682 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
683 ictl |= SD_INT_DATA_COMPLETE;
684 } else {
685 ictl |= SD_INT_DMA_DONE;
686 }
687 } else {
688 ictl |= SD_INT_RESP_COMPLETE;
689 }
690
691 SDHC_WRITE(sc, SD_ICTL_REG, ictl);
692
693 SDHC_WRITE(sc, SD_CNTL_REG, cntl);
694
695 pdma = SDHC_READ(sc, SD_PDMA_REG);
696 if (cmd->c_datalen > 0) {
697 pdma |= SD_PDMA_DMA_MODE;
698 } else {
699 pdma &= ~SD_PDMA_DMA_MODE;
700 }
701 SDHC_WRITE(sc, SD_PDMA_REG, pdma);
702
703 SDHC_WRITE(sc, SD_ARGU_REG, cmd->c_arg);
704
705 cmd->c_error = meson_sdhc_wait_idle(sc);
706 if (cmd->c_error) {
707 goto done;
708 }
709
710 if (cmd->c_datalen > 0) {
711 cmd->c_error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap,
712 sc->sc_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK);
713 if (cmd->c_error) {
714 device_printf(sc->sc_dev, "bus_dmamap_load failed\n");
715 goto done;
716 }
717 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
718 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
719 MAXPHYS, BUS_DMASYNC_PREREAD);
720 } else {
721 memcpy(sc->sc_bbuf, cmd->c_data, cmd->c_datalen);
722 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
723 MAXPHYS, BUS_DMASYNC_PREWRITE);
724 }
725 SDHC_WRITE(sc, SD_ADDR_REG, sc->sc_dmamap->dm_segs[0].ds_addr);
726 use_bbuf = true;
727 }
728
729 cmd->c_resid = cmd->c_datalen;
730 SDHC_WRITE(sc, SD_SEND_REG, cmdval | cmd->c_opcode);
731
732 if (cmd->c_datalen > 0) {
733 uint32_t wbit = ISSET(cmd->c_flags, SCF_CMD_READ) ?
734 SD_INT_DATA_COMPLETE : SD_INT_DMA_DONE;
735 cmd->c_error = meson_sdhc_wait_ista(sc,
736 SD_INT_ERROR | wbit, hz * 10);
737 if (cmd->c_error == 0 &&
738 (sc->sc_intr_ista & SD_INT_ERROR)) {
739 cmd->c_error = ETIMEDOUT;
740 }
741 if (cmd->c_error) {
742 goto done;
743 }
744 } else {
745 cmd->c_error = meson_sdhc_wait_ista(sc,
746 SD_INT_ERROR | SD_INT_RESP_COMPLETE, hz * 10);
747 if (cmd->c_error == 0 && (sc->sc_intr_ista & SD_INT_ERROR)) {
748 if (sc->sc_intr_ista & SD_INT_TIMEOUT) {
749 cmd->c_error = ETIMEDOUT;
750 } else {
751 cmd->c_error = EIO;
752 }
753 }
754 if (cmd->c_error) {
755 goto done;
756 }
757 }
758
759 SDHC_WRITE(sc, SD_ISTA_REG, sc->sc_intr_ista);
760
761 if (cmd->c_flags & SCF_RSP_PRESENT) {
762 pdma = SDHC_READ(sc, SD_PDMA_REG);
763 pdma &= ~SD_PDMA_DMA_MODE;
764 if (cmd->c_flags & SCF_RSP_136) {
765 for (i = 4; i >= 1; i--) {
766 pdma &= ~SD_PDMA_PIO_RDRESP;
767 pdma |= __SHIFTIN(i, SD_PDMA_PIO_RDRESP);
768 SDHC_WRITE(sc, SD_PDMA_REG, pdma);
769 cmd->c_resp[i - 1] = SDHC_READ(sc, SD_ARGU_REG);
770
771 }
772 if (cmd->c_flags & SCF_RSP_CRC) {
773 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) |
774 (cmd->c_resp[1] << 24);
775 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) |
776 (cmd->c_resp[2] << 24);
777 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) |
778 (cmd->c_resp[3] << 24);
779 cmd->c_resp[3] = (cmd->c_resp[3] >> 8);
780 }
781 } else {
782 pdma &= ~SD_PDMA_PIO_RDRESP;
783 pdma |= __SHIFTIN(0, SD_PDMA_PIO_RDRESP);
784 SDHC_WRITE(sc, SD_PDMA_REG, pdma);
785 cmd->c_resp[0] = SDHC_READ(sc, SD_ARGU_REG);
786 }
787 }
788
789 done:
790 if (use_bbuf) {
791 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
792 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
793 MAXPHYS, BUS_DMASYNC_POSTREAD);
794 } else {
795 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
796 MAXPHYS, BUS_DMASYNC_POSTWRITE);
797 }
798 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap);
799 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
800 memcpy(cmd->c_data, sc->sc_bbuf, cmd->c_datalen);
801 }
802 }
803
804 cmd->c_flags |= SCF_ITSDONE;
805
806 SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
807 SDHC_WRITE(sc, SD_ICTL_REG, 0);
808
809 srst = SDHC_READ(sc, SD_SRST_REG);
810 srst |= (SD_SRST_TX_FIFO | SD_SRST_RX_FIFO);
811 SDHC_WRITE(sc, SD_SRST_REG, srst);
812
813 mutex_exit(&sc->sc_intr_lock);
814 }
815
816 static void
meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t sch,int enable)817 meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
818 {
819 }
820
821 static void
meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)822 meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
823 {
824 }
825
826 static int
meson_sdhc_signal_voltage(sdmmc_chipset_handle_t sch,int signal_voltage)827 meson_sdhc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage)
828 {
829 struct meson_sdhc_softc *sc = sch;
830 u_int uvol;
831 int error;
832
833 if (sc->sc_reg_vqmmc == NULL)
834 return 0;
835
836 switch (signal_voltage) {
837 case SDMMC_SIGNAL_VOLTAGE_330:
838 uvol = 3300000;
839 break;
840 case SDMMC_SIGNAL_VOLTAGE_180:
841 uvol = 1800000;
842 break;
843 default:
844 return EINVAL;
845 }
846
847 error = fdtbus_regulator_supports_voltage(sc->sc_reg_vqmmc, uvol, uvol);
848 if (error != 0)
849 return 0;
850
851 error = fdtbus_regulator_set_voltage(sc->sc_reg_vqmmc, uvol, uvol);
852 if (error != 0)
853 return error;
854
855 error = fdtbus_regulator_enable(sc->sc_reg_vqmmc);
856 if (error != 0)
857 return error;
858
859 sc->sc_signal_voltage = signal_voltage;
860 return 0;
861 }
862
863 static int
meson_sdhc_execute_tuning(sdmmc_chipset_handle_t sch,int timing)864 meson_sdhc_execute_tuning(sdmmc_chipset_handle_t sch, int timing)
865 {
866 static const uint8_t tuning_blk_8bit[] = {
867 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
868 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
869 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
870 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
871 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
872 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
873 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
874 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
875 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
876 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
877 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
878 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
879 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
880 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
881 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
882 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
883 };
884 static const uint8_t tuning_blk_4bit[] = {
885 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
886 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
887 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
888 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
889 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
890 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
891 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
892 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
893 };
894
895 struct meson_sdhc_softc *sc = sch;
896 struct sdmmc_command cmd;
897 uint8_t data[sizeof(tuning_blk_8bit)];
898 const uint8_t *tblk;
899 size_t tsize;
900 struct window_s {
901 int start;
902 u_int size;
903 } best = { .start = -1, .size = 0 },
904 curr = { .start = -1, .size = 0 },
905 wrap = { .start = 0, .size = 0 };
906 u_int ph, rx_phase, clk_div;
907 int opcode;
908
909 switch (timing) {
910 case SDMMC_TIMING_MMC_HS200:
911 tblk = tuning_blk_8bit;
912 tsize = sizeof(tuning_blk_8bit);
913 opcode = MMC_SEND_TUNING_BLOCK_HS200;
914 break;
915 case SDMMC_TIMING_UHS_SDR50:
916 case SDMMC_TIMING_UHS_SDR104:
917 tblk = tuning_blk_4bit;
918 tsize = sizeof(tuning_blk_4bit);
919 opcode = MMC_SEND_TUNING_BLOCK;
920 break;
921 default:
922 return EINVAL;
923 }
924
925 const uint32_t clkc = SDHC_READ(sc, SD_CLKC_REG);
926 clk_div = __SHIFTOUT(clkc, SD_CLKC_CLK_DIV);
927
928 for (ph = 0; ph <= clk_div; ph++) {
929 SDHC_SET_CLEAR(sc, SD_CLK2_REG,
930 __SHIFTIN(ph, SD_CLK2_RX_CLK_PHASE), SD_CLK2_RX_CLK_PHASE);
931 delay(10);
932
933 u_int nmatch = 0;
934 #define NUMTRIES 10
935 for (u_int i = 0; i < NUMTRIES; i++) {
936 memset(data, 0, tsize);
937 memset(&cmd, 0, sizeof(cmd));
938 cmd.c_data = data;
939 cmd.c_datalen = cmd.c_blklen = tsize;
940 cmd.c_opcode = opcode;
941 cmd.c_arg = 0;
942 cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1;
943 meson_sdhc_exec_command(sc, &cmd);
944 if (cmd.c_error == 0 && memcmp(data, tblk, tsize) == 0)
945 nmatch++;
946 }
947 if (nmatch == NUMTRIES) { /* good phase value */
948 if (wrap.start == 0)
949 wrap.size++;
950 if (curr.start == -1)
951 curr.start = ph;
952 curr.size++;
953 } else {
954 wrap.start = -1;
955 if (curr.start != -1) { /* end of current window */
956 if (best.start == -1 || best.size < curr.size)
957 best = curr;
958 curr = (struct window_s)
959 { .start = -1, .size = 0 };
960 }
961 }
962 #undef NUMTRIES
963 }
964
965 if (curr.start != -1) { /* the current window wraps around */
966 curr.size += wrap.size;
967 if (curr.size > ph)
968 curr.size = ph;
969 if (best.start == -1 || best.size < curr.size)
970 best = curr;
971 }
972
973 if (best.start == -1) { /* no window - use default rx_phase */
974 rx_phase = meson_sdhc_default_rx_phase(sc);
975 } else {
976 rx_phase = best.start + best.size / 2;
977 if (rx_phase >= ph)
978 rx_phase -= ph;
979 }
980
981 SDHC_SET_CLEAR(sc, SD_CLK2_REG,
982 __SHIFTIN(rx_phase, SD_CLK2_RX_CLK_PHASE), SD_CLK2_RX_CLK_PHASE);
983
984 return 0;
985 }
986