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