aml8726_sdxc-m8.c revision 318197
1/*- 2 * Copyright 2015 John Wehle <john@feith.com> 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/* 28 * Amlogic aml8726-m8 (and later) SDXC host controller driver. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: stable/11/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c 318197 2017-05-11 20:55:11Z marius $"); 33 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/bus.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/lock.h> 40#include <sys/mutex.h> 41#include <sys/resource.h> 42#include <sys/rman.h> 43 44#include <sys/gpio.h> 45 46#include <machine/bus.h> 47#include <machine/cpu.h> 48 49#include <dev/fdt/fdt_common.h> 50#include <dev/ofw/ofw_bus.h> 51#include <dev/ofw/ofw_bus_subr.h> 52 53#include <dev/mmc/bridge.h> 54#include <dev/mmc/mmcreg.h> 55#include <dev/mmc/mmcbrvar.h> 56 57#include <arm/amlogic/aml8726/aml8726_soc.h> 58#include <arm/amlogic/aml8726/aml8726_sdxc-m8.h> 59 60#include "gpio_if.h" 61#include "mmcbr_if.h" 62 63/* 64 * The table is sorted from highest to lowest and 65 * last entry in the table is mark by freq == 0. 66 */ 67struct { 68 uint32_t voltage; 69 uint32_t freq; 70 uint32_t rx_phase; 71} aml8726_sdxc_clk_phases[] = { 72 { 73 MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340, 74 100000000, 75 1 76 }, 77 { 78 MMC_OCR_320_330 | MMC_OCR_330_340, 79 45000000, 80 15 81 }, 82 { 83 MMC_OCR_LOW_VOLTAGE, 84 45000000, 85 11 86 }, 87 { 88 MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340, 89 24999999, 90 15 91 }, 92 { 93 MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340, 94 5000000, 95 23 96 }, 97 { 98 MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340, 99 1000000, 100 55 101 }, 102 { 103 MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340, 104 0, 105 1061 106 }, 107}; 108 109struct aml8726_sdxc_gpio { 110 device_t dev; 111 uint32_t pin; 112 uint32_t pol; 113}; 114 115struct aml8726_sdxc_softc { 116 device_t dev; 117 boolean_t auto_fill_flush; 118 struct resource *res[2]; 119 struct mtx mtx; 120 struct callout ch; 121 unsigned int ref_freq; 122 struct aml8726_sdxc_gpio pwr_en; 123 int voltages[2]; 124 struct aml8726_sdxc_gpio vselect; 125 struct aml8726_sdxc_gpio card_rst; 126 bus_dma_tag_t dmatag; 127 bus_dmamap_t dmamap; 128 void *ih_cookie; 129 struct mmc_host host; 130 int bus_busy; 131 struct { 132 uint32_t time; 133 uint32_t error; 134 } busy; 135 struct mmc_command *cmd; 136}; 137 138static struct resource_spec aml8726_sdxc_spec[] = { 139 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 140 { SYS_RES_IRQ, 0, RF_ACTIVE }, 141 { -1, 0 } 142}; 143 144#define AML_SDXC_LOCK(sc) mtx_lock(&(sc)->mtx) 145#define AML_SDXC_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 146#define AML_SDXC_LOCK_ASSERT(sc) mtx_assert(&(sc)->mtx, MA_OWNED) 147#define AML_SDXC_LOCK_INIT(sc) \ 148 mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \ 149 "sdxc", MTX_DEF) 150#define AML_SDXC_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx); 151 152#define CSR_WRITE_4(sc, reg, val) bus_write_4((sc)->res[0], reg, (val)) 153#define CSR_READ_4(sc, reg) bus_read_4((sc)->res[0], reg) 154#define CSR_BARRIER(sc, reg) bus_barrier((sc)->res[0], reg, 4, \ 155 (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)) 156 157#define PIN_ON_FLAG(pol) ((pol) == 0 ? \ 158 GPIO_PIN_LOW : GPIO_PIN_HIGH) 159#define PIN_OFF_FLAG(pol) ((pol) == 0 ? \ 160 GPIO_PIN_HIGH : GPIO_PIN_LOW) 161 162#define msecs_to_ticks(ms) (((ms)*hz)/1000 + 1) 163 164static void aml8726_sdxc_timeout(void *arg); 165 166static void 167aml8726_sdxc_mapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error) 168{ 169 bus_addr_t *busaddrp; 170 171 /* 172 * There should only be one bus space address since 173 * bus_dma_tag_create was called with nsegments = 1. 174 */ 175 176 busaddrp = (bus_addr_t *)arg; 177 *busaddrp = segs->ds_addr; 178} 179 180static int 181aml8726_sdxc_power_off(struct aml8726_sdxc_softc *sc) 182{ 183 184 if (sc->pwr_en.dev == NULL) 185 return (0); 186 187 return (GPIO_PIN_SET(sc->pwr_en.dev, sc->pwr_en.pin, 188 PIN_OFF_FLAG(sc->pwr_en.pol))); 189} 190 191static int 192aml8726_sdxc_power_on(struct aml8726_sdxc_softc *sc) 193{ 194 195 if (sc->pwr_en.dev == NULL) 196 return (0); 197 198 return (GPIO_PIN_SET(sc->pwr_en.dev, sc->pwr_en.pin, 199 PIN_ON_FLAG(sc->pwr_en.pol))); 200} 201 202static void 203aml8726_sdxc_soft_reset(struct aml8726_sdxc_softc *sc) 204{ 205 206 CSR_WRITE_4(sc, AML_SDXC_SOFT_RESET_REG, AML_SDXC_SOFT_RESET); 207 CSR_BARRIER(sc, AML_SDXC_SOFT_RESET_REG); 208 DELAY(5); 209} 210 211static void 212aml8726_sdxc_engage_dma(struct aml8726_sdxc_softc *sc) 213{ 214 int i; 215 uint32_t pdmar; 216 uint32_t sr; 217 struct mmc_data *data; 218 219 data = sc->cmd->data; 220 221 if (data == NULL || data->len == 0) 222 return; 223 224 /* 225 * Engaging the DMA hardware is recommended before writing 226 * to AML_SDXC_SEND_REG so that the FIFOs are ready to go. 227 * 228 * Presumably AML_SDXC_CNTRL_REG and AML_SDXC_DMA_ADDR_REG 229 * must be set up prior to this happening. 230 */ 231 232 pdmar = CSR_READ_4(sc, AML_SDXC_PDMA_REG); 233 234 pdmar &= ~AML_SDXC_PDMA_RX_FLUSH_MODE_SW; 235 pdmar |= AML_SDXC_PDMA_DMA_EN; 236 237 if (sc->auto_fill_flush == true) { 238 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 239 CSR_BARRIER(sc, AML_SDXC_PDMA_REG); 240 return; 241 } 242 243 if ((data->flags & MMC_DATA_READ) != 0) { 244 pdmar |= AML_SDXC_PDMA_RX_FLUSH_MODE_SW; 245 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 246 CSR_BARRIER(sc, AML_SDXC_PDMA_REG); 247 } else { 248 pdmar |= AML_SDXC_PDMA_TX_FILL; 249 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 250 CSR_BARRIER(sc, AML_SDXC_PDMA_REG); 251 252 /* 253 * Wait up to 100us for data to show up. 254 */ 255 for (i = 0; i < 100; i++) { 256 sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG); 257 if ((sr & AML_SDXC_STATUS_TX_CNT_MASK) != 0) 258 break; 259 DELAY(1); 260 } 261 if (i >= 100) 262 device_printf(sc->dev, "TX FIFO fill timeout\n"); 263 } 264} 265 266static void 267aml8726_sdxc_disengage_dma(struct aml8726_sdxc_softc *sc) 268{ 269 int i; 270 uint32_t pdmar; 271 uint32_t sr; 272 struct mmc_data *data; 273 274 data = sc->cmd->data; 275 276 if (data == NULL || data->len == 0) 277 return; 278 279 pdmar = CSR_READ_4(sc, AML_SDXC_PDMA_REG); 280 281 if (sc->auto_fill_flush == true) { 282 pdmar &= ~AML_SDXC_PDMA_DMA_EN; 283 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 284 CSR_BARRIER(sc, AML_SDXC_PDMA_REG); 285 return; 286 } 287 288 if ((data->flags & MMC_DATA_READ) != 0) { 289 pdmar |= AML_SDXC_PDMA_RX_FLUSH_NOW; 290 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 291 CSR_BARRIER(sc, AML_SDXC_PDMA_REG); 292 293 /* 294 * Wait up to 100us for data to drain. 295 */ 296 for (i = 0; i < 100; i++) { 297 sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG); 298 if ((sr & AML_SDXC_STATUS_RX_CNT_MASK) == 0) 299 break; 300 DELAY(1); 301 } 302 if (i >= 100) 303 device_printf(sc->dev, "RX FIFO drain timeout\n"); 304 } 305 306 pdmar &= ~(AML_SDXC_PDMA_DMA_EN | AML_SDXC_PDMA_RX_FLUSH_MODE_SW); 307 308 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 309 CSR_BARRIER(sc, AML_SDXC_PDMA_REG); 310} 311 312static int 313aml8726_sdxc_start_command(struct aml8726_sdxc_softc *sc, 314 struct mmc_command *cmd) 315{ 316 bus_addr_t baddr; 317 uint32_t block_size; 318 uint32_t ctlr; 319 uint32_t ier; 320 uint32_t sndr; 321 uint32_t timeout; 322 int error; 323 struct mmc_data *data; 324 325 AML_SDXC_LOCK_ASSERT(sc); 326 327 if (cmd->opcode > 0x3f) 328 return (MMC_ERR_INVALID); 329 330 /* 331 * Ensure the hardware state machine is in a known state. 332 */ 333 aml8726_sdxc_soft_reset(sc); 334 335 sndr = cmd->opcode; 336 337 if ((cmd->flags & MMC_RSP_136) != 0) { 338 sndr |= AML_SDXC_SEND_CMD_HAS_RESP; 339 sndr |= AML_SDXC_SEND_RESP_136; 340 /* 341 * According to the SD spec the 136 bit response is 342 * used for getting the CID or CSD in which case the 343 * CRC7 is embedded in the contents rather than being 344 * calculated over the entire response (the controller 345 * always checks the CRC7 over the entire response). 346 */ 347 sndr |= AML_SDXC_SEND_RESP_NO_CRC7_CHECK; 348 } else if ((cmd->flags & MMC_RSP_PRESENT) != 0) 349 sndr |= AML_SDXC_SEND_CMD_HAS_RESP; 350 351 if ((cmd->flags & MMC_RSP_CRC) == 0) 352 sndr |= AML_SDXC_SEND_RESP_NO_CRC7_CHECK; 353 354 if (cmd->opcode == MMC_STOP_TRANSMISSION) 355 sndr |= AML_SDXC_SEND_DATA_STOP; 356 357 data = cmd->data; 358 359 baddr = 0; 360 ctlr = CSR_READ_4(sc, AML_SDXC_CNTRL_REG); 361 ier = AML_SDXC_IRQ_ENABLE_STANDARD; 362 timeout = AML_SDXC_CMD_TIMEOUT; 363 364 ctlr &= ~AML_SDXC_CNTRL_PKG_LEN_MASK; 365 366 if (data && data->len && 367 (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) { 368 block_size = data->len; 369 370 if ((data->flags & MMC_DATA_MULTI) != 0) { 371 block_size = MMC_SECTOR_SIZE; 372 if ((data->len % block_size) != 0) 373 return (MMC_ERR_INVALID); 374 } 375 376 if (block_size > 512) 377 return (MMC_ERR_INVALID); 378 379 sndr |= AML_SDXC_SEND_CMD_HAS_DATA; 380 sndr |= ((data->flags & MMC_DATA_WRITE) != 0) ? 381 AML_SDXC_SEND_DATA_WRITE : 0; 382 sndr |= (((data->len / block_size) - 1) << 383 AML_SDXC_SEND_REP_PKG_CNT_SHIFT); 384 385 ctlr |= ((block_size < 512) ? block_size : 0) << 386 AML_SDXC_CNTRL_PKG_LEN_SHIFT; 387 388 ier &= ~AML_SDXC_IRQ_ENABLE_RESP_OK; 389 ier |= (sc->auto_fill_flush == true || 390 (data->flags & MMC_DATA_WRITE) != 0) ? 391 AML_SDXC_IRQ_ENABLE_DMA_DONE : 392 AML_SDXC_IRQ_ENABLE_TRANSFER_DONE_OK; 393 394 error = bus_dmamap_load(sc->dmatag, sc->dmamap, 395 data->data, data->len, aml8726_sdxc_mapmem, &baddr, 396 BUS_DMA_NOWAIT); 397 if (error) 398 return (MMC_ERR_NO_MEMORY); 399 400 if ((data->flags & MMC_DATA_READ) != 0) { 401 bus_dmamap_sync(sc->dmatag, sc->dmamap, 402 BUS_DMASYNC_PREREAD); 403 timeout = AML_SDXC_READ_TIMEOUT * 404 (data->len / block_size); 405 } else { 406 bus_dmamap_sync(sc->dmatag, sc->dmamap, 407 BUS_DMASYNC_PREWRITE); 408 timeout = AML_SDXC_WRITE_TIMEOUT * 409 (data->len / block_size); 410 } 411 } 412 413 sc->cmd = cmd; 414 415 cmd->error = MMC_ERR_NONE; 416 417 sc->busy.time = 0; 418 sc->busy.error = MMC_ERR_NONE; 419 420 if (timeout > AML_SDXC_MAX_TIMEOUT) 421 timeout = AML_SDXC_MAX_TIMEOUT; 422 423 callout_reset(&sc->ch, msecs_to_ticks(timeout), 424 aml8726_sdxc_timeout, sc); 425 426 CSR_WRITE_4(sc, AML_SDXC_IRQ_ENABLE_REG, ier); 427 428 CSR_WRITE_4(sc, AML_SDXC_CNTRL_REG, ctlr); 429 CSR_WRITE_4(sc, AML_SDXC_DMA_ADDR_REG, (uint32_t)baddr); 430 CSR_WRITE_4(sc, AML_SDXC_CMD_ARGUMENT_REG, cmd->arg); 431 432 aml8726_sdxc_engage_dma(sc); 433 434 CSR_WRITE_4(sc, AML_SDXC_SEND_REG, sndr); 435 CSR_BARRIER(sc, AML_SDXC_SEND_REG); 436 437 return (MMC_ERR_NONE); 438} 439 440static void 441aml8726_sdxc_finish_command(struct aml8726_sdxc_softc *sc, int mmc_error) 442{ 443 int mmc_stop_error; 444 struct mmc_command *cmd; 445 struct mmc_command *stop_cmd; 446 struct mmc_data *data; 447 448 AML_SDXC_LOCK_ASSERT(sc); 449 450 /* Clear all interrupts since the request is no longer in flight. */ 451 CSR_WRITE_4(sc, AML_SDXC_IRQ_STATUS_REG, AML_SDXC_IRQ_STATUS_CLEAR); 452 CSR_BARRIER(sc, AML_SDXC_IRQ_STATUS_REG); 453 454 /* In some cases (e.g. finish called via timeout) this is a NOP. */ 455 callout_stop(&sc->ch); 456 457 cmd = sc->cmd; 458 sc->cmd = NULL; 459 460 cmd->error = mmc_error; 461 462 data = cmd->data; 463 464 if (data && data->len 465 && (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) { 466 if ((data->flags & MMC_DATA_READ) != 0) 467 bus_dmamap_sync(sc->dmatag, sc->dmamap, 468 BUS_DMASYNC_POSTREAD); 469 else 470 bus_dmamap_sync(sc->dmatag, sc->dmamap, 471 BUS_DMASYNC_POSTWRITE); 472 bus_dmamap_unload(sc->dmatag, sc->dmamap); 473 } 474 475 /* 476 * If there's a linked stop command, then start the stop command. 477 * In order to establish a known state attempt the stop command 478 * even if the original request encountered an error. 479 */ 480 481 stop_cmd = (cmd->mrq->stop != cmd) ? cmd->mrq->stop : NULL; 482 483 if (stop_cmd != NULL) { 484 485 /* 486 * If the original command executed successfully, then 487 * the hardware will also have automatically executed 488 * a stop command so don't bother with the one supplied 489 * with the original request. 490 */ 491 492 if (mmc_error == MMC_ERR_NONE) { 493 stop_cmd->error = MMC_ERR_NONE; 494 stop_cmd->resp[0] = cmd->resp[0]; 495 stop_cmd->resp[1] = cmd->resp[1]; 496 stop_cmd->resp[2] = cmd->resp[2]; 497 stop_cmd->resp[3] = cmd->resp[3]; 498 } else { 499 mmc_stop_error = aml8726_sdxc_start_command(sc, 500 stop_cmd); 501 if (mmc_stop_error == MMC_ERR_NONE) { 502 AML_SDXC_UNLOCK(sc); 503 return; 504 } 505 stop_cmd->error = mmc_stop_error; 506 } 507 } 508 509 AML_SDXC_UNLOCK(sc); 510 511 /* Execute the callback after dropping the lock. */ 512 if (cmd->mrq != NULL) 513 cmd->mrq->done(cmd->mrq); 514} 515 516static void 517aml8726_sdxc_timeout(void *arg) 518{ 519 struct aml8726_sdxc_softc *sc = (struct aml8726_sdxc_softc *)arg; 520 521 /* 522 * The command failed to complete in time so forcefully 523 * terminate it. 524 */ 525 aml8726_sdxc_soft_reset(sc); 526 527 /* 528 * Ensure the command has terminated before continuing on 529 * to things such as bus_dmamap_sync / bus_dmamap_unload. 530 */ 531 while ((CSR_READ_4(sc, AML_SDXC_STATUS_REG) & 532 AML_SDXC_STATUS_BUSY) != 0) 533 cpu_spinwait(); 534 535 aml8726_sdxc_finish_command(sc, MMC_ERR_TIMEOUT); 536} 537 538static void 539aml8726_sdxc_busy_check(void *arg) 540{ 541 struct aml8726_sdxc_softc *sc = (struct aml8726_sdxc_softc *)arg; 542 uint32_t sr; 543 544 sc->busy.time += AML_SDXC_BUSY_POLL_INTVL; 545 546 sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG); 547 548 if ((sr & AML_SDXC_STATUS_DAT0) == 0) { 549 if (sc->busy.time < AML_SDXC_BUSY_TIMEOUT) { 550 callout_reset(&sc->ch, 551 msecs_to_ticks(AML_SDXC_BUSY_POLL_INTVL), 552 aml8726_sdxc_busy_check, sc); 553 AML_SDXC_UNLOCK(sc); 554 return; 555 } 556 if (sc->busy.error == MMC_ERR_NONE) 557 sc->busy.error = MMC_ERR_TIMEOUT; 558 } 559 560 aml8726_sdxc_finish_command(sc, sc->busy.error); 561} 562 563static void 564aml8726_sdxc_intr(void *arg) 565{ 566 struct aml8726_sdxc_softc *sc = (struct aml8726_sdxc_softc *)arg; 567 uint32_t isr; 568 uint32_t pdmar; 569 uint32_t sndr; 570 uint32_t sr; 571 int i; 572 int mmc_error; 573 int start; 574 int stop; 575 576 AML_SDXC_LOCK(sc); 577 578 isr = CSR_READ_4(sc, AML_SDXC_IRQ_STATUS_REG); 579 sndr = CSR_READ_4(sc, AML_SDXC_SEND_REG); 580 sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG); 581 582 if (sc->cmd == NULL) 583 goto spurious; 584 585 mmc_error = MMC_ERR_NONE; 586 587 if ((isr & (AML_SDXC_IRQ_STATUS_TX_FIFO_EMPTY | 588 AML_SDXC_IRQ_STATUS_RX_FIFO_FULL)) != 0) 589 mmc_error = MMC_ERR_FIFO; 590 else if ((isr & (AML_SDXC_IRQ_ENABLE_A_PKG_CRC_ERR | 591 AML_SDXC_IRQ_ENABLE_RESP_CRC_ERR)) != 0) 592 mmc_error = MMC_ERR_BADCRC; 593 else if ((isr & (AML_SDXC_IRQ_ENABLE_A_PKG_TIMEOUT_ERR | 594 AML_SDXC_IRQ_ENABLE_RESP_TIMEOUT_ERR)) != 0) 595 mmc_error = MMC_ERR_TIMEOUT; 596 else if ((isr & (AML_SDXC_IRQ_STATUS_RESP_OK | 597 AML_SDXC_IRQ_STATUS_DMA_DONE | 598 AML_SDXC_IRQ_STATUS_TRANSFER_DONE_OK)) != 0) { 599 ; 600 } 601 else { 602spurious: 603 /* 604 * Clear spurious interrupts while leaving intacted any 605 * interrupts that may have occurred after we read the 606 * interrupt status register. 607 */ 608 609 CSR_WRITE_4(sc, AML_SDXC_IRQ_STATUS_REG, 610 (AML_SDXC_IRQ_STATUS_CLEAR & isr)); 611 CSR_BARRIER(sc, AML_SDXC_IRQ_STATUS_REG); 612 AML_SDXC_UNLOCK(sc); 613 return; 614 } 615 616 aml8726_sdxc_disengage_dma(sc); 617 618 if ((sndr & AML_SDXC_SEND_CMD_HAS_RESP) != 0) { 619 start = 0; 620 stop = 1; 621 if ((sndr & AML_SDXC_SEND_RESP_136) != 0) { 622 start = 1; 623 stop = start + 4; 624 } 625 for (i = start; i < stop; i++) { 626 pdmar = CSR_READ_4(sc, AML_SDXC_PDMA_REG); 627 pdmar &= ~(AML_SDXC_PDMA_DMA_EN | 628 AML_SDXC_PDMA_RESP_INDEX_MASK); 629 pdmar |= i << AML_SDXC_PDMA_RESP_INDEX_SHIFT; 630 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 631 sc->cmd->resp[(stop - 1) - i] = CSR_READ_4(sc, 632 AML_SDXC_CMD_ARGUMENT_REG); 633 } 634 } 635 636 if ((sr & AML_SDXC_STATUS_BUSY) != 0 && 637 /* 638 * A multiblock operation may keep the hardware 639 * busy until stop transmission is executed. 640 */ 641 (isr & (AML_SDXC_IRQ_STATUS_DMA_DONE | 642 AML_SDXC_IRQ_STATUS_TRANSFER_DONE_OK)) == 0) { 643 if (mmc_error == MMC_ERR_NONE) 644 mmc_error = MMC_ERR_FAILED; 645 646 /* 647 * Issue a soft reset to terminate the command. 648 * 649 * Ensure the command has terminated before continuing on 650 * to things such as bus_dmamap_sync / bus_dmamap_unload. 651 */ 652 653 aml8726_sdxc_soft_reset(sc); 654 655 while ((CSR_READ_4(sc, AML_SDXC_STATUS_REG) & 656 AML_SDXC_STATUS_BUSY) != 0) 657 cpu_spinwait(); 658 } 659 660 /* 661 * The stop command can be generated either manually or 662 * automatically by the hardware if MISC_MANUAL_STOP_MODE 663 * has not been set. In either case check for busy. 664 */ 665 666 if (((sc->cmd->flags & MMC_RSP_BUSY) != 0 || 667 (sndr & AML_SDXC_SEND_INDEX_MASK) == MMC_STOP_TRANSMISSION) && 668 (sr & AML_SDXC_STATUS_DAT0) == 0) { 669 sc->busy.error = mmc_error; 670 callout_reset(&sc->ch, 671 msecs_to_ticks(AML_SDXC_BUSY_POLL_INTVL), 672 aml8726_sdxc_busy_check, sc); 673 CSR_WRITE_4(sc, AML_SDXC_IRQ_STATUS_REG, 674 (AML_SDXC_IRQ_STATUS_CLEAR & isr)); 675 CSR_BARRIER(sc, AML_SDXC_IRQ_STATUS_REG); 676 AML_SDXC_UNLOCK(sc); 677 return; 678 } 679 680 aml8726_sdxc_finish_command(sc, mmc_error); 681} 682 683static int 684aml8726_sdxc_probe(device_t dev) 685{ 686 687 if (!ofw_bus_status_okay(dev)) 688 return (ENXIO); 689 690 if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-sdxc-m8")) 691 return (ENXIO); 692 693 device_set_desc(dev, "Amlogic aml8726-m8 SDXC"); 694 695 return (BUS_PROBE_DEFAULT); 696} 697 698static int 699aml8726_sdxc_attach(device_t dev) 700{ 701 struct aml8726_sdxc_softc *sc = device_get_softc(dev); 702 char *voltages; 703 char *voltage; 704 int error; 705 int nvoltages; 706 pcell_t prop[3]; 707 phandle_t node; 708 ssize_t len; 709 device_t child; 710 uint32_t ectlr; 711 uint32_t miscr; 712 uint32_t pdmar; 713 714 sc->dev = dev; 715 716 sc->auto_fill_flush = false; 717 718 pdmar = AML_SDXC_PDMA_DMA_URGENT | 719 (49 << AML_SDXC_PDMA_TX_THOLD_SHIFT) | 720 (7 << AML_SDXC_PDMA_RX_THOLD_SHIFT) | 721 (15 << AML_SDXC_PDMA_RD_BURST_SHIFT) | 722 (7 << AML_SDXC_PDMA_WR_BURST_SHIFT); 723 724 miscr = (2 << AML_SDXC_MISC_WCRC_OK_PAT_SHIFT) | 725 (5 << AML_SDXC_MISC_WCRC_ERR_PAT_SHIFT); 726 727 ectlr = (12 << AML_SDXC_ENH_CNTRL_SDIO_IRQ_PERIOD_SHIFT); 728 729 /* 730 * Certain bitfields are dependent on the hardware revision. 731 */ 732 switch (aml8726_soc_hw_rev) { 733 case AML_SOC_HW_REV_M8: 734 switch (aml8726_soc_metal_rev) { 735 case AML_SOC_M8_METAL_REV_M2_A: 736 sc->auto_fill_flush = true; 737 miscr |= (6 << AML_SDXC_MISC_TXSTART_THOLD_SHIFT); 738 ectlr |= (64 << AML_SDXC_ENH_CNTRL_RX_FULL_THOLD_SHIFT) | 739 AML_SDXC_ENH_CNTRL_WR_RESP_MODE_SKIP_M8M2; 740 break; 741 default: 742 miscr |= (7 << AML_SDXC_MISC_TXSTART_THOLD_SHIFT); 743 ectlr |= (63 << AML_SDXC_ENH_CNTRL_RX_FULL_THOLD_SHIFT) | 744 AML_SDXC_ENH_CNTRL_DMA_NO_WR_RESP_CHECK_M8 | 745 (255 << AML_SDXC_ENH_CNTRL_RX_TIMEOUT_SHIFT_M8); 746 747 break; 748 } 749 break; 750 case AML_SOC_HW_REV_M8B: 751 miscr |= (7 << AML_SDXC_MISC_TXSTART_THOLD_SHIFT); 752 ectlr |= (63 << AML_SDXC_ENH_CNTRL_RX_FULL_THOLD_SHIFT) | 753 AML_SDXC_ENH_CNTRL_DMA_NO_WR_RESP_CHECK_M8 | 754 (255 << AML_SDXC_ENH_CNTRL_RX_TIMEOUT_SHIFT_M8); 755 break; 756 default: 757 device_printf(dev, "unsupported SoC\n"); 758 return (ENXIO); 759 /* NOTREACHED */ 760 } 761 762 node = ofw_bus_get_node(dev); 763 764 len = OF_getencprop(node, "clock-frequency", prop, sizeof(prop)); 765 if ((len / sizeof(prop[0])) != 1 || prop[0] == 0) { 766 device_printf(dev, 767 "missing clock-frequency attribute in FDT\n"); 768 return (ENXIO); 769 } 770 771 sc->ref_freq = prop[0]; 772 773 sc->pwr_en.dev = NULL; 774 775 len = OF_getencprop(node, "mmc-pwr-en", prop, sizeof(prop)); 776 if (len > 0) { 777 if ((len / sizeof(prop[0])) == 3) { 778 sc->pwr_en.dev = OF_device_from_xref(prop[0]); 779 sc->pwr_en.pin = prop[1]; 780 sc->pwr_en.pol = prop[2]; 781 } 782 783 if (sc->pwr_en.dev == NULL) { 784 device_printf(dev, 785 "unable to process mmc-pwr-en attribute in FDT\n"); 786 return (ENXIO); 787 } 788 789 /* Turn off power and then configure the output driver. */ 790 if (aml8726_sdxc_power_off(sc) != 0 || 791 GPIO_PIN_SETFLAGS(sc->pwr_en.dev, sc->pwr_en.pin, 792 GPIO_PIN_OUTPUT) != 0) { 793 device_printf(dev, 794 "could not use gpio to control power\n"); 795 return (ENXIO); 796 } 797 } 798 799 len = OF_getprop_alloc(node, "mmc-voltages", 800 sizeof(char), (void **)&voltages); 801 802 if (len < 0) { 803 device_printf(dev, "missing mmc-voltages attribute in FDT\n"); 804 return (ENXIO); 805 } 806 807 sc->voltages[0] = 0; 808 sc->voltages[1] = 0; 809 810 voltage = voltages; 811 nvoltages = 0; 812 813 while (len && nvoltages < 2) { 814 if (strncmp("1.8", voltage, len) == 0) 815 sc->voltages[nvoltages] = MMC_OCR_LOW_VOLTAGE; 816 else if (strncmp("3.3", voltage, len) == 0) 817 sc->voltages[nvoltages] = MMC_OCR_320_330 | 818 MMC_OCR_330_340; 819 else { 820 device_printf(dev, 821 "unknown voltage attribute %.*s in FDT\n", 822 len, voltage); 823 OF_prop_free(voltages); 824 return (ENXIO); 825 } 826 827 nvoltages++; 828 829 /* queue up next string */ 830 while (*voltage && len) { 831 voltage++; 832 len--; 833 } 834 if (len) { 835 voltage++; 836 len--; 837 } 838 } 839 840 OF_prop_free(voltages); 841 842 sc->vselect.dev = NULL; 843 844 len = OF_getencprop(node, "mmc-vselect", prop, sizeof(prop)); 845 if (len > 0) { 846 if ((len / sizeof(prop[0])) == 2) { 847 sc->vselect.dev = OF_device_from_xref(prop[0]); 848 sc->vselect.pin = prop[1]; 849 sc->vselect.pol = 1; 850 } 851 852 if (sc->vselect.dev == NULL) { 853 device_printf(dev, 854 "unable to process mmc-vselect attribute in FDT\n"); 855 return (ENXIO); 856 } 857 858 /* 859 * With the power off select voltage 0 and then 860 * configure the output driver. 861 */ 862 if (GPIO_PIN_SET(sc->vselect.dev, sc->vselect.pin, 0) != 0 || 863 GPIO_PIN_SETFLAGS(sc->vselect.dev, sc->vselect.pin, 864 GPIO_PIN_OUTPUT) != 0) { 865 device_printf(dev, 866 "could not use gpio to set voltage\n"); 867 return (ENXIO); 868 } 869 } 870 871 if (nvoltages == 0) { 872 device_printf(dev, "no voltages in FDT\n"); 873 return (ENXIO); 874 } else if (nvoltages == 1 && sc->vselect.dev != NULL) { 875 device_printf(dev, "only one voltage in FDT\n"); 876 return (ENXIO); 877 } else if (nvoltages == 2 && sc->vselect.dev == NULL) { 878 device_printf(dev, "too many voltages in FDT\n"); 879 return (ENXIO); 880 } 881 882 sc->card_rst.dev = NULL; 883 884 len = OF_getencprop(node, "mmc-rst", prop, sizeof(prop)); 885 if (len > 0) { 886 if ((len / sizeof(prop[0])) == 3) { 887 sc->card_rst.dev = OF_device_from_xref(prop[0]); 888 sc->card_rst.pin = prop[1]; 889 sc->card_rst.pol = prop[2]; 890 } 891 892 if (sc->card_rst.dev == NULL) { 893 device_printf(dev, 894 "unable to process mmc-rst attribute in FDT\n"); 895 return (ENXIO); 896 } 897 } 898 899 if (bus_alloc_resources(dev, aml8726_sdxc_spec, sc->res)) { 900 device_printf(dev, "could not allocate resources for device\n"); 901 return (ENXIO); 902 } 903 904 AML_SDXC_LOCK_INIT(sc); 905 906 error = bus_dma_tag_create(bus_get_dma_tag(dev), AML_SDXC_ALIGN_DMA, 0, 907 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 908 AML_SDXC_MAX_DMA, 1, AML_SDXC_MAX_DMA, 0, NULL, NULL, &sc->dmatag); 909 if (error) 910 goto fail; 911 912 error = bus_dmamap_create(sc->dmatag, 0, &sc->dmamap); 913 914 if (error) 915 goto fail; 916 917 error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, 918 NULL, aml8726_sdxc_intr, sc, &sc->ih_cookie); 919 if (error) { 920 device_printf(dev, "could not setup interrupt handler\n"); 921 goto fail; 922 } 923 924 callout_init_mtx(&sc->ch, &sc->mtx, CALLOUT_RETURNUNLOCKED); 925 926 sc->host.f_min = 200000; 927 sc->host.f_max = 100000000; 928 sc->host.host_ocr = sc->voltages[0] | sc->voltages[1]; 929 sc->host.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | 930 MMC_CAP_HSPEED; 931 932 aml8726_sdxc_soft_reset(sc); 933 934 CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar); 935 936 CSR_WRITE_4(sc, AML_SDXC_MISC_REG, miscr); 937 938 CSR_WRITE_4(sc, AML_SDXC_ENH_CNTRL_REG, ectlr); 939 940 child = device_add_child(dev, "mmc", -1); 941 942 if (!child) { 943 device_printf(dev, "could not add mmc\n"); 944 error = ENXIO; 945 goto fail; 946 } 947 948 error = device_probe_and_attach(child); 949 950 if (error) { 951 device_printf(dev, "could not attach mmc\n"); 952 goto fail; 953 } 954 955 return (0); 956 957fail: 958 if (sc->ih_cookie) 959 bus_teardown_intr(dev, sc->res[1], sc->ih_cookie); 960 961 if (sc->dmamap) 962 bus_dmamap_destroy(sc->dmatag, sc->dmamap); 963 964 if (sc->dmatag) 965 bus_dma_tag_destroy(sc->dmatag); 966 967 AML_SDXC_LOCK_DESTROY(sc); 968 969 (void)aml8726_sdxc_power_off(sc); 970 971 bus_release_resources(dev, aml8726_sdxc_spec, sc->res); 972 973 return (error); 974} 975 976static int 977aml8726_sdxc_detach(device_t dev) 978{ 979 struct aml8726_sdxc_softc *sc = device_get_softc(dev); 980 981 AML_SDXC_LOCK(sc); 982 983 if (sc->cmd != NULL) { 984 AML_SDXC_UNLOCK(sc); 985 return (EBUSY); 986 } 987 988 /* 989 * Turn off the power, reset the hardware state machine, 990 * and disable the interrupts. 991 */ 992 aml8726_sdxc_power_off(sc); 993 aml8726_sdxc_soft_reset(sc); 994 CSR_WRITE_4(sc, AML_SDXC_IRQ_ENABLE_REG, 0); 995 996 AML_SDXC_UNLOCK(sc); 997 998 bus_generic_detach(dev); 999 1000 bus_teardown_intr(dev, sc->res[1], sc->ih_cookie); 1001 1002 bus_dmamap_destroy(sc->dmatag, sc->dmamap); 1003 1004 bus_dma_tag_destroy(sc->dmatag); 1005 1006 AML_SDXC_LOCK_DESTROY(sc); 1007 1008 bus_release_resources(dev, aml8726_sdxc_spec, sc->res); 1009 1010 return (0); 1011} 1012 1013static int 1014aml8726_sdxc_shutdown(device_t dev) 1015{ 1016 struct aml8726_sdxc_softc *sc = device_get_softc(dev); 1017 1018 /* 1019 * Turn off the power, reset the hardware state machine, 1020 * and disable the interrupts. 1021 */ 1022 aml8726_sdxc_power_off(sc); 1023 aml8726_sdxc_soft_reset(sc); 1024 CSR_WRITE_4(sc, AML_SDXC_IRQ_ENABLE_REG, 0); 1025 1026 return (0); 1027} 1028 1029static int 1030aml8726_sdxc_update_ios(device_t bus, device_t child) 1031{ 1032 struct aml8726_sdxc_softc *sc = device_get_softc(bus); 1033 struct mmc_ios *ios = &sc->host.ios; 1034 unsigned int divisor; 1035 int error; 1036 int i; 1037 uint32_t cctlr; 1038 uint32_t clk2r; 1039 uint32_t ctlr; 1040 uint32_t freq; 1041 1042 ctlr = (7 << AML_SDXC_CNTRL_TX_ENDIAN_SHIFT) | 1043 (7 << AML_SDXC_CNTRL_RX_ENDIAN_SHIFT) | 1044 (0xf << AML_SDXC_CNTRL_RX_PERIOD_SHIFT) | 1045 (0x7f << AML_SDXC_CNTRL_RX_TIMEOUT_SHIFT); 1046 1047 switch (ios->bus_width) { 1048 case bus_width_8: 1049 ctlr |= AML_SDXC_CNTRL_BUS_WIDTH_8; 1050 break; 1051 case bus_width_4: 1052 ctlr |= AML_SDXC_CNTRL_BUS_WIDTH_4; 1053 break; 1054 case bus_width_1: 1055 ctlr |= AML_SDXC_CNTRL_BUS_WIDTH_1; 1056 break; 1057 default: 1058 return (EINVAL); 1059 } 1060 1061 CSR_WRITE_4(sc, AML_SDXC_CNTRL_REG, ctlr); 1062 1063 /* 1064 * Disable clocks and then clock module prior to setting desired values. 1065 */ 1066 cctlr = CSR_READ_4(sc, AML_SDXC_CLK_CNTRL_REG); 1067 cctlr &= ~(AML_SDXC_CLK_CNTRL_TX_CLK_EN | AML_SDXC_CLK_CNTRL_RX_CLK_EN | 1068 AML_SDXC_CLK_CNTRL_SD_CLK_EN); 1069 CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr); 1070 CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG); 1071 cctlr &= ~AML_SDXC_CLK_CNTRL_CLK_MODULE_EN; 1072 CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr); 1073 CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG); 1074 1075 /* 1076 * aml8726-m8 1077 * 1078 * Clock select 1 fclk_div2 (1.275 GHz) 1079 */ 1080 cctlr &= ~AML_SDXC_CLK_CNTRL_CLK_SEL_MASK; 1081 cctlr |= (1 << AML_SDXC_CLK_CNTRL_CLK_SEL_SHIFT); 1082 1083 divisor = sc->ref_freq / ios->clock - 1; 1084 if (divisor == 0 || divisor == -1) 1085 divisor = 1; 1086 if ((sc->ref_freq / (divisor + 1)) > ios->clock) 1087 divisor += 1; 1088 if (divisor > (AML_SDXC_CLK_CNTRL_CLK_DIV_MASK >> 1089 AML_SDXC_CLK_CNTRL_CLK_DIV_SHIFT)) 1090 divisor = AML_SDXC_CLK_CNTRL_CLK_DIV_MASK >> 1091 AML_SDXC_CLK_CNTRL_CLK_DIV_SHIFT; 1092 1093 cctlr &= ~AML_SDXC_CLK_CNTRL_CLK_DIV_MASK; 1094 cctlr |= divisor << AML_SDXC_CLK_CNTRL_CLK_DIV_SHIFT; 1095 1096 cctlr &= ~AML_SDXC_CLK_CNTRL_MEM_PWR_MASK; 1097 cctlr |= AML_SDXC_CLK_CNTRL_MEM_PWR_ON; 1098 1099 CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr); 1100 CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG); 1101 1102 /* 1103 * Enable clock module and then clocks after setting desired values. 1104 */ 1105 cctlr |= AML_SDXC_CLK_CNTRL_CLK_MODULE_EN; 1106 CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr); 1107 CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG); 1108 cctlr |= AML_SDXC_CLK_CNTRL_TX_CLK_EN | AML_SDXC_CLK_CNTRL_RX_CLK_EN | 1109 AML_SDXC_CLK_CNTRL_SD_CLK_EN; 1110 CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr); 1111 CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG); 1112 1113 freq = sc->ref_freq / divisor; 1114 1115 for (i = 0; aml8726_sdxc_clk_phases[i].voltage; i++) { 1116 if ((aml8726_sdxc_clk_phases[i].voltage & 1117 (1 << ios->vdd)) != 0 && 1118 freq > aml8726_sdxc_clk_phases[i].freq) 1119 break; 1120 if (aml8726_sdxc_clk_phases[i].freq == 0) 1121 break; 1122 } 1123 1124 clk2r = (1 << AML_SDXC_CLK2_SD_PHASE_SHIFT) | 1125 (aml8726_sdxc_clk_phases[i].rx_phase << 1126 AML_SDXC_CLK2_RX_PHASE_SHIFT); 1127 CSR_WRITE_4(sc, AML_SDXC_CLK2_REG, clk2r); 1128 CSR_BARRIER(sc, AML_SDXC_CLK2_REG); 1129 1130 error = 0; 1131 1132 switch (ios->power_mode) { 1133 case power_up: 1134 /* 1135 * Configure and power on the regulator so that the 1136 * voltage stabilizes prior to powering on the card. 1137 */ 1138 if (sc->vselect.dev != NULL) { 1139 for (i = 0; i < 2; i++) 1140 if ((sc->voltages[i] & (1 << ios->vdd)) != 0) 1141 break; 1142 if (i >= 2) 1143 return (EINVAL); 1144 error = GPIO_PIN_SET(sc->vselect.dev, 1145 sc->vselect.pin, i); 1146 } 1147 break; 1148 case power_on: 1149 error = aml8726_sdxc_power_on(sc); 1150 if (error) 1151 break; 1152 1153 if (sc->card_rst.dev != NULL) { 1154 if (GPIO_PIN_SET(sc->card_rst.dev, sc->card_rst.pin, 1155 PIN_ON_FLAG(sc->card_rst.pol)) != 0 || 1156 GPIO_PIN_SETFLAGS(sc->card_rst.dev, 1157 sc->card_rst.pin, 1158 GPIO_PIN_OUTPUT) != 0) 1159 error = ENXIO; 1160 1161 DELAY(5); 1162 1163 if (GPIO_PIN_SET(sc->card_rst.dev, sc->card_rst.pin, 1164 PIN_OFF_FLAG(sc->card_rst.pol)) != 0) 1165 error = ENXIO; 1166 1167 DELAY(5); 1168 1169 if (error) { 1170 device_printf(sc->dev, 1171 "could not use gpio to reset card\n"); 1172 break; 1173 } 1174 } 1175 break; 1176 case power_off: 1177 error = aml8726_sdxc_power_off(sc); 1178 break; 1179 default: 1180 return (EINVAL); 1181 } 1182 1183 return (error); 1184} 1185 1186static int 1187aml8726_sdxc_request(device_t bus, device_t child, struct mmc_request *req) 1188{ 1189 struct aml8726_sdxc_softc *sc = device_get_softc(bus); 1190 int mmc_error; 1191 1192 AML_SDXC_LOCK(sc); 1193 1194 if (sc->cmd != NULL) { 1195 AML_SDXC_UNLOCK(sc); 1196 return (EBUSY); 1197 } 1198 1199 mmc_error = aml8726_sdxc_start_command(sc, req->cmd); 1200 1201 AML_SDXC_UNLOCK(sc); 1202 1203 /* Execute the callback after dropping the lock. */ 1204 if (mmc_error != MMC_ERR_NONE) { 1205 req->cmd->error = mmc_error; 1206 req->done(req); 1207 } 1208 1209 return (0); 1210} 1211 1212static int 1213aml8726_sdxc_read_ivar(device_t bus, device_t child, 1214 int which, uintptr_t *result) 1215{ 1216 struct aml8726_sdxc_softc *sc = device_get_softc(bus); 1217 1218 switch (which) { 1219 case MMCBR_IVAR_BUS_MODE: 1220 *(int *)result = sc->host.ios.bus_mode; 1221 break; 1222 case MMCBR_IVAR_BUS_WIDTH: 1223 *(int *)result = sc->host.ios.bus_width; 1224 break; 1225 case MMCBR_IVAR_CHIP_SELECT: 1226 *(int *)result = sc->host.ios.chip_select; 1227 break; 1228 case MMCBR_IVAR_CLOCK: 1229 *(int *)result = sc->host.ios.clock; 1230 break; 1231 case MMCBR_IVAR_F_MIN: 1232 *(int *)result = sc->host.f_min; 1233 break; 1234 case MMCBR_IVAR_F_MAX: 1235 *(int *)result = sc->host.f_max; 1236 break; 1237 case MMCBR_IVAR_HOST_OCR: 1238 *(int *)result = sc->host.host_ocr; 1239 break; 1240 case MMCBR_IVAR_MODE: 1241 *(int *)result = sc->host.mode; 1242 break; 1243 case MMCBR_IVAR_OCR: 1244 *(int *)result = sc->host.ocr; 1245 break; 1246 case MMCBR_IVAR_POWER_MODE: 1247 *(int *)result = sc->host.ios.power_mode; 1248 break; 1249 case MMCBR_IVAR_VDD: 1250 *(int *)result = sc->host.ios.vdd; 1251 break; 1252 case MMCBR_IVAR_CAPS: 1253 *(int *)result = sc->host.caps; 1254 break; 1255 case MMCBR_IVAR_MAX_DATA: 1256 *(int *)result = AML_SDXC_MAX_DMA / MMC_SECTOR_SIZE; 1257 break; 1258 default: 1259 return (EINVAL); 1260 } 1261 1262 return (0); 1263} 1264 1265static int 1266aml8726_sdxc_write_ivar(device_t bus, device_t child, 1267 int which, uintptr_t value) 1268{ 1269 struct aml8726_sdxc_softc *sc = device_get_softc(bus); 1270 1271 switch (which) { 1272 case MMCBR_IVAR_BUS_MODE: 1273 sc->host.ios.bus_mode = value; 1274 break; 1275 case MMCBR_IVAR_BUS_WIDTH: 1276 sc->host.ios.bus_width = value; 1277 break; 1278 case MMCBR_IVAR_CHIP_SELECT: 1279 sc->host.ios.chip_select = value; 1280 break; 1281 case MMCBR_IVAR_CLOCK: 1282 sc->host.ios.clock = value; 1283 break; 1284 case MMCBR_IVAR_MODE: 1285 sc->host.mode = value; 1286 break; 1287 case MMCBR_IVAR_OCR: 1288 sc->host.ocr = value; 1289 break; 1290 case MMCBR_IVAR_POWER_MODE: 1291 sc->host.ios.power_mode = value; 1292 break; 1293 case MMCBR_IVAR_VDD: 1294 sc->host.ios.vdd = value; 1295 break; 1296 /* These are read-only */ 1297 case MMCBR_IVAR_CAPS: 1298 case MMCBR_IVAR_HOST_OCR: 1299 case MMCBR_IVAR_F_MIN: 1300 case MMCBR_IVAR_F_MAX: 1301 case MMCBR_IVAR_MAX_DATA: 1302 default: 1303 return (EINVAL); 1304 } 1305 1306 return (0); 1307} 1308 1309static int 1310aml8726_sdxc_get_ro(device_t bus, device_t child) 1311{ 1312 1313 return (0); 1314} 1315 1316static int 1317aml8726_sdxc_acquire_host(device_t bus, device_t child) 1318{ 1319 struct aml8726_sdxc_softc *sc = device_get_softc(bus); 1320 1321 AML_SDXC_LOCK(sc); 1322 1323 while (sc->bus_busy) 1324 mtx_sleep(sc, &sc->mtx, PZERO, "sdxc", hz / 5); 1325 sc->bus_busy++; 1326 1327 AML_SDXC_UNLOCK(sc); 1328 1329 return (0); 1330} 1331 1332static int 1333aml8726_sdxc_release_host(device_t bus, device_t child) 1334{ 1335 struct aml8726_sdxc_softc *sc = device_get_softc(bus); 1336 1337 AML_SDXC_LOCK(sc); 1338 1339 sc->bus_busy--; 1340 wakeup(sc); 1341 1342 AML_SDXC_UNLOCK(sc); 1343 1344 return (0); 1345} 1346 1347static device_method_t aml8726_sdxc_methods[] = { 1348 /* Device interface */ 1349 DEVMETHOD(device_probe, aml8726_sdxc_probe), 1350 DEVMETHOD(device_attach, aml8726_sdxc_attach), 1351 DEVMETHOD(device_detach, aml8726_sdxc_detach), 1352 DEVMETHOD(device_shutdown, aml8726_sdxc_shutdown), 1353 1354 /* Bus interface */ 1355 DEVMETHOD(bus_read_ivar, aml8726_sdxc_read_ivar), 1356 DEVMETHOD(bus_write_ivar, aml8726_sdxc_write_ivar), 1357 1358 /* MMC bridge interface */ 1359 DEVMETHOD(mmcbr_update_ios, aml8726_sdxc_update_ios), 1360 DEVMETHOD(mmcbr_request, aml8726_sdxc_request), 1361 DEVMETHOD(mmcbr_get_ro, aml8726_sdxc_get_ro), 1362 DEVMETHOD(mmcbr_acquire_host, aml8726_sdxc_acquire_host), 1363 DEVMETHOD(mmcbr_release_host, aml8726_sdxc_release_host), 1364 1365 DEVMETHOD_END 1366}; 1367 1368static driver_t aml8726_sdxc_driver = { 1369 "aml8726_sdxc", 1370 aml8726_sdxc_methods, 1371 sizeof(struct aml8726_sdxc_softc), 1372}; 1373 1374static devclass_t aml8726_sdxc_devclass; 1375 1376DRIVER_MODULE(aml8726_sdxc, simplebus, aml8726_sdxc_driver, 1377 aml8726_sdxc_devclass, NULL, NULL); 1378MODULE_DEPEND(aml8726_sdxc, aml8726_gpio, 1, 1, 1); 1379MMC_DECLARE_BRIDGE(aml8726_sdxc); 1380