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