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 #ifdef notyet 255 static inline uint16_t 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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