lpc_mmc.c revision 266084
1/*- 2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@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: stable/10/sys/arm/lpc/lpc_mmc.c 266084 2014-05-14 19:18:58Z 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/time.h> 46#include <sys/timetc.h> 47#include <sys/watchdog.h> 48 49#include <sys/kdb.h> 50 51#include <machine/bus.h> 52#include <machine/cpu.h> 53#include <machine/cpufunc.h> 54#include <machine/resource.h> 55#include <machine/intr.h> 56 57#include <dev/ofw/ofw_bus.h> 58#include <dev/ofw/ofw_bus_subr.h> 59 60#include <dev/mmc/bridge.h> 61#include <dev/mmc/mmcreg.h> 62#include <dev/mmc/mmcbrvar.h> 63 64#include <arm/lpc/lpcreg.h> 65#include <arm/lpc/lpcvar.h> 66 67#ifdef DEBUG 68#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 69 printf(fmt,##args); } while (0) 70#else 71#define debugf(fmt, args...) 72#endif 73 74struct lpc_mmc_dmamap_arg { 75 bus_addr_t lm_dma_busaddr; 76}; 77 78struct lpc_mmc_softc { 79 device_t lm_dev; 80 struct mtx lm_mtx; 81 struct resource * lm_mem_res; 82 struct resource * lm_irq_res; 83 bus_space_tag_t lm_bst; 84 bus_space_handle_t lm_bsh; 85 void * lm_intrhand; 86 struct mmc_host lm_host; 87 struct mmc_request * lm_req; 88 struct mmc_data * lm_data; 89 uint32_t lm_flags; 90#define LPC_SD_FLAGS_IGNORECRC (1 << 0) 91 int lm_xfer_direction; 92#define DIRECTION_READ 0 93#define DIRECTION_WRITE 1 94 int lm_xfer_done; 95 int lm_bus_busy; 96 bus_dma_tag_t lm_dma_tag; 97 bus_dmamap_t lm_dma_map; 98 bus_addr_t lm_buffer_phys; 99 void * lm_buffer; 100}; 101 102#define LPC_SD_MAX_BLOCKSIZE 1024 103/* XXX */ 104#define LPC_MMC_DMACH_READ 1 105#define LPC_MMC_DMACH_WRITE 0 106 107 108static int lpc_mmc_probe(device_t); 109static int lpc_mmc_attach(device_t); 110static int lpc_mmc_detach(device_t); 111static void lpc_mmc_intr(void *); 112 113static void lpc_mmc_cmd(struct lpc_mmc_softc *, struct mmc_command *); 114static void lpc_mmc_setup_xfer(struct lpc_mmc_softc *, struct mmc_data *); 115 116static int lpc_mmc_update_ios(device_t, device_t); 117static int lpc_mmc_request(device_t, device_t, struct mmc_request *); 118static int lpc_mmc_get_ro(device_t, device_t); 119static int lpc_mmc_acquire_host(device_t, device_t); 120static int lpc_mmc_release_host(device_t, device_t); 121 122static void lpc_mmc_dma_rxfinish(void *); 123static void lpc_mmc_dma_rxerror(void *); 124static void lpc_mmc_dma_txfinish(void *); 125static void lpc_mmc_dma_txerror(void *); 126 127static void lpc_mmc_dmamap_cb(void *, bus_dma_segment_t *, int, int); 128 129#define lpc_mmc_lock(_sc) \ 130 mtx_lock(&_sc->lm_mtx); 131#define lpc_mmc_unlock(_sc) \ 132 mtx_unlock(&_sc->lm_mtx); 133#define lpc_mmc_read_4(_sc, _reg) \ 134 bus_space_read_4(_sc->lm_bst, _sc->lm_bsh, _reg) 135#define lpc_mmc_write_4(_sc, _reg, _value) \ 136 bus_space_write_4(_sc->lm_bst, _sc->lm_bsh, _reg, _value) 137 138static struct lpc_dmac_channel_config lpc_mmc_dma_rxconf = { 139 .ldc_fcntl = LPC_DMAC_FLOW_D_P2M, 140 .ldc_src_periph = LPC_DMAC_SD_ID, 141 .ldc_src_width = LPC_DMAC_CH_CONTROL_WIDTH_4, 142 .ldc_src_incr = 0, 143 .ldc_src_burst = LPC_DMAC_CH_CONTROL_BURST_8, 144 .ldc_dst_periph = LPC_DMAC_SD_ID, 145 .ldc_dst_width = LPC_DMAC_CH_CONTROL_WIDTH_4, 146 .ldc_dst_incr = 1, 147 .ldc_dst_burst = LPC_DMAC_CH_CONTROL_BURST_8, 148 .ldc_success_handler = lpc_mmc_dma_rxfinish, 149 .ldc_error_handler = lpc_mmc_dma_rxerror, 150}; 151 152static struct lpc_dmac_channel_config lpc_mmc_dma_txconf = { 153 .ldc_fcntl = LPC_DMAC_FLOW_P_M2P, 154 .ldc_src_periph = LPC_DMAC_SD_ID, 155 .ldc_src_width = LPC_DMAC_CH_CONTROL_WIDTH_4, 156 .ldc_src_incr = 1, 157 .ldc_src_burst = LPC_DMAC_CH_CONTROL_BURST_8, 158 .ldc_dst_periph = LPC_DMAC_SD_ID, 159 .ldc_dst_width = LPC_DMAC_CH_CONTROL_WIDTH_4, 160 .ldc_dst_incr = 0, 161 .ldc_dst_burst = LPC_DMAC_CH_CONTROL_BURST_8, 162 .ldc_success_handler = lpc_mmc_dma_txfinish, 163 .ldc_error_handler = lpc_mmc_dma_txerror, 164}; 165 166static int 167lpc_mmc_probe(device_t dev) 168{ 169 if (!ofw_bus_is_compatible(dev, "lpc,mmc")) 170 return (ENXIO); 171 172 device_set_desc(dev, "LPC32x0 MMC/SD controller"); 173 return (BUS_PROBE_DEFAULT); 174} 175 176static int 177lpc_mmc_attach(device_t dev) 178{ 179 struct lpc_mmc_softc *sc = device_get_softc(dev); 180 struct lpc_mmc_dmamap_arg ctx; 181 device_t child; 182 int rid, err; 183 184 sc->lm_dev = dev; 185 sc->lm_req = NULL; 186 187 mtx_init(&sc->lm_mtx, "lpcmmc", "mmc", MTX_DEF); 188 189 rid = 0; 190 sc->lm_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 191 RF_ACTIVE); 192 if (!sc->lm_mem_res) { 193 device_printf(dev, "cannot allocate memory window\n"); 194 return (ENXIO); 195 } 196 197 sc->lm_bst = rman_get_bustag(sc->lm_mem_res); 198 sc->lm_bsh = rman_get_bushandle(sc->lm_mem_res); 199 200 debugf("virtual register space: 0x%08lx\n", sc->lm_bsh); 201 202 rid = 0; 203 sc->lm_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 204 RF_ACTIVE); 205 if (!sc->lm_irq_res) { 206 device_printf(dev, "cannot allocate interrupt\n"); 207 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res); 208 return (ENXIO); 209 } 210 211 if (bus_setup_intr(dev, sc->lm_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 212 NULL, lpc_mmc_intr, sc, &sc->lm_intrhand)) 213 { 214 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res); 215 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res); 216 device_printf(dev, "cannot setup interrupt handler\n"); 217 return (ENXIO); 218 } 219 220 sc->lm_host.f_min = 312500; 221 sc->lm_host.f_max = 2500000; 222 sc->lm_host.host_ocr = MMC_OCR_300_310 | MMC_OCR_310_320 | 223 MMC_OCR_320_330 | MMC_OCR_330_340; 224#if 0 225 sc->lm_host.caps = MMC_CAP_4_BIT_DATA; 226#endif 227 228 lpc_pwr_write(dev, LPC_CLKPWR_MS_CTRL, 229 LPC_CLKPWR_MS_CTRL_CLOCK_EN | LPC_CLKPWR_MS_CTRL_SD_CLOCK | 1); 230 lpc_mmc_write_4(sc, LPC_SD_POWER, LPC_SD_POWER_CTRL_ON); 231 232 device_set_ivars(dev, &sc->lm_host); 233 234 child = device_add_child(dev, "mmc", -1); 235 if (!child) { 236 device_printf(dev, "attaching MMC bus failed!\n"); 237 bus_teardown_intr(dev, sc->lm_irq_res, sc->lm_intrhand); 238 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res); 239 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res); 240 return (ENXIO); 241 } 242 243 /* Alloc DMA memory */ 244 err = bus_dma_tag_create( 245 bus_get_dma_tag(sc->lm_dev), 246 4, 0, /* alignment, boundary */ 247 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 248 BUS_SPACE_MAXADDR, /* highaddr */ 249 NULL, NULL, /* filter, filterarg */ 250 LPC_SD_MAX_BLOCKSIZE, 1, /* maxsize, nsegments */ 251 LPC_SD_MAX_BLOCKSIZE, 0, /* maxsegsize, flags */ 252 NULL, NULL, /* lockfunc, lockarg */ 253 &sc->lm_dma_tag); 254 255 err = bus_dmamem_alloc(sc->lm_dma_tag, (void **)&sc->lm_buffer, 256 0, &sc->lm_dma_map); 257 if (err) { 258 device_printf(dev, "cannot allocate framebuffer\n"); 259 goto fail; 260 } 261 262 err = bus_dmamap_load(sc->lm_dma_tag, sc->lm_dma_map, sc->lm_buffer, 263 LPC_SD_MAX_BLOCKSIZE, lpc_mmc_dmamap_cb, &ctx, BUS_DMA_NOWAIT); 264 if (err) { 265 device_printf(dev, "cannot load DMA map\n"); 266 goto fail; 267 } 268 269 sc->lm_buffer_phys = ctx.lm_dma_busaddr; 270 271 lpc_mmc_dma_rxconf.ldc_handler_arg = (void *)sc; 272 err = lpc_dmac_config_channel(dev, LPC_MMC_DMACH_READ, &lpc_mmc_dma_rxconf); 273 if (err) { 274 device_printf(dev, "cannot allocate RX DMA channel\n"); 275 goto fail; 276 } 277 278 279 lpc_mmc_dma_txconf.ldc_handler_arg = (void *)sc; 280 err = lpc_dmac_config_channel(dev, LPC_MMC_DMACH_WRITE, &lpc_mmc_dma_txconf); 281 if (err) { 282 device_printf(dev, "cannot allocate TX DMA channel\n"); 283 goto fail; 284 } 285 286 bus_generic_probe(dev); 287 bus_generic_attach(dev); 288 289 return (0); 290 291fail: 292 if (sc->lm_intrhand) 293 bus_teardown_intr(dev, sc->lm_irq_res, sc->lm_intrhand); 294 if (sc->lm_irq_res) 295 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res); 296 if (sc->lm_mem_res) 297 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res); 298 return (err); 299} 300 301static int 302lpc_mmc_detach(device_t dev) 303{ 304 return (EBUSY); 305} 306 307static void 308lpc_mmc_intr(void *arg) 309{ 310 struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg; 311 struct mmc_command *cmd; 312 uint32_t status; 313 314 status = lpc_mmc_read_4(sc, LPC_SD_STATUS); 315 316 debugf("interrupt: 0x%08x\n", status); 317 318 if (status & LPC_SD_STATUS_CMDCRCFAIL) { 319 cmd = sc->lm_req->cmd; 320 cmd->error = sc->lm_flags & LPC_SD_FLAGS_IGNORECRC 321 ? MMC_ERR_NONE : MMC_ERR_BADCRC; 322 cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0); 323 sc->lm_req->done(sc->lm_req); 324 sc->lm_req = NULL; 325 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDCRCFAIL); 326 } 327 328 if (status & LPC_SD_STATUS_CMDACTIVE) 329 { 330 debugf("command active\n"); 331 cmd = sc->lm_req->cmd; 332 cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0); 333 sc->lm_req->done(sc->lm_req); 334 sc->lm_req = NULL; 335 } 336 337 if (status & LPC_SD_STATUS_DATATIMEOUT) { 338 device_printf(sc->lm_dev, "data timeout\n"); 339 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATATIMEOUT); 340 } 341 342 if (status & LPC_SD_STATUS_TXUNDERRUN) { 343 device_printf(sc->lm_dev, "TX underrun\n"); 344 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_TXUNDERRUN); 345 } 346 347 if (status & LPC_SD_STATUS_CMDRESPEND) { 348 debugf("command response\n"); 349 cmd = sc->lm_req->cmd; 350 351 if (cmd->flags & MMC_RSP_136) { 352 cmd->resp[3] = lpc_mmc_read_4(sc, LPC_SD_RESP3); 353 cmd->resp[2] = lpc_mmc_read_4(sc, LPC_SD_RESP2); 354 cmd->resp[1] = lpc_mmc_read_4(sc, LPC_SD_RESP1); 355 } 356 357 cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0); 358 cmd->error = MMC_ERR_NONE; 359 360 if (cmd->data && (cmd->data->flags & MMC_DATA_WRITE)) 361 lpc_mmc_setup_xfer(sc, sc->lm_req->cmd->data); 362 363 if (!cmd->data) { 364 sc->lm_req->done(sc->lm_req); 365 sc->lm_req = NULL; 366 } 367 368 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDRESPEND); 369 } 370 371 if (status & LPC_SD_STATUS_CMDSENT) { 372 debugf("command sent\n"); 373 cmd = sc->lm_req->cmd; 374 cmd->error = MMC_ERR_NONE; 375 sc->lm_req->done(sc->lm_req); 376 sc->lm_req = NULL; 377 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDSENT); 378 } 379 380 if (status & LPC_SD_STATUS_DATAEND) { 381 if (sc->lm_xfer_direction == DIRECTION_READ) 382 lpc_dmac_start_burst(sc->lm_dev, LPC_DMAC_SD_ID); 383 384 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATAEND); 385 } 386 387 if (status & LPC_SD_STATUS_CMDTIMEOUT) { 388 device_printf(sc->lm_dev, "command response timeout\n"); 389 cmd = sc->lm_req->cmd; 390 cmd->error = MMC_ERR_TIMEOUT; 391 sc->lm_req->done(sc->lm_req); 392 sc->lm_req = NULL; 393 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDTIMEOUT); 394 return; 395 } 396 397 if (status & LPC_SD_STATUS_STARTBITERR) { 398 device_printf(sc->lm_dev, "start bit error\n"); 399 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_STARTBITERR); 400 } 401 402 if (status & LPC_SD_STATUS_DATACRCFAIL) { 403 device_printf(sc->lm_dev, "data CRC error\n"); 404 debugf("data buffer: %p\n", sc->lm_buffer); 405 cmd = sc->lm_req->cmd; 406 cmd->error = MMC_ERR_BADCRC; 407 sc->lm_req->done(sc->lm_req); 408 sc->lm_req = NULL; 409 410 if (sc->lm_xfer_direction == DIRECTION_READ) 411 lpc_dmac_start_burst(sc->lm_dev, LPC_DMAC_SD_ID); 412 413 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATACRCFAIL); 414 } 415 416 if (status & LPC_SD_STATUS_DATABLOCKEND) { 417 debugf("data block end\n"); 418 if (sc->lm_xfer_direction == DIRECTION_READ) 419 memcpy(sc->lm_data->data, sc->lm_buffer, sc->lm_data->len); 420 421 if (sc->lm_xfer_direction == DIRECTION_WRITE) { 422 lpc_dmac_disable_channel(sc->lm_dev, LPC_MMC_DMACH_WRITE); 423 lpc_mmc_write_4(sc, LPC_SD_DATACTRL, 0); 424 } 425 426 sc->lm_req->done(sc->lm_req); 427 sc->lm_req = NULL; 428 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATABLOCKEND); 429 } 430 431 debugf("done\n"); 432} 433 434static int 435lpc_mmc_request(device_t bus, device_t child, struct mmc_request *req) 436{ 437 struct lpc_mmc_softc *sc = device_get_softc(bus); 438 439 debugf("request: %p\n", req); 440 441 lpc_mmc_lock(sc); 442 if (sc->lm_req) 443 return (EBUSY); 444 445 sc->lm_req = req; 446 447 if (req->cmd->data && req->cmd->data->flags & MMC_DATA_WRITE) { 448 memcpy(sc->lm_buffer, req->cmd->data->data, req->cmd->data->len); 449 lpc_mmc_cmd(sc, req->cmd); 450 lpc_mmc_unlock(sc); 451 return (0); 452 } 453 454 if (req->cmd->data) 455 lpc_mmc_setup_xfer(sc, req->cmd->data); 456 457 lpc_mmc_cmd(sc, req->cmd); 458 lpc_mmc_unlock(sc); 459 460 return (0); 461} 462 463static void 464lpc_mmc_cmd(struct lpc_mmc_softc *sc, struct mmc_command *cmd) 465{ 466 uint32_t cmdreg = 0; 467 468 debugf("cmd: %d arg: 0x%08x\n", cmd->opcode, cmd->arg); 469 470 if (lpc_mmc_read_4(sc, LPC_SD_COMMAND) & LPC_SD_COMMAND_ENABLE) { 471 lpc_mmc_write_4(sc, LPC_SD_COMMAND, 0); 472 DELAY(1000); 473 } 474 475 sc->lm_flags &= ~LPC_SD_FLAGS_IGNORECRC; 476 477 if (cmd->flags & MMC_RSP_PRESENT) 478 cmdreg |= LPC_SD_COMMAND_RESPONSE; 479 480 if (MMC_RSP(cmd->flags) == MMC_RSP_R2) 481 cmdreg |= LPC_SD_COMMAND_LONGRSP; 482 483 if (MMC_RSP(cmd->flags) == MMC_RSP_R3) 484 sc->lm_flags |= LPC_SD_FLAGS_IGNORECRC; 485 486 cmdreg |= LPC_SD_COMMAND_ENABLE; 487 cmdreg |= (cmd->opcode & LPC_SD_COMMAND_CMDINDEXMASK); 488 489 lpc_mmc_write_4(sc, LPC_SD_MASK0, 0xffffffff); 490 lpc_mmc_write_4(sc, LPC_SD_MASK1, 0xffffffff); 491 lpc_mmc_write_4(sc, LPC_SD_ARGUMENT, cmd->arg); 492 lpc_mmc_write_4(sc, LPC_SD_COMMAND, cmdreg); 493} 494 495static void 496lpc_mmc_setup_xfer(struct lpc_mmc_softc *sc, struct mmc_data *data) 497{ 498 uint32_t datactrl = 0; 499 int data_words = data->len / 4; 500 501 sc->lm_data = data; 502 sc->lm_xfer_done = 0; 503 504 debugf("data: %p, len: %d, %s\n", data, 505 data->len, (data->flags & MMC_DATA_READ) ? "read" : "write"); 506 507 if (data->flags & MMC_DATA_READ) { 508 sc->lm_xfer_direction = DIRECTION_READ; 509 lpc_dmac_setup_transfer(sc->lm_dev, LPC_MMC_DMACH_READ, 510 LPC_SD_PHYS_BASE + LPC_SD_FIFO, sc->lm_buffer_phys, 511 data_words, 0); 512 } 513 514 if (data->flags & MMC_DATA_WRITE) { 515 sc->lm_xfer_direction = DIRECTION_WRITE; 516 lpc_dmac_setup_transfer(sc->lm_dev, LPC_MMC_DMACH_WRITE, 517 sc->lm_buffer_phys, LPC_SD_PHYS_BASE + LPC_SD_FIFO, 518 data_words, 0); 519 } 520 521 datactrl |= (sc->lm_xfer_direction 522 ? LPC_SD_DATACTRL_WRITE 523 : LPC_SD_DATACTRL_READ); 524 525 datactrl |= LPC_SD_DATACTRL_DMAENABLE | LPC_SD_DATACTRL_ENABLE; 526 datactrl |= (ffs(data->len) - 1) << 4; 527 528 debugf("datactrl: 0x%08x\n", datactrl); 529 530 lpc_mmc_write_4(sc, LPC_SD_DATATIMER, 0xFFFF0000); 531 lpc_mmc_write_4(sc, LPC_SD_DATALENGTH, data->len); 532 lpc_mmc_write_4(sc, LPC_SD_DATACTRL, datactrl); 533} 534 535static int 536lpc_mmc_read_ivar(device_t bus, device_t child, int which, 537 uintptr_t *result) 538{ 539 struct lpc_mmc_softc *sc = device_get_softc(bus); 540 541 switch (which) { 542 default: 543 return (EINVAL); 544 case MMCBR_IVAR_BUS_MODE: 545 *(int *)result = sc->lm_host.ios.bus_mode; 546 break; 547 case MMCBR_IVAR_BUS_WIDTH: 548 *(int *)result = sc->lm_host.ios.bus_width; 549 break; 550 case MMCBR_IVAR_CHIP_SELECT: 551 *(int *)result = sc->lm_host.ios.chip_select; 552 break; 553 case MMCBR_IVAR_CLOCK: 554 *(int *)result = sc->lm_host.ios.clock; 555 break; 556 case MMCBR_IVAR_F_MIN: 557 *(int *)result = sc->lm_host.f_min; 558 break; 559 case MMCBR_IVAR_F_MAX: 560 *(int *)result = sc->lm_host.f_max; 561 break; 562 case MMCBR_IVAR_HOST_OCR: 563 *(int *)result = sc->lm_host.host_ocr; 564 break; 565 case MMCBR_IVAR_MODE: 566 *(int *)result = sc->lm_host.mode; 567 break; 568 case MMCBR_IVAR_OCR: 569 *(int *)result = sc->lm_host.ocr; 570 break; 571 case MMCBR_IVAR_POWER_MODE: 572 *(int *)result = sc->lm_host.ios.power_mode; 573 break; 574 case MMCBR_IVAR_VDD: 575 *(int *)result = sc->lm_host.ios.vdd; 576 break; 577 case MMCBR_IVAR_CAPS: 578 *(int *)result = sc->lm_host.caps; 579 break; 580 case MMCBR_IVAR_MAX_DATA: 581 *(int *)result = 1; 582 break; 583 } 584 585 return (0); 586} 587 588static int 589lpc_mmc_write_ivar(device_t bus, device_t child, int which, 590 uintptr_t value) 591{ 592 struct lpc_mmc_softc *sc = device_get_softc(bus); 593 594 switch (which) { 595 default: 596 return (EINVAL); 597 case MMCBR_IVAR_BUS_MODE: 598 sc->lm_host.ios.bus_mode = value; 599 break; 600 case MMCBR_IVAR_BUS_WIDTH: 601 sc->lm_host.ios.bus_width = value; 602 break; 603 case MMCBR_IVAR_CHIP_SELECT: 604 sc->lm_host.ios.chip_select = value; 605 break; 606 case MMCBR_IVAR_CLOCK: 607 sc->lm_host.ios.clock = value; 608 break; 609 case MMCBR_IVAR_MODE: 610 sc->lm_host.mode = value; 611 break; 612 case MMCBR_IVAR_OCR: 613 sc->lm_host.ocr = value; 614 break; 615 case MMCBR_IVAR_POWER_MODE: 616 sc->lm_host.ios.power_mode = value; 617 break; 618 case MMCBR_IVAR_VDD: 619 sc->lm_host.ios.vdd = value; 620 break; 621 /* These are read-only */ 622 case MMCBR_IVAR_CAPS: 623 case MMCBR_IVAR_HOST_OCR: 624 case MMCBR_IVAR_F_MIN: 625 case MMCBR_IVAR_F_MAX: 626 case MMCBR_IVAR_MAX_DATA: 627 return (EINVAL); 628 } 629 return (0); 630} 631 632static int 633lpc_mmc_update_ios(device_t bus, device_t child) 634{ 635 struct lpc_mmc_softc *sc = device_get_softc(bus); 636 struct mmc_ios *ios = &sc->lm_host.ios; 637 uint32_t clkdiv = 0, pwr = 0; 638 639 if (ios->bus_width == bus_width_4) 640 clkdiv |= LPC_SD_CLOCK_WIDEBUS; 641 642 /* Calculate clock divider */ 643 clkdiv = (LPC_SD_CLK / (2 * ios->clock)) - 1; 644 645 /* Clock rate should not exceed rate requested in ios */ 646 if ((LPC_SD_CLK / (2 * (clkdiv + 1))) > ios->clock) 647 clkdiv++; 648 649 debugf("clock: %dHz, clkdiv: %d\n", ios->clock, clkdiv); 650 651 if (ios->bus_width == bus_width_4) { 652 debugf("using wide bus mode\n"); 653 clkdiv |= LPC_SD_CLOCK_WIDEBUS; 654 } 655 656 lpc_mmc_write_4(sc, LPC_SD_CLOCK, clkdiv | LPC_SD_CLOCK_ENABLE); 657 658 switch (ios->power_mode) { 659 case power_off: 660 pwr |= LPC_SD_POWER_CTRL_OFF; 661 break; 662 case power_up: 663 pwr |= LPC_SD_POWER_CTRL_UP; 664 break; 665 case power_on: 666 pwr |= LPC_SD_POWER_CTRL_ON; 667 break; 668 } 669 670 if (ios->bus_mode == opendrain) 671 pwr |= LPC_SD_POWER_OPENDRAIN; 672 673 lpc_mmc_write_4(sc, LPC_SD_POWER, pwr); 674 675 return (0); 676} 677 678static int 679lpc_mmc_get_ro(device_t bus, device_t child) 680{ 681 682 return (0); 683} 684 685static int 686lpc_mmc_acquire_host(device_t bus, device_t child) 687{ 688 struct lpc_mmc_softc *sc = device_get_softc(bus); 689 int error = 0; 690 691 lpc_mmc_lock(sc); 692 while (sc->lm_bus_busy) 693 error = mtx_sleep(sc, &sc->lm_mtx, PZERO, "mmcah", 0); 694 695 sc->lm_bus_busy++; 696 lpc_mmc_unlock(sc); 697 return (error); 698} 699 700static int 701lpc_mmc_release_host(device_t bus, device_t child) 702{ 703 struct lpc_mmc_softc *sc = device_get_softc(bus); 704 705 lpc_mmc_lock(sc); 706 sc->lm_bus_busy--; 707 wakeup(sc); 708 lpc_mmc_unlock(sc); 709 return (0); 710} 711 712static void lpc_mmc_dma_rxfinish(void *arg) 713{ 714} 715 716static void lpc_mmc_dma_rxerror(void *arg) 717{ 718 struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg; 719 device_printf(sc->lm_dev, "DMA RX error\n"); 720} 721 722static void lpc_mmc_dma_txfinish(void *arg) 723{ 724} 725 726static void lpc_mmc_dma_txerror(void *arg) 727{ 728 struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg; 729 device_printf(sc->lm_dev, "DMA TX error\n"); 730} 731 732static void 733lpc_mmc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) 734{ 735 struct lpc_mmc_dmamap_arg *ctx; 736 737 if (err) 738 return; 739 740 ctx = (struct lpc_mmc_dmamap_arg *)arg; 741 ctx->lm_dma_busaddr = segs[0].ds_addr; 742} 743 744static device_method_t lpc_mmc_methods[] = { 745 /* Device interface */ 746 DEVMETHOD(device_probe, lpc_mmc_probe), 747 DEVMETHOD(device_attach, lpc_mmc_attach), 748 DEVMETHOD(device_detach, lpc_mmc_detach), 749 750 /* Bus interface */ 751 DEVMETHOD(bus_read_ivar, lpc_mmc_read_ivar), 752 DEVMETHOD(bus_write_ivar, lpc_mmc_write_ivar), 753 DEVMETHOD(bus_print_child, bus_generic_print_child), 754 755 /* MMC bridge interface */ 756 DEVMETHOD(mmcbr_update_ios, lpc_mmc_update_ios), 757 DEVMETHOD(mmcbr_request, lpc_mmc_request), 758 DEVMETHOD(mmcbr_get_ro, lpc_mmc_get_ro), 759 DEVMETHOD(mmcbr_acquire_host, lpc_mmc_acquire_host), 760 DEVMETHOD(mmcbr_release_host, lpc_mmc_release_host), 761 762 { 0, 0 } 763}; 764 765static devclass_t lpc_mmc_devclass; 766 767static driver_t lpc_mmc_driver = { 768 "lpcmmc", 769 lpc_mmc_methods, 770 sizeof(struct lpc_mmc_softc), 771}; 772 773DRIVER_MODULE(lpcmmc, simplebus, lpc_mmc_driver, lpc_mmc_devclass, 0, 0); 774