1 /* $OpenBSD: dwmmc.c,v 1.29 2023/07/01 08:27:26 jsing Exp $ */
2 /*
3 * Copyright (c) 2017 Mark Kettenis
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <sys/param.h>
19 #include <sys/kernel.h>
20 #include <sys/malloc.h>
21 #include <sys/systm.h>
22
23 #include <machine/bus.h>
24 #include <machine/fdt.h>
25 #include <machine/intr.h>
26
27 #include <dev/ofw/openfirm.h>
28 #include <dev/ofw/ofw_clock.h>
29 #include <dev/ofw/ofw_gpio.h>
30 #include <dev/ofw/ofw_pinctrl.h>
31 #include <dev/ofw/fdt.h>
32
33 #include <dev/sdmmc/sdmmcvar.h>
34 #include <dev/sdmmc/sdmmc_ioreg.h>
35
36 #define SDMMC_CTRL 0x0000
37 #define SDMMC_CTRL_USE_INTERNAL_DMAC (1 << 25)
38 #define SDMMC_CTRL_DMA_ENABLE (1 << 5)
39 #define SDMMC_CTRL_INT_ENABLE (1 << 4)
40 #define SDMMC_CTRL_DMA_RESET (1 << 2)
41 #define SDMMC_CTRL_FIFO_RESET (1 << 1)
42 #define SDMMC_CTRL_CONTROLLER_RESET (1 << 0)
43 #define SDMMC_CTRL_ALL_RESET (SDMMC_CTRL_CONTROLLER_RESET | \
44 SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_DMA_RESET)
45 #define SDMMC_PWREN 0x0004
46 #define SDMMC_CLKDIV 0x0008
47 #define SDMMC_CLKSRC 0x000c
48 #define SDMMC_CLKENA 0x0010
49 #define SDMMC_CLKENA_CCLK_LOW_POWER (1 << 16)
50 #define SDMMC_CLKENA_CCLK_ENABLE (1 << 0)
51 #define SDMMC_TMOUT 0x0014
52 #define SDMMC_CTYPE 0x0018
53 #define SDMMC_CTYPE_8BIT (1 << 16)
54 #define SDMMC_CTYPE_4BIT (1 << 0)
55 #define SDMMC_BLKSIZ 0x001c
56 #define SDMMC_BYTCNT 0x0020
57 #define SDMMC_INTMASK 0x0024
58 #define SDMMC_CMDARG 0x0028
59 #define SDMMC_CMD 0x002c
60 #define SDMMC_CMD_START_CMD (1U << 31)
61 #define SDMMC_CMD_USE_HOLD_REG (1 << 29)
62 #define SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY (1 << 21)
63 #define SDMMC_CMD_SEND_INITIALIZATION (1 << 15)
64 #define SDMMC_CMD_STOP_ABORT_CMD (1 << 14)
65 #define SDMMC_CMD_WAIT_PRVDATA_COMPLETE (1 << 13)
66 #define SDMMC_CMD_SEND_AUTO_STOP (1 << 12)
67 #define SDMMC_CMD_WR (1 << 10)
68 #define SDMMC_CMD_DATA_EXPECTED (1 << 9)
69 #define SDMMC_CMD_CHECK_REPONSE_CRC (1 << 8)
70 #define SDMMC_CMD_RESPONSE_LENGTH (1 << 7)
71 #define SDMMC_CMD_RESPONSE_EXPECT (1 << 6)
72 #define SDMMC_RESP0 0x0030
73 #define SDMMC_RESP1 0x0034
74 #define SDMMC_RESP2 0x0038
75 #define SDMMC_RESP3 0x003c
76 #define SDMMC_MINTSTS 0x0040
77 #define SDMMC_RINTSTS 0x0044
78 #define SDMMC_RINTSTS_SDIO (1 << 24)
79 #define SDMMC_RINTSTS_EBE (1 << 15)
80 #define SDMMC_RINTSTS_ACD (1 << 14)
81 #define SDMMC_RINTSTS_SBE (1 << 13)
82 #define SDMMC_RINTSTS_HLE (1 << 12)
83 #define SDMMC_RINTSTS_FRUN (1 << 11)
84 #define SDMMC_RINTSTS_HTO (1 << 10)
85 #define SDMMC_RINTSTS_DRTO (1 << 9)
86 #define SDMMC_RINTSTS_RTO (1 << 8)
87 #define SDMMC_RINTSTS_DCRC (1 << 7)
88 #define SDMMC_RINTSTS_RCRC (1 << 6)
89 #define SDMMC_RINTSTS_RXDR (1 << 5)
90 #define SDMMC_RINTSTS_TXDR (1 << 4)
91 #define SDMMC_RINTSTS_DTO (1 << 3)
92 #define SDMMC_RINTSTS_CD (1 << 2)
93 #define SDMMC_RINTSTS_RE (1 << 1)
94 #define SDMMC_RINTSTS_CDT (1 << 0)
95 #define SDMMC_RINTSTS_DATA_ERR (SDMMC_RINTSTS_EBE | SDMMC_RINTSTS_SBE | \
96 SDMMC_RINTSTS_HLE | SDMMC_RINTSTS_FRUN | SDMMC_RINTSTS_DCRC)
97 #define SDMMC_RINTSTS_DATA_TO (SDMMC_RINTSTS_HTO | SDMMC_RINTSTS_DRTO)
98 #define SDMMC_STATUS 0x0048
99 #define SDMMC_STATUS_FIFO_COUNT(x) (((x) >> 17) & 0x1fff)
100 #define SDMMC_STATUS_DATA_BUSY (1 << 9)
101 #define SDMMC_FIFOTH 0x004c
102 #define SDMMC_FIFOTH_MSIZE_SHIFT 28
103 #define SDMMC_FIFOTH_RXWM_SHIFT 16
104 #define SDMMC_FIFOTH_RXWM(x) (((x) >> 16) & 0xfff)
105 #define SDMMC_FIFOTH_TXWM_SHIFT 0
106 #define SDMMC_CDETECT 0x0050
107 #define SDMMC_CDETECT_CARD_DETECT_0 (1 << 0)
108 #define SDMMC_WRTPRT 0x0054
109 #define SDMMC_TCBCNT 0x005c
110 #define SDMMC_TBBCNT 0x0060
111 #define SDMMC_DEBNCE 0x0064
112 #define SDMMC_USRID 0x0068
113 #define SDMMC_VERID 0x006c
114 #define SDMMC_HCON 0x0070
115 #define SDMMC_HCON_DATA_WIDTH(x) (((x) >> 7) & 0x7)
116 #define SDMMC_HCON_DMA64 (1 << 27)
117 #define SDMMC_UHS_REG 0x0074
118 #define SDMMC_RST_n 0x0078
119 #define SDMMC_BMOD 0x0080
120 #define SDMMC_BMOD_DE (1 << 7)
121 #define SDMMC_BMOD_FB (1 << 1)
122 #define SDMMC_BMOD_SWR (1 << 0)
123 #define SDMMC_PLDMND 0x0084
124 #define SDMMC_DBADDR 0x0088
125 #define SDMMC_IDSTS32 0x008c
126 #define SDMMC_IDSTS_NIS (1 << 8)
127 #define SDMMC_IDSTS_RI (1 << 1)
128 #define SDMMC_IDSTS_TI (1 << 0)
129 #define SDMMC_IDINTEN32 0x0090
130 #define SDMMC_IDINTEN_NI (1 << 8)
131 #define SDMMC_IDINTEN_RI (1 << 1)
132 #define SDMMC_IDINTEN_TI (1 << 0)
133 #define SDMMC_DSCADDR 0x0094
134 #define SDMMC_BUFADDR 0x0098
135 #define SDMMC_CLKSEL 0x009c
136 #define SDMMC_CARDTHRCTL 0x0100
137 #define SDMMC_CARDTHRCTL_RDTHR_SHIFT 16
138 #define SDMMC_CARDTHRCTL_RDTHREN (1 << 0)
139 #define SDMMC_BACK_END_POWER 0x0104
140 #define SDMMC_EMMC_DDR_REG 0x0108
141 #define SDMMC_FIFO_BASE 0x0200
142
143 #define SDMMC_DBADDRL 0x0088
144 #define SDMMC_DBADDRH 0x008c
145 #define SDMMC_IDSTS64 0x0090
146 #define SDMMC_IDINTEN64 0x0094
147 #define SDMMC_DSCADDRL 0x0098
148 #define SDMMC_DSCADDRH 0x009c
149 #define SDMMC_BUFADDRL 0x00a0
150 #define SDMMC_BUFADDRH 0x00a4
151
152 #define SDMMC_IDSTS(sc) \
153 ((sc)->sc_dma64 ? SDMMC_IDSTS64 : SDMMC_IDSTS32)
154
155 #define HREAD4(sc, reg) \
156 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
157 #define HWRITE4(sc, reg, val) \
158 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
159 #define HSET4(sc, reg, bits) \
160 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
161 #define HCLR4(sc, reg, bits) \
162 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
163
164 struct dwmmc_desc32 {
165 uint32_t des[4];
166 };
167
168 struct dwmmc_desc64 {
169 uint32_t des[8];
170 };
171
172 #define DWMMC_NDESC (PAGE_SIZE / sizeof(struct dwmmc_desc64))
173 #define DWMMC_MAXSEGSZ 0x1000
174
175 #define DES0_OWN (1U << 31)
176 #define DES0_CES (1 << 30)
177 #define DES0_ER (1 << 5)
178 #define DES0_CH (1 << 4)
179 #define DES0_FS (1 << 3)
180 #define DES0_LD (1 << 2)
181 #define DES0_DIC (1 << 1)
182
183 #define DES1_BS2(sz) (((sz) & 0x1fff) << 13)
184 #define DES1_BS1(sz) (((sz) & 0x1fff) << 0)
185 #define DES2_BS2(sz) DES1_BS2(sz)
186 #define DES2_BS1(sz) DES1_BS1(sz)
187
188 struct dwmmc_softc {
189 struct device sc_dev;
190 bus_space_tag_t sc_iot;
191 bus_space_handle_t sc_ioh;
192 bus_size_t sc_size;
193 bus_dma_tag_t sc_dmat;
194 bus_dmamap_t sc_dmap;
195 int sc_node;
196
197 void *sc_ih;
198
199 uint32_t sc_clkbase;
200 uint32_t sc_fifo_depth;
201 uint32_t sc_fifo_width;
202 void (*sc_read_data)(struct dwmmc_softc *, u_char *, int);
203 void (*sc_write_data)(struct dwmmc_softc *, u_char *, int);
204 int sc_blklen;
205
206 bus_dmamap_t sc_desc_map;
207 bus_dma_segment_t sc_desc_segs[1];
208 caddr_t sc_desc;
209 int sc_dma64;
210 int sc_dmamode;
211 uint32_t sc_idsts;
212
213 uint32_t sc_gpio[4];
214 int sc_sdio_irq;
215 uint32_t sc_pwrseq;
216 uint32_t sc_vdd;
217
218 struct device *sc_sdmmc;
219 };
220
221 int dwmmc_match(struct device *, void *, void *);
222 void dwmmc_attach(struct device *, struct device *, void *);
223
224 const struct cfattach dwmmc_ca = {
225 sizeof(struct dwmmc_softc), dwmmc_match, dwmmc_attach
226 };
227
228 struct cfdriver dwmmc_cd = {
229 NULL, "dwmmc", DV_DULL
230 };
231
232 int dwmmc_intr(void *);
233
234 int dwmmc_host_reset(sdmmc_chipset_handle_t);
235 uint32_t dwmmc_host_ocr(sdmmc_chipset_handle_t);
236 int dwmmc_host_maxblklen(sdmmc_chipset_handle_t);
237 int dwmmc_card_detect(sdmmc_chipset_handle_t);
238 int dwmmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
239 int dwmmc_bus_clock(sdmmc_chipset_handle_t, int, int);
240 int dwmmc_bus_width(sdmmc_chipset_handle_t, int);
241 void dwmmc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
242 void dwmmc_card_intr_mask(sdmmc_chipset_handle_t, int);
243 void dwmmc_card_intr_ack(sdmmc_chipset_handle_t);
244
245 struct sdmmc_chip_functions dwmmc_chip_functions = {
246 .host_reset = dwmmc_host_reset,
247 .host_ocr = dwmmc_host_ocr,
248 .host_maxblklen = dwmmc_host_maxblklen,
249 .card_detect = dwmmc_card_detect,
250 .bus_power = dwmmc_bus_power,
251 .bus_clock = dwmmc_bus_clock,
252 .bus_width = dwmmc_bus_width,
253 .exec_command = dwmmc_exec_command,
254 .card_intr_mask = dwmmc_card_intr_mask,
255 .card_intr_ack = dwmmc_card_intr_ack,
256 };
257
258 void dwmmc_pio_mode(struct dwmmc_softc *);
259 int dwmmc_alloc_descriptors(struct dwmmc_softc *);
260 void dwmmc_init_descriptors(struct dwmmc_softc *);
261 void dwmmc_transfer_data(struct dwmmc_softc *, struct sdmmc_command *);
262 void dwmmc_read_data32(struct dwmmc_softc *, u_char *, int);
263 void dwmmc_write_data32(struct dwmmc_softc *, u_char *, int);
264 void dwmmc_read_data64(struct dwmmc_softc *, u_char *, int);
265 void dwmmc_write_data64(struct dwmmc_softc *, u_char *, int);
266 void dwmmc_pwrseq_pre(uint32_t);
267 void dwmmc_pwrseq_post(uint32_t);
268
269 int
dwmmc_match(struct device * parent,void * match,void * aux)270 dwmmc_match(struct device *parent, void *match, void *aux)
271 {
272 struct fdt_attach_args *faa = aux;
273
274 return (OF_is_compatible(faa->fa_node, "hisilicon,hi3660-dw-mshc") ||
275 OF_is_compatible(faa->fa_node, "hisilicon,hi3670-dw-mshc") ||
276 OF_is_compatible(faa->fa_node, "rockchip,rk3288-dw-mshc") ||
277 OF_is_compatible(faa->fa_node, "samsung,exynos5420-dw-mshc") ||
278 OF_is_compatible(faa->fa_node, "snps,dw-mshc") ||
279 OF_is_compatible(faa->fa_node, "starfive,jh7110-mmc"));
280 }
281
282 void
dwmmc_attach(struct device * parent,struct device * self,void * aux)283 dwmmc_attach(struct device *parent, struct device *self, void *aux)
284 {
285 struct dwmmc_softc *sc = (struct dwmmc_softc *)self;
286 struct fdt_attach_args *faa = aux;
287 struct sdmmcbus_attach_args saa;
288 uint32_t freq = 0, div = 0;
289 uint32_t hcon, width;
290 uint32_t fifoth;
291 int error, timeout;
292
293 if (faa->fa_nreg < 1) {
294 printf(": no registers\n");
295 return;
296 }
297
298 sc->sc_node = faa->fa_node;
299 sc->sc_iot = faa->fa_iot;
300 sc->sc_size = faa->fa_reg[0].size;
301
302 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
303 faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
304 printf(": can't map registers\n");
305 return;
306 }
307
308 pinctrl_byname(faa->fa_node, "default");
309
310 clock_enable_all(faa->fa_node);
311 reset_deassert_all(faa->fa_node);
312
313 /*
314 * Determine FIFO width from hardware configuration register.
315 * We only support 32-bit and 64-bit FIFOs.
316 */
317 hcon = HREAD4(sc, SDMMC_HCON);
318 switch (SDMMC_HCON_DATA_WIDTH(hcon)) {
319 case 1:
320 sc->sc_fifo_width = 4;
321 sc->sc_read_data = dwmmc_read_data32;
322 sc->sc_write_data = dwmmc_write_data32;
323 break;
324 case 2:
325 sc->sc_fifo_width = 8;
326 sc->sc_read_data = dwmmc_read_data64;
327 sc->sc_write_data = dwmmc_write_data64;
328 break;
329 default:
330 printf(": unsupported FIFO width\n");
331 return;
332 }
333
334 sc->sc_fifo_depth = OF_getpropint(faa->fa_node, "fifo-depth", 0);
335 if (sc->sc_fifo_depth == 0) {
336 fifoth = HREAD4(sc, SDMMC_FIFOTH);
337 sc->sc_fifo_depth = SDMMC_FIFOTH_RXWM(fifoth) + 1;
338 }
339
340 if (hcon & SDMMC_HCON_DMA64)
341 sc->sc_dma64 = 1;
342
343 /* Some SoCs pre-divide the clock. */
344 if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-dw-mshc"))
345 div = 1;
346 if (OF_is_compatible(faa->fa_node, "hisilicon,hi3660-dw-mshc") ||
347 OF_is_compatible(faa->fa_node, "hisilicon,hi3670-dw-mshc"))
348 div = 7;
349
350 /* Force the base clock to 50MHz on Rockchip SoCs. */
351 if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-dw-mshc"))
352 freq = 50000000;
353
354 freq = OF_getpropint(faa->fa_node, "clock-frequency", freq);
355 if (freq > 0)
356 clock_set_frequency(faa->fa_node, "ciu", (div + 1) * freq);
357
358 sc->sc_clkbase = clock_get_frequency(faa->fa_node, "ciu");
359 /* if ciu clock is missing the rate is clock-frequency */
360 if (sc->sc_clkbase == 0)
361 sc->sc_clkbase = freq;
362 if (sc->sc_clkbase == 0) {
363 printf(": no clock base\n");
364 return;
365 }
366 div = OF_getpropint(faa->fa_node, "samsung,dw-mshc-ciu-div", div);
367 sc->sc_clkbase /= (div + 1);
368
369 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_BIO,
370 dwmmc_intr, sc, sc->sc_dev.dv_xname);
371 if (sc->sc_ih == NULL) {
372 printf(": can't establish interrupt\n");
373 goto unmap;
374 }
375
376 OF_getpropintarray(faa->fa_node, "cd-gpios", sc->sc_gpio,
377 sizeof(sc->sc_gpio));
378 if (sc->sc_gpio[0])
379 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT);
380
381 sc->sc_sdio_irq = (OF_getproplen(sc->sc_node, "cap-sdio-irq") == 0);
382 sc->sc_pwrseq = OF_getpropint(sc->sc_node, "mmc-pwrseq", 0);
383
384 printf(": %d MHz base clock\n", sc->sc_clkbase / 1000000);
385
386 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_ALL_RESET);
387 for (timeout = 5000; timeout > 0; timeout--) {
388 if ((HREAD4(sc, SDMMC_CTRL) & SDMMC_CTRL_ALL_RESET) == 0)
389 break;
390 delay(100);
391 }
392 if (timeout == 0)
393 printf("%s: reset failed\n", sc->sc_dev.dv_xname);
394
395 /* Enable interrupts, but mask them all. */
396 HWRITE4(sc, SDMMC_INTMASK, 0);
397 HWRITE4(sc, SDMMC_RINTSTS, 0xffffffff);
398 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_INT_ENABLE);
399
400 dwmmc_bus_width(sc, 1);
401
402 /* Start out in non-DMA mode. */
403 dwmmc_pio_mode(sc);
404
405 sc->sc_dmat = faa->fa_dmat;
406 dwmmc_alloc_descriptors(sc);
407 dwmmc_init_descriptors(sc);
408
409 error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, DWMMC_NDESC,
410 DWMMC_MAXSEGSZ, 0, BUS_DMA_WAITOK|BUS_DMA_ALLOCNOW, &sc->sc_dmap);
411 if (error) {
412 printf(": can't create DMA map\n");
413 goto unmap;
414 }
415
416 memset(&saa, 0, sizeof(saa));
417 saa.saa_busname = "sdmmc";
418 saa.sct = &dwmmc_chip_functions;
419 saa.sch = sc;
420 saa.dmat = sc->sc_dmat;
421 saa.dmap = sc->sc_dmap;
422 saa.caps |= SMC_CAPS_DMA;
423
424 if (OF_getproplen(sc->sc_node, "cap-mmc-highspeed") == 0)
425 saa.caps |= SMC_CAPS_MMC_HIGHSPEED;
426 if (OF_getproplen(sc->sc_node, "cap-sd-highspeed") == 0)
427 saa.caps |= SMC_CAPS_SD_HIGHSPEED;
428
429 width = OF_getpropint(faa->fa_node, "bus-width", 1);
430 if (width >= 8)
431 saa.caps |= SMC_CAPS_8BIT_MODE;
432 if (width >= 4)
433 saa.caps |= SMC_CAPS_4BIT_MODE;
434
435 sc->sc_sdmmc = config_found(self, &saa, NULL);
436 return;
437
438 unmap:
439 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
440 }
441
442 int
dwmmc_alloc_descriptors(struct dwmmc_softc * sc)443 dwmmc_alloc_descriptors(struct dwmmc_softc *sc)
444 {
445 int error, rseg;
446
447 /* Allocate descriptor memory */
448 error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE,
449 PAGE_SIZE, sc->sc_desc_segs, 1, &rseg,
450 BUS_DMA_WAITOK | BUS_DMA_ZERO);
451 if (error)
452 return error;
453 error = bus_dmamem_map(sc->sc_dmat, sc->sc_desc_segs, rseg,
454 PAGE_SIZE, &sc->sc_desc, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
455 if (error) {
456 bus_dmamem_free(sc->sc_dmat, sc->sc_desc_segs, rseg);
457 return error;
458 }
459 error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE,
460 0, BUS_DMA_WAITOK, &sc->sc_desc_map);
461 if (error) {
462 bus_dmamem_unmap(sc->sc_dmat, sc->sc_desc, PAGE_SIZE);
463 bus_dmamem_free(sc->sc_dmat, sc->sc_desc_segs, rseg);
464 return error;
465 }
466 error = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_map,
467 sc->sc_desc, PAGE_SIZE, NULL, BUS_DMA_WAITOK | BUS_DMA_WRITE);
468 if (error) {
469 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_map);
470 bus_dmamem_unmap(sc->sc_dmat, sc->sc_desc, PAGE_SIZE);
471 bus_dmamem_free(sc->sc_dmat, sc->sc_desc_segs, rseg);
472 return error;
473 }
474
475 return 0;
476 }
477
478 void
dwmmc_init_descriptors32(struct dwmmc_softc * sc)479 dwmmc_init_descriptors32(struct dwmmc_softc *sc)
480 {
481 struct dwmmc_desc32 *desc;
482 bus_addr_t addr;
483 int i;
484
485 desc = (void *)sc->sc_desc;
486 addr = sc->sc_desc_map->dm_segs[0].ds_addr;
487 for (i = 0; i < DWMMC_NDESC; i++) {
488 addr += sizeof(struct dwmmc_desc32);
489 desc[i].des[3] = addr;
490 }
491 desc[DWMMC_NDESC - 1].des[3] = sc->sc_desc_map->dm_segs[0].ds_addr;
492 desc[DWMMC_NDESC - 1].des[0] = DES0_ER;
493 bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0,
494 PAGE_SIZE, BUS_DMASYNC_PREWRITE);
495
496 HWRITE4(sc, SDMMC_IDSTS32, 0xffffffff);
497 HWRITE4(sc, SDMMC_IDINTEN32,
498 SDMMC_IDINTEN_NI | SDMMC_IDINTEN_RI | SDMMC_IDINTEN_TI);
499 HWRITE4(sc, SDMMC_DBADDR, sc->sc_desc_map->dm_segs[0].ds_addr);
500 }
501
502 void
dwmmc_init_descriptors64(struct dwmmc_softc * sc)503 dwmmc_init_descriptors64(struct dwmmc_softc *sc)
504 {
505 struct dwmmc_desc64 *desc;
506 bus_addr_t addr;
507 int i;
508
509 desc = (void *)sc->sc_desc;
510 addr = sc->sc_desc_map->dm_segs[0].ds_addr;
511 for (i = 0; i < DWMMC_NDESC; i++) {
512 addr += sizeof(struct dwmmc_desc64);
513 desc[i].des[6] = addr;
514 desc[i].des[7] = (uint64_t)addr >> 32;
515 }
516 desc[DWMMC_NDESC - 1].des[6] = sc->sc_desc_map->dm_segs[0].ds_addr;
517 desc[DWMMC_NDESC - 1].des[7] =
518 (uint64_t)sc->sc_desc_map->dm_segs[0].ds_addr >> 32;
519 desc[DWMMC_NDESC - 1].des[0] = DES0_ER;
520 bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0,
521 PAGE_SIZE, BUS_DMASYNC_PREWRITE);
522
523 HWRITE4(sc, SDMMC_IDSTS64, 0xffffffff);
524 HWRITE4(sc, SDMMC_IDINTEN64,
525 SDMMC_IDINTEN_NI | SDMMC_IDINTEN_RI | SDMMC_IDINTEN_TI);
526 HWRITE4(sc, SDMMC_DBADDRL, sc->sc_desc_map->dm_segs[0].ds_addr);
527 HWRITE4(sc, SDMMC_DBADDRH,
528 (uint64_t)sc->sc_desc_map->dm_segs[0].ds_addr >> 32);
529 }
530
531 void
dwmmc_init_descriptors(struct dwmmc_softc * sc)532 dwmmc_init_descriptors(struct dwmmc_softc *sc)
533 {
534 if (sc->sc_dma64)
535 dwmmc_init_descriptors64(sc);
536 else
537 dwmmc_init_descriptors32(sc);
538 }
539
540 int
dwmmc_intr(void * arg)541 dwmmc_intr(void *arg)
542 {
543 struct dwmmc_softc *sc = arg;
544 uint32_t stat;
545 int handled = 0;
546
547 stat = HREAD4(sc, SDMMC_IDSTS(sc));
548 if (stat) {
549 HWRITE4(sc, SDMMC_IDSTS(sc), stat);
550 sc->sc_idsts |= stat;
551 wakeup(&sc->sc_idsts);
552 handled = 1;
553 }
554
555 stat = HREAD4(sc, SDMMC_MINTSTS);
556 if (stat & SDMMC_RINTSTS_SDIO) {
557 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_SDIO);
558 HCLR4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO);
559 sdmmc_card_intr(sc->sc_sdmmc);
560 handled = 1;
561 }
562
563 return handled;
564 }
565
566 void
dwmmc_card_intr_mask(sdmmc_chipset_handle_t sch,int enable)567 dwmmc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
568 {
569 struct dwmmc_softc *sc = sch;
570
571 if (enable)
572 HSET4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO);
573 else
574 HCLR4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO);
575 }
576
577 void
dwmmc_card_intr_ack(sdmmc_chipset_handle_t sch)578 dwmmc_card_intr_ack(sdmmc_chipset_handle_t sch)
579 {
580 struct dwmmc_softc *sc = sch;
581
582 HSET4(sc, SDMMC_INTMASK, SDMMC_RINTSTS_SDIO);
583 }
584
585 int
dwmmc_host_reset(sdmmc_chipset_handle_t sch)586 dwmmc_host_reset(sdmmc_chipset_handle_t sch)
587 {
588 printf("%s\n", __func__);
589 return 0;
590 }
591
592 uint32_t
dwmmc_host_ocr(sdmmc_chipset_handle_t sch)593 dwmmc_host_ocr(sdmmc_chipset_handle_t sch)
594 {
595 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V;
596 }
597
598 int
dwmmc_host_maxblklen(sdmmc_chipset_handle_t sch)599 dwmmc_host_maxblklen(sdmmc_chipset_handle_t sch)
600 {
601 return 512;
602 }
603
604 int
dwmmc_card_detect(sdmmc_chipset_handle_t sch)605 dwmmc_card_detect(sdmmc_chipset_handle_t sch)
606 {
607 struct dwmmc_softc *sc = sch;
608 uint32_t cdetect;
609
610 /* XXX treat broken-cd as non-removable */
611 if (OF_getproplen(sc->sc_node, "non-removable") == 0 ||
612 OF_getproplen(sc->sc_node, "broken-cd") == 0)
613 return 1;
614
615 if (sc->sc_gpio[0]) {
616 int inverted, val;
617
618 val = gpio_controller_get_pin(sc->sc_gpio);
619
620 inverted = (OF_getproplen(sc->sc_node, "cd-inverted") == 0);
621 return inverted ? !val : val;
622 }
623
624 cdetect = HREAD4(sc, SDMMC_CDETECT);
625 return !(cdetect & SDMMC_CDETECT_CARD_DETECT_0);
626 }
627
628 int
dwmmc_bus_power(sdmmc_chipset_handle_t sch,uint32_t ocr)629 dwmmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
630 {
631 struct dwmmc_softc *sc = sch;
632 uint32_t vdd = 0;
633
634 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V))
635 vdd = 3300000;
636
637 if (sc->sc_vdd == 0 && vdd > 0)
638 dwmmc_pwrseq_pre(sc->sc_pwrseq);
639
640 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V))
641 HSET4(sc, SDMMC_PWREN, 1);
642 else
643 HCLR4(sc, SDMMC_PWREN, 0);
644
645 if (sc->sc_vdd == 0 && vdd > 0)
646 dwmmc_pwrseq_post(sc->sc_pwrseq);
647
648 sc->sc_vdd = vdd;
649 return 0;
650 }
651
652 int
dwmmc_bus_clock(sdmmc_chipset_handle_t sch,int freq,int timing)653 dwmmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, int timing)
654 {
655 struct dwmmc_softc *sc = sch;
656 int div = 0, timeout;
657 uint32_t clkena;
658
659 HWRITE4(sc, SDMMC_CLKENA, 0);
660 HWRITE4(sc, SDMMC_CLKSRC, 0);
661
662 if (freq == 0)
663 return 0;
664
665 if (sc->sc_clkbase / 1000 > freq) {
666 for (div = 1; div < 256; div++)
667 if (sc->sc_clkbase / (2 * 1000 * div) <= freq)
668 break;
669 }
670 HWRITE4(sc, SDMMC_CLKDIV, div);
671
672 /* Update clock. */
673 HWRITE4(sc, SDMMC_CMD, SDMMC_CMD_START_CMD |
674 SDMMC_CMD_WAIT_PRVDATA_COMPLETE |
675 SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY);
676 for (timeout = 1000; timeout > 0; timeout--) {
677 if ((HREAD4(sc, SDMMC_CMD) & SDMMC_CMD_START_CMD) == 0)
678 break;
679 }
680 if (timeout == 0) {
681 printf("%s: timeout\n", __func__);
682 return ETIMEDOUT;
683 }
684
685 /* Enable clock; low power mode only for memory mode. */
686 clkena = SDMMC_CLKENA_CCLK_ENABLE;
687 if (!sc->sc_sdio_irq)
688 clkena |= SDMMC_CLKENA_CCLK_LOW_POWER;
689 HWRITE4(sc, SDMMC_CLKENA, clkena);
690
691 /* Update clock again. */
692 HWRITE4(sc, SDMMC_CMD, SDMMC_CMD_START_CMD |
693 SDMMC_CMD_WAIT_PRVDATA_COMPLETE |
694 SDMMC_CMD_UPDATE_CLOCK_REGISTERS_ONLY);
695 for (timeout = 1000; timeout > 0; timeout--) {
696 if ((HREAD4(sc, SDMMC_CMD) & SDMMC_CMD_START_CMD) == 0)
697 break;
698 }
699 if (timeout == 0) {
700 printf("%s: timeout\n", __func__);
701 return ETIMEDOUT;
702 }
703
704 delay(1000000);
705
706 return 0;
707 }
708
709 int
dwmmc_bus_width(sdmmc_chipset_handle_t sch,int width)710 dwmmc_bus_width(sdmmc_chipset_handle_t sch, int width)
711 {
712 struct dwmmc_softc *sc = sch;
713
714 switch (width) {
715 case 1:
716 HCLR4(sc, SDMMC_CTYPE, SDMMC_CTYPE_8BIT|SDMMC_CTYPE_4BIT);
717 break;
718 case 4:
719 HSET4(sc, SDMMC_CTYPE, SDMMC_CTYPE_4BIT);
720 HCLR4(sc, SDMMC_CTYPE, SDMMC_CTYPE_8BIT);
721 break;
722 case 8:
723 HSET4(sc, SDMMC_CTYPE, SDMMC_CTYPE_8BIT);
724 break;
725 default:
726 return EINVAL;
727 }
728
729 return 0;
730 }
731
732 void
dwmmc_pio_mode(struct dwmmc_softc * sc)733 dwmmc_pio_mode(struct dwmmc_softc *sc)
734 {
735 /* Disable DMA. */
736 HCLR4(sc, SDMMC_CTRL, SDMMC_CTRL_USE_INTERNAL_DMAC |
737 SDMMC_CTRL_DMA_ENABLE);
738
739 /* Set FIFO thresholds. */
740 HWRITE4(sc, SDMMC_FIFOTH, 2 << SDMMC_FIFOTH_MSIZE_SHIFT |
741 (sc->sc_fifo_depth / 2 - 1) << SDMMC_FIFOTH_RXWM_SHIFT |
742 (sc->sc_fifo_depth / 2) << SDMMC_FIFOTH_TXWM_SHIFT);
743
744 sc->sc_dmamode = 0;
745 sc->sc_blklen = 0;
746 }
747
748 void
dwmmc_dma_mode(struct dwmmc_softc * sc)749 dwmmc_dma_mode(struct dwmmc_softc *sc)
750 {
751 int timeout;
752
753 /* Reset DMA. */
754 HSET4(sc, SDMMC_BMOD, SDMMC_BMOD_SWR);
755 for (timeout = 1000; timeout > 0; timeout--) {
756 if ((HREAD4(sc, SDMMC_BMOD) & SDMMC_BMOD_SWR) == 0)
757 break;
758 delay(100);
759 }
760 if (timeout == 0)
761 printf("%s: DMA reset failed\n", sc->sc_dev.dv_xname);
762
763 /* Enable DMA. */
764 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_USE_INTERNAL_DMAC |
765 SDMMC_CTRL_DMA_ENABLE);
766 HSET4(sc, SDMMC_BMOD, SDMMC_BMOD_FB | SDMMC_BMOD_DE);
767
768 sc->sc_dmamode = 1;
769 }
770
771 void
dwmmc_dma_setup32(struct dwmmc_softc * sc,struct sdmmc_command * cmd)772 dwmmc_dma_setup32(struct dwmmc_softc *sc, struct sdmmc_command *cmd)
773 {
774 struct dwmmc_desc32 *desc = (void *)sc->sc_desc;
775 uint32_t flags;
776 int seg;
777
778 flags = DES0_OWN | DES0_FS | DES0_CH | DES0_DIC;
779 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
780 bus_addr_t addr = cmd->c_dmamap->dm_segs[seg].ds_addr;
781 bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len;
782
783 if (seg == cmd->c_dmamap->dm_nsegs - 1) {
784 flags |= DES0_LD;
785 flags &= ~DES0_DIC;
786 }
787
788 KASSERT((desc[seg].des[0] & DES0_OWN) == 0);
789 desc[seg].des[0] = flags;
790 desc[seg].des[1] = DES1_BS1(len);
791 desc[seg].des[2] = addr;
792 flags &= ~DES0_FS;
793 }
794 }
795
796 void
dwmmc_dma_setup64(struct dwmmc_softc * sc,struct sdmmc_command * cmd)797 dwmmc_dma_setup64(struct dwmmc_softc *sc, struct sdmmc_command *cmd)
798 {
799 struct dwmmc_desc64 *desc = (void *)sc->sc_desc;
800 uint32_t flags;
801 int seg;
802
803 flags = DES0_OWN | DES0_FS | DES0_CH | DES0_DIC;
804 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
805 bus_addr_t addr = cmd->c_dmamap->dm_segs[seg].ds_addr;
806 bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len;
807
808 if (seg == cmd->c_dmamap->dm_nsegs - 1) {
809 flags |= DES0_LD;
810 flags &= ~DES0_DIC;
811 }
812
813 KASSERT((desc[seg].des[0] & DES0_OWN) == 0);
814 desc[seg].des[0] = flags;
815 desc[seg].des[2] = DES2_BS1(len);
816 desc[seg].des[4] = addr;
817 desc[seg].des[5] = (uint64_t)addr >> 32;
818 flags &= ~DES0_FS;
819 }
820 }
821
822 void
dwmmc_dma_setup(struct dwmmc_softc * sc,struct sdmmc_command * cmd)823 dwmmc_dma_setup(struct dwmmc_softc *sc, struct sdmmc_command *cmd)
824 {
825 if (sc->sc_dma64)
826 dwmmc_dma_setup64(sc, cmd);
827 else
828 dwmmc_dma_setup32(sc, cmd);
829
830 bus_dmamap_sync(sc->sc_dmat, sc->sc_desc_map, 0, PAGE_SIZE,
831 BUS_DMASYNC_PREWRITE);
832
833 sc->sc_idsts = 0;
834 }
835
836 void
dwmmc_dma_reset(struct dwmmc_softc * sc,struct sdmmc_command * cmd)837 dwmmc_dma_reset(struct dwmmc_softc *sc, struct sdmmc_command *cmd)
838 {
839 int timeout;
840
841 /* Reset DMA unit. */
842 HSET4(sc, SDMMC_BMOD, SDMMC_BMOD_SWR);
843 for (timeout = 1000; timeout > 0; timeout--) {
844 if ((HREAD4(sc, SDMMC_BMOD) &
845 SDMMC_BMOD_SWR) == 0)
846 break;
847 delay(100);
848 }
849
850 dwmmc_pio_mode(sc);
851
852 /* Clear descriptors that were in use, */
853 memset(sc->sc_desc, 0, PAGE_SIZE);
854 dwmmc_init_descriptors(sc);
855 }
856
857 void
dwmmc_fifo_setup(struct dwmmc_softc * sc,int blklen)858 dwmmc_fifo_setup(struct dwmmc_softc *sc, int blklen)
859 {
860 int blkdepth = blklen / sc->sc_fifo_width;
861 int txwm = sc->sc_fifo_depth / 2;
862 int rxwm, msize = 0;
863
864 /*
865 * Bursting is only possible of the block size is a multiple of
866 * the FIFO width.
867 */
868 if (blklen % sc->sc_fifo_width == 0)
869 msize = 7;
870
871 /* Magic to calculate the maximum burst size. */
872 while (msize > 0) {
873 if (blkdepth % (2 << msize) == 0 &&
874 (sc->sc_fifo_depth - txwm) % (2 << msize) == 0)
875 break;
876 msize--;
877 }
878 rxwm = (2 << msize) - 1;
879
880 HWRITE4(sc, SDMMC_FIFOTH,
881 msize << SDMMC_FIFOTH_MSIZE_SHIFT |
882 rxwm << SDMMC_FIFOTH_RXWM_SHIFT |
883 txwm << SDMMC_FIFOTH_TXWM_SHIFT);
884
885 sc->sc_blklen = blklen;
886 }
887
888 void
dwmmc_exec_command(sdmmc_chipset_handle_t sch,struct sdmmc_command * cmd)889 dwmmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
890 {
891 struct dwmmc_softc *sc = sch;
892 uint32_t cmdval = SDMMC_CMD_START_CMD | SDMMC_CMD_USE_HOLD_REG;
893 uint32_t status;
894 int error, timeout;
895 int s;
896
897 #if 0
898 printf("%s: cmd %d arg 0x%x flags 0x%x data %p datalen %d blklen %d\n",
899 sc->sc_dev.dv_xname, cmd->c_opcode, cmd->c_arg, cmd->c_flags,
900 cmd->c_data, cmd->c_datalen, cmd->c_blklen);
901 #endif
902
903 s = splbio();
904
905 for (timeout = 10000; timeout > 0; timeout--) {
906 status = HREAD4(sc, SDMMC_STATUS);
907 if ((status & SDMMC_STATUS_DATA_BUSY) == 0)
908 break;
909 delay(100);
910 }
911 if (timeout == 0) {
912 printf("%s: timeout on data busy\n", sc->sc_dev.dv_xname);
913 goto done;
914 }
915
916 if (cmd->c_opcode == MMC_STOP_TRANSMISSION)
917 cmdval |= SDMMC_CMD_STOP_ABORT_CMD;
918 else if (cmd->c_opcode != MMC_SEND_STATUS)
919 cmdval |= SDMMC_CMD_WAIT_PRVDATA_COMPLETE;
920
921 if (cmd->c_opcode == 0)
922 cmdval |= SDMMC_CMD_SEND_INITIALIZATION;
923 if (cmd->c_flags & SCF_RSP_PRESENT)
924 cmdval |= SDMMC_CMD_RESPONSE_EXPECT;
925 if (cmd->c_flags & SCF_RSP_136)
926 cmdval |= SDMMC_CMD_RESPONSE_LENGTH;
927 if (cmd->c_flags & SCF_RSP_CRC)
928 cmdval |= SDMMC_CMD_CHECK_REPONSE_CRC;
929
930 if (cmd->c_datalen > 0) {
931 HWRITE4(sc, SDMMC_TMOUT, 0xffffffff);
932 HWRITE4(sc, SDMMC_BYTCNT, cmd->c_datalen);
933 HWRITE4(sc, SDMMC_BLKSIZ, cmd->c_blklen);
934
935 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
936 /* Set card read threshold to the size of a block. */
937 HWRITE4(sc, SDMMC_CARDTHRCTL,
938 cmd->c_blklen << SDMMC_CARDTHRCTL_RDTHR_SHIFT |
939 SDMMC_CARDTHRCTL_RDTHREN);
940 }
941
942 cmdval |= SDMMC_CMD_DATA_EXPECTED;
943 if (!ISSET(cmd->c_flags, SCF_CMD_READ))
944 cmdval |= SDMMC_CMD_WR;
945 if (cmd->c_datalen > cmd->c_blklen &&
946 cmd->c_opcode != SD_IO_RW_EXTENDED)
947 cmdval |= SDMMC_CMD_SEND_AUTO_STOP;
948 }
949
950 if (cmd->c_datalen > 0 && !cmd->c_dmamap) {
951 HSET4(sc, SDMMC_CTRL, SDMMC_CTRL_FIFO_RESET);
952 for (timeout = 1000; timeout > 0; timeout--) {
953 if ((HREAD4(sc, SDMMC_CTRL) &
954 SDMMC_CTRL_FIFO_RESET) == 0)
955 break;
956 delay(100);
957 }
958 if (timeout == 0)
959 printf("%s: FIFO reset failed\n", sc->sc_dev.dv_xname);
960
961 /* Disable DMA if we are switching back to PIO. */
962 if (sc->sc_dmamode)
963 dwmmc_pio_mode(sc);
964 }
965
966 if (cmd->c_datalen > 0 && cmd->c_dmamap) {
967 dwmmc_dma_setup(sc, cmd);
968 HWRITE4(sc, SDMMC_PLDMND, 1);
969
970 /* Enable DMA if we did PIO before. */
971 if (!sc->sc_dmamode)
972 dwmmc_dma_mode(sc);
973
974 /* Reconfigure FIFO thresholds if block size changed. */
975 if (cmd->c_blklen != sc->sc_blklen)
976 dwmmc_fifo_setup(sc, cmd->c_blklen);
977 }
978
979 HWRITE4(sc, SDMMC_RINTSTS, ~SDMMC_RINTSTS_SDIO);
980
981 HWRITE4(sc, SDMMC_CMDARG, cmd->c_arg);
982 HWRITE4(sc, SDMMC_CMD, cmdval | cmd->c_opcode);
983
984 for (timeout = 1000; timeout > 0; timeout--) {
985 status = HREAD4(sc, SDMMC_RINTSTS);
986 if (status & SDMMC_RINTSTS_CD)
987 break;
988 delay(100);
989 }
990 if (timeout == 0 || status & SDMMC_RINTSTS_RTO) {
991 cmd->c_error = ETIMEDOUT;
992 dwmmc_dma_reset(sc, cmd);
993 goto done;
994 }
995
996 if (cmd->c_flags & SCF_RSP_PRESENT) {
997 if (cmd->c_flags & SCF_RSP_136) {
998 cmd->c_resp[0] = HREAD4(sc, SDMMC_RESP0);
999 cmd->c_resp[1] = HREAD4(sc, SDMMC_RESP1);
1000 cmd->c_resp[2] = HREAD4(sc, SDMMC_RESP2);
1001 cmd->c_resp[3] = HREAD4(sc, SDMMC_RESP3);
1002 if (cmd->c_flags & SCF_RSP_CRC) {
1003 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) |
1004 (cmd->c_resp[1] << 24);
1005 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) |
1006 (cmd->c_resp[2] << 24);
1007 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) |
1008 (cmd->c_resp[3] << 24);
1009 cmd->c_resp[3] = (cmd->c_resp[3] >> 8);
1010 }
1011 } else {
1012 cmd->c_resp[0] = HREAD4(sc, SDMMC_RESP0);
1013 }
1014 }
1015
1016 if (cmd->c_datalen > 0 && !cmd->c_dmamap)
1017 dwmmc_transfer_data(sc, cmd);
1018
1019 if (cmd->c_datalen > 0 && cmd->c_dmamap) {
1020 while (sc->sc_idsts == 0) {
1021 error = tsleep_nsec(&sc->sc_idsts, PWAIT, "idsts",
1022 SEC_TO_NSEC(1));
1023 if (error) {
1024 cmd->c_error = error;
1025 dwmmc_dma_reset(sc, cmd);
1026 goto done;
1027 }
1028 }
1029
1030 for (timeout = 10000; timeout > 0; timeout--) {
1031 status = HREAD4(sc, SDMMC_RINTSTS);
1032 if (status & SDMMC_RINTSTS_DTO)
1033 break;
1034 delay(100);
1035 }
1036 if (timeout == 0) {
1037 cmd->c_error = ETIMEDOUT;
1038 dwmmc_dma_reset(sc, cmd);
1039 goto done;
1040 }
1041 }
1042
1043 if (cmdval & SDMMC_CMD_SEND_AUTO_STOP) {
1044 for (timeout = 10000; timeout > 0; timeout--) {
1045 status = HREAD4(sc, SDMMC_RINTSTS);
1046 if (status & SDMMC_RINTSTS_ACD)
1047 break;
1048 delay(10);
1049 }
1050 if (timeout == 0) {
1051 cmd->c_error = ETIMEDOUT;
1052 dwmmc_dma_reset(sc, cmd);
1053 goto done;
1054 }
1055 }
1056
1057 done:
1058 cmd->c_flags |= SCF_ITSDONE;
1059 #if 0
1060 printf("%s: err %d rintsts 0x%x\n", sc->sc_dev.dv_xname, cmd->c_error,
1061 HREAD4(sc, SDMMC_RINTSTS));
1062 #endif
1063 splx(s);
1064 }
1065
1066 void
dwmmc_transfer_data(struct dwmmc_softc * sc,struct sdmmc_command * cmd)1067 dwmmc_transfer_data(struct dwmmc_softc *sc, struct sdmmc_command *cmd)
1068 {
1069 int datalen = cmd->c_datalen;
1070 u_char *datap = cmd->c_data;
1071 uint32_t status;
1072 int count, timeout;
1073 int fifodr = SDMMC_RINTSTS_DTO | SDMMC_RINTSTS_HTO;
1074
1075 if (ISSET(cmd->c_flags, SCF_CMD_READ))
1076 fifodr |= SDMMC_RINTSTS_RXDR;
1077 else
1078 fifodr |= SDMMC_RINTSTS_TXDR;
1079
1080 while (datalen > 0) {
1081 status = HREAD4(sc, SDMMC_RINTSTS);
1082 if (status & SDMMC_RINTSTS_DATA_ERR) {
1083 cmd->c_error = EIO;
1084 return;
1085 }
1086 if (status & SDMMC_RINTSTS_DRTO) {
1087 cmd->c_error = ETIMEDOUT;
1088 return;
1089 }
1090
1091 for (timeout = 10000; timeout > 0; timeout--) {
1092 status = HREAD4(sc, SDMMC_RINTSTS);
1093 if (status & fifodr)
1094 break;
1095 delay(100);
1096 }
1097 if (timeout == 0) {
1098 cmd->c_error = ETIMEDOUT;
1099 return;
1100 }
1101
1102 count = SDMMC_STATUS_FIFO_COUNT(HREAD4(sc, SDMMC_STATUS));
1103 if (!ISSET(cmd->c_flags, SCF_CMD_READ))
1104 count = sc->sc_fifo_depth - count;
1105
1106 count = MIN(datalen, count * sc->sc_fifo_width);
1107 if (ISSET(cmd->c_flags, SCF_CMD_READ))
1108 sc->sc_read_data(sc, datap, count);
1109 else
1110 sc->sc_write_data(sc, datap, count);
1111
1112 datap += count;
1113 datalen -= count;
1114 }
1115
1116 for (timeout = 10000; timeout > 0; timeout--) {
1117 status = HREAD4(sc, SDMMC_RINTSTS);
1118 if (status & SDMMC_RINTSTS_DTO)
1119 break;
1120 delay(100);
1121 }
1122 if (timeout == 0)
1123 cmd->c_error = ETIMEDOUT;
1124 }
1125
1126 void
dwmmc_read_data32(struct dwmmc_softc * sc,u_char * datap,int datalen)1127 dwmmc_read_data32(struct dwmmc_softc *sc, u_char *datap, int datalen)
1128 {
1129 while (datalen > 3) {
1130 *(uint32_t *)datap = HREAD4(sc, SDMMC_FIFO_BASE);
1131 datap += 4;
1132 datalen -= 4;
1133 }
1134 if (datalen > 0) {
1135 uint32_t rv = HREAD4(sc, SDMMC_FIFO_BASE);
1136 do {
1137 *datap++ = rv & 0xff;
1138 rv = rv >> 8;
1139 } while (--datalen > 0);
1140 }
1141 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_RXDR);
1142 }
1143
1144 void
dwmmc_write_data32(struct dwmmc_softc * sc,u_char * datap,int datalen)1145 dwmmc_write_data32(struct dwmmc_softc *sc, u_char *datap, int datalen)
1146 {
1147 while (datalen > 3) {
1148 HWRITE4(sc, SDMMC_FIFO_BASE, *((uint32_t *)datap));
1149 datap += 4;
1150 datalen -= 4;
1151 }
1152 if (datalen > 0) {
1153 uint32_t rv = *datap++;
1154 if (datalen > 1)
1155 rv |= *datap++ << 8;
1156 if (datalen > 2)
1157 rv |= *datap++ << 16;
1158 HWRITE4(sc, SDMMC_FIFO_BASE, rv);
1159 }
1160 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_TXDR);
1161 }
1162
1163 void
dwmmc_read_data64(struct dwmmc_softc * sc,u_char * datap,int datalen)1164 dwmmc_read_data64(struct dwmmc_softc *sc, u_char *datap, int datalen)
1165 {
1166 while (datalen > 7) {
1167 *(uint32_t *)datap = HREAD4(sc, SDMMC_FIFO_BASE);
1168 datap += 4;
1169 datalen -= 4;
1170 *(uint32_t *)datap = HREAD4(sc, SDMMC_FIFO_BASE + 4);
1171 datap += 4;
1172 datalen -= 4;
1173 }
1174 if (datalen > 0) {
1175 uint64_t rv = HREAD4(sc, SDMMC_FIFO_BASE) |
1176 ((uint64_t)HREAD4(sc, SDMMC_FIFO_BASE + 4) << 32);
1177 do {
1178 *datap++ = rv & 0xff;
1179 rv = rv >> 8;
1180 } while (--datalen > 0);
1181 }
1182 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_RXDR);
1183 }
1184
1185 void
dwmmc_write_data64(struct dwmmc_softc * sc,u_char * datap,int datalen)1186 dwmmc_write_data64(struct dwmmc_softc *sc, u_char *datap, int datalen)
1187 {
1188 while (datalen > 7) {
1189 HWRITE4(sc, SDMMC_FIFO_BASE, *((uint32_t *)datap));
1190 datap += 4;
1191 datalen -= 4;
1192 HWRITE4(sc, SDMMC_FIFO_BASE + 4, *((uint32_t *)datap));
1193 datap += 4;
1194 datalen -= 4;
1195 }
1196 if (datalen > 0) {
1197 uint32_t rv = *datap++;
1198 if (datalen > 1)
1199 rv |= *datap++ << 8;
1200 if (datalen > 2)
1201 rv |= *datap++ << 16;
1202 if (datalen > 3)
1203 rv |= *datap++ << 24;
1204 HWRITE4(sc, SDMMC_FIFO_BASE, rv);
1205 if (datalen > 4)
1206 rv = *datap++;
1207 if (datalen > 5)
1208 rv |= *datap++ << 8;
1209 if (datalen > 6)
1210 rv |= *datap++ << 16;
1211 HWRITE4(sc, SDMMC_FIFO_BASE + 4, rv);
1212 }
1213 HWRITE4(sc, SDMMC_RINTSTS, SDMMC_RINTSTS_TXDR);
1214 }
1215
1216 void
dwmmc_pwrseq_pre(uint32_t phandle)1217 dwmmc_pwrseq_pre(uint32_t phandle)
1218 {
1219 uint32_t *gpios, *gpio;
1220 int node;
1221 int len;
1222
1223 node = OF_getnodebyphandle(phandle);
1224 if (node == 0)
1225 return;
1226
1227 if (!OF_is_compatible(node, "mmc-pwrseq-simple"))
1228 return;
1229
1230 pinctrl_byname(node, "default");
1231
1232 clock_enable(node, "ext_clock");
1233
1234 len = OF_getproplen(node, "reset-gpios");
1235 if (len <= 0)
1236 return;
1237
1238 gpios = malloc(len, M_TEMP, M_WAITOK);
1239 OF_getpropintarray(node, "reset-gpios", gpios, len);
1240
1241 gpio = gpios;
1242 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) {
1243 gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT);
1244 gpio_controller_set_pin(gpio, 1);
1245 gpio = gpio_controller_next_pin(gpio);
1246 }
1247
1248 free(gpios, M_TEMP, len);
1249 }
1250
1251 void
dwmmc_pwrseq_post(uint32_t phandle)1252 dwmmc_pwrseq_post(uint32_t phandle)
1253 {
1254 uint32_t *gpios, *gpio;
1255 int node;
1256 int len;
1257
1258 node = OF_getnodebyphandle(phandle);
1259 if (node == 0)
1260 return;
1261
1262 if (!OF_is_compatible(node, "mmc-pwrseq-simple"))
1263 return;
1264
1265 len = OF_getproplen(node, "reset-gpios");
1266 if (len <= 0)
1267 return;
1268
1269 gpios = malloc(len, M_TEMP, M_WAITOK);
1270 OF_getpropintarray(node, "reset-gpios", gpios, len);
1271
1272 gpio = gpios;
1273 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) {
1274 gpio_controller_set_pin(gpio, 0);
1275 gpio = gpio_controller_next_pin(gpio);
1276 }
1277
1278 free(gpios, M_TEMP, len);
1279 }
1280