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