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