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