bcm2835_sdhci.c revision 248407
1/*- 2 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c 248407 2013-03-17 03:04:43Z ian $"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bio.h> 33#include <sys/bus.h> 34#include <sys/conf.h> 35#include <sys/endian.h> 36#include <sys/kernel.h> 37#include <sys/kthread.h> 38#include <sys/lock.h> 39#include <sys/malloc.h> 40#include <sys/module.h> 41#include <sys/mutex.h> 42#include <sys/queue.h> 43#include <sys/resource.h> 44#include <sys/rman.h> 45#include <sys/taskqueue.h> 46#include <sys/time.h> 47#include <sys/timetc.h> 48#include <sys/watchdog.h> 49 50#include <sys/kdb.h> 51 52#include <machine/bus.h> 53#include <machine/cpu.h> 54#include <machine/cpufunc.h> 55#include <machine/resource.h> 56#include <machine/frame.h> 57#include <machine/intr.h> 58 59#include <dev/fdt/fdt_common.h> 60#include <dev/ofw/ofw_bus.h> 61#include <dev/ofw/ofw_bus_subr.h> 62 63#include <dev/mmc/bridge.h> 64#include <dev/mmc/mmcreg.h> 65#include <dev/mmc/mmcbrvar.h> 66 67#include <dev/sdhci/sdhci.h> 68#include "sdhci_if.h" 69 70#include "bcm2835_dma.h" 71#include "bcm2835_vcbus.h" 72 73#define BCM2835_DEFAULT_SDHCI_FREQ 50 74 75#define BCM_SDHCI_BUFFER_SIZE 512 76 77#define DEBUG 78 79#ifdef DEBUG 80#define dprintf(fmt, args...) do { printf("%s(): ", __func__); \ 81 printf(fmt,##args); } while (0) 82#else 83#define dprintf(fmt, args...) 84#endif 85 86/* 87 * Arasan HC seems to have problem with Data CRC on lower frequencies. 88 * Use this tunable to cap initialization sequence frequency at higher 89 * value. Default is standard 400kHz 90 */ 91static int bcm2835_sdhci_min_freq = 400000; 92static int bcm2835_sdhci_hs = 1; 93static int bcm2835_sdhci_pio_mode = 0; 94 95TUNABLE_INT("hw.bcm2835.sdhci.min_freq", &bcm2835_sdhci_min_freq); 96TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs); 97TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode); 98 99struct bcm_sdhci_dmamap_arg { 100 bus_addr_t sc_dma_busaddr; 101}; 102 103struct bcm_sdhci_softc { 104 device_t sc_dev; 105 struct mtx sc_mtx; 106 struct resource * sc_mem_res; 107 struct resource * sc_irq_res; 108 bus_space_tag_t sc_bst; 109 bus_space_handle_t sc_bsh; 110 void * sc_intrhand; 111 struct mmc_request * sc_req; 112 struct mmc_data * sc_data; 113 uint32_t sc_flags; 114#define LPC_SD_FLAGS_IGNORECRC (1 << 0) 115 int sc_xfer_direction; 116#define DIRECTION_READ 0 117#define DIRECTION_WRITE 1 118 int sc_xfer_done; 119 int sc_bus_busy; 120 struct sdhci_slot sc_slot; 121 int sc_dma_inuse; 122 int sc_dma_ch; 123 bus_dma_tag_t sc_dma_tag; 124 bus_dmamap_t sc_dma_map; 125 void *sc_dma_buffer; 126 vm_paddr_t sc_dma_buffer_phys; 127 vm_paddr_t sc_sdhci_buffer_phys;; 128}; 129 130static int bcm_sdhci_probe(device_t); 131static int bcm_sdhci_attach(device_t); 132static int bcm_sdhci_detach(device_t); 133static void bcm_sdhci_intr(void *); 134 135static int bcm_sdhci_get_ro(device_t, device_t); 136static void bcm_sdhci_dma_intr(int ch, void *arg); 137 138#define bcm_sdhci_lock(_sc) \ 139 mtx_lock(&_sc->sc_mtx); 140#define bcm_sdhci_unlock(_sc) \ 141 mtx_unlock(&_sc->sc_mtx); 142 143static void 144bcm_dmamap_cb(void *arg, bus_dma_segment_t *segs, 145 int nseg, int err) 146{ 147 bus_addr_t *addr; 148 149 if (err) 150 return; 151 152 addr = (bus_addr_t*)arg; 153 *addr = segs[0].ds_addr; 154} 155 156static int 157bcm_sdhci_probe(device_t dev) 158{ 159 if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-sdhci")) 160 return (ENXIO); 161 162 device_set_desc(dev, "Broadcom 2708 SDHCI controller"); 163 return (BUS_PROBE_DEFAULT); 164} 165 166static int 167bcm_sdhci_attach(device_t dev) 168{ 169 struct bcm_sdhci_softc *sc = device_get_softc(dev); 170 int rid, err; 171 phandle_t node; 172 pcell_t cell; 173 int default_freq; 174 void *buffer; 175 vm_paddr_t buffer_phys; 176 177 sc->sc_dev = dev; 178 sc->sc_req = NULL; 179 err = 0; 180 181 default_freq = BCM2835_DEFAULT_SDHCI_FREQ; 182 node = ofw_bus_get_node(sc->sc_dev); 183 if ((OF_getprop(node, "clock-frequency", &cell, sizeof(cell))) > 0) 184 default_freq = (int)fdt32_to_cpu(cell)/1000000; 185 186 dprintf("SDHCI frequency: %dMHz\n", default_freq); 187 188 mtx_init(&sc->sc_mtx, "bcm sdhci", "sdhci", MTX_DEF); 189 190 rid = 0; 191 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 192 RF_ACTIVE); 193 if (!sc->sc_mem_res) { 194 device_printf(dev, "cannot allocate memory window\n"); 195 err = ENXIO; 196 goto fail; 197 } 198 199 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); 200 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); 201 202 rid = 0; 203 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 204 RF_ACTIVE); 205 if (!sc->sc_irq_res) { 206 device_printf(dev, "cannot allocate interrupt\n"); 207 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 208 err = ENXIO; 209 goto fail; 210 } 211 212 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 213 NULL, bcm_sdhci_intr, sc, &sc->sc_intrhand)) 214 { 215 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 216 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 217 device_printf(dev, "cannot setup interrupt handler\n"); 218 err = ENXIO; 219 goto fail; 220 } 221 222 if (!bcm2835_sdhci_pio_mode) 223 sc->sc_slot.opt = SDHCI_PLATFORM_TRANSFER; 224 225 sc->sc_slot.caps = SDHCI_CAN_VDD_330 | SDHCI_CAN_VDD_180; 226 if (bcm2835_sdhci_hs) 227 sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD; 228 sc->sc_slot.caps |= (default_freq << SDHCI_CLOCK_BASE_SHIFT); 229 sc->sc_slot.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK 230 | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL 231 | SDHCI_QUIRK_MISSING_CAPS; 232 233 sdhci_init_slot(dev, &sc->sc_slot, 0); 234 235 sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST1); 236 if (sc->sc_dma_ch == BCM_DMA_CH_INVALID) 237 sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST2); 238 if (sc->sc_dma_ch == BCM_DMA_CH_INVALID) 239 sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_ANY); 240 if (sc->sc_dma_ch == BCM_DMA_CH_INVALID) 241 goto fail; 242 243 bcm_dma_setup_intr(sc->sc_dma_ch, bcm_sdhci_dma_intr, sc); 244 245 /* Allocate DMA buffers */ 246 err = bus_dma_tag_create(bus_get_dma_tag(dev), 247 1, 0, BUS_SPACE_MAXADDR_32BIT, 248 BUS_SPACE_MAXADDR, NULL, NULL, 249 BCM_SDHCI_BUFFER_SIZE, 1, BCM_SDHCI_BUFFER_SIZE, 250 BUS_DMA_ALLOCNOW, NULL, NULL, 251 &sc->sc_dma_tag); 252 253 if (err) { 254 device_printf(dev, "failed allocate DMA tag"); 255 goto fail; 256 } 257 258 err = bus_dmamem_alloc(sc->sc_dma_tag, &buffer, 259 BUS_DMA_WAITOK | BUS_DMA_COHERENT| BUS_DMA_ZERO, 260 &sc->sc_dma_map); 261 262 if (err) { 263 device_printf(dev, "cannot allocate DMA memory\n"); 264 goto fail; 265 } 266 267 err = bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, buffer, 268 BCM_SDHCI_BUFFER_SIZE, bcm_dmamap_cb, &buffer_phys, 269 BUS_DMA_WAITOK); 270 if (err) { 271 device_printf(dev, "cannot load DMA memory\n"); 272 goto fail; 273 } 274 275 /* 276 * Sanity check: two least bits of address should be zero 277 */ 278 if ((uintptr_t)buffer & 3) { 279 device_printf(dev, 280 "DMA address is not word-aligned\n"); 281 goto fail; 282 } 283 284 sc->sc_dma_buffer = buffer; 285 sc->sc_dma_buffer_phys = buffer_phys; 286 sc->sc_sdhci_buffer_phys = BUS_SPACE_PHYSADDR(sc->sc_mem_res, 287 SDHCI_BUFFER); 288 289 bus_generic_probe(dev); 290 bus_generic_attach(dev); 291 292 sdhci_start_slot(&sc->sc_slot); 293 294 return (0); 295 296fail: 297 if (sc->sc_intrhand) 298 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); 299 if (sc->sc_irq_res) 300 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 301 if (sc->sc_mem_res) 302 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 303 304 return (err); 305} 306 307static int 308bcm_sdhci_detach(device_t dev) 309{ 310 311 return (EBUSY); 312} 313 314static void 315bcm_sdhci_intr(void *arg) 316{ 317 struct bcm_sdhci_softc *sc = arg; 318 319 sdhci_generic_intr(&sc->sc_slot); 320} 321 322static int 323bcm_sdhci_get_ro(device_t bus, device_t child) 324{ 325 326 return (0); 327} 328 329static inline uint32_t 330RD4(struct bcm_sdhci_softc *sc, bus_size_t off) 331{ 332 uint32_t val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off); 333 return val; 334} 335 336static inline void 337WR4(struct bcm_sdhci_softc *sc, bus_size_t off, uint32_t val) 338{ 339 bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val); 340 341 if ((off != SDHCI_BUFFER && off != SDHCI_INT_STATUS && off != SDHCI_CLOCK_CONTROL)) 342 { 343 int timeout = 100000; 344 while (val != bus_space_read_4(sc->sc_bst, sc->sc_bsh, off) 345 && --timeout > 0) 346 continue; 347 348 if (timeout <= 0) 349 printf("sdhci_brcm: writing 0x%X to reg 0x%X " 350 "always gives 0x%X\n", 351 val, (uint32_t)off, 352 bus_space_read_4(sc->sc_bst, sc->sc_bsh, off)); 353 } 354} 355 356static uint8_t 357bcm_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off) 358{ 359 struct bcm_sdhci_softc *sc = device_get_softc(dev); 360 uint32_t val = RD4(sc, off & ~3); 361 362 return ((val >> (off & 3)*8) & 0xff); 363} 364 365static uint16_t 366bcm_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off) 367{ 368 struct bcm_sdhci_softc *sc = device_get_softc(dev); 369 uint32_t val = RD4(sc, off & ~3); 370 371 return ((val >> (off & 3)*8) & 0xffff); 372} 373 374static uint32_t 375bcm_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off) 376{ 377 struct bcm_sdhci_softc *sc = device_get_softc(dev); 378 379 return RD4(sc, off); 380} 381 382static void 383bcm_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, 384 uint32_t *data, bus_size_t count) 385{ 386 struct bcm_sdhci_softc *sc = device_get_softc(dev); 387 388 bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count); 389} 390 391static void 392bcm_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val) 393{ 394 struct bcm_sdhci_softc *sc = device_get_softc(dev); 395 uint32_t val32 = RD4(sc, off & ~3); 396 val32 &= ~(0xff << (off & 3)*8); 397 val32 |= (val << (off & 3)*8); 398 WR4(sc, off & ~3, val32); 399} 400 401static void 402bcm_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val) 403{ 404 struct bcm_sdhci_softc *sc = device_get_softc(dev); 405 static uint32_t cmd_and_trandfer_mode; 406 uint32_t val32; 407 if (off == SDHCI_COMMAND_FLAGS) 408 val32 = cmd_and_trandfer_mode; 409 else 410 val32 = RD4(sc, off & ~3); 411 val32 &= ~(0xffff << (off & 3)*8); 412 val32 |= (val << (off & 3)*8); 413 if (off == SDHCI_TRANSFER_MODE) 414 cmd_and_trandfer_mode = val32; 415 else 416 WR4(sc, off & ~3, val32); 417} 418 419static void 420bcm_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val) 421{ 422 struct bcm_sdhci_softc *sc = device_get_softc(dev); 423 WR4(sc, off, val); 424} 425 426static void 427bcm_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, 428 uint32_t *data, bus_size_t count) 429{ 430 struct bcm_sdhci_softc *sc = device_get_softc(dev); 431 432 bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count); 433} 434 435static uint32_t 436bcm_sdhci_min_freq(device_t dev, struct sdhci_slot *slot) 437{ 438 439 return bcm2835_sdhci_min_freq; 440} 441 442static void 443bcm_sdhci_dma_intr(int ch, void *arg) 444{ 445 struct bcm_sdhci_softc *sc = (struct bcm_sdhci_softc *)arg; 446 struct sdhci_slot *slot = &sc->sc_slot; 447 uint32_t reg, mask; 448 void *buffer; 449 size_t len; 450 int left; 451 452 mtx_lock(&slot->mtx); 453 454 /* copy DMA buffer to VA if READ */ 455 len = bcm_dma_length(sc->sc_dma_ch); 456 if (slot->curcmd->data->flags & MMC_DATA_READ) { 457 bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, 458 BUS_DMASYNC_POSTREAD); 459 460 mask = SDHCI_INT_DATA_AVAIL; 461 /* all dma data in single or contiguous page */ 462 buffer = (uint8_t*)(slot->curcmd->data->data) + slot->offset; 463 memcpy(buffer, sc->sc_dma_buffer, len); 464 } else { 465 bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, 466 BUS_DMASYNC_POSTWRITE); 467 mask = SDHCI_INT_SPACE_AVAIL; 468 } 469 470 slot->offset += len; 471 sc->sc_dma_inuse = 0; 472 473 left = min(BCM_SDHCI_BUFFER_SIZE, 474 slot->curcmd->data->len - slot->offset); 475 476 /* DATA END? */ 477 reg = bcm_sdhci_read_4(slot->bus, slot, SDHCI_INT_STATUS); 478 479 if (reg & SDHCI_INT_DATA_END) { 480 /* ACK for all outstanding interrupts */ 481 bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS, reg); 482 483 /* enable INT */ 484 slot->intmask |= SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL 485 | SDHCI_INT_DATA_END; 486 bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE, 487 slot->intmask); 488 489 /* finish this data */ 490 sdhci_finish_data(slot); 491 } 492 else { 493 /* already available? */ 494 if (reg & mask) { 495 sc->sc_dma_inuse = 1; 496 497 /* ACK for DATA_AVAIL or SPACE_AVAIL */ 498 bcm_sdhci_write_4(slot->bus, slot, 499 SDHCI_INT_STATUS, mask); 500 501 /* continue next DMA transfer */ 502 if (slot->curcmd->data->flags & MMC_DATA_READ) { 503 bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, 504 BUS_DMASYNC_PREREAD); 505 506 /* DMA start */ 507 if (bcm_dma_start(sc->sc_dma_ch, 508 sc->sc_sdhci_buffer_phys, 509 sc->sc_dma_buffer_phys, left) != 0) 510 device_printf(sc->sc_dev, "failed DMA start\n"); 511 } else { 512 buffer = (char*)slot->curcmd->data->data + slot->offset; 513 memcpy(sc->sc_dma_buffer, buffer, left); 514 515 bus_dmamap_sync(sc->sc_dma_tag, 516 sc->sc_dma_map, BUS_DMASYNC_PREWRITE); 517 518 /* DMA start */ 519 if (bcm_dma_start(sc->sc_dma_ch, 520 sc->sc_dma_buffer_phys, 521 sc->sc_sdhci_buffer_phys, left) != 0) 522 device_printf(sc->sc_dev, "failed DMA start\n"); 523 } 524 } else { 525 /* wait for next data by INT */ 526 527 /* enable INT */ 528 slot->intmask |= SDHCI_INT_DATA_AVAIL | 529 SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END; 530 bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE, 531 slot->intmask); 532 } 533 } 534 535 mtx_unlock(&slot->mtx); 536} 537 538static void 539bcm_sdhci_read_dma(struct sdhci_slot *slot) 540{ 541 struct bcm_sdhci_softc *sc = device_get_softc(slot->bus); 542 size_t left; 543 544 if (sc->sc_dma_inuse) { 545 device_printf(sc->sc_dev, "DMA in use\n"); 546 return; 547 } 548 549 sc->sc_dma_inuse = 1; 550 551 left = min(BCM_SDHCI_BUFFER_SIZE, 552 slot->curcmd->data->len - slot->offset); 553 554 KASSERT((left & 3) == 0, 555 ("%s: len = %d, not word-aligned", __func__, left)); 556 557 bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC, 558 BCM_DMA_SAME_ADDR, BCM_DMA_32BIT); 559 bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_NONE, 560 BCM_DMA_INC_ADDR, 561 (left & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT); 562 563 bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, 564 BUS_DMASYNC_PREREAD); 565 566 /* DMA start */ 567 if (bcm_dma_start(sc->sc_dma_ch, sc->sc_sdhci_buffer_phys, 568 sc->sc_dma_buffer_phys, left) != 0) 569 device_printf(sc->sc_dev, "failed DMA start\n"); 570} 571 572static void 573bcm_sdhci_write_dma(struct sdhci_slot *slot) 574{ 575 struct bcm_sdhci_softc *sc = device_get_softc(slot->bus); 576 char *buffer; 577 size_t left; 578 579 if (sc->sc_dma_inuse) { 580 device_printf(sc->sc_dev, "DMA in use\n"); 581 return; 582 } 583 584 sc->sc_dma_inuse = 1; 585 586 left = min(BCM_SDHCI_BUFFER_SIZE, 587 slot->curcmd->data->len - slot->offset); 588 589 KASSERT((left & 3) == 0, 590 ("%s: len = %d, not word-aligned", __func__, left)); 591 592 buffer = (char*)slot->curcmd->data->data + slot->offset; 593 memcpy(sc->sc_dma_buffer, buffer, left); 594 595 bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_NONE, 596 BCM_DMA_INC_ADDR, 597 (left & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT); 598 bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC, 599 BCM_DMA_SAME_ADDR, BCM_DMA_32BIT); 600 601 bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, 602 BUS_DMASYNC_PREWRITE); 603 604 /* DMA start */ 605 if (bcm_dma_start(sc->sc_dma_ch, sc->sc_dma_buffer_phys, 606 sc->sc_sdhci_buffer_phys, left) != 0) 607 device_printf(sc->sc_dev, "failed DMA start\n"); 608} 609 610static int 611bcm_sdhci_will_handle_transfer(device_t dev, struct sdhci_slot *slot) 612{ 613 size_t left; 614 615 /* Do not use DMA for transfers less then block size */ 616 left = min(BCM_DMA_BLOCK_SIZE, 617 slot->curcmd->data->len - slot->offset); 618 if (left < BCM_DMA_BLOCK_SIZE) 619 return (0); 620 621 return (1); 622} 623 624static void 625bcm_sdhci_start_transfer(device_t dev, struct sdhci_slot *slot, 626 uint32_t *intmask) 627{ 628 629 /* Disable INT */ 630 slot->intmask &= ~(SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END); 631 bcm_sdhci_write_4(dev, slot, SDHCI_SIGNAL_ENABLE, slot->intmask); 632 633 /* DMA transfer FIFO 1KB */ 634 if (slot->curcmd->data->flags & MMC_DATA_READ) 635 bcm_sdhci_read_dma(slot); 636 else 637 bcm_sdhci_write_dma(slot); 638} 639 640static void 641bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot) 642{ 643 644 sdhci_finish_data(slot); 645} 646 647static device_method_t bcm_sdhci_methods[] = { 648 /* Device interface */ 649 DEVMETHOD(device_probe, bcm_sdhci_probe), 650 DEVMETHOD(device_attach, bcm_sdhci_attach), 651 DEVMETHOD(device_detach, bcm_sdhci_detach), 652 653 /* Bus interface */ 654 DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar), 655 DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar), 656 DEVMETHOD(bus_print_child, bus_generic_print_child), 657 658 /* MMC bridge interface */ 659 DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios), 660 DEVMETHOD(mmcbr_request, sdhci_generic_request), 661 DEVMETHOD(mmcbr_get_ro, bcm_sdhci_get_ro), 662 DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host), 663 DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), 664 665 DEVMETHOD(sdhci_min_freq, bcm_sdhci_min_freq), 666 /* Platform transfer methods */ 667 DEVMETHOD(sdhci_platform_will_handle, bcm_sdhci_will_handle_transfer), 668 DEVMETHOD(sdhci_platform_start_transfer, bcm_sdhci_start_transfer), 669 DEVMETHOD(sdhci_platform_finish_transfer, bcm_sdhci_finish_transfer), 670 /* SDHCI registers accessors */ 671 DEVMETHOD(sdhci_read_1, bcm_sdhci_read_1), 672 DEVMETHOD(sdhci_read_2, bcm_sdhci_read_2), 673 DEVMETHOD(sdhci_read_4, bcm_sdhci_read_4), 674 DEVMETHOD(sdhci_read_multi_4, bcm_sdhci_read_multi_4), 675 DEVMETHOD(sdhci_write_1, bcm_sdhci_write_1), 676 DEVMETHOD(sdhci_write_2, bcm_sdhci_write_2), 677 DEVMETHOD(sdhci_write_4, bcm_sdhci_write_4), 678 DEVMETHOD(sdhci_write_multi_4, bcm_sdhci_write_multi_4), 679 680 { 0, 0 } 681}; 682 683static devclass_t bcm_sdhci_devclass; 684 685static driver_t bcm_sdhci_driver = { 686 "sdhci_bcm", 687 bcm_sdhci_methods, 688 sizeof(struct bcm_sdhci_softc), 689}; 690 691DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass, 0, 0); 692MODULE_DEPEND(sdhci_bcm, sdhci, 1, 1, 1); 693