xref: /freebsd/sys/arm/broadcom/bcm2835/bcm2835_sdhost.c (revision a4e5e0106ac7145f56eb39a691e302cabb4635be)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2018 Klaus P. Ohrhallinger <k@7he.at>
5  * All rights reserved.
6  *
7  * Based on bcm2835_sdhci.c:
8  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  */
33 #include <sys/cdefs.h>
34 /*
35  * pin 48-53 - card slot
36  * pin 34-39 - radio module
37  *
38  * alt-0 - rubbish SDHCI  (0x7e202000) aka sdhost
39  * alt-3 - advanced SDHCI (0x7e300000) aka sdhci/mmc/sdio
40  *
41  * driving card slot with mmc:
42  *
43  * sdhost_pins {
44  *         brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;
45  *         brcm,function = <0x7>;
46  *         brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>;
47  *         phandle = <0x17>;
48  * };
49  * sdio_pins {
50  *         brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>;
51  *         brcm,function = <0x4>;
52  *         brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>;
53  *         phandle = <0x18>;
54  * };
55  *
56  * driving card slot with sdhost:
57  *
58  * sdhost_pins {
59  *         brcm,pins = <0x30 0x31 0x32 0x33 0x34 0x35>;
60  *         brcm,function = <0x4>;
61  *         brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>;
62  *         phandle = <0x17>;
63  * };
64  * sdio_pins {
65  *         brcm,pins = <0x22 0x23 0x24 0x25 0x26 0x27>;
66  *         brcm,function = <0x7>;
67  *         brcm,pull = <0x0 0x2 0x2 0x2 0x2 0x2>;
68  *         phandle = <0x18>;
69  * };
70  *
71  */
72 
73 #include <sys/param.h>
74 #include <sys/systm.h>
75 #include <sys/kobj.h>
76 #include <sys/bus.h>
77 #include <sys/kernel.h>
78 #include <sys/lock.h>
79 #include <sys/malloc.h>
80 #include <sys/module.h>
81 #include <sys/mutex.h>
82 #include <sys/rman.h>
83 #include <sys/sysctl.h>
84 #include <sys/taskqueue.h>
85 #include <sys/gpio.h>
86 
87 #include <machine/bus.h>
88 
89 #include <dev/ofw/ofw_bus.h>
90 #include <dev/ofw/ofw_bus_subr.h>
91 
92 #include <dev/mmc/bridge.h>
93 #include <dev/mmc/mmcreg.h>
94 
95 #include <dev/sdhci/sdhci.h>
96 
97 #include "mmcbr_if.h"
98 #include "sdhci_if.h"
99 
100 #include "opt_mmccam.h"
101 
102 #include "bcm2835_dma.h"
103 #include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
104 #include "bcm2835_vcbus.h"
105 
106 /* #define SDHOST_DEBUG */
107 
108 /* Registers */
109 #define HC_COMMAND		0x00	/* Command and flags */
110 #define HC_ARGUMENT		0x04
111 #define HC_TIMEOUTCOUNTER	0x08
112 #define HC_CLOCKDIVISOR		0x0c
113 #define HC_RESPONSE_0		0x10
114 #define HC_RESPONSE_1		0x14
115 #define HC_RESPONSE_2		0x18
116 #define HC_RESPONSE_3		0x1c
117 #define HC_HOSTSTATUS		0x20
118 #define HC_POWER		0x30
119 #define HC_DEBUG		0x34
120 #define HC_HOSTCONFIG		0x38
121 #define HC_BLOCKSIZE		0x3c
122 #define HC_DATAPORT		0x40
123 #define HC_BLOCKCOUNT		0x50
124 
125 /* Flags for HC_COMMAND register */
126 #define HC_CMD_ENABLE			0x8000
127 #define HC_CMD_FAILED			0x4000
128 #define HC_CMD_BUSY			0x0800
129 #define HC_CMD_RESPONSE_NONE		0x0400
130 #define HC_CMD_RESPONSE_LONG		0x0200
131 #define HC_CMD_WRITE			0x0080
132 #define HC_CMD_READ			0x0040
133 #define HC_CMD_COMMAND_MASK		0x003f
134 
135 #define HC_CLOCKDIVISOR_MAXVAL		0x07ff
136 
137 /* Flags for HC_HOSTSTATUS register */
138 #define HC_HSTST_HAVEDATA		0x0001
139 #define HC_HSTST_ERROR_FIFO		0x0008
140 #define HC_HSTST_ERROR_CRC7		0x0010
141 #define HC_HSTST_ERROR_CRC16		0x0020
142 #define HC_HSTST_TIMEOUT_CMD		0x0040
143 #define HC_HSTST_TIMEOUT_DATA		0x0080
144 #define HC_HSTST_INT_BLOCK		0x0200
145 #define HC_HSTST_INT_BUSY		0x0400
146 
147 #define HC_HSTST_RESET			0xffff
148 
149 #define HC_HSTST_MASK_ERROR_DATA	(HC_HSTST_ERROR_FIFO | \
150     HC_HSTST_ERROR_CRC7 | HC_HSTST_ERROR_CRC16 | HC_HSTST_TIMEOUT_DATA)
151 
152 #define HC_HSTST_MASK_ERROR_ALL		(HC_HSTST_MASK_ERROR_DATA | \
153     HC_HSTST_TIMEOUT_CMD)
154 
155 /* Flags for HC_HOSTCONFIG register */
156 #define HC_HSTCF_INTBUS_WIDE		0x0002
157 #define HC_HSTCF_EXTBUS_4BIT		0x0004
158 #define HC_HSTCF_SLOW_CARD		0x0008
159 #define HC_HSTCF_INT_DATA		0x0010
160 #define HC_HSTCF_INT_BLOCK		0x0100
161 #define HC_HSTCF_INT_BUSY		0x0400
162 
163 /* Flags for HC_DEBUG register */
164 #define HC_DBG_FIFO_THRESH_WRITE_SHIFT	9
165 #define HC_DBG_FIFO_THRESH_READ_SHIFT	14
166 #define HC_DBG_FIFO_THRESH_MASK		0x001f
167 
168 /* Settings */
169 #define HC_FIFO_SIZE		16
170 #define HC_FIFO_THRESH_READ	4
171 #define HC_FIFO_THRESH_WRITE	4
172 
173 #define HC_TIMEOUT_DEFAULT	0x00f00000
174 
175 #define	BCM2835_DEFAULT_SDHCI_FREQ	50
176 
177 static int bcm2835_sdhost_debug = 0;
178 
179 #ifdef SDHOST_DEBUG
180 
181 TUNABLE_INT("hw.bcm2835.sdhost.debug", &bcm2835_sdhost_debug);
182 SYSCTL_INT(_hw_sdhci, OID_AUTO, bcm2835_sdhost_debug, CTLFLAG_RWTUN,
183     &bcm2835_sdhost_debug, 0, "bcm2835-sdhost Debug level");
184 
185 #define dprintf(fmt, args...) \
186 	do { \
187 		if (bcm2835_sdhost_debug > 0) \
188 			printf(fmt,##args); \
189 	} while (0)
190 #else
191 
192 #define dprintf(fmt, args...)
193 
194 #endif /* ! SDHOST_DEBUG */
195 
196 static struct ofw_compat_data compat_data[] = {
197 	{"brcm,bcm2835-sdhost",		1},
198 	{NULL,				0}
199 };
200 
201 struct bcm_sdhost_softc {
202 	device_t		sc_dev;
203 	struct resource *	sc_mem_res;
204 	struct resource *	sc_irq_res;
205 	bus_space_tag_t		sc_bst;
206 	bus_space_handle_t	sc_bsh;
207 	void *			sc_intrhand;
208 	struct mmc_request *	sc_req;
209 	struct sdhci_slot	sc_slot;
210 
211 	struct mtx		mtx;
212 
213 	char			cmdbusy;
214 	char			mmc_app_cmd;
215 
216 	u_int32_t		sdhci_int_status;
217 	u_int32_t		sdhci_signal_enable;
218 	u_int32_t		sdhci_present_state;
219 	u_int32_t		sdhci_blocksize;
220 	u_int32_t		sdhci_blockcount;
221 
222 	u_int32_t		sdcard_rca;
223 };
224 
225 static int bcm_sdhost_probe(device_t);
226 static int bcm_sdhost_attach(device_t);
227 static int bcm_sdhost_detach(device_t);
228 static void bcm_sdhost_intr(void *);
229 
230 static int bcm_sdhost_get_ro(device_t, device_t);
231 
232 static inline uint32_t
233 RD4(struct bcm_sdhost_softc *sc, bus_size_t off)
234 {
235 	uint32_t val;
236 
237 	val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off);
238 
239 	return (val);
240 }
241 
242 static inline void
243 WR4(struct bcm_sdhost_softc *sc, bus_size_t off, uint32_t val)
244 {
245 
246 	bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val);
247 }
248 
249 #ifdef notyet
250 static inline uint16_t
251 RD2(struct bcm_sdhost_softc *sc, bus_size_t off)
252 {
253 	uint32_t val;
254 
255 	val = RD4(sc, off & ~3);
256 
257 	return ((val >> (off & 3)*8) & 0xffff);
258 }
259 #endif
260 
261 static inline uint8_t
262 RD1(struct bcm_sdhost_softc *sc, bus_size_t off)
263 {
264 	uint32_t val;
265 
266 	val = RD4(sc, off & ~3);
267 
268 	return ((val >> (off & 3)*8) & 0xff);
269 }
270 
271 static inline void
272 WR2(struct bcm_sdhost_softc *sc, bus_size_t off, uint16_t val)
273 {
274 	uint32_t val32;
275 
276 	val32 = RD4(sc, off & ~3);
277 	val32 &= ~(0xffff << (off & 3)*8);
278 	val32 |= (val << (off & 3)*8);
279 	WR4(sc, off & ~3, val32);
280 }
281 
282 static inline void
283 WR1(struct bcm_sdhost_softc *sc, bus_size_t off, uint8_t val)
284 {
285 	uint32_t val32;
286 
287 	val32 = RD4(sc, off & ~3);
288 	val32 &= ~(0xff << (off & 3)*8);
289 	val32 |= (val << (off & 3)*8);
290 	WR4(sc, off & ~3, val32);
291 }
292 
293 static void
294 bcm_sdhost_print_regs(struct bcm_sdhost_softc *sc, struct sdhci_slot *slot,
295     int line, int error)
296 {
297 
298 	if (bcm2835_sdhost_debug > 0 || error > 0) {
299 		printf("%s: sc=%p slot=%p\n",
300 		    __func__, sc, slot);
301 		printf("HC_COMMAND:        0x%08x\n",
302 		    RD4(sc, HC_COMMAND));
303 		printf("HC_ARGUMENT:       0x%08x\n",
304 		    RD4(sc, HC_ARGUMENT));
305 		printf("HC_TIMEOUTCOUNTER: 0x%08x\n",
306 		    RD4(sc, HC_TIMEOUTCOUNTER));
307 		printf("HC_CLOCKDIVISOR:   0x%08x\n",
308 		    RD4(sc, HC_CLOCKDIVISOR));
309 		printf("HC_RESPONSE_0:     0x%08x\n",
310 		    RD4(sc, HC_RESPONSE_0));
311 		printf("HC_RESPONSE_1:     0x%08x\n",
312 		    RD4(sc, HC_RESPONSE_1));
313 		printf("HC_RESPONSE_2:     0x%08x\n",
314 		    RD4(sc, HC_RESPONSE_2));
315 		printf("HC_RESPONSE_3:     0x%08x\n",
316 		    RD4(sc, HC_RESPONSE_3));
317 		printf("HC_HOSTSTATUS:     0x%08x\n",
318 		    RD4(sc, HC_HOSTSTATUS));
319 		printf("HC_POWER:          0x%08x\n",
320 		    RD4(sc, HC_POWER));
321 		printf("HC_DEBUG:          0x%08x\n",
322 		    RD4(sc, HC_DEBUG));
323 		printf("HC_HOSTCONFIG:     0x%08x\n",
324 		    RD4(sc, HC_HOSTCONFIG));
325 		printf("HC_BLOCKSIZE:      0x%08x\n",
326 		    RD4(sc, HC_BLOCKSIZE));
327 		printf("HC_BLOCKCOUNT:     0x%08x\n",
328 		    RD4(sc, HC_BLOCKCOUNT));
329 
330 	} else {
331 		/*
332 		printf("%04d | HC_COMMAND: 0x%08x HC_ARGUMENT: 0x%08x "
333 		    "HC_HOSTSTATUS: 0x%08x HC_HOSTCONFIG: 0x%08x\n",
334 		    line, RD4(sc, HC_COMMAND), RD4(sc, HC_ARGUMENT),
335 		    RD4(sc, HC_HOSTSTATUS), RD4(sc, HC_HOSTCONFIG));
336 		*/
337 	}
338 }
339 
340 static void
341 bcm_sdhost_reset(device_t dev, struct sdhci_slot *slot)
342 {
343 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
344 	u_int32_t dbg;
345 
346 	WR4(sc, HC_POWER, 0);
347 
348 	WR4(sc, HC_COMMAND, 0);
349 	WR4(sc, HC_ARGUMENT, 0);
350 	WR4(sc, HC_TIMEOUTCOUNTER, HC_TIMEOUT_DEFAULT);
351 	WR4(sc, HC_CLOCKDIVISOR, 0);
352 	WR4(sc, HC_HOSTSTATUS, HC_HSTST_RESET);
353 	WR4(sc, HC_HOSTCONFIG, 0);
354 	WR4(sc, HC_BLOCKSIZE, 0);
355 	WR4(sc, HC_BLOCKCOUNT, 0);
356 
357 	dbg = RD4(sc, HC_DEBUG);
358 	dbg &= ~( (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_READ_SHIFT) |
359 	          (HC_DBG_FIFO_THRESH_MASK << HC_DBG_FIFO_THRESH_WRITE_SHIFT) );
360 	dbg |= (HC_FIFO_THRESH_READ << HC_DBG_FIFO_THRESH_READ_SHIFT) |
361 	       (HC_FIFO_THRESH_WRITE << HC_DBG_FIFO_THRESH_WRITE_SHIFT);
362 	WR4(sc, HC_DEBUG, dbg);
363 
364 	DELAY(250000);
365 
366 	WR4(sc, HC_POWER, 1);
367 
368 	DELAY(250000);
369 
370 	sc->sdhci_present_state = SDHCI_CARD_PRESENT | SDHCI_CARD_STABLE |
371 		SDHCI_WRITE_PROTECT;
372 
373 	WR4(sc, HC_CLOCKDIVISOR, HC_CLOCKDIVISOR_MAXVAL);
374 	WR4(sc, HC_HOSTCONFIG, HC_HSTCF_INT_BUSY);
375 }
376 
377 static int
378 bcm_sdhost_probe(device_t dev)
379 {
380 
381 	dprintf("%s:\n", __func__);
382 
383 	if (!ofw_bus_status_okay(dev))
384 		return (ENXIO);
385 
386 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
387 		return (ENXIO);
388 
389 	device_set_desc(dev, "Broadcom 2708 SDHOST controller");
390 
391 	return (BUS_PROBE_DEFAULT);
392 }
393 
394 static int
395 bcm_sdhost_attach(device_t dev)
396 {
397 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
398 	int rid, err;
399 	u_int default_freq;
400 
401 	dprintf("%s: dev=%p sc=%p unit=%d\n",
402 	    __func__, dev, sc, device_get_unit(dev));
403 
404 	mtx_init(&sc->mtx, "BCM SDHOST mtx", "bcm_sdhost",
405 	    MTX_DEF | MTX_RECURSE);
406 
407 	sc->sc_dev = dev;
408 	sc->sc_req = NULL;
409 
410 	sc->cmdbusy = 0;
411 	sc->mmc_app_cmd = 0;
412 	sc->sdhci_int_status = 0;
413 	sc->sdhci_signal_enable = 0;
414 	sc->sdhci_present_state = 0;
415 	sc->sdhci_blocksize = 0;
416 	sc->sdhci_blockcount = 0;
417 
418 	sc->sdcard_rca = 0;
419 
420 	default_freq = 50;
421 	err = 0;
422 
423 	if (bootverbose)
424 		device_printf(dev, "SDHCI frequency: %dMHz\n", default_freq);
425 
426 	rid = 0;
427 	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
428 	    RF_ACTIVE);
429 	if (!sc->sc_mem_res) {
430 		device_printf(dev, "cannot allocate memory window\n");
431 		err = ENXIO;
432 		goto fail;
433 	}
434 
435 	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
436 	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
437 
438 	bcm_sdhost_reset(dev, &sc->sc_slot);
439 
440 	bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0);
441 
442 	rid = 0;
443 	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
444 	    RF_ACTIVE);
445 	if (!sc->sc_irq_res) {
446 		device_printf(dev, "cannot allocate interrupt\n");
447 		err = ENXIO;
448 		goto fail;
449 	}
450 
451 	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
452 	    NULL, bcm_sdhost_intr, sc, &sc->sc_intrhand)) {
453 		device_printf(dev, "cannot setup interrupt handler\n");
454 		err = ENXIO;
455 		goto fail;
456 	}
457 
458 	sc->sc_slot.caps = 0;
459 	sc->sc_slot.caps |= SDHCI_CAN_VDD_330;
460 	sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD;
461 	sc->sc_slot.caps |= (default_freq << SDHCI_CLOCK_BASE_SHIFT);
462 
463 	sc->sc_slot.quirks = 0;
464 	sc->sc_slot.quirks |= SDHCI_QUIRK_MISSING_CAPS;
465 	sc->sc_slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE;
466 
467 	sc->sc_slot.opt = 0;
468 
469 	/* XXX ?
470 	sc->slot->timeout_clk = ...;
471 	*/
472 
473 	sdhci_init_slot(dev, &sc->sc_slot, 0);
474 
475 	bus_generic_probe(dev);
476 	bus_generic_attach(dev);
477 
478 	sdhci_start_slot(&sc->sc_slot);
479 
480 	return (0);
481 
482     fail:
483 	if (sc->sc_intrhand)
484 		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
485 	if (sc->sc_irq_res)
486 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
487 	if (sc->sc_mem_res)
488 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
489 
490 	return (err);
491 }
492 
493 static int
494 bcm_sdhost_detach(device_t dev)
495 {
496 
497 	dprintf("%s:\n", __func__);
498 
499 	return (EBUSY);
500 }
501 
502 /*
503  * rv 0 --> command finished
504  * rv 1 --> command timed out
505  */
506 static inline int
507 bcm_sdhost_waitcommand(struct bcm_sdhost_softc *sc)
508 {
509 	int timeout = 1000;
510 
511 	mtx_assert(&sc->mtx, MA_OWNED);
512 
513 	while ((RD4(sc, HC_COMMAND) & HC_CMD_ENABLE) && --timeout > 0) {
514 		DELAY(100);
515 	}
516 
517 	return ((timeout > 0) ? 0 : 1);
518 }
519 
520 static int
521 bcm_sdhost_waitcommand_status(struct bcm_sdhost_softc *sc)
522 {
523 	u_int32_t cdst;
524 	int i;
525 
526 	/* wait for card to change status from
527 	 * ''prg'' to ''trn''
528 	 * card status: sd specs p. 103
529 	 */
530 	i = 0;
531 	do {
532 		DELAY(1000);
533 		WR4(sc, HC_ARGUMENT, sc->sdcard_rca << 16);
534 		WR4(sc, HC_COMMAND,
535 		    MMC_SEND_STATUS | HC_CMD_ENABLE);
536 		bcm_sdhost_waitcommand(sc);
537 		cdst = RD4(sc, HC_RESPONSE_0);
538 		dprintf("%s: card status %08x (cs %d)\n",
539 		    __func__, cdst, (cdst & 0x0e00) >> 9);
540 		if (i++ > 100) {
541 			printf("%s: giving up, "
542 			    "card status %08x (cs %d)\n",
543 			    __func__, cdst,
544 			    (cdst & 0x0e00) >> 9);
545 			return (1);
546 			break;
547 		}
548 	} while (((cdst & 0x0e00) >> 9) != 4);
549 
550 	return (0);
551 }
552 
553 static void
554 bcm_sdhost_intr(void *arg)
555 {
556 	struct bcm_sdhost_softc *sc = arg;
557 	struct sdhci_slot *slot = &sc->sc_slot;
558 	uint32_t hstst;
559 	uint32_t cmd;
560 
561 	mtx_lock(&sc->mtx);
562 
563 	hstst = RD4(sc, HC_HOSTSTATUS);
564 	cmd = RD4(sc, HC_COMMAND);
565 	if (hstst & HC_HSTST_HAVEDATA) {
566 		if (cmd & HC_CMD_READ) {
567 			sc->sdhci_present_state |= SDHCI_DATA_AVAILABLE;
568 			sc->sdhci_int_status |= SDHCI_INT_DATA_AVAIL;
569 		} else if (cmd & HC_CMD_WRITE) {
570 			sc->sdhci_present_state |= SDHCI_SPACE_AVAILABLE;
571 			sc->sdhci_int_status |= SDHCI_INT_SPACE_AVAIL;
572 		} else {
573 			panic("%s: hstst & HC_HSTST_HAVEDATA but no "
574 			    "HC_CMD_READ or HC_CMD_WRITE: cmd=%0x8 "
575 			    "hstst=%08x\n", __func__, cmd, hstst);
576 		}
577 	} else {
578 		sc->sdhci_present_state &=
579 		    ~(SDHCI_DATA_AVAILABLE|SDHCI_SPACE_AVAILABLE);
580 		sc->sdhci_int_status &=
581 		    ~(SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL);
582 	}
583 
584 	if (hstst & HC_HSTST_MASK_ERROR_ALL) {
585 		printf("%s: ERROR: HC_HOSTSTATUS: %08x\n", __func__, hstst);
586 		bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1);
587 		sc->sdhci_int_status |= SDHCI_INT_ERROR;
588 	} else {
589 		sc->sdhci_int_status &= ~SDHCI_INT_ERROR;
590 	}
591 
592 	dprintf("%s: hstst=%08x offset=%08lx sdhci_present_state=%08x "
593 	    "sdhci_int_status=%08x\n", __func__, hstst, slot->offset,
594 	    sc->sdhci_present_state, sc->sdhci_int_status);
595 
596 	sdhci_generic_intr(&sc->sc_slot);
597 
598 	sc->sdhci_int_status &=
599 	    ~(SDHCI_INT_ERROR|SDHCI_INT_DATA_AVAIL|SDHCI_INT_DATA_END);
600 	sc->sdhci_present_state &= ~SDHCI_DATA_AVAILABLE;
601 
602 	if ((hstst & HC_HSTST_HAVEDATA) &&
603 	    (sc->sdhci_blocksize * sc->sdhci_blockcount == slot->offset)) {
604 		dprintf("%s: offset=%08lx sdhci_blocksize=%08x "
605 		    "sdhci_blockcount=%08x\n", __func__, slot->offset,
606 		    sc->sdhci_blocksize, sc->sdhci_blockcount);
607 		sc->sdhci_int_status &=
608 		    ~(SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL);
609 		sc->sdhci_int_status |= SDHCI_INT_DATA_END;
610 		sdhci_generic_intr(&sc->sc_slot);
611 		sc->sdhci_int_status &= ~SDHCI_INT_DATA_END;
612 
613 		if ((cmd & HC_CMD_COMMAND_MASK) == MMC_READ_MULTIPLE_BLOCK ||
614 		    (cmd & HC_CMD_COMMAND_MASK) == MMC_WRITE_MULTIPLE_BLOCK) {
615 			WR4(sc, HC_ARGUMENT, 0x00000000);
616 			WR4(sc, HC_COMMAND,
617 			    MMC_STOP_TRANSMISSION | HC_CMD_ENABLE);
618 
619 			if (bcm_sdhost_waitcommand(sc)) {
620 				printf("%s: timeout #1\n", __func__);
621 				bcm_sdhost_print_regs(sc, &sc->sc_slot,
622 				    __LINE__, 1);
623 			}
624 		}
625 
626 		if (cmd & HC_CMD_WRITE) {
627 			if (bcm_sdhost_waitcommand_status(sc) != 0)
628 				sc->sdhci_int_status |= SDHCI_INT_ERROR;
629 		}
630 
631 		slot->data_done = 1;
632 
633 		sc->sdhci_int_status |= SDHCI_INT_RESPONSE;
634 		sdhci_generic_intr(&sc->sc_slot);
635 		sc->sdhci_int_status &= ~(SDHCI_INT_RESPONSE|SDHCI_INT_ERROR);
636 	}
637 
638 	/* this resets the interrupt */
639 	WR4(sc, HC_HOSTSTATUS,
640 	    (HC_HSTST_INT_BUSY|HC_HSTST_INT_BLOCK|HC_HSTST_HAVEDATA));
641 
642 	mtx_unlock(&sc->mtx);
643 }
644 
645 static int
646 bcm_sdhost_get_ro(device_t bus, device_t child)
647 {
648 
649 	dprintf("%s:\n", __func__);
650 
651 	return (0);
652 }
653 
654 static bool
655 bcm_sdhost_get_card_present(device_t dev, struct sdhci_slot *slot)
656 {
657 
658 	dprintf("%s:\n", __func__);
659 
660 	return (1);
661 }
662 
663 static void
664 bcm_sdhost_command(device_t dev, struct sdhci_slot *slot, uint16_t val)
665 {
666 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
667 	struct mmc_data *data = slot->curcmd->data;
668 	uint16_t val2;
669 	uint8_t opcode;
670 	uint8_t flags;
671 
672 	mtx_assert(&sc->mtx, MA_OWNED);
673 
674 	if (RD4(sc, HC_COMMAND) & HC_CMD_ENABLE) {
675 		panic("%s: HC_CMD_ENABLE on entry\n", __func__);
676 	}
677 
678 	if (sc->cmdbusy == 1)
679 		panic("%s: cmdbusy\n", __func__);
680 
681 	sc->cmdbusy = 1;
682 
683 	val2 = ((val >> 8) & HC_CMD_COMMAND_MASK) | HC_CMD_ENABLE;
684 
685 	opcode = val >> 8;
686 	flags = val & 0xff;
687 
688 	if (opcode == MMC_APP_CMD)
689 		sc->mmc_app_cmd = 1;
690 
691 	if ((flags & SDHCI_CMD_RESP_MASK) == SDHCI_CMD_RESP_LONG)
692 		val2 |= HC_CMD_RESPONSE_LONG;
693 	else if ((flags & SDHCI_CMD_RESP_MASK) == SDHCI_CMD_RESP_SHORT_BUSY)
694 		/* XXX XXX when enabled, cmd 7 (select card) blocks forever */
695 		;/*val2 |= HC_CMD_BUSY; */
696 	else if ((flags & SDHCI_CMD_RESP_MASK) == SDHCI_CMD_RESP_SHORT)
697 		;
698 	else
699 		val2 |= HC_CMD_RESPONSE_NONE;
700 
701 	if (val2 & HC_CMD_BUSY)
702 		sc->sdhci_present_state |=
703 		    SDHCI_CMD_INHIBIT | SDHCI_DAT_INHIBIT;
704 
705 	if (data != NULL && data->flags & MMC_DATA_READ)
706 		val2 |= HC_CMD_READ;
707 	else if (data != NULL && data->flags & MMC_DATA_WRITE)
708 		val2 |= HC_CMD_WRITE;
709 
710 	dprintf("%s: SDHCI_COMMAND_FLAGS --> HC_COMMAND   %04x --> %04x\n",
711 	    __func__, val, val2);
712 
713 	if (opcode == MMC_READ_MULTIPLE_BLOCK ||
714 	    opcode == MMC_WRITE_MULTIPLE_BLOCK) {
715 		u_int32_t save_sdarg;
716 
717 		dprintf("%s: issuing MMC_SET_BLOCK_COUNT: CMD %08x ARG %08x\n",
718 		    __func__, MMC_SET_BLOCK_COUNT | HC_CMD_ENABLE,
719 		    sc->sdhci_blockcount);
720 
721 		save_sdarg = RD4(sc, HC_ARGUMENT);
722 		WR4(sc, HC_ARGUMENT, sc->sdhci_blockcount);
723 		WR4(sc, HC_COMMAND, MMC_SET_BLOCK_COUNT | HC_CMD_ENABLE);
724 
725 		/* Seems to always return timeout */
726 
727 		if (bcm_sdhost_waitcommand(sc)) {
728 			printf("%s: timeout #2\n", __func__);
729 			bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1);
730 		} else {
731 			bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0);
732 		}
733 		WR4(sc, HC_ARGUMENT, save_sdarg);
734 
735 	} else if (opcode == MMC_SELECT_CARD) {
736 		sc->sdcard_rca = (RD4(sc, HC_ARGUMENT) >> 16);
737 	}
738 
739 	/* actually issuing the command */
740 	WR4(sc, HC_COMMAND, val2);
741 
742 	if (val2 & HC_CMD_READ || val2 & HC_CMD_WRITE) {
743 		u_int8_t hstcfg;
744 
745 		hstcfg = RD4(sc, HC_HOSTCONFIG);
746 		hstcfg |= (HC_HSTCF_INT_BUSY | HC_HSTCF_INT_DATA);
747 		WR4(sc, HC_HOSTCONFIG, hstcfg);
748 		slot->data_done = 0;
749 
750 		if (bcm_sdhost_waitcommand(sc)) {
751 			printf("%s: timeout #3\n", __func__);
752 			bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1);
753 		}
754 
755 	} else if (opcode == MMC_ERASE) {
756 		if (bcm_sdhost_waitcommand_status(sc) != 0) {
757 			printf("%s: timeout #4\n", __func__);
758 			bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1);
759 		}
760 		slot->data_done = 1;
761 		sc->sdhci_present_state &=
762 		    ~(SDHCI_CMD_INHIBIT | SDHCI_DAT_INHIBIT);
763 
764 	} else {
765 		if (bcm_sdhost_waitcommand(sc)) {
766 			printf("%s: timeout #5\n", __func__);
767 			bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1);
768 		}
769 		slot->data_done = 1;
770 		sc->sdhci_present_state &=
771 		    ~(SDHCI_CMD_INHIBIT | SDHCI_DAT_INHIBIT);
772 	}
773 
774 	bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 0);
775 
776 	if (RD4(sc, HC_HOSTSTATUS) & HC_HSTST_TIMEOUT_CMD)
777 		slot->curcmd->error = MMC_ERR_TIMEOUT;
778 	else if (RD4(sc, HC_COMMAND) & HC_CMD_FAILED)
779 		slot->curcmd->error = MMC_ERR_FAILED;
780 
781 	dprintf("%s: curcmd->flags=%d data_done=%d\n",
782 	    __func__, slot->curcmd->flags, slot->data_done);
783 
784 	if (val2 & HC_CMD_RESPONSE_NONE)
785 		slot->curcmd->error = 0;
786 
787 	if (sc->mmc_app_cmd == 1 && opcode != MMC_APP_CMD)
788 		sc->mmc_app_cmd = 0;
789 
790 	if (RD4(sc, HC_COMMAND) & HC_CMD_ENABLE) {
791 		bcm_sdhost_print_regs(sc, &sc->sc_slot, __LINE__, 1);
792 		panic("%s: still HC_CMD_ENABLE on exit\n", __func__);
793 	}
794 
795 	sc->cmdbusy = 0;
796 
797 	if (!(val2 & HC_CMD_READ || val2 & HC_CMD_WRITE))
798 		sc->sdhci_int_status |= SDHCI_INT_RESPONSE;
799 
800 	/* HACK, so sdhci_finish_command() does not
801 	 * have to be exported
802 	 */
803 	mtx_unlock(&slot->mtx);
804 	sdhci_generic_intr(slot);
805 	mtx_lock(&slot->mtx);
806 	sc->sdhci_int_status &= ~SDHCI_INT_RESPONSE;
807 }
808 
809 static uint8_t
810 bcm_sdhost_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
811 {
812 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
813 	uint32_t val1, val2;
814 
815 	mtx_lock(&sc->mtx);
816 
817 	switch (off) {
818 	case SDHCI_HOST_CONTROL:
819 		val1 = RD4(sc, HC_HOSTCONFIG);
820 		val2 = 0;
821 		if (val1 & HC_HSTCF_EXTBUS_4BIT)
822 			val2 |= SDHCI_CTRL_4BITBUS;
823 		dprintf("%s: SDHCI_HOST_CONTROL --> HC_HOSTCONFIG val2 %02x\n",
824 		    __func__, val2);
825 		break;
826 	case SDHCI_POWER_CONTROL:
827 		val1 = RD1(sc, HC_POWER);
828 		val2 = (val1 == 1) ? 0x0f : 0;
829 		dprintf("%s: SDHCI_POWER_CONTROL --> HC_POWER     val2 %02x\n",
830 		    __func__, val2);
831 		break;
832 	case SDHCI_BLOCK_GAP_CONTROL:
833 		dprintf("%s: SDHCI_BLOCK_GAP_CONTROL\n", __func__);
834 		val2 = 0;
835 		break;
836 	case SDHCI_WAKE_UP_CONTROL:
837 		dprintf("%s: SDHCI_WAKE_UP_CONTROL\n", __func__);
838 		val2 = 0;
839 		break;
840 	case SDHCI_TIMEOUT_CONTROL:
841 		dprintf("%s: SDHCI_TIMEOUT_CONTROL\n", __func__);
842 		val2 = 0;
843 		break;
844 	case SDHCI_SOFTWARE_RESET:
845 		dprintf("%s: SDHCI_SOFTWARE_RESET\n", __func__);
846 		val2 = 0;
847 		break;
848 	case SDHCI_ADMA_ERR:
849 		dprintf("%s: SDHCI_ADMA_ERR\n", __func__);
850 		val2 = 0;
851 		break;
852 	default:
853 		dprintf("%s: UNKNOWN off=%08lx\n", __func__, off);
854 		val2 = 0;
855 		break;
856 	}
857 
858 	mtx_unlock(&sc->mtx);
859 
860 	return (val2);
861 }
862 
863 static uint16_t
864 bcm_sdhost_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
865 {
866 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
867 	uint32_t val2, val; /* = RD4(sc, off & ~3); */
868 
869 	mtx_lock(&sc->mtx);
870 
871 	switch (off) {
872 	case SDHCI_BLOCK_SIZE:
873 		val2 = sc->sdhci_blocksize;
874 		dprintf("%s: SDHCI_BLOCK_SIZE      --> HC_BLOCKSIZE   %08x\n",
875 		    __func__, val2);
876 		break;
877 	case SDHCI_BLOCK_COUNT:
878 		val2 = sc->sdhci_blockcount;
879 		dprintf("%s: SDHCI_BLOCK_COUNT     --> HC_BLOCKCOUNT  %08x\n",
880 		    __func__, val2);
881 		break;
882 	case SDHCI_TRANSFER_MODE:
883 		dprintf("%s: SDHCI_TRANSFER_MODE\n", __func__);
884 		val2 = 0;
885 		break;
886 	case SDHCI_CLOCK_CONTROL:
887 		val = RD4(sc, HC_CLOCKDIVISOR);
888 		val2 = (val << SDHCI_DIVIDER_SHIFT) |
889 		    SDHCI_CLOCK_CARD_EN | SDHCI_CLOCK_INT_EN |
890 		    SDHCI_CLOCK_INT_STABLE;
891 		dprintf("%s: SDHCI_CLOCK_CONTROL     %04x --> %04x\n",
892 		    __func__, val, val2);
893 		break;
894 	case SDHCI_ACMD12_ERR:
895 		dprintf("%s: SDHCI_ACMD12_ERR\n", __func__);
896 		val2 = 0;
897 		break;
898 	case SDHCI_HOST_CONTROL2:
899 		dprintf("%s: SDHCI_HOST_CONTROL2\n", __func__);
900 		val2 = 0;
901 		break;
902 	case SDHCI_SLOT_INT_STATUS:
903 		dprintf("%s: SDHCI_SLOT_INT_STATUS\n", __func__);
904 		val2 = 0;
905 		break;
906 	case SDHCI_HOST_VERSION:
907 		dprintf("%s: SDHCI_HOST_VERSION\n", __func__);
908 		val2 = 0;
909 		break;
910 	default:
911 		dprintf("%s: UNKNOWN off=%08lx\n", __func__, off);
912 		val2 = 0;
913 		break;
914 	}
915 
916 	mtx_unlock(&sc->mtx);
917 
918 	return (val2);
919 }
920 
921 static uint32_t
922 bcm_sdhost_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
923 {
924 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
925 	uint32_t val2;
926 
927 	mtx_lock(&sc->mtx);
928 
929 	switch (off) {
930 	case SDHCI_DMA_ADDRESS:
931 		dprintf("%s: SDHCI_DMA_ADDRESS\n", __func__);
932 		val2 = 0;
933 		break;
934 	case SDHCI_ARGUMENT:
935 		dprintf("%s: SDHCI_ARGUMENT\n", __func__);
936 		val2 = (RD4(sc, HC_COMMAND) << 16) |
937 		    (RD4(sc, HC_ARGUMENT) & 0x0000ffff);
938 		break;
939 	case SDHCI_RESPONSE + 0:
940 		val2 = RD4(sc, HC_RESPONSE_0);
941 		dprintf("%s: SDHCI_RESPONSE+0       %08x\n", __func__, val2);
942 		break;
943 	case SDHCI_RESPONSE + 4:
944 		val2 = RD4(sc, HC_RESPONSE_1);
945 		dprintf("%s: SDHCI_RESPONSE+4       %08x\n", __func__, val2);
946 		break;
947 	case SDHCI_RESPONSE + 8:
948 		val2 = RD4(sc, HC_RESPONSE_2);
949 		dprintf("%s: SDHCI_RESPONSE+8       %08x\n", __func__, val2);
950 		break;
951 	case SDHCI_RESPONSE + 12:
952 		val2 = RD4(sc, HC_RESPONSE_3);
953 		dprintf("%s: SDHCI_RESPONSE+12      %08x\n", __func__, val2);
954 		break;
955 	case SDHCI_BUFFER:
956 		dprintf("%s: SDHCI_BUFFER\n", __func__);
957 		val2 = 0;
958 		break;
959 	case SDHCI_PRESENT_STATE:
960 		dprintf("%s: SDHCI_PRESENT_STATE      %08x\n",
961 		    __func__, sc->sdhci_present_state);
962 		val2 = sc->sdhci_present_state;
963 		break;
964 	case SDHCI_INT_STATUS:
965 		dprintf("%s: SDHCI_INT_STATUS        %08x\n",
966 		    __func__, sc->sdhci_int_status);
967 		val2 = sc->sdhci_int_status;
968 		break;
969 	case SDHCI_INT_ENABLE:
970 		dprintf("%s: SDHCI_INT_ENABLE\n", __func__);
971 		val2 = 0;
972 		break;
973 	case SDHCI_SIGNAL_ENABLE:
974 		dprintf("%s: SDHCI_SIGNAL_ENABLE      %08x\n",
975 		    __func__, sc->sdhci_signal_enable);
976 		val2 = sc->sdhci_signal_enable;
977 		break;
978 	case SDHCI_CAPABILITIES:
979 		val2 = 0;
980 		break;
981 	case SDHCI_CAPABILITIES2:
982 		dprintf("%s: SDHCI_CAPABILITIES2\n", __func__);
983 		val2 = 0;
984 		break;
985 	case SDHCI_MAX_CURRENT:
986 		dprintf("%s: SDHCI_MAX_CURRENT\n", __func__);
987 		val2 = 0;
988 		break;
989 	case SDHCI_ADMA_ADDRESS_LO:
990 		dprintf("%s: SDHCI_ADMA_ADDRESS_LO\n", __func__);
991 		val2 = 0;
992 		break;
993 	default:
994 		dprintf("%s: UNKNOWN off=%08lx\n", __func__, off);
995 		val2 = 0;
996 		break;
997 	}
998 
999 	mtx_unlock(&sc->mtx);
1000 
1001 	return (val2);
1002 }
1003 
1004 static void
1005 bcm_sdhost_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
1006     uint32_t *data, bus_size_t count)
1007 {
1008 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
1009 	bus_size_t i;
1010 	bus_size_t avail;
1011 	uint32_t edm;
1012 
1013 	mtx_lock(&sc->mtx);
1014 
1015 	dprintf("%s: off=%08lx count=%08lx\n", __func__, off, count);
1016 
1017 	for (i = 0; i < count;) {
1018 		edm = RD4(sc, HC_DEBUG);
1019 		avail = ((edm >> 4) & 0x1f);
1020 		if (i + avail > count)
1021 			avail = count - i;
1022 		if (avail > 0)
1023 			bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh,
1024 			    HC_DATAPORT, data + i, avail);
1025 		i += avail;
1026 		DELAY(1);
1027 	}
1028 
1029 	mtx_unlock(&sc->mtx);
1030 }
1031 
1032 static void
1033 bcm_sdhost_write_1(device_t dev, struct sdhci_slot *slot,
1034     bus_size_t off, uint8_t val)
1035 {
1036 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
1037 	uint32_t val2;
1038 
1039 	mtx_lock(&sc->mtx);
1040 
1041 	switch (off) {
1042 	case SDHCI_HOST_CONTROL:
1043 		val2 = RD4(sc, HC_HOSTCONFIG);
1044 		val2 |= HC_HSTCF_INT_BUSY;
1045 		val2 |= HC_HSTCF_INTBUS_WIDE | HC_HSTCF_SLOW_CARD;
1046 		if (val & SDHCI_CTRL_4BITBUS)
1047 			val2 |= HC_HSTCF_EXTBUS_4BIT;
1048 		dprintf("%s: SDHCI_HOST_CONTROL --> HC_HOSTC %04x --> %04x\n",
1049 		    __func__, val, val2);
1050 		WR4(sc, HC_HOSTCONFIG, val2);
1051 		break;
1052 	case SDHCI_POWER_CONTROL:
1053 		val2 = (val != 0) ? 1 : 0;
1054 		dprintf("%s: SDHCI_POWER_CONTROL --> HC_POWER %02x --> %02x\n",
1055 		    __func__, val, val2);
1056 		WR1(sc, HC_POWER, val2);
1057 		break;
1058 	case SDHCI_BLOCK_GAP_CONTROL:
1059 		dprintf("%s: SDHCI_BLOCK_GAP_CONTROL   val=%02x\n",
1060 		    __func__, val);
1061 		break;
1062 	case SDHCI_TIMEOUT_CONTROL:
1063 		dprintf("%s: SDHCI_TIMEOUT_CONTROL     val=%02x\n",
1064 		    __func__, val);
1065 		break;
1066 	case SDHCI_SOFTWARE_RESET:
1067 		dprintf("%s: SDHCI_SOFTWARE_RESET      val=%02x\n",
1068 		    __func__, val);
1069 		break;
1070 	case SDHCI_ADMA_ERR:
1071 		dprintf("%s: SDHCI_ADMA_ERR            val=%02x\n",
1072 		    __func__, val);
1073 		break;
1074 	default:
1075 		dprintf("%s: UNKNOWN off=%08lx val=%08x\n",
1076 		    __func__, off, val);
1077 		break;
1078 	}
1079 
1080 	mtx_unlock(&sc->mtx);
1081 }
1082 
1083 static void
1084 bcm_sdhost_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
1085 {
1086 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
1087 	uint16_t val2;
1088 
1089 	mtx_lock(&sc->mtx);
1090 
1091 	switch (off) {
1092 	case SDHCI_BLOCK_SIZE:
1093 		dprintf("%s: SDHCI_BLOCK_SIZE          val=%04x\n" ,
1094 		    __func__, val);
1095 		sc->sdhci_blocksize = val;
1096 		WR2(sc, HC_BLOCKSIZE, val);
1097 		break;
1098 
1099 	case SDHCI_BLOCK_COUNT:
1100 		dprintf("%s: SDHCI_BLOCK_COUNT         val=%04x\n" ,
1101 		    __func__, val);
1102 		sc->sdhci_blockcount = val;
1103 		WR2(sc, HC_BLOCKCOUNT, val);
1104 		break;
1105 
1106 	case SDHCI_TRANSFER_MODE:
1107 		dprintf("%s: SDHCI_TRANSFER_MODE       val=%04x\n" ,
1108 		    __func__, val);
1109 		break;
1110 
1111 	case SDHCI_COMMAND_FLAGS:
1112 		bcm_sdhost_command(dev, slot, val);
1113 		break;
1114 
1115 	case SDHCI_CLOCK_CONTROL:
1116 		val2 = (val & ~SDHCI_DIVIDER_MASK) >> SDHCI_DIVIDER_SHIFT;
1117 		/* get crc16 errors with cdiv=0 */
1118 		if (val2 == 0)
1119 			val2 = 1;
1120 		dprintf("%s: SDHCI_CLOCK_CONTROL       %04x --> SCDIV %04x\n",
1121 		    __func__, val, val2);
1122 		WR4(sc, HC_CLOCKDIVISOR, val2);
1123 		break;
1124 
1125 	case SDHCI_ACMD12_ERR:
1126 		dprintf("%s: SDHCI_ACMD12_ERR          val=%04x\n" ,
1127 		    __func__, val);
1128 		break;
1129 
1130 	case SDHCI_HOST_CONTROL2:
1131 		dprintf("%s: SDHCI_HOST_CONTROL2       val=%04x\n" ,
1132 		    __func__, val);
1133 		break;
1134 
1135 	case SDHCI_SLOT_INT_STATUS:
1136 		dprintf("%s: SDHCI_SLOT_INT_STATUS     val=%04x\n" ,
1137 		    __func__, val);
1138 		break;
1139 
1140 	default:
1141 		dprintf("%s: UNKNOWN off=%08lx val=%04x\n",
1142 		    __func__, off, val);
1143 		break;
1144 	}
1145 
1146 	mtx_unlock(&sc->mtx);
1147 }
1148 
1149 static void
1150 bcm_sdhost_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
1151 {
1152 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
1153 	uint32_t val2;
1154 	uint32_t hstcfg;
1155 
1156 	mtx_lock(&sc->mtx);
1157 
1158 	switch (off) {
1159 	case SDHCI_ARGUMENT:
1160 		val2 = val;
1161 		dprintf("%s: SDHCI_ARGUMENT --> HC_ARGUMENT   val=%08x\n",
1162 		    __func__, val);
1163 		WR4(sc, HC_ARGUMENT, val2);
1164 		break;
1165 	case SDHCI_INT_STATUS:
1166 		dprintf("%s: SDHCI_INT_STATUS           val=%08x\n",
1167 		    __func__, val);
1168 		sc->sdhci_int_status = val;
1169 		break;
1170 	case SDHCI_INT_ENABLE:
1171 		dprintf("%s: SDHCI_INT_ENABLE          val=%08x\n" ,
1172 		     __func__, val);
1173 		break;
1174 	case SDHCI_SIGNAL_ENABLE:
1175 		sc->sdhci_signal_enable = val;
1176 		hstcfg = RD4(sc, HC_HOSTCONFIG);
1177 		if (val != 0)
1178 			hstcfg &= ~(HC_HSTCF_INT_BLOCK | HC_HSTCF_INT_DATA);
1179 		else
1180 			hstcfg |= (HC_HSTCF_INT_BUSY|HC_HSTCF_INT_BLOCK|
1181 			         HC_HSTCF_INT_DATA);
1182 		hstcfg |= HC_HSTCF_INT_BUSY;
1183 		dprintf("%s: SDHCI_SIGNAL_ENABLE --> HC_HOSTC %08x --> %08x\n" ,
1184 		    __func__, val, hstcfg);
1185 		WR4(sc, HC_HOSTCONFIG, hstcfg);
1186 		break;
1187 	case SDHCI_CAPABILITIES:
1188 		dprintf("%s: SDHCI_CAPABILITIES        val=%08x\n",
1189 		    __func__, val);
1190 		break;
1191 	case SDHCI_CAPABILITIES2:
1192 		dprintf("%s: SDHCI_CAPABILITIES2       val=%08x\n",
1193 		    __func__, val);
1194 		break;
1195 	case SDHCI_MAX_CURRENT:
1196 		dprintf("%s: SDHCI_MAX_CURRENT         val=%08x\n",
1197 		    __func__, val);
1198 		break;
1199 	case SDHCI_ADMA_ADDRESS_LO:
1200 		dprintf("%s: SDHCI_ADMA_ADDRESS_LO     val=%08x\n",
1201 		    __func__, val);
1202 		break;
1203 	default:
1204 		dprintf("%s: UNKNOWN off=%08lx val=%08x\n",
1205 		    __func__, off, val);
1206 		break;
1207 	}
1208 
1209 	mtx_unlock(&sc->mtx);
1210 }
1211 
1212 static void
1213 bcm_sdhost_write_multi_4(device_t dev, struct sdhci_slot *slot,
1214     bus_size_t off, uint32_t *data, bus_size_t count)
1215 {
1216 	struct bcm_sdhost_softc *sc = device_get_softc(dev);
1217 	bus_size_t i;
1218 	bus_size_t space;
1219 	uint32_t edm;
1220 
1221 	mtx_lock(&sc->mtx);
1222 
1223 	dprintf("%s: off=%08lx count=%02lx\n", __func__, off, count);
1224 
1225 	for (i = 0; i < count;) {
1226 		edm = RD4(sc, HC_DEBUG);
1227 		space = HC_FIFO_SIZE - ((edm >> 4) & 0x1f);
1228 		if (i + space > count)
1229 			space = count - i;
1230 		if (space > 0)
1231 			bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh,
1232 			    HC_DATAPORT, data + i, space);
1233 		i += space;
1234 		DELAY(1);
1235         }
1236 
1237 	/* wait until FIFO is really empty */
1238 	while (((RD4(sc, HC_DEBUG) >> 4) & 0x1f) > 0)
1239 		DELAY(1);
1240 
1241 	mtx_unlock(&sc->mtx);
1242 }
1243 
1244 static device_method_t bcm_sdhost_methods[] = {
1245 	/* Device interface */
1246 	DEVMETHOD(device_probe,		bcm_sdhost_probe),
1247 	DEVMETHOD(device_attach,	bcm_sdhost_attach),
1248 	DEVMETHOD(device_detach,	bcm_sdhost_detach),
1249 
1250 	/* Bus interface */
1251 	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
1252 	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
1253 
1254 	/* MMC bridge interface */
1255 	DEVMETHOD(mmcbr_update_ios,	sdhci_generic_update_ios),
1256 	DEVMETHOD(mmcbr_request,	sdhci_generic_request),
1257 	DEVMETHOD(mmcbr_get_ro,		bcm_sdhost_get_ro),
1258 	DEVMETHOD(mmcbr_acquire_host,	sdhci_generic_acquire_host),
1259 	DEVMETHOD(mmcbr_release_host,	sdhci_generic_release_host),
1260 
1261 	/* SDHCI registers accessors */
1262 	DEVMETHOD(sdhci_read_1,		bcm_sdhost_read_1),
1263 	DEVMETHOD(sdhci_read_2,		bcm_sdhost_read_2),
1264 	DEVMETHOD(sdhci_read_4,		bcm_sdhost_read_4),
1265 	DEVMETHOD(sdhci_read_multi_4,	bcm_sdhost_read_multi_4),
1266 	DEVMETHOD(sdhci_write_1,	bcm_sdhost_write_1),
1267 	DEVMETHOD(sdhci_write_2,	bcm_sdhost_write_2),
1268 	DEVMETHOD(sdhci_write_4,	bcm_sdhost_write_4),
1269 	DEVMETHOD(sdhci_write_multi_4,	bcm_sdhost_write_multi_4),
1270 	DEVMETHOD(sdhci_get_card_present,bcm_sdhost_get_card_present),
1271 
1272 	DEVMETHOD_END
1273 };
1274 
1275 static driver_t bcm_sdhost_driver = {
1276 	"sdhost_bcm",
1277 	bcm_sdhost_methods,
1278 	sizeof(struct bcm_sdhost_softc),
1279 };
1280 
1281 DRIVER_MODULE(sdhost_bcm, simplebus, bcm_sdhost_driver, NULL, NULL);
1282 SDHCI_DEPEND(sdhost_bcm);
1283 #ifndef MMCCAM
1284 MMC_DECLARE_BRIDGE(sdhost_bcm);
1285 #endif
1286