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