1 /* $OpenBSD: ommmc.c,v 1.41 2024/05/22 05:51:49 jsg Exp $ */
2
3 /*
4 * Copyright (c) 2009 Dale Rahn <drahn@openbsd.org>
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /* Omap SD/MMC support derived from /sys/dev/sdmmc/sdhc.c */
21
22
23 #include <sys/param.h>
24 #include <sys/device.h>
25 #include <sys/systm.h>
26 #include <machine/bus.h>
27 #include <machine/fdt.h>
28
29 #include <dev/sdmmc/sdmmcchip.h>
30 #include <dev/sdmmc/sdmmcvar.h>
31
32 #include <armv7/omap/prcmvar.h>
33
34 #include <dev/ofw/openfirm.h>
35 #include <dev/ofw/ofw_gpio.h>
36 #include <dev/ofw/ofw_pinctrl.h>
37 #include <dev/ofw/fdt.h>
38
39 /*
40 * NOTE: on OMAP4430/AM335x these registers skew by 0x100
41 * this is handled by mapping at base address + 0x100
42 */
43 /* registers */
44 #define MMCHS_SYSCONFIG 0x010
45 #define MMCHS_SYSSTATUS 0x014
46 #define MMCHS_CSRE 0x024
47 #define MMCHS_SYSTEST 0x028
48 #define MMCHS_SYSTEST_SDCD (1 << 15)
49 #define MMCHS_CON 0x02C
50 #define MMCHS_CON_INIT (1<<1)
51 #define MMCHS_CON_DW8 (1<<5)
52 #define MMCHS_CON_OD (1<<0)
53 #define MMCHS_PWCNT 0x030
54 #define MMCHS_BLK 0x104
55 #define MMCHS_BLK_NBLK_MAX 0xffff
56 #define MMCHS_BLK_NBLK_SHIFT 16
57 #define MMCHS_BLK_NBLK_MASK (MMCHS_BLK_NBLK_MAX<<MMCHS_BLK_NBLK_SHIFT)
58 #define MMCHS_BLK_BLEN_MAX 0x400
59 #define MMCHS_BLK_BLEN_SHIFT 0
60 #define MMCHS_BLK_BLEN_MASK (MMCHS_BLK_BLEN_MAX<<MMCHS_BLK_BLEN_SHIFT)
61 #define MMCHS_ARG 0x108
62 #define MMCHS_CMD 0x10C
63 #define MMCHS_CMD_INDX_SHIFT 24
64 #define MMCHS_CMD_INDX_SHIFT_MASK (0x3f << MMCHS_CMD_INDX_SHIFT)
65 #define MMCHS_CMD_CMD_TYPE_SHIFT 22
66 #define MMCHS_CMD_DP_SHIFT 21
67 #define MMCHS_CMD_DP (1 << MMCHS_CMD_DP_SHIFT)
68 #define MMCHS_CMD_CICE_SHIFT 20
69 #define MMCHS_CMD_CICE (1 << MMCHS_CMD_CICE_SHIFT)
70 #define MMCHS_CMD_CCCE_SHIFT 19
71 #define MMCHS_CMD_CCCE (1 << MMCHS_CMD_CCCE_SHIFT)
72 #define MMCHS_CMD_RSP_TYPE_SHIFT 16
73 #define MMCHS_CMD_RESP_NONE (0x0 << MMCHS_CMD_RSP_TYPE_SHIFT)
74 #define MMCHS_CMD_RESP136 (0x1 << MMCHS_CMD_RSP_TYPE_SHIFT)
75 #define MMCHS_CMD_RESP48 (0x2 << MMCHS_CMD_RSP_TYPE_SHIFT)
76 #define MMCHS_CMD_RESP48B (0x3 << MMCHS_CMD_RSP_TYPE_SHIFT)
77 #define MMCHS_CMD_MSBS (1 << 5)
78 #define MMCHS_CMD_DDIR (1 << 4)
79 #define MMCHS_CMD_ACEN (1 << 2)
80 #define MMCHS_CMD_BCE (1 << 1)
81 #define MMCHS_CMD_DE (1 << 0)
82 #define MMCHS_RSP10 0x110
83 #define MMCHS_RSP32 0x114
84 #define MMCHS_RSP54 0x118
85 #define MMCHS_RSP76 0x11C
86 #define MMCHS_DATA 0x120
87 #define MMCHS_PSTATE 0x124
88 #define MMCHS_PSTATE_CLEV (1<<24)
89 #define MMCHS_PSTATE_DLEV_SH 20
90 #define MMCHS_PSTATE_DLEV_M (0xf << MMCHS_PSTATE_DLEV_SH)
91 #define MMCHS_PSTATE_BRE (1<<11)
92 #define MMCHS_PSTATE_BWE (1<<10)
93 #define MMCHS_PSTATE_RTA (1<<9)
94 #define MMCHS_PSTATE_WTA (1<<8)
95 #define MMCHS_PSTATE_DLA (1<<2)
96 #define MMCHS_PSTATE_DATI (1<<1)
97 #define MMCHS_PSTATE_CMDI (1<<0)
98 #define MMCHS_PSTATE_FMT "\20" \
99 "\x098_CLEV" \
100 "\x08b_BRE" \
101 "\x08a_BWE" \
102 "\x089_RTA" \
103 "\x088_WTA" \
104 "\x082_DLA" \
105 "\x081_DATI" \
106 "\x080_CMDI"
107 #define MMCHS_HCTL 0x128
108 #define MMCHS_HCTL_SDVS_SHIFT 9
109 #define MMCHS_HCTL_SDVS_MASK (0x7<<MMCHS_HCTL_SDVS_SHIFT)
110 #define MMCHS_HCTL_SDVS_V18 (0x5<<MMCHS_HCTL_SDVS_SHIFT)
111 #define MMCHS_HCTL_SDVS_V30 (0x6<<MMCHS_HCTL_SDVS_SHIFT)
112 #define MMCHS_HCTL_SDVS_V33 (0x7<<MMCHS_HCTL_SDVS_SHIFT)
113 #define MMCHS_HCTL_SDBP (1<<8)
114 #define MMCHS_HCTL_HSPE (1<<2)
115 #define MMCHS_HCTL_DTW (1<<1)
116 #define MMCHS_SYSCTL 0x12C
117 #define MMCHS_SYSCTL_SRD (1<<26)
118 #define MMCHS_SYSCTL_SRC (1<<25)
119 #define MMCHS_SYSCTL_SRA (1<<24)
120 #define MMCHS_SYSCTL_DTO_SH 16
121 #define MMCHS_SYSCTL_DTO_MASK 0x000f0000
122 #define MMCHS_SYSCTL_CLKD_SH 6
123 #define MMCHS_SYSCTL_CLKD_MASK 0x0000ffc0
124 #define MMCHS_SYSCTL_CEN (1<<2)
125 #define MMCHS_SYSCTL_ICS (1<<1)
126 #define MMCHS_SYSCTL_ICE (1<<0)
127 #define MMCHS_STAT 0x130
128 #define MMCHS_STAT_BADA (1<<29)
129 #define MMCHS_STAT_CERR (1<<28)
130 #define MMCHS_STAT_ACE (1<<24)
131 #define MMCHS_STAT_DEB (1<<22)
132 #define MMCHS_STAT_DCRC (1<<21)
133 #define MMCHS_STAT_DTO (1<<20)
134 #define MMCHS_STAT_CIE (1<<19)
135 #define MMCHS_STAT_CEB (1<<18)
136 #define MMCHS_STAT_CCRC (1<<17)
137 #define MMCHS_STAT_CTO (1<<16)
138 #define MMCHS_STAT_ERRI (1<<15)
139 #define MMCHS_STAT_OBI (1<<9)
140 #define MMCHS_STAT_CIRQ (1<<8)
141 #define MMCHS_STAT_BRR (1<<5)
142 #define MMCHS_STAT_BWR (1<<4)
143 #define MMCHS_STAT_BGE (1<<2)
144 #define MMCHS_STAT_TC (1<<1)
145 #define MMCHS_STAT_CC (1<<0)
146 #define MMCHS_STAT_FMT "\20" \
147 "\x09d_BADA" \
148 "\x09c_CERR" \
149 "\x098_ACE" \
150 "\x096_DEB" \
151 "\x095_DCRC" \
152 "\x094_DTO" \
153 "\x093_CIE" \
154 "\x092_CEB" \
155 "\x091_CCRC" \
156 "\x090_CTO" \
157 "\x08f_ERRI" \
158 "\x089_OBI" \
159 "\x088_CIRQ" \
160 "\x085_BRR" \
161 "\x084_BWR" \
162 "\x082_BGE" \
163 "\x081_TC" \
164 "\x080_CC"
165 #define MMCHS_IE 0x134
166 #define MMCHS_ISE 0x138
167 #define MMCHS_AC12 0x13C
168 #define MMCHS_CAPA 0x140
169 #define MMCHS_CAPA_VS18 (1 << 26)
170 #define MMCHS_CAPA_VS30 (1 << 25)
171 #define MMCHS_CAPA_VS33 (1 << 24)
172 #define MMCHS_CAPA_SRS (1 << 23)
173 #define MMCHS_CAPA_DS (1 << 22)
174 #define MMCHS_CAPA_HSS (1 << 21)
175 #define MMCHS_CAPA_MBL_SHIFT 16
176 #define MMCHS_CAPA_MBL_MASK (3 << MMCHS_CAPA_MBL_SHIFT)
177 #define MMCHS_CUR_CAPA 0x148
178 #define MMCHS_REV 0x1fc
179
180 #define SDHC_COMMAND_TIMEOUT 1 /* sec */
181 #define SDHC_BUFFER_TIMEOUT 1 /* sec */
182 #define SDHC_TRANSFER_TIMEOUT 1 /* sec */
183
184 int ommmc_match(struct device *, void *, void *);
185 void ommmc_attach(struct device *, struct device *, void *);
186
187 struct ommmc_softc {
188 struct device sc_dev;
189 bus_space_tag_t sc_iot;
190 bus_space_handle_t sc_ioh;
191 int sc_node;
192 void *sc_ih; /* Interrupt handler */
193 uint32_t sc_flags;
194 #define FL_HSS (1 << 0)
195 uint32_t sc_gpio[4];
196
197 struct device *sdmmc; /* generic SD/MMC device */
198 int clockbit; /* clock control bit */
199 uint32_t clkbase; /* base clock frequency in kHz */
200 int maxblklen; /* maximum block length */
201 int flags; /* flags for this host */
202 uint32_t ocr; /* OCR value from capabilities */
203 uint32_t intr_status; /* soft interrupt status */
204 uint32_t intr_error_status; /* */
205 };
206
207
208 /* Host controller functions called by the attachment driver. */
209 void ommmc_power(int, void *);
210 void ommmc_shutdown(void *);
211 int ommmc_intr(void *);
212
213 /* RESET MODES */
214 #define MMC_RESET_DAT 1
215 #define MMC_RESET_CMD 2
216 #define MMC_RESET_ALL (MMC_RESET_CMD|MMC_RESET_DAT)
217
218 /* flag values */
219 #define SHF_USE_DMA 0x0001
220
221 #define HREAD4(sc, reg) \
222 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
223 #define HWRITE4(sc, reg, val) \
224 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
225 #define HSET4(sc, reg, bits) \
226 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
227 #define HCLR4(sc, reg, bits) \
228 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
229
230 int ommmc_host_reset(sdmmc_chipset_handle_t);
231 uint32_t ommmc_host_ocr(sdmmc_chipset_handle_t);
232 int ommmc_host_maxblklen(sdmmc_chipset_handle_t);
233 int ommmc_card_detect(sdmmc_chipset_handle_t);
234 int ommmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
235 int ommmc_bus_clock(sdmmc_chipset_handle_t, int, int);
236 int ommmc_bus_width(sdmmc_chipset_handle_t, int);
237 void ommmc_card_intr_mask(sdmmc_chipset_handle_t, int);
238 void ommmc_card_intr_ack(sdmmc_chipset_handle_t);
239 void ommmc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
240 int ommmc_start_command(struct ommmc_softc *, struct sdmmc_command *);
241 int ommmc_wait_state(struct ommmc_softc *, uint32_t, uint32_t);
242 int ommmc_soft_reset(struct ommmc_softc *, int);
243 int ommmc_wait_intr(struct ommmc_softc *, int, int);
244 void ommmc_transfer_data(struct ommmc_softc *, struct sdmmc_command *);
245 void ommmc_read_data(struct ommmc_softc *, uint8_t *, int);
246 void ommmc_write_data(struct ommmc_softc *, uint8_t *, int);
247
248 /* #define SDHC_DEBUG */
249 #ifdef SDHC_DEBUG
250 int ommmcdebug = 20;
251 #define DPRINTF(n,s) do { if ((n) <= ommmcdebug) printf s; } while (0)
252 void ommmc_dump_regs(struct ommmc_softc *);
253 #else
254 #define DPRINTF(n,s) do {} while(0)
255 #endif
256
257 struct sdmmc_chip_functions ommmc_functions = {
258 /* host controller reset */
259 ommmc_host_reset,
260 /* host controller capabilities */
261 ommmc_host_ocr,
262 ommmc_host_maxblklen,
263 /* card detection */
264 ommmc_card_detect,
265 /* bus power and clock frequency */
266 ommmc_bus_power,
267 ommmc_bus_clock,
268 ommmc_bus_width,
269 /* command execution */
270 ommmc_exec_command,
271 /* card interrupt */
272 ommmc_card_intr_mask,
273 ommmc_card_intr_ack
274 };
275
276 struct cfdriver ommmc_cd = {
277 NULL, "ommmc", DV_DULL
278 };
279
280 const struct cfattach ommmc_ca = {
281 sizeof(struct ommmc_softc), ommmc_match, ommmc_attach
282 };
283
284 int
ommmc_match(struct device * parent,void * match,void * aux)285 ommmc_match(struct device *parent, void *match, void *aux)
286 {
287 struct fdt_attach_args *faa = aux;
288
289 return (OF_is_compatible(faa->fa_node, "ti,omap3-hsmmc") ||
290 OF_is_compatible(faa->fa_node, "ti,omap4-hsmmc") ||
291 OF_is_compatible(faa->fa_node, "ti,am335-sdhci"));
292 }
293
294 void
ommmc_attach(struct device * parent,struct device * self,void * aux)295 ommmc_attach(struct device *parent, struct device *self, void *aux)
296 {
297 struct ommmc_softc *sc = (struct ommmc_softc *) self;
298 struct fdt_attach_args *faa = aux;
299 struct sdmmcbus_attach_args saa;
300 uint32_t caps, width;
301 uint32_t addr, size;
302 int len, unit;
303 char hwmods[128];
304
305 if (faa->fa_nreg < 1)
306 return;
307
308 if (faa->fa_reg[0].size <= 0x100)
309 return;
310
311 if (OF_is_compatible(faa->fa_node, "ti,omap4-hsmmc") ||
312 OF_is_compatible(faa->fa_node, "ti,am335-sdhci")) {
313 addr = faa->fa_reg[0].addr + 0x100;
314 size = faa->fa_reg[0].size - 0x100;
315 } else {
316 addr = faa->fa_reg[0].addr;
317 size = faa->fa_reg[0].size;
318 }
319
320 unit = -1;
321 if ((len = OF_getprop(faa->fa_node, "ti,hwmods", hwmods,
322 sizeof(hwmods))) == 5) {
323 if (!strncmp(hwmods, "mmc", 3) &&
324 (hwmods[3] > '0') && (hwmods[3] <= '9'))
325 unit = hwmods[3] - '1';
326 }
327
328 sc->sc_iot = faa->fa_iot;
329 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh))
330 panic("%s: bus_space_map failed!", __func__);
331
332 sc->sc_node = faa->fa_node;
333 printf("\n");
334
335 pinctrl_byname(faa->fa_node, "default");
336
337 /* Enable ICLKEN, FCLKEN? */
338 if (unit != -1)
339 prcm_enablemodule(PRCM_MMC0 + unit);
340
341 sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_SDMMC,
342 ommmc_intr, sc, DEVNAME(sc));
343 if (sc->sc_ih == NULL) {
344 printf("%s: cannot map interrupt\n", DEVNAME(sc));
345 goto err;
346 }
347
348 OF_getpropintarray(faa->fa_node, "cd-gpios", sc->sc_gpio,
349 sizeof(sc->sc_gpio));
350 if (sc->sc_gpio[0])
351 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT);
352
353 /* Controller Voltage Capabilities Initialization */
354 HSET4(sc, MMCHS_CAPA, MMCHS_CAPA_VS18 | MMCHS_CAPA_VS30);
355
356 #ifdef SDHC_DEBUG
357 ommmc_dump_regs(sc);
358 #endif
359
360 /*
361 * Reset the host controller and enable interrupts.
362 */
363 ommmc_host_reset(sc);
364
365 /* Determine host capabilities. */
366 caps = HREAD4(sc, MMCHS_CAPA);
367
368 #if 0
369 /* we want this !! */
370 /* Use DMA if the host system and the controller support it. */
371 if (usedma && ISSET(caps, SDHC_DMA_SUPPORT))
372 SET(sc->flags, SHF_USE_DMA);
373 #endif
374
375 /*
376 * Determine the base clock frequency. (2.2.24)
377 */
378
379 sc->clkbase = 96 * 1000;
380 #if 0
381 if (SDHC_BASE_FREQ_KHZ(caps) != 0)
382 sc->clkbase = SDHC_BASE_FREQ_KHZ(caps);
383 #endif
384 if (sc->clkbase == 0) {
385 /* The attachment driver must tell us. */
386 printf("%s: base clock frequency unknown\n", DEVNAME(sc));
387 goto err;
388 } else if (sc->clkbase < 10000 || sc->clkbase > 96000) {
389 /* SDHC 1.0 supports only 10-63 MHz. */
390 printf("%s: base clock frequency out of range: %u MHz\n",
391 DEVNAME(sc), sc->clkbase / 1000);
392 goto err;
393 }
394
395 /*
396 * XXX Set the data timeout counter value according to
397 * capabilities. (2.2.15)
398 */
399
400
401 /*
402 * Determine SD bus voltage levels supported by the controller.
403 */
404 if (caps & MMCHS_CAPA_VS18)
405 SET(sc->ocr, MMC_OCR_1_65V_1_95V);
406 if (caps & MMCHS_CAPA_VS30)
407 SET(sc->ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V);
408 if (caps & MMCHS_CAPA_VS33)
409 SET(sc->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
410
411 /*
412 * Omap max block size is fixed (single buffer), could limit
413 * this to 512 for double buffering, but dont see the point.
414 */
415 switch ((caps & MMCHS_CAPA_MBL_MASK) >> MMCHS_CAPA_MBL_SHIFT) {
416 case 0:
417 sc->maxblklen = 512;
418 break;
419 case 1:
420 sc->maxblklen = 1024;
421 break;
422 case 2:
423 sc->maxblklen = 2048;
424 break;
425 default:
426 sc->maxblklen = 512;
427 printf("invalid capability blocksize in capa %08x,"
428 " trying 512\n", HREAD4(sc, MMCHS_CAPA));
429 }
430 /*
431 * MMC does not support blksize > 512 yet
432 */
433 sc->maxblklen = 512;
434 /*
435 * Attach the generic SD/MMC bus driver. (The bus driver must
436 * not invoke any chipset functions before it is attached.)
437 */
438 bzero(&saa, sizeof(saa));
439 saa.saa_busname = "sdmmc";
440 saa.sct = &ommmc_functions;
441 saa.sch = sc;
442 if (OF_getproplen(faa->fa_node, "ti,needs-special-hs-handling") == 0 &&
443 (caps & MMCHS_CAPA_HSS)) {
444 sc->sc_flags |= FL_HSS;
445 saa.caps |= SMC_CAPS_MMC_HIGHSPEED | SMC_CAPS_SD_HIGHSPEED;
446 }
447 width = OF_getpropint(faa->fa_node, "bus-width", 1);
448 /* with bbb emmc width > 1 ommmc_wait_intr MMCHS_STAT_CC times out */
449 if (unit > 0)
450 width = 1;
451 if (width >= 8)
452 saa.caps |= SMC_CAPS_8BIT_MODE;
453 if (width >= 4)
454 saa.caps |= SMC_CAPS_4BIT_MODE;
455
456 sc->sdmmc = config_found(&sc->sc_dev, &saa, NULL);
457 if (sc->sdmmc == NULL) {
458 printf("%s: can't attach sdmmc\n", DEVNAME(sc));
459 goto err;
460 }
461
462 return;
463 err:
464 if (sc->sc_ih != NULL)
465 arm_intr_disestablish(sc->sc_ih);
466 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
467 }
468
469
470 /*
471 * Power hook established by or called from attachment driver.
472 */
473 void
ommmc_power(int why,void * arg)474 ommmc_power(int why, void *arg)
475 {
476 #if 0
477 struct ommmc_softc *sc = arg;
478 int n, i;
479 #endif
480
481 switch(why) {
482 case DVACT_SUSPEND:
483 /* XXX poll for command completion or suspend command
484 * in progress */
485
486 /* Save the host controller state. */
487 #if 0
488 for (i = 0; i < sizeof sc->regs; i++)
489 sc->regs[i] = HREAD1(sc, i);
490 #endif
491 break;
492
493 case DVACT_RESUME:
494 /* Restore the host controller state. */
495 #if 0
496 (void)ommmc_host_reset(sc);
497 for (i = 0; i < sizeof sc->regs; i++)
498 HWRITE1(sc, i, sc->regs[i]);
499 #endif
500 break;
501 }
502 }
503
504 /*
505 * Shutdown hook established by or called from attachment driver.
506 */
507 void
ommmc_shutdown(void * arg)508 ommmc_shutdown(void *arg)
509 {
510 struct ommmc_softc *sc = arg;
511
512 /* XXX chip locks up if we don't disable it before reboot. */
513 (void)ommmc_host_reset(sc);
514 }
515
516 /*
517 * Reset the host controller. Called during initialization, when
518 * cards are removed, upon resume, and during error recovery.
519 */
520 int
ommmc_host_reset(sdmmc_chipset_handle_t sch)521 ommmc_host_reset(sdmmc_chipset_handle_t sch)
522 {
523 struct ommmc_softc *sc = sch;
524 uint32_t imask;
525 int error;
526 int s;
527
528 s = splsdmmc();
529
530 /* Disable all interrupts. */
531 HWRITE4(sc, MMCHS_IE, 0);
532 HWRITE4(sc, MMCHS_ISE, 0);
533
534 /*
535 * Reset the entire host controller and wait up to 100ms for
536 * the controller to clear the reset bit.
537 */
538 if ((error = ommmc_soft_reset(sc, MMCHS_SYSCTL_SRA)) != 0) {
539 splx(s);
540 return (error);
541 }
542
543 #if 0
544 HSET4(sc, MMCHS_CON, MMCHS_CON_INIT);
545 HWRITE4(sc, MMCHS_CMD, 0);
546 delay(100); /* should delay 1ms */
547
548 HWRITE4(sc, MMCHS_STAT, MMCHS_STAT_CC);
549 HCLR4(sc, MMCHS_CON, MMCHS_CON_INIT);
550 HWRITE4(sc, MMCHS_STAT, ~0);
551 #endif
552
553
554 /* Set data timeout counter value to max for now. */
555 HSET4(sc, MMCHS_SYSCTL, 0xe << MMCHS_SYSCTL_DTO_SH);
556
557 /* Enable interrupts. */
558 imask = MMCHS_STAT_BRR | MMCHS_STAT_BWR | MMCHS_STAT_BGE |
559 MMCHS_STAT_TC | MMCHS_STAT_CC;
560
561 imask |= MMCHS_STAT_BADA | MMCHS_STAT_CERR | MMCHS_STAT_DEB |
562 MMCHS_STAT_DCRC | MMCHS_STAT_DTO | MMCHS_STAT_CIE |
563 MMCHS_STAT_CEB | MMCHS_STAT_CCRC | MMCHS_STAT_CTO;
564
565 HWRITE4(sc, MMCHS_IE, imask);
566 HWRITE4(sc, MMCHS_ISE, imask);
567
568 /* Switch back to 1-bit bus. */
569 HCLR4(sc, MMCHS_CON, MMCHS_CON_DW8);
570 HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_DTW);
571
572 splx(s);
573 return (0);
574 }
575
576 uint32_t
ommmc_host_ocr(sdmmc_chipset_handle_t sch)577 ommmc_host_ocr(sdmmc_chipset_handle_t sch)
578 {
579 struct ommmc_softc *sc = sch;
580 return (sc->ocr);
581 }
582
583 int
ommmc_host_maxblklen(sdmmc_chipset_handle_t sch)584 ommmc_host_maxblklen(sdmmc_chipset_handle_t sch)
585 {
586 struct ommmc_softc *sc = sch;
587 return (sc->maxblklen);
588 }
589
590 /*
591 * Return non-zero if the card is currently inserted.
592 */
593 int
ommmc_card_detect(sdmmc_chipset_handle_t sch)594 ommmc_card_detect(sdmmc_chipset_handle_t sch)
595 {
596 struct ommmc_softc *sc = sch;
597
598 if (OF_getproplen(sc->sc_node, "non-removable") == 0)
599 return 1;
600
601 if (sc->sc_gpio[0]) {
602 int inverted, val;
603
604 val = gpio_controller_get_pin(sc->sc_gpio);
605
606 inverted = (OF_getproplen(sc->sc_node, "cd-inverted") == 0);
607 return inverted ? !val : val;
608 }
609
610 return !ISSET(HREAD4(sc, MMCHS_SYSTEST), MMCHS_SYSTEST_SDCD) ?
611 1 : 0;
612 }
613
614 /*
615 * Set or change SD bus voltage and enable or disable SD bus power.
616 * Return zero on success.
617 */
618 int
ommmc_bus_power(sdmmc_chipset_handle_t sch,uint32_t ocr)619 ommmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
620 {
621 struct ommmc_softc *sc = sch;
622 uint32_t vdd;
623 uint32_t reg;
624 int s;
625
626 s = splsdmmc();
627
628 /*
629 * Disable bus power before voltage change.
630 */
631 HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_SDBP);
632
633 /* If power is disabled, reset the host and return now. */
634 if (ocr == 0) {
635 splx(s);
636 (void)ommmc_host_reset(sc);
637 return (0);
638 }
639
640 /*
641 * Select the maximum voltage according to capabilities.
642 */
643 ocr &= sc->ocr;
644
645 if (ISSET(ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V))
646 vdd = MMCHS_HCTL_SDVS_V33;
647 else if (ISSET(ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V))
648 vdd = MMCHS_HCTL_SDVS_V30;
649 else if (ISSET(ocr, MMC_OCR_1_65V_1_95V))
650 vdd = MMCHS_HCTL_SDVS_V18;
651 else {
652 /* Unsupported voltage level requested. */
653 splx(s);
654 return (EINVAL);
655 }
656
657 /*
658 * Enable bus power. Wait at least 1 ms (or 74 clocks) plus
659 * voltage ramp until power rises.
660 */
661 reg = HREAD4(sc, MMCHS_HCTL);
662 reg &= ~MMCHS_HCTL_SDVS_MASK;
663 reg |= vdd;
664 HWRITE4(sc, MMCHS_HCTL, reg);
665
666 HSET4(sc, MMCHS_HCTL, MMCHS_HCTL_SDBP);
667 delay(10000); /* XXX */
668
669 /*
670 * The host system may not power the bus due to battery low,
671 * etc. In that case, the host controller should clear the
672 * bus power bit.
673 */
674 if (!ISSET(HREAD4(sc, MMCHS_HCTL), MMCHS_HCTL_SDBP)) {
675 splx(s);
676 return (ENXIO);
677 }
678
679 splx(s);
680 return (0);
681 }
682
683 /*
684 * Return the smallest possible base clock frequency divisor value
685 * for the CLOCK_CTL register to produce `freq' (kHz).
686 */
687 static int
ommmc_clock_divisor(struct ommmc_softc * sc,uint32_t freq)688 ommmc_clock_divisor(struct ommmc_softc *sc, uint32_t freq)
689 {
690 int div;
691 uint32_t maxclk = MMCHS_SYSCTL_CLKD_MASK>>MMCHS_SYSCTL_CLKD_SH;
692
693 for (div = 1; div <= maxclk; div++)
694 if ((sc->clkbase / div) <= freq) {
695 return (div);
696 }
697
698 printf("divisor failure\n");
699 /* No divisor found. */
700 return (-1);
701 }
702
703 /*
704 * Set or change SDCLK frequency or disable the SD clock.
705 * Return zero on success.
706 */
707 int
ommmc_bus_clock(sdmmc_chipset_handle_t sch,int freq,int timing)708 ommmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, int timing)
709 {
710 int error = 0;
711 struct ommmc_softc *sc = sch;
712 uint32_t reg;
713 int s;
714 int div;
715 int timo;
716
717 s = splsdmmc();
718
719 /* Must not stop the clock if commands are in progress. */
720 for (timo = 1000; timo > 0; timo--) {
721 if (!ISSET(HREAD4(sc, MMCHS_PSTATE),
722 MMCHS_PSTATE_CMDI|MMCHS_PSTATE_DATI))
723 break;
724 delay(10);
725 }
726 if (timo == 0) {
727 error = ETIMEDOUT;
728 goto ret;
729 }
730
731 /*
732 * Stop SD clock before changing the frequency.
733 */
734 HCLR4(sc, MMCHS_SYSCTL, MMCHS_SYSCTL_CEN);
735 if (freq == SDMMC_SDCLK_OFF)
736 goto ret;
737
738 /*
739 * Set the minimum base clock frequency divisor.
740 */
741 if ((div = ommmc_clock_divisor(sc, freq)) < 0) {
742 /* Invalid base clock frequency or `freq' value. */
743 error = EINVAL;
744 goto ret;
745 }
746 reg = HREAD4(sc, MMCHS_SYSCTL);
747 reg &= ~MMCHS_SYSCTL_CLKD_MASK;
748 reg |= div << MMCHS_SYSCTL_CLKD_SH;
749 HWRITE4(sc, MMCHS_SYSCTL, reg);
750
751 if ((timing == SDMMC_TIMING_HIGHSPEED) && (sc->sc_flags & FL_HSS))
752 HSET4(sc, MMCHS_HCTL, MMCHS_HCTL_HSPE);
753 else
754 HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_HSPE);
755
756 /*
757 * Start internal clock. Wait 10ms for stabilization.
758 */
759 HSET4(sc, MMCHS_SYSCTL, MMCHS_SYSCTL_ICE);
760 for (timo = 1000; timo > 0; timo--) {
761 if (ISSET(HREAD4(sc, MMCHS_SYSCTL), MMCHS_SYSCTL_ICS))
762 break;
763 delay(10);
764 }
765 if (timo == 0) {
766 error = ETIMEDOUT;
767 goto ret;
768 }
769
770 /*
771 * Enable SD clock.
772 */
773 HSET4(sc, MMCHS_SYSCTL, MMCHS_SYSCTL_CEN);
774 ret:
775 splx(s);
776 return (error);
777 }
778
779 int
ommmc_bus_width(sdmmc_chipset_handle_t sch,int width)780 ommmc_bus_width(sdmmc_chipset_handle_t sch, int width)
781 {
782 struct ommmc_softc *sc = sch;
783 int s;
784
785 if (width != 1 && width != 4 && width != 8)
786 return (1);
787
788 s = splsdmmc();
789
790 if (width == 8)
791 HSET4(sc, MMCHS_CON, MMCHS_CON_DW8);
792 else
793 HCLR4(sc, MMCHS_CON, MMCHS_CON_DW8);
794
795 if (width == 4)
796 HSET4(sc, MMCHS_HCTL, MMCHS_HCTL_DTW);
797 else if (width == 1)
798 HCLR4(sc, MMCHS_HCTL, MMCHS_HCTL_DTW);
799
800 splx(s);
801
802 return (0);
803 }
804
805 void
ommmc_card_intr_mask(sdmmc_chipset_handle_t sch,int enable)806 ommmc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
807 {
808 /* - this is SDIO card interrupt */
809 struct ommmc_softc *sc = sch;
810
811 if (enable) {
812 HSET4(sc, MMCHS_IE, MMCHS_STAT_CIRQ);
813 HSET4(sc, MMCHS_ISE, MMCHS_STAT_CIRQ);
814 } else {
815 HCLR4(sc, MMCHS_IE, MMCHS_STAT_CIRQ);
816 HCLR4(sc, MMCHS_ISE, MMCHS_STAT_CIRQ);
817 }
818 }
819
820 void
ommmc_card_intr_ack(sdmmc_chipset_handle_t sch)821 ommmc_card_intr_ack(sdmmc_chipset_handle_t sch)
822 {
823 struct ommmc_softc *sc = sch;
824
825 HWRITE4(sc, MMCHS_STAT, MMCHS_STAT_CIRQ);
826 }
827
828 int
ommmc_wait_state(struct ommmc_softc * sc,uint32_t mask,uint32_t value)829 ommmc_wait_state(struct ommmc_softc *sc, uint32_t mask, uint32_t value)
830 {
831 uint32_t state;
832 int timeout;
833
834 state = HREAD4(sc, MMCHS_PSTATE);
835 DPRINTF(3,("%s: wait_state %x %x %x(state=%b)\n", DEVNAME(sc),
836 mask, value, state, state, MMCHS_PSTATE_FMT));
837 for (timeout = 1000; timeout > 0; timeout--) {
838 if (((state = HREAD4(sc, MMCHS_PSTATE)) & mask) == value)
839 return (0);
840 delay(10);
841 }
842 DPRINTF(0,("%s: timeout waiting for %x (state=%b)\n", DEVNAME(sc),
843 value, state, MMCHS_PSTATE_FMT));
844 return (ETIMEDOUT);
845 }
846
847 void
ommmc_exec_command(sdmmc_chipset_handle_t sch,struct sdmmc_command * cmd)848 ommmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
849 {
850 struct ommmc_softc *sc = sch;
851 int error;
852
853 /*
854 * Start the MMC command, or mark `cmd' as failed and return.
855 */
856 error = ommmc_start_command(sc, cmd);
857 if (error != 0) {
858 cmd->c_error = error;
859 SET(cmd->c_flags, SCF_ITSDONE);
860 return;
861 }
862
863 /*
864 * Wait until the command phase is done, or until the command
865 * is marked done for any other reason.
866 */
867 if (!ommmc_wait_intr(sc, MMCHS_STAT_CC, SDHC_COMMAND_TIMEOUT)) {
868 cmd->c_error = ETIMEDOUT;
869 SET(cmd->c_flags, SCF_ITSDONE);
870 return;
871 }
872
873 /*
874 * The host controller removes bits [0:7] from the response
875 * data (CRC) and we pass the data up unchanged to the bus
876 * driver (without padding).
877 */
878 if (cmd->c_error == 0 && ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
879 if (ISSET(cmd->c_flags, SCF_RSP_136)) {
880 uint32_t v0,v1,v2,v3;
881 v0 = HREAD4(sc, MMCHS_RSP10);
882 v1 = HREAD4(sc, MMCHS_RSP32);
883 v2 = HREAD4(sc, MMCHS_RSP54);
884 v3 = HREAD4(sc, MMCHS_RSP76);
885
886 cmd->c_resp[0] = (v0 >> 8) | ((v1 & 0xff) << 24);
887 cmd->c_resp[1] = (v1 >> 8) | ((v2 & 0xff) << 24);
888 cmd->c_resp[2] = (v2 >> 8) | ((v3 & 0xff) << 24);
889 cmd->c_resp[3] = v3 >> 8;
890 #ifdef SDHC_DEBUG
891 printf("resp[0] 0x%08x\nresp[1] 0x%08x\nresp[2] 0x%08x\nresp[3] 0x%08x\n", cmd->c_resp[0], cmd->c_resp[1], cmd->c_resp[2], cmd->c_resp[3]);
892 #endif
893 } else {
894 cmd->c_resp[0] = HREAD4(sc, MMCHS_RSP10);
895 #ifdef SDHC_DEBUG
896 printf("resp[0] 0x%08x\n", cmd->c_resp[0]);
897 #endif
898 }
899 }
900
901 /*
902 * If the command has data to transfer in any direction,
903 * execute the transfer now.
904 */
905 if (cmd->c_error == 0 && cmd->c_data != NULL)
906 ommmc_transfer_data(sc, cmd);
907
908 #if 0
909 /* Turn off the LED. */
910 HCLR1(sc, SDHC_HOST_CTL, SDHC_LED_ON);
911 #endif
912
913 DPRINTF(1,("%s: cmd %u done (flags=%#x error=%d)\n",
914 DEVNAME(sc), cmd->c_opcode, cmd->c_flags, cmd->c_error));
915 SET(cmd->c_flags, SCF_ITSDONE);
916 }
917
918 int
ommmc_start_command(struct ommmc_softc * sc,struct sdmmc_command * cmd)919 ommmc_start_command(struct ommmc_softc *sc, struct sdmmc_command *cmd)
920 {
921 uint32_t blksize = 0;
922 uint32_t blkcount = 0;
923 uint32_t command;
924 int error;
925 int s;
926
927 DPRINTF(1,("%s: start cmd %u arg=%#x data=%p dlen=%d flags=%#x\n",
928 DEVNAME(sc), cmd->c_opcode, cmd->c_arg, cmd->c_data,
929 cmd->c_datalen, cmd->c_flags));
930
931 /*
932 * The maximum block length for commands should be the minimum
933 * of the host buffer size and the card buffer size. (1.7.2)
934 */
935
936 /* Fragment the data into proper blocks. */
937 if (cmd->c_datalen > 0) {
938 blksize = MIN(cmd->c_datalen, cmd->c_blklen);
939 blkcount = cmd->c_datalen / blksize;
940 if (cmd->c_datalen % blksize > 0) {
941 /* XXX: Split this command. (1.7.4) */
942 printf("%s: data not a multiple of %d bytes\n",
943 DEVNAME(sc), blksize);
944 return (EINVAL);
945 }
946 }
947
948 /* Check limit imposed by 9-bit block count. (1.7.2) */
949 if (blkcount > MMCHS_BLK_NBLK_MAX) {
950 printf("%s: too much data\n", DEVNAME(sc));
951 return (EINVAL);
952 }
953
954 /* Prepare transfer mode register value. (2.2.5) */
955 command = 0;
956 if (ISSET(cmd->c_flags, SCF_CMD_READ))
957 command |= MMCHS_CMD_DDIR;
958 if (blkcount > 0) {
959 command |= MMCHS_CMD_BCE;
960 if (blkcount > 1) {
961 command |= MMCHS_CMD_MSBS;
962 /* XXX only for memory commands? */
963 command |= MMCHS_CMD_ACEN;
964 }
965 }
966 #ifdef notyet
967 if (ISSET(sc->flags, SHF_USE_DMA))
968 command |= MMCHS_CMD_DE;
969 #endif
970
971 /*
972 * Prepare command register value. (2.2.6)
973 */
974 command |= (cmd->c_opcode << MMCHS_CMD_INDX_SHIFT) &
975 MMCHS_CMD_INDX_SHIFT_MASK;
976
977 if (ISSET(cmd->c_flags, SCF_RSP_CRC))
978 command |= MMCHS_CMD_CCCE;
979 if (ISSET(cmd->c_flags, SCF_RSP_IDX))
980 command |= MMCHS_CMD_CICE;
981 if (cmd->c_data != NULL)
982 command |= MMCHS_CMD_DP;
983
984 if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT))
985 command |= MMCHS_CMD_RESP_NONE;
986 else if (ISSET(cmd->c_flags, SCF_RSP_136))
987 command |= MMCHS_CMD_RESP136;
988 else if (ISSET(cmd->c_flags, SCF_RSP_BSY))
989 command |= MMCHS_CMD_RESP48B;
990 else
991 command |= MMCHS_CMD_RESP48;
992
993 /* Wait until command and data inhibit bits are clear. (1.5) */
994 if ((error = ommmc_wait_state(sc, MMCHS_PSTATE_CMDI, 0)) != 0)
995 return (error);
996
997 s = splsdmmc();
998
999 #if 0
1000 /* Alert the user not to remove the card. */
1001 HSET1(sc, SDHC_HOST_CTL, SDHC_LED_ON);
1002 #endif
1003
1004 /* XXX: Set DMA start address if SHF_USE_DMA is set. */
1005
1006 DPRINTF(1,("%s: cmd=%#x blksize=%d blkcount=%d\n",
1007 DEVNAME(sc), command, blksize, blkcount));
1008
1009 /*
1010 * Start a CPU data transfer. Writing to the high order byte
1011 * of the SDHC_COMMAND register triggers the SD command. (1.5)
1012 */
1013 HWRITE4(sc, MMCHS_BLK, (blkcount << MMCHS_BLK_NBLK_SHIFT) |
1014 (blksize << MMCHS_BLK_BLEN_SHIFT));
1015 HWRITE4(sc, MMCHS_ARG, cmd->c_arg);
1016 HWRITE4(sc, MMCHS_CMD, command);
1017
1018 splx(s);
1019 return (0);
1020 }
1021
1022 void
ommmc_transfer_data(struct ommmc_softc * sc,struct sdmmc_command * cmd)1023 ommmc_transfer_data(struct ommmc_softc *sc, struct sdmmc_command *cmd)
1024 {
1025 uint8_t *datap = cmd->c_data;
1026 int i, datalen;
1027 int mask;
1028 int error;
1029
1030 mask = ISSET(cmd->c_flags, SCF_CMD_READ) ?
1031 MMCHS_PSTATE_BRE : MMCHS_PSTATE_BWE;
1032 error = 0;
1033 datalen = cmd->c_datalen;
1034
1035 DPRINTF(1,("%s: resp=%#x datalen=%d\n", DEVNAME(sc),
1036 MMC_R1(cmd->c_resp), datalen));
1037
1038 while (datalen > 0) {
1039 if (!ommmc_wait_intr(sc, MMCHS_STAT_BRR| MMCHS_STAT_BWR,
1040 SDHC_BUFFER_TIMEOUT)) {
1041 error = ETIMEDOUT;
1042 break;
1043 }
1044
1045 if ((error = ommmc_wait_state(sc, mask, mask)) != 0)
1046 break;
1047
1048 i = MIN(datalen, cmd->c_blklen);
1049 if (ISSET(cmd->c_flags, SCF_CMD_READ))
1050 ommmc_read_data(sc, datap, i);
1051 else
1052 ommmc_write_data(sc, datap, i);
1053
1054 datap += i;
1055 datalen -= i;
1056 }
1057
1058 if (error == 0 && !ommmc_wait_intr(sc, MMCHS_STAT_TC,
1059 SDHC_TRANSFER_TIMEOUT))
1060 error = ETIMEDOUT;
1061
1062 if (error != 0)
1063 cmd->c_error = error;
1064 SET(cmd->c_flags, SCF_ITSDONE);
1065
1066 DPRINTF(1,("%s: data transfer done (error=%d)\n",
1067 DEVNAME(sc), cmd->c_error));
1068 }
1069
1070 void
ommmc_read_data(struct ommmc_softc * sc,uint8_t * datap,int datalen)1071 ommmc_read_data(struct ommmc_softc *sc, uint8_t *datap, int datalen)
1072 {
1073 while (datalen > 3) {
1074 *(uint32_t *)datap = HREAD4(sc, MMCHS_DATA);
1075 datap += 4;
1076 datalen -= 4;
1077 }
1078 if (datalen > 0) {
1079 uint32_t rv = HREAD4(sc, MMCHS_DATA);
1080 do {
1081 *datap++ = rv & 0xff;
1082 rv = rv >> 8;
1083 } while (--datalen > 0);
1084 }
1085 }
1086
1087 void
ommmc_write_data(struct ommmc_softc * sc,uint8_t * datap,int datalen)1088 ommmc_write_data(struct ommmc_softc *sc, uint8_t *datap, int datalen)
1089 {
1090 while (datalen > 3) {
1091 DPRINTF(3,("%08x\n", *(uint32_t *)datap));
1092 HWRITE4(sc, MMCHS_DATA, *((uint32_t *)datap));
1093 datap += 4;
1094 datalen -= 4;
1095 }
1096 if (datalen > 0) {
1097 uint32_t rv = *datap++;
1098 if (datalen > 1)
1099 rv |= *datap++ << 8;
1100 if (datalen > 2)
1101 rv |= *datap++ << 16;
1102 DPRINTF(3,("rv %08x\n", rv));
1103 HWRITE4(sc, MMCHS_DATA, rv);
1104 }
1105 }
1106
1107 /* Prepare for another command. */
1108 int
ommmc_soft_reset(struct ommmc_softc * sc,int mask)1109 ommmc_soft_reset(struct ommmc_softc *sc, int mask)
1110 {
1111
1112 int timo;
1113
1114 DPRINTF(1,("%s: software reset reg=%#x\n", DEVNAME(sc), mask));
1115
1116 HSET4(sc, MMCHS_SYSCTL, mask);
1117 /*
1118 * If we read the software reset register too fast after writing it we
1119 * can get back a zero that means the reset hasn't started yet rather
1120 * than that the reset is complete. Per TI recommendations, work around
1121 * it by reading until we see the reset bit asserted, then read until
1122 * it's clear.
1123 */
1124 for (timo = 1000; timo > 0; timo--) {
1125 if (ISSET(HREAD4(sc, MMCHS_SYSCTL), mask))
1126 break;
1127 delay(1);
1128 }
1129 for (timo = 1000; timo > 0; timo--) {
1130 if (!ISSET(HREAD4(sc, MMCHS_SYSCTL), mask))
1131 break;
1132 delay(10);
1133 }
1134 if (timo == 0) {
1135 DPRINTF(1,("%s: timeout reg=%#x\n", DEVNAME(sc),
1136 HREAD4(sc, MMCHS_SYSCTL)));
1137 return (ETIMEDOUT);
1138 }
1139
1140 return (0);
1141 }
1142
1143 int
ommmc_wait_intr(struct ommmc_softc * sc,int mask,int sec)1144 ommmc_wait_intr(struct ommmc_softc *sc, int mask, int sec)
1145 {
1146 int status;
1147 int s;
1148
1149 mask |= MMCHS_STAT_ERRI;
1150
1151 s = splsdmmc();
1152 status = sc->intr_status & mask;
1153 while (status == 0) {
1154 if (tsleep_nsec(&sc->intr_status, PWAIT, "hcintr",
1155 SEC_TO_NSEC(sec)) == EWOULDBLOCK) {
1156 status |= MMCHS_STAT_ERRI;
1157 break;
1158 }
1159 status = sc->intr_status & mask;
1160 }
1161 sc->intr_status &= ~status;
1162
1163 DPRINTF(2,("%s: intr status %#x error %#x\n", DEVNAME(sc), status,
1164 sc->intr_error_status));
1165
1166 /* Command timeout has higher priority than command complete. */
1167 if (ISSET(status, MMCHS_STAT_ERRI)) {
1168 sc->intr_error_status = 0;
1169 (void)ommmc_soft_reset(sc, MMCHS_SYSCTL_SRC|MMCHS_SYSCTL_SRD);
1170 status = 0;
1171 }
1172
1173 splx(s);
1174 return (status);
1175 }
1176
1177 /*
1178 * Established by attachment driver at interrupt priority IPL_SDMMC.
1179 */
1180 int
ommmc_intr(void * arg)1181 ommmc_intr(void *arg)
1182 {
1183 struct ommmc_softc *sc = arg;
1184
1185 uint32_t status;
1186
1187 /* Find out which interrupts are pending. */
1188 status = HREAD4(sc, MMCHS_STAT);
1189
1190 /* Acknowledge the interrupts we are about to handle. */
1191 HWRITE4(sc, MMCHS_STAT, status);
1192 DPRINTF(2,("%s: interrupt status=%b\n", DEVNAME(sc),
1193 status, MMCHS_STAT_FMT));
1194
1195 /*
1196 * Service error interrupts.
1197 */
1198 if (ISSET(status, MMCHS_STAT_ERRI)) {
1199 if (ISSET(status, MMCHS_STAT_CTO|
1200 MMCHS_STAT_DTO)) {
1201 sc->intr_status |= status;
1202 sc->intr_error_status |= status & 0xffff0000;
1203 wakeup(&sc->intr_status);
1204 }
1205 }
1206
1207 #if 0
1208 /*
1209 * Wake up the sdmmc event thread to scan for cards.
1210 */
1211 if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION))
1212 ommmc_needs_discover(sc->sdmmc);
1213 #endif
1214
1215 /*
1216 * Wake up the blocking process to service command
1217 * related interrupt(s).
1218 */
1219 if (ISSET(status, MMCHS_STAT_BRR|
1220 MMCHS_STAT_BWR|MMCHS_STAT_TC|
1221 MMCHS_STAT_CC)) {
1222 sc->intr_status |= status;
1223 wakeup(&sc->intr_status);
1224 }
1225
1226 /*
1227 * Service SD card interrupts.
1228 */
1229 if (ISSET(status, MMCHS_STAT_CIRQ)) {
1230 DPRINTF(0,("%s: card interrupt\n", DEVNAME(sc)));
1231 HCLR4(sc, MMCHS_STAT, MMCHS_STAT_CIRQ);
1232 sdmmc_card_intr(sc->sdmmc);
1233 }
1234 return 1;
1235 }
1236
1237 #ifdef SDHC_DEBUG
1238 void
ommmc_dump_regs(struct ommmc_softc * sc)1239 ommmc_dump_regs(struct ommmc_softc *sc)
1240 {
1241 }
1242 #endif
1243