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