1/* $NetBSD: meson_sdhc.c,v 1.6 2021/11/07 17:11:58 jmcneill Exp $ */ 2 3/*- 4 * Copyright (c) 2015-2019 Jared McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__KERNEL_RCSID(0, "$NetBSD: meson_sdhc.c,v 1.6 2021/11/07 17:11:58 jmcneill Exp $"); 31 32#include <sys/param.h> 33#include <sys/bus.h> 34#include <sys/device.h> 35#include <sys/intr.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/gpio.h> 39 40#include <dev/sdmmc/sdmmcvar.h> 41#include <dev/sdmmc/sdmmcchip.h> 42#include <dev/sdmmc/sdmmc_ioreg.h> 43 44#include <dev/fdt/fdtvar.h> 45 46#include <arm/amlogic/meson_sdhcreg.h> 47 48enum { 49 SDHC_PORT_A = 0, 50 SDHC_PORT_B = 1, 51 SDHC_PORT_C = 2 52}; 53 54static int meson_sdhc_match(device_t, cfdata_t, void *); 55static void meson_sdhc_attach(device_t, device_t, void *); 56static void meson_sdhc_attach_i(device_t); 57 58static int meson_sdhc_intr(void *); 59 60struct meson_sdhc_softc { 61 device_t sc_dev; 62 bus_space_tag_t sc_bst; 63 bus_space_handle_t sc_bsh; 64 bus_dma_tag_t sc_dmat; 65 void *sc_ih; 66 67 device_t sc_sdmmc_dev; 68 kmutex_t sc_intr_lock; 69 kcondvar_t sc_intr_cv; 70 71 uint32_t sc_intr_ista; 72 73 bus_dmamap_t sc_dmamap; 74 bus_dma_segment_t sc_segs[1]; 75 void *sc_bbuf; 76 77 u_int sc_bus_freq; 78 79 struct fdtbus_gpio_pin *sc_gpio_cd; 80 int sc_gpio_cd_inverted; 81 struct fdtbus_gpio_pin *sc_gpio_wp; 82 int sc_gpio_wp_inverted; 83 84 struct fdtbus_regulator *sc_reg_vmmc; 85 struct fdtbus_regulator *sc_reg_vqmmc; 86 87 bool sc_non_removable; 88 bool sc_broken_cd; 89 90 int sc_port; 91 int sc_slot_phandle; 92 int sc_signal_voltage; 93}; 94 95CFATTACH_DECL_NEW(meson_sdhc, sizeof(struct meson_sdhc_softc), 96 meson_sdhc_match, meson_sdhc_attach, NULL, NULL); 97 98static int meson_sdhc_host_reset(sdmmc_chipset_handle_t); 99static uint32_t meson_sdhc_host_ocr(sdmmc_chipset_handle_t); 100static int meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t); 101static int meson_sdhc_card_detect(sdmmc_chipset_handle_t); 102static int meson_sdhc_write_protect(sdmmc_chipset_handle_t); 103static int meson_sdhc_bus_power(sdmmc_chipset_handle_t, uint32_t); 104static int meson_sdhc_bus_clock(sdmmc_chipset_handle_t, int); 105static int meson_sdhc_bus_width(sdmmc_chipset_handle_t, int); 106static int meson_sdhc_bus_rod(sdmmc_chipset_handle_t, int); 107static void meson_sdhc_exec_command(sdmmc_chipset_handle_t, 108 struct sdmmc_command *); 109static void meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t, int); 110static void meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t); 111static int meson_sdhc_signal_voltage(sdmmc_chipset_handle_t, int); 112static int meson_sdhc_execute_tuning(sdmmc_chipset_handle_t, int); 113 114static int meson_sdhc_default_rx_phase(struct meson_sdhc_softc *); 115static int meson_sdhc_set_clock(struct meson_sdhc_softc *, u_int); 116static int meson_sdhc_wait_idle(struct meson_sdhc_softc *); 117static int meson_sdhc_wait_ista(struct meson_sdhc_softc *, uint32_t, int); 118 119static void meson_sdhc_dmainit(struct meson_sdhc_softc *); 120 121static struct sdmmc_chip_functions meson_sdhc_chip_functions = { 122 .host_reset = meson_sdhc_host_reset, 123 .host_ocr = meson_sdhc_host_ocr, 124 .host_maxblklen = meson_sdhc_host_maxblklen, 125 .card_detect = meson_sdhc_card_detect, 126 .write_protect = meson_sdhc_write_protect, 127 .bus_power = meson_sdhc_bus_power, 128 .bus_clock = meson_sdhc_bus_clock, 129 .bus_width = meson_sdhc_bus_width, 130 .bus_rod = meson_sdhc_bus_rod, 131 .exec_command = meson_sdhc_exec_command, 132 .card_enable_intr = meson_sdhc_card_enable_intr, 133 .card_intr_ack = meson_sdhc_card_intr_ack, 134 .signal_voltage = meson_sdhc_signal_voltage, 135 .execute_tuning = meson_sdhc_execute_tuning, 136}; 137 138#define SDHC_WRITE(sc, reg, val) \ 139 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 140#define SDHC_READ(sc, reg) \ 141 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 142#define SDHC_SET_CLEAR meson_sdhc_set_clear 143 144static inline void 145meson_sdhc_set_clear(struct meson_sdhc_softc *sc, bus_addr_t reg, uint32_t set, uint32_t clr) 146{ 147 const uint32_t old = SDHC_READ(sc, reg); 148 const uint32_t new = set | (old & ~clr); 149 if (old != new) 150 SDHC_WRITE(sc, reg, new); 151} 152 153static const struct device_compatible_entry compat_data[] = { 154 { .compat = "amlogic,meson8-sdhc" }, 155 { .compat = "amlogic,meson8b-sdhc" }, /* DTCOMPAT */ 156 DEVICE_COMPAT_EOL 157}; 158 159static const struct device_compatible_entry slot_compat_data[] = { 160 { .compat = "mmc-slot" }, 161 DEVICE_COMPAT_EOL 162}; 163 164static int 165meson_sdhc_match(device_t parent, cfdata_t cf, void *aux) 166{ 167 struct fdt_attach_args * const faa = aux; 168 169 return of_compatible_match(faa->faa_phandle, compat_data); 170} 171 172static void 173meson_sdhc_attach(device_t parent, device_t self, void *aux) 174{ 175 struct meson_sdhc_softc * const sc = device_private(self); 176 struct fdt_attach_args * const faa = aux; 177 const int phandle = faa->faa_phandle; 178 char intrstr[128]; 179 struct clk *clk_clkin, *clk_core; 180 bus_addr_t addr, port; 181 bus_size_t size; 182 int child; 183 184 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 185 aprint_error(": couldn't get registers\n"); 186 return; 187 } 188 189 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 190 aprint_error(": failed to decode interrupt\n"); 191 return; 192 } 193 194 clk_core = fdtbus_clock_get(phandle, "core"); 195 if (clk_core == NULL) { 196 clk_core = fdtbus_clock_get(phandle, "pclk"); 197 } 198 if (clk_core == NULL || clk_enable(clk_core) != 0) { 199 aprint_error(": failed to enable core/pclk clock\n"); 200 return; 201 } 202 203 clk_clkin = fdtbus_clock_get(phandle, "clkin"); 204 if (clk_clkin == NULL) { 205 clk_clkin = fdtbus_clock_get(phandle, "clkin2"); 206 } 207 if (clk_clkin == NULL || clk_enable(clk_clkin) != 0) { 208 aprint_error(": failed to get clkin/clkin2 clock\n"); 209 return; 210 } 211 212 sc->sc_dev = self; 213 sc->sc_bst = faa->faa_bst; 214 sc->sc_dmat = faa->faa_dmat; 215 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 216 aprint_error(": failed to map registers\n"); 217 return; 218 } 219 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO); 220 cv_init(&sc->sc_intr_cv, "sdhcintr"); 221 sc->sc_signal_voltage = SDMMC_SIGNAL_VOLTAGE_330; 222 223 sc->sc_port = -1; 224 for (child = OF_child(phandle); child; child = OF_peer(child)) 225 if (of_compatible_match(child, slot_compat_data)) { 226 if (fdtbus_get_reg(child, 0, &port, NULL) == 0) { 227 sc->sc_slot_phandle = child; 228 sc->sc_port = port; 229 } 230 break; 231 } 232 if (sc->sc_port == -1) { 233 aprint_error(": couldn't get mmc slot\n"); 234 return; 235 } 236 237 aprint_naive("\n"); 238 aprint_normal(": SDHC controller (port %c)\n", sc->sc_port + 'A'); 239 240 sc->sc_reg_vmmc = fdtbus_regulator_acquire(sc->sc_slot_phandle, "vmmc-supply"); 241 sc->sc_reg_vqmmc = fdtbus_regulator_acquire(sc->sc_slot_phandle, "vqmmc-supply"); 242 243 sc->sc_gpio_cd = fdtbus_gpio_acquire(sc->sc_slot_phandle, "cd-gpios", 244 GPIO_PIN_INPUT); 245 sc->sc_gpio_wp = fdtbus_gpio_acquire(sc->sc_slot_phandle, "wp-gpios", 246 GPIO_PIN_INPUT); 247 248 sc->sc_gpio_cd_inverted = of_hasprop(sc->sc_slot_phandle, "cd-inverted"); 249 sc->sc_gpio_wp_inverted = of_hasprop(sc->sc_slot_phandle, "wp-inverted"); 250 251 sc->sc_non_removable = of_hasprop(sc->sc_slot_phandle, "non-removable"); 252 sc->sc_broken_cd = of_hasprop(sc->sc_slot_phandle, "broken-cd"); 253 254 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 0, 255 meson_sdhc_intr, sc, device_xname(self)); 256 if (sc->sc_ih == NULL) { 257 aprint_error_dev(self, "couldn't establish interrupt on %s\n", 258 intrstr); 259 return; 260 } 261 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 262 263 sc->sc_bus_freq = clk_get_rate(clk_clkin); 264 265 aprint_normal_dev(self, "core %u Hz, clkin %u Hz\n", clk_get_rate(clk_core), clk_get_rate(clk_clkin)); 266 267 meson_sdhc_dmainit(sc); 268 269 config_interrupts(self, meson_sdhc_attach_i); 270} 271 272static void 273meson_sdhc_attach_i(device_t self) 274{ 275 struct meson_sdhc_softc *sc = device_private(self); 276 struct sdmmcbus_attach_args saa; 277 u_int pll_freq; 278 279 pll_freq = sc->sc_bus_freq / 1000; 280 281 meson_sdhc_host_reset(sc); 282 meson_sdhc_bus_width(sc, 1); 283 284 memset(&saa, 0, sizeof(saa)); 285 saa.saa_busname = "sdmmc"; 286 saa.saa_sct = &meson_sdhc_chip_functions; 287 saa.saa_dmat = sc->sc_dmat; 288 saa.saa_sch = sc; 289 saa.saa_clkmin = 400; 290 saa.saa_clkmax = pll_freq; 291 /* Do not advertise DMA capabilities, we handle DMA ourselves */ 292 saa.saa_caps = SMC_CAPS_4BIT_MODE| 293 SMC_CAPS_SD_HIGHSPEED| 294 SMC_CAPS_MMC_HIGHSPEED| 295 SMC_CAPS_UHS_SDR50| 296 SMC_CAPS_UHS_SDR104| 297 SMC_CAPS_AUTO_STOP; 298 299 if (sc->sc_port == SDHC_PORT_C) { 300 saa.saa_caps |= SMC_CAPS_MMC_HS200; 301 saa.saa_caps |= SMC_CAPS_8BIT_MODE; 302 } 303 304 sc->sc_sdmmc_dev = config_found(self, &saa, NULL, CFARGS_NONE); 305} 306 307static int 308meson_sdhc_intr(void *priv) 309{ 310 struct meson_sdhc_softc *sc = priv; 311 uint32_t ista; 312 313 mutex_enter(&sc->sc_intr_lock); 314 ista = SDHC_READ(sc, SD_ISTA_REG); 315 316 if (!ista) { 317 mutex_exit(&sc->sc_intr_lock); 318 return 0; 319 } 320 321 SDHC_WRITE(sc, SD_ISTA_REG, ista); 322 323 sc->sc_intr_ista |= ista; 324 cv_broadcast(&sc->sc_intr_cv); 325 326 mutex_exit(&sc->sc_intr_lock); 327 328 return 1; 329} 330 331static void 332meson_sdhc_dmainit(struct meson_sdhc_softc *sc) 333{ 334 int error, rseg; 335 336 error = bus_dmamem_alloc(sc->sc_dmat, MAXPHYS, PAGE_SIZE, MAXPHYS, 337 sc->sc_segs, 1, &rseg, BUS_DMA_WAITOK); 338 if (error) { 339 device_printf(sc->sc_dev, "bus_dmamem_alloc failed: %d\n", error); 340 return; 341 } 342 KASSERT(rseg == 1); 343 344 error = bus_dmamem_map(sc->sc_dmat, sc->sc_segs, rseg, MAXPHYS, 345 &sc->sc_bbuf, BUS_DMA_WAITOK); 346 if (error) { 347 device_printf(sc->sc_dev, "bus_dmamem_map failed\n"); 348 return; 349 } 350 351 error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, 1, MAXPHYS, 0, 352 BUS_DMA_WAITOK, &sc->sc_dmamap); 353 if (error) { 354 device_printf(sc->sc_dev, "bus_dmamap_create failed\n"); 355 return; 356 } 357 358} 359 360static int 361meson_sdhc_default_rx_phase(struct meson_sdhc_softc *sc) 362{ 363 const u_int pll_freq = sc->sc_bus_freq / 1000; 364 const u_int clkc = SDHC_READ(sc, SD_CLKC_REG); 365 const u_int clk_div = __SHIFTOUT(clkc, SD_CLKC_CLK_DIV); 366 const u_int act_freq = pll_freq / clk_div; 367 368 if (act_freq > 90000) { 369 return 1; 370 } else if (act_freq > 45000) { 371 if (sc->sc_signal_voltage == SDMMC_SIGNAL_VOLTAGE_330) { 372 return 15; 373 } else { 374 return 11; 375 } 376 } else if (act_freq >= 25000) { 377 return 15; 378 } else if (act_freq > 5000) { 379 return 23; 380 } else if (act_freq > 1000) { 381 return 55; 382 } else { 383 return 1061; 384 } 385} 386 387static int 388meson_sdhc_set_clock(struct meson_sdhc_softc *sc, u_int freq) 389{ 390 uint32_t clkc; 391 uint32_t clk2; 392 u_int pll_freq, clk_div; 393 394 clkc = SDHC_READ(sc, SD_CLKC_REG); 395 clkc &= ~SD_CLKC_TX_CLK_ENABLE; 396 clkc &= ~SD_CLKC_RX_CLK_ENABLE; 397 clkc &= ~SD_CLKC_SD_CLK_ENABLE; 398 SDHC_WRITE(sc, SD_CLKC_REG, clkc); 399 clkc &= ~SD_CLKC_MOD_CLK_ENABLE; 400 SDHC_WRITE(sc, SD_CLKC_REG, clkc); 401 402 if (freq == 0) 403 return 0; 404 405 clkc &= ~SD_CLKC_CLK_DIV; 406 clkc &= ~SD_CLKC_CLK_IN_SEL; 407 408 clkc |= __SHIFTIN(SD_CLKC_CLK_IN_SEL_FCLK_DIV3, 409 SD_CLKC_CLK_IN_SEL); 410 411 pll_freq = sc->sc_bus_freq / 1000; /* 2.55GHz */ 412 clk_div = howmany(pll_freq, freq); 413 414 clkc |= __SHIFTIN(clk_div - 1, SD_CLKC_CLK_DIV); 415 416 SDHC_WRITE(sc, SD_CLKC_REG, clkc); 417 418 clkc |= SD_CLKC_MOD_CLK_ENABLE; 419 SDHC_WRITE(sc, SD_CLKC_REG, clkc); 420 421 clkc |= SD_CLKC_TX_CLK_ENABLE; 422 clkc |= SD_CLKC_RX_CLK_ENABLE; 423 clkc |= SD_CLKC_SD_CLK_ENABLE; 424 SDHC_WRITE(sc, SD_CLKC_REG, clkc); 425 426 clk2 = SDHC_READ(sc, SD_CLK2_REG); 427 clk2 &= ~SD_CLK2_SD_CLK_PHASE; 428 clk2 |= __SHIFTIN(1, SD_CLK2_SD_CLK_PHASE); 429 clk2 &= ~SD_CLK2_RX_CLK_PHASE; 430 clk2 |= __SHIFTIN(meson_sdhc_default_rx_phase(sc), 431 SD_CLK2_RX_CLK_PHASE); 432 SDHC_WRITE(sc, SD_CLK2_REG, clk2); 433 434 return 0; 435} 436 437static int 438meson_sdhc_wait_idle(struct meson_sdhc_softc *sc) 439{ 440 int i; 441 442 for (i = 0; i < 1000000; i++) { 443 const uint32_t stat = SDHC_READ(sc, SD_STAT_REG); 444 const uint32_t esta = SDHC_READ(sc, SD_ESTA_REG); 445 if ((stat & SD_STAT_BUSY) == 0 && 446 (esta & SD_ESTA_BUSY) == 0) 447 return 0; 448 delay(1); 449 } 450 451 return EBUSY; 452} 453 454static int 455meson_sdhc_wait_ista(struct meson_sdhc_softc *sc, uint32_t mask, int timeout) 456{ 457 int retry, error; 458 459 KASSERT(mutex_owned(&sc->sc_intr_lock)); 460 461 if (sc->sc_intr_ista & mask) 462 return 0; 463 464 retry = timeout / hz; 465 466 while (retry > 0) { 467 error = cv_timedwait(&sc->sc_intr_cv, &sc->sc_intr_lock, hz); 468 if (error && error != EWOULDBLOCK) 469 return error; 470 if (sc->sc_intr_ista & mask) 471 return 0; 472 --retry; 473 } 474 475 return ETIMEDOUT; 476} 477 478static int 479meson_sdhc_host_reset(sdmmc_chipset_handle_t sch) 480{ 481 struct meson_sdhc_softc *sc = sch; 482 uint32_t enhc; 483 484 SDHC_WRITE(sc, SD_SRST_REG, 485 SD_SRST_MAIN_CTRL | SD_SRST_TX_FIFO | SD_SRST_RX_FIFO | 486 SD_SRST_DPHY_TX | SD_SRST_DPHY_RX | SD_SRST_DMA_IF); 487 488 delay(50); 489 490 SDHC_WRITE(sc, SD_SRST_REG, 0); 491 492 delay(10); 493 494 SDHC_WRITE(sc, SD_CNTL_REG, 495 __SHIFTIN(0x7, SD_CNTL_TX_ENDIAN_CTRL) | 496 __SHIFTIN(0x7, SD_CNTL_RX_ENDIAN_CTRL) | 497 __SHIFTIN(0xf, SD_CNTL_RX_PERIOD) | 498 __SHIFTIN(0x7f, SD_CNTL_RX_TIMEOUT)); 499 500 SDHC_WRITE(sc, SD_CLKC_REG, 501 SDHC_READ(sc, SD_CLKC_REG) & ~SD_CLKC_MEM_PWR); 502 503 SDHC_WRITE(sc, SD_PDMA_REG, 504 __SHIFTIN(7, SD_PDMA_TX_BURST_LEN) | 505 __SHIFTIN(49, SD_PDMA_TXFIFO_THRESHOLD) | 506 __SHIFTIN(15, SD_PDMA_RX_BURST_LEN) | 507 __SHIFTIN(7, SD_PDMA_RXFIFO_THRESHOLD) | 508 SD_PDMA_DMA_URGENT); 509 510 SDHC_WRITE(sc, SD_MISC_REG, 511 __SHIFTIN(7, SD_MISC_TXSTART_THRESHOLD) | 512 __SHIFTIN(5, SD_MISC_WCRC_ERR_PATTERN) | 513 __SHIFTIN(2, SD_MISC_WCRC_OK_PATTERN)); 514 515 enhc = SDHC_READ(sc, SD_ENHC_REG); 516 enhc &= ~SD_ENHC_RXFIFO_THRESHOLD; 517 enhc |= __SHIFTIN(63, SD_ENHC_RXFIFO_THRESHOLD); 518 enhc &= ~SD_ENHC_DMA_RX_RESP; 519 enhc |= SD_ENHC_DMA_TX_RESP; 520 enhc &= ~SD_ENHC_SDIO_IRQ_PERIOD; 521 enhc |= __SHIFTIN(12, SD_ENHC_SDIO_IRQ_PERIOD); 522 enhc &= ~SD_ENHC_RX_TIMEOUT; 523 enhc |= __SHIFTIN(0xff, SD_ENHC_RX_TIMEOUT); 524 SDHC_WRITE(sc, SD_ENHC_REG, enhc); 525 526 SDHC_WRITE(sc, SD_ICTL_REG, 0); 527 SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR); 528 529 return 0; 530} 531 532static uint32_t 533meson_sdhc_host_ocr(sdmmc_chipset_handle_t sch) 534{ 535 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | 536 MMC_OCR_HCS | MMC_OCR_S18A; 537} 538 539static int 540meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t sch) 541{ 542 return 512; 543} 544 545static int 546meson_sdhc_card_detect(sdmmc_chipset_handle_t sch) 547{ 548 struct meson_sdhc_softc *sc = sch; 549 int val; 550 551 if (sc->sc_non_removable || sc->sc_broken_cd) { 552 return 1; 553 } else if (sc->sc_gpio_cd != NULL) { 554 val = fdtbus_gpio_read(sc->sc_gpio_cd); 555 if (sc->sc_gpio_cd_inverted) 556 val = !val; 557 return val; 558 } else { 559 return 1; 560 } 561} 562 563static int 564meson_sdhc_write_protect(sdmmc_chipset_handle_t sch) 565{ 566 struct meson_sdhc_softc *sc = sch; 567 int val; 568 569 if (sc->sc_gpio_wp != NULL) { 570 val = fdtbus_gpio_read(sc->sc_gpio_wp); 571 if (sc->sc_gpio_wp_inverted) 572 val = !val; 573 return val; 574 } 575 576 return 0; 577} 578 579static int 580meson_sdhc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 581{ 582 return 0; 583} 584 585static int 586meson_sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq) 587{ 588 struct meson_sdhc_softc *sc = sch; 589 590 return meson_sdhc_set_clock(sc, freq); 591} 592 593static int 594meson_sdhc_bus_width(sdmmc_chipset_handle_t sch, int width) 595{ 596 struct meson_sdhc_softc *sc = sch; 597 uint32_t cntl; 598 599 cntl = SDHC_READ(sc, SD_CNTL_REG); 600 cntl &= ~SD_CNTL_DAT_TYPE; 601 switch (width) { 602 case 1: 603 cntl |= __SHIFTIN(0, SD_CNTL_DAT_TYPE); 604 break; 605 case 4: 606 cntl |= __SHIFTIN(1, SD_CNTL_DAT_TYPE); 607 break; 608 case 8: 609 cntl |= __SHIFTIN(2, SD_CNTL_DAT_TYPE); 610 break; 611 default: 612 return EINVAL; 613 } 614 615 SDHC_WRITE(sc, SD_CNTL_REG, cntl); 616 617 return 0; 618} 619 620static int 621meson_sdhc_bus_rod(sdmmc_chipset_handle_t sch, int on) 622{ 623 return ENOTSUP; 624} 625 626static void 627meson_sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 628{ 629 struct meson_sdhc_softc *sc = sch; 630 uint32_t cmdval = 0, cntl, srst, pdma, ictl; 631 bool use_bbuf = false; 632 int i; 633 634 KASSERT(cmd->c_blklen <= 512); 635 636 mutex_enter(&sc->sc_intr_lock); 637 638 /* Filter SDIO commands */ 639 switch (cmd->c_opcode) { 640 case SD_IO_SEND_OP_COND: 641 case SD_IO_RW_DIRECT: 642 case SD_IO_RW_EXTENDED: 643 cmd->c_error = EINVAL; 644 goto done; 645 } 646 647 if (cmd->c_opcode == MMC_STOP_TRANSMISSION) 648 cmdval |= SD_SEND_DATA_STOP; 649 if (cmd->c_flags & SCF_RSP_PRESENT) 650 cmdval |= SD_SEND_COMMAND_HAS_RESP; 651 if (cmd->c_flags & SCF_RSP_136) { 652 cmdval |= SD_SEND_RESPONSE_LENGTH; 653 cmdval |= SD_SEND_RESPONSE_NO_CRC; 654 } 655 if ((cmd->c_flags & SCF_RSP_CRC) == 0) 656 cmdval |= SD_SEND_RESPONSE_NO_CRC; 657 658 SDHC_WRITE(sc, SD_ICTL_REG, 0); 659 SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR); 660 sc->sc_intr_ista = 0; 661 662 ictl = SD_INT_ERROR; 663 664 cntl = SDHC_READ(sc, SD_CNTL_REG); 665 cntl &= ~SD_CNTL_PACK_LEN; 666 if (cmd->c_datalen > 0) { 667 unsigned int nblks; 668 669 cmdval |= SD_SEND_COMMAND_HAS_DATA; 670 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) { 671 cmdval |= SD_SEND_DATA_DIRECTION; 672 } 673 674 nblks = cmd->c_datalen / cmd->c_blklen; 675 if (nblks == 0 || (cmd->c_datalen % cmd->c_blklen) != 0) 676 ++nblks; 677 678 cntl |= __SHIFTIN(cmd->c_blklen & 0x1ff, SD_CNTL_PACK_LEN); 679 680 cmdval |= __SHIFTIN(nblks - 1, SD_SEND_TOTAL_PACK); 681 682 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 683 ictl |= SD_INT_DATA_COMPLETE; 684 } else { 685 ictl |= SD_INT_DMA_DONE; 686 } 687 } else { 688 ictl |= SD_INT_RESP_COMPLETE; 689 } 690 691 SDHC_WRITE(sc, SD_ICTL_REG, ictl); 692 693 SDHC_WRITE(sc, SD_CNTL_REG, cntl); 694 695 pdma = SDHC_READ(sc, SD_PDMA_REG); 696 if (cmd->c_datalen > 0) { 697 pdma |= SD_PDMA_DMA_MODE; 698 } else { 699 pdma &= ~SD_PDMA_DMA_MODE; 700 } 701 SDHC_WRITE(sc, SD_PDMA_REG, pdma); 702 703 SDHC_WRITE(sc, SD_ARGU_REG, cmd->c_arg); 704 705 cmd->c_error = meson_sdhc_wait_idle(sc); 706 if (cmd->c_error) { 707 goto done; 708 } 709 710 if (cmd->c_datalen > 0) { 711 cmd->c_error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, 712 sc->sc_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK); 713 if (cmd->c_error) { 714 device_printf(sc->sc_dev, "bus_dmamap_load failed\n"); 715 goto done; 716 } 717 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 718 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, 719 MAXPHYS, BUS_DMASYNC_PREREAD); 720 } else { 721 memcpy(sc->sc_bbuf, cmd->c_data, cmd->c_datalen); 722 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, 723 MAXPHYS, BUS_DMASYNC_PREWRITE); 724 } 725 SDHC_WRITE(sc, SD_ADDR_REG, sc->sc_dmamap->dm_segs[0].ds_addr); 726 use_bbuf = true; 727 } 728 729 cmd->c_resid = cmd->c_datalen; 730 SDHC_WRITE(sc, SD_SEND_REG, cmdval | cmd->c_opcode); 731 732 if (cmd->c_datalen > 0) { 733 uint32_t wbit = ISSET(cmd->c_flags, SCF_CMD_READ) ? 734 SD_INT_DATA_COMPLETE : SD_INT_DMA_DONE; 735 cmd->c_error = meson_sdhc_wait_ista(sc, 736 SD_INT_ERROR | wbit, hz * 10); 737 if (cmd->c_error == 0 && 738 (sc->sc_intr_ista & SD_INT_ERROR)) { 739 cmd->c_error = ETIMEDOUT; 740 } 741 if (cmd->c_error) { 742 goto done; 743 } 744 } else { 745 cmd->c_error = meson_sdhc_wait_ista(sc, 746 SD_INT_ERROR | SD_INT_RESP_COMPLETE, hz * 10); 747 if (cmd->c_error == 0 && (sc->sc_intr_ista & SD_INT_ERROR)) { 748 if (sc->sc_intr_ista & SD_INT_TIMEOUT) { 749 cmd->c_error = ETIMEDOUT; 750 } else { 751 cmd->c_error = EIO; 752 } 753 } 754 if (cmd->c_error) { 755 goto done; 756 } 757 } 758 759 SDHC_WRITE(sc, SD_ISTA_REG, sc->sc_intr_ista); 760 761 if (cmd->c_flags & SCF_RSP_PRESENT) { 762 pdma = SDHC_READ(sc, SD_PDMA_REG); 763 pdma &= ~SD_PDMA_DMA_MODE; 764 if (cmd->c_flags & SCF_RSP_136) { 765 for (i = 4; i >= 1; i--) { 766 pdma &= ~SD_PDMA_PIO_RDRESP; 767 pdma |= __SHIFTIN(i, SD_PDMA_PIO_RDRESP); 768 SDHC_WRITE(sc, SD_PDMA_REG, pdma); 769 cmd->c_resp[i - 1] = SDHC_READ(sc, SD_ARGU_REG); 770 771 } 772 if (cmd->c_flags & SCF_RSP_CRC) { 773 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 774 (cmd->c_resp[1] << 24); 775 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 776 (cmd->c_resp[2] << 24); 777 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 778 (cmd->c_resp[3] << 24); 779 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 780 } 781 } else { 782 pdma &= ~SD_PDMA_PIO_RDRESP; 783 pdma |= __SHIFTIN(0, SD_PDMA_PIO_RDRESP); 784 SDHC_WRITE(sc, SD_PDMA_REG, pdma); 785 cmd->c_resp[0] = SDHC_READ(sc, SD_ARGU_REG); 786 } 787 } 788 789done: 790 if (use_bbuf) { 791 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 792 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, 793 MAXPHYS, BUS_DMASYNC_POSTREAD); 794 } else { 795 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, 796 MAXPHYS, BUS_DMASYNC_POSTWRITE); 797 } 798 bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap); 799 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 800 memcpy(cmd->c_data, sc->sc_bbuf, cmd->c_datalen); 801 } 802 } 803 804 cmd->c_flags |= SCF_ITSDONE; 805 806 SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR); 807 SDHC_WRITE(sc, SD_ICTL_REG, 0); 808 809 srst = SDHC_READ(sc, SD_SRST_REG); 810 srst |= (SD_SRST_TX_FIFO | SD_SRST_RX_FIFO); 811 SDHC_WRITE(sc, SD_SRST_REG, srst); 812 813 mutex_exit(&sc->sc_intr_lock); 814} 815 816static void 817meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) 818{ 819} 820 821static void 822meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t sch) 823{ 824} 825 826static int 827meson_sdhc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage) 828{ 829 struct meson_sdhc_softc *sc = sch; 830 u_int uvol; 831 int error; 832 833 if (sc->sc_reg_vqmmc == NULL) 834 return 0; 835 836 switch (signal_voltage) { 837 case SDMMC_SIGNAL_VOLTAGE_330: 838 uvol = 3300000; 839 break; 840 case SDMMC_SIGNAL_VOLTAGE_180: 841 uvol = 1800000; 842 break; 843 default: 844 return EINVAL; 845 } 846 847 error = fdtbus_regulator_supports_voltage(sc->sc_reg_vqmmc, uvol, uvol); 848 if (error != 0) 849 return 0; 850 851 error = fdtbus_regulator_set_voltage(sc->sc_reg_vqmmc, uvol, uvol); 852 if (error != 0) 853 return error; 854 855 error = fdtbus_regulator_enable(sc->sc_reg_vqmmc); 856 if (error != 0) 857 return error; 858 859 sc->sc_signal_voltage = signal_voltage; 860 return 0; 861} 862 863static int 864meson_sdhc_execute_tuning(sdmmc_chipset_handle_t sch, int timing) 865{ 866 static const uint8_t tuning_blk_8bit[] = { 867 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 868 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc, 869 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff, 870 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff, 871 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd, 872 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 873 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff, 874 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff, 875 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 876 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 877 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 878 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 879 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 880 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 881 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 882 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 883 }; 884 static const uint8_t tuning_blk_4bit[] = { 885 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 886 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, 887 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb, 888 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef, 889 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c, 890 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee, 891 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff, 892 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde, 893 }; 894 895 struct meson_sdhc_softc *sc = sch; 896 struct sdmmc_command cmd; 897 uint8_t data[sizeof(tuning_blk_8bit)]; 898 const uint8_t *tblk; 899 size_t tsize; 900 struct window_s { 901 int start; 902 u_int size; 903 } best = { .start = -1, .size = 0 }, 904 curr = { .start = -1, .size = 0 }, 905 wrap = { .start = 0, .size = 0 }; 906 u_int ph, rx_phase, clk_div; 907 int opcode; 908 909 switch (timing) { 910 case SDMMC_TIMING_MMC_HS200: 911 tblk = tuning_blk_8bit; 912 tsize = sizeof(tuning_blk_8bit); 913 opcode = MMC_SEND_TUNING_BLOCK_HS200; 914 break; 915 case SDMMC_TIMING_UHS_SDR50: 916 case SDMMC_TIMING_UHS_SDR104: 917 tblk = tuning_blk_4bit; 918 tsize = sizeof(tuning_blk_4bit); 919 opcode = MMC_SEND_TUNING_BLOCK; 920 break; 921 default: 922 return EINVAL; 923 } 924 925 const uint32_t clkc = SDHC_READ(sc, SD_CLKC_REG); 926 clk_div = __SHIFTOUT(clkc, SD_CLKC_CLK_DIV); 927 928 for (ph = 0; ph <= clk_div; ph++) { 929 SDHC_SET_CLEAR(sc, SD_CLK2_REG, 930 __SHIFTIN(ph, SD_CLK2_RX_CLK_PHASE), SD_CLK2_RX_CLK_PHASE); 931 delay(10); 932 933 u_int nmatch = 0; 934#define NUMTRIES 10 935 for (u_int i = 0; i < NUMTRIES; i++) { 936 memset(data, 0, tsize); 937 memset(&cmd, 0, sizeof(cmd)); 938 cmd.c_data = data; 939 cmd.c_datalen = cmd.c_blklen = tsize; 940 cmd.c_opcode = opcode; 941 cmd.c_arg = 0; 942 cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1; 943 meson_sdhc_exec_command(sc, &cmd); 944 if (cmd.c_error == 0 && memcmp(data, tblk, tsize) == 0) 945 nmatch++; 946 } 947 if (nmatch == NUMTRIES) { /* good phase value */ 948 if (wrap.start == 0) 949 wrap.size++; 950 if (curr.start == -1) 951 curr.start = ph; 952 curr.size++; 953 } else { 954 wrap.start = -1; 955 if (curr.start != -1) { /* end of current window */ 956 if (best.start == -1 || best.size < curr.size) 957 best = curr; 958 curr = (struct window_s) 959 { .start = -1, .size = 0 }; 960 } 961 } 962#undef NUMTRIES 963 } 964 965 if (curr.start != -1) { /* the current window wraps around */ 966 curr.size += wrap.size; 967 if (curr.size > ph) 968 curr.size = ph; 969 if (best.start == -1 || best.size < curr.size) 970 best = curr; 971 } 972 973 if (best.start == -1) { /* no window - use default rx_phase */ 974 rx_phase = meson_sdhc_default_rx_phase(sc); 975 } else { 976 rx_phase = best.start + best.size / 2; 977 if (rx_phase >= ph) 978 rx_phase -= ph; 979 } 980 981 SDHC_SET_CLEAR(sc, SD_CLK2_REG, 982 __SHIFTIN(rx_phase, SD_CLK2_RX_CLK_PHASE), SD_CLK2_RX_CLK_PHASE); 983 984 return 0; 985} 986