1 /* $OpenBSD: sximmc.c,v 1.4 2018/05/27 18:03:22 kettenis Exp $ */ 2 /* $NetBSD: awin_mmc.c,v 1.23 2015/11/14 10:32:40 bouyer Exp $ */ 3 4 /*- 5 * Copyright (c) 2014 Jared D. McNeill <jmcneill@invisible.ca> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/device.h> 33 #include <sys/kernel.h> 34 #include <sys/malloc.h> 35 36 #include <machine/intr.h> 37 #include <machine/bus.h> 38 #include <machine/fdt.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/ofw/openfirm.h> 45 #include <dev/ofw/ofw_clock.h> 46 #include <dev/ofw/ofw_gpio.h> 47 #include <dev/ofw/ofw_pinctrl.h> 48 #include <dev/ofw/ofw_regulator.h> 49 #include <dev/ofw/fdt.h> 50 51 //#define SXIMMC_DEBUG 52 53 #define SXIMMC_GCTRL 0x0000 54 #define SXIMMC_CLKCR 0x0004 55 #define SXIMMC_TIMEOUT 0x0008 56 #define SXIMMC_WIDTH 0x000C 57 #define SXIMMC_BLKSZ 0x0010 58 #define SXIMMC_BYTECNT 0x0014 59 #define SXIMMC_CMD 0x0018 60 #define SXIMMC_ARG 0x001C 61 #define SXIMMC_RESP0 0x0020 62 #define SXIMMC_RESP1 0x0024 63 #define SXIMMC_RESP2 0x0028 64 #define SXIMMC_RESP3 0x002C 65 #define SXIMMC_IMASK 0x0030 66 #define SXIMMC_MINT 0x0034 67 #define SXIMMC_RINT 0x0038 68 #define SXIMMC_STATUS 0x003C 69 #define SXIMMC_FTRGLEVEL 0x0040 70 #define SXIMMC_FUNCSEL 0x0044 71 #define SXIMMC_CBCR 0x0048 72 #define SXIMMC_BBCR 0x004C 73 #define SXIMMC_DBGC 0x0050 74 #define SXIMMC_A12A 0x0058 /* A80 */ 75 #define SXIMMC_HWRST 0x0078 /* A80 */ 76 #define SXIMMC_DMAC 0x0080 77 #define SXIMMC_DLBA 0x0084 78 #define SXIMMC_IDST 0x0088 79 #define SXIMMC_IDIE 0x008C 80 #define SXIMMC_CHDA 0x0090 81 #define SXIMMC_CBDA 0x0094 82 #define SXIMMC_FIFO_A10 0x0100 83 #define SXIMMC_FIFO_A31 0x0200 84 85 #define SXIMMC_GCTRL_ACCESS_BY_AHB (1U << 31) 86 #define SXIMMC_GCTRL_WAIT_MEM_ACCESS_DONE (1U << 30) 87 #define SXIMMC_GCTRL_DDR_MODE (1U << 10) 88 #define SXIMMC_GCTRL_DEBOUNCEEN (1U << 8) 89 #define SXIMMC_GCTRL_DMAEN (1U << 5) 90 #define SXIMMC_GCTRL_INTEN (1U << 4) 91 #define SXIMMC_GCTRL_DMARESET (1U << 2) 92 #define SXIMMC_GCTRL_FIFORESET (1U << 1) 93 #define SXIMMC_GCTRL_SOFTRESET (1U << 0) 94 #define SXIMMC_GCTRL_RESET \ 95 (SXIMMC_GCTRL_SOFTRESET | SXIMMC_GCTRL_FIFORESET | \ 96 SXIMMC_GCTRL_DMARESET) 97 98 #define SXIMMC_CLKCR_LOWPOWERON (1U << 17) 99 #define SXIMMC_CLKCR_CARDCLKON (1U << 16) 100 #define SXIMMC_CLKCR_DIV 0x0000ffff 101 102 #define SXIMMC_WIDTH_1 0 103 #define SXIMMC_WIDTH_4 1 104 #define SXIMMC_WIDTH_8 2 105 106 #define SXIMMC_CMD_START (1U << 31) 107 #define SXIMMC_CMD_USE_HOLD_REG (1U << 29) 108 #define SXIMMC_CMD_VOL_SWITCH (1U << 28) 109 #define SXIMMC_CMD_BOOT_ABORT (1U << 27) 110 #define SXIMMC_CMD_BOOT_ACK_EXP (1U << 26) 111 #define SXIMMC_CMD_ALT_BOOT_OPT (1U << 25) 112 #define SXIMMC_CMD_ENBOOT (1U << 24) 113 #define SXIMMC_CMD_CCS_EXP (1U << 23) 114 #define SXIMMC_CMD_RD_CEATA_DEV (1U << 22) 115 #define SXIMMC_CMD_UPCLK_ONLY (1U << 21) 116 #define SXIMMC_CMD_SEND_INIT_SEQ (1U << 15) 117 #define SXIMMC_CMD_STOP_ABORT_CMD (1U << 14) 118 #define SXIMMC_CMD_WAIT_PRE_OVER (1U << 13) 119 #define SXIMMC_CMD_SEND_AUTO_STOP (1U << 12) 120 #define SXIMMC_CMD_SEQMOD (1U << 11) 121 #define SXIMMC_CMD_WRITE (1U << 10) 122 #define SXIMMC_CMD_DATA_EXP (1U << 9) 123 #define SXIMMC_CMD_CHECK_RSP_CRC (1U << 8) 124 #define SXIMMC_CMD_LONG_RSP (1U << 7) 125 #define SXIMMC_CMD_RSP_EXP (1U << 6) 126 127 #define SXIMMC_INT_CARD_REMOVE (1U << 31) 128 #define SXIMMC_INT_CARD_INSERT (1U << 30) 129 #define SXIMMC_INT_SDIO_INT (1U << 16) 130 #define SXIMMC_INT_END_BIT_ERR (1U << 15) 131 #define SXIMMC_INT_AUTO_CMD_DONE (1U << 14) 132 #define SXIMMC_INT_START_BIT_ERR (1U << 13) 133 #define SXIMMC_INT_HW_LOCKED (1U << 12) 134 #define SXIMMC_INT_FIFO_RUN_ERR (1U << 11) 135 #define SXIMMC_INT_VOL_CHG_DONE (1U << 10) 136 #define SXIMMC_INT_DATA_STARVE (1U << 10) 137 #define SXIMMC_INT_BOOT_START (1U << 9) 138 #define SXIMMC_INT_DATA_TIMEOUT (1U << 9) 139 #define SXIMMC_INT_ACK_RCV (1U << 8) 140 #define SXIMMC_INT_RESP_TIMEOUT (1U << 8) 141 #define SXIMMC_INT_DATA_CRC_ERR (1U << 7) 142 #define SXIMMC_INT_RESP_CRC_ERR (1U << 6) 143 #define SXIMMC_INT_RX_DATA_REQ (1U << 5) 144 #define SXIMMC_INT_TX_DATA_REQ (1U << 4) 145 #define SXIMMC_INT_DATA_OVER (1U << 3) 146 #define SXIMMC_INT_CMD_DONE (1U << 2) 147 #define SXIMMC_INT_RESP_ERR (1U << 1) 148 #define SXIMMC_INT_ERROR \ 149 (SXIMMC_INT_RESP_ERR | SXIMMC_INT_RESP_CRC_ERR | \ 150 SXIMMC_INT_DATA_CRC_ERR | SXIMMC_INT_RESP_TIMEOUT | \ 151 SXIMMC_INT_FIFO_RUN_ERR | SXIMMC_INT_HW_LOCKED | \ 152 SXIMMC_INT_START_BIT_ERR | SXIMMC_INT_END_BIT_ERR) 153 154 #define SXIMMC_STATUS_DMAREQ (1U << 31) 155 #define SXIMMC_STATUS_DATA_FSM_BUSY (1U << 10) 156 #define SXIMMC_STATUS_CARD_DATA_BUSY (1U << 9) 157 #define SXIMMC_STATUS_CARD_PRESENT (1U << 8) 158 #define SXIMMC_STATUS_FIFO_FULL (1U << 3) 159 #define SXIMMC_STATUS_FIFO_EMPTY (1U << 2) 160 #define SXIMMC_STATUS_TXWL_FLAG (1U << 1) 161 #define SXIMMC_STATUS_RXWL_FLAG (1U << 0) 162 163 #define SXIMMC_FUNCSEL_CEATA_DEV_INTEN (1U << 10) 164 #define SXIMMC_FUNCSEL_SEND_AUTO_STOP_CCSD (1U << 9) 165 #define SXIMMC_FUNCSEL_SEND_CCSD (1U << 8) 166 #define SXIMMC_FUNCSEL_ABT_RD_DATA (1U << 2) 167 #define SXIMMC_FUNCSEL_SDIO_RD_WAIT (1U << 1) 168 #define SXIMMC_FUNCSEL_SEND_IRQ_RSP (1U << 0) 169 170 #define SXIMMC_DMAC_REFETCH_DES (1U << 31) 171 #define SXIMMC_DMAC_IDMA_ON (1U << 7) 172 #define SXIMMC_DMAC_FIX_BURST (1U << 1) 173 #define SXIMMC_DMAC_SOFTRESET (1U << 0) 174 175 #define SXIMMC_IDST_HOST_ABT (1U << 10) 176 #define SXIMMC_IDST_ABNORMAL_INT_SUM (1U << 9) 177 #define SXIMMC_IDST_NORMAL_INT_SUM (1U << 8) 178 #define SXIMMC_IDST_CARD_ERR_SUM (1U << 5) 179 #define SXIMMC_IDST_DES_INVALID (1U << 4) 180 #define SXIMMC_IDST_FATAL_BUS_ERR (1U << 2) 181 #define SXIMMC_IDST_RECEIVE_INT (1U << 1) 182 #define SXIMMC_IDST_TRANSMIT_INT (1U << 0) 183 #define SXIMMC_IDST_ERROR \ 184 (SXIMMC_IDST_ABNORMAL_INT_SUM | SXIMMC_IDST_CARD_ERR_SUM | \ 185 SXIMMC_IDST_DES_INVALID | SXIMMC_IDST_FATAL_BUS_ERR) 186 #define SXIMMC_IDST_COMPLETE \ 187 (SXIMMC_IDST_RECEIVE_INT | SXIMMC_IDST_TRANSMIT_INT) 188 189 struct sximmc_idma_descriptor { 190 uint32_t dma_config; 191 #define SXIMMC_IDMA_CONFIG_DIC (1U << 1) 192 #define SXIMMC_IDMA_CONFIG_LD (1U << 2) 193 #define SXIMMC_IDMA_CONFIG_FD (1U << 3) 194 #define SXIMMC_IDMA_CONFIG_CH (1U << 4) 195 #define SXIMMC_IDMA_CONFIG_ER (1U << 5) 196 #define SXIMMC_IDMA_CONFIG_CES (1U << 30) 197 #define SXIMMC_IDMA_CONFIG_OWN (1U << 31) 198 uint32_t dma_buf_size; 199 uint32_t dma_buf_addr; 200 uint32_t dma_next; 201 } __packed; 202 203 #define SXIMMC_NDESC 32 204 205 #define SXIMMC_DMA_FTRGLEVEL_A20 0x20070008 206 #define SXIMMC_DMA_FTRGLEVEL_A80 0x200f0010 207 208 int sximmc_match(struct device *, void *, void *); 209 void sximmc_attach(struct device *, struct device *, void *); 210 211 int sximmc_intr(void *); 212 213 int sximmc_host_reset(sdmmc_chipset_handle_t); 214 uint32_t sximmc_host_ocr(sdmmc_chipset_handle_t); 215 int sximmc_host_maxblklen(sdmmc_chipset_handle_t); 216 int sximmc_card_detect(sdmmc_chipset_handle_t); 217 int sximmc_write_protect(sdmmc_chipset_handle_t); 218 int sximmc_bus_power(sdmmc_chipset_handle_t, uint32_t); 219 int sximmc_bus_clock(sdmmc_chipset_handle_t, int, int); 220 int sximmc_bus_width(sdmmc_chipset_handle_t, int); 221 void sximmc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *); 222 void sximmc_card_intr_mask(sdmmc_chipset_handle_t, int); 223 void sximmc_card_intr_ack(sdmmc_chipset_handle_t); 224 225 void sximmc_pwrseq_pre(uint32_t); 226 void sximmc_pwrseq_post(uint32_t); 227 228 struct sdmmc_chip_functions sximmc_chip_functions = { 229 .host_reset = sximmc_host_reset, 230 .host_ocr = sximmc_host_ocr, 231 .host_maxblklen = sximmc_host_maxblklen, 232 .card_detect = sximmc_card_detect, 233 .bus_power = sximmc_bus_power, 234 .bus_clock = sximmc_bus_clock, 235 .bus_width = sximmc_bus_width, 236 .exec_command = sximmc_exec_command, 237 .card_intr_mask = sximmc_card_intr_mask, 238 .card_intr_ack = sximmc_card_intr_ack, 239 }; 240 241 struct sximmc_softc { 242 struct device sc_dev; 243 bus_space_tag_t sc_bst; 244 bus_space_handle_t sc_bsh; 245 bus_space_handle_t sc_clk_bsh; 246 bus_dma_tag_t sc_dmat; 247 int sc_node; 248 249 int sc_use_dma; 250 251 void *sc_ih; 252 253 struct device *sc_sdmmc_dev; 254 255 uint32_t sc_fifo_reg; 256 uint32_t sc_dma_ftrglevel; 257 258 uint32_t sc_idma_xferlen; 259 bus_dma_segment_t sc_idma_segs[1]; 260 int sc_idma_nsegs; 261 bus_size_t sc_idma_size; 262 bus_dmamap_t sc_idma_map; 263 int sc_idma_ndesc; 264 char *sc_idma_desc; 265 266 uint32_t sc_intr_rint; 267 uint32_t sc_intr_mint; 268 uint32_t sc_idma_idst; 269 270 uint32_t sc_gpio[4]; 271 uint32_t sc_vmmc; 272 uint32_t sc_vqmmc; 273 uint32_t sc_pwrseq; 274 uint32_t sc_vdd; 275 }; 276 277 struct cfdriver sximmc_cd = { 278 NULL, "sximmc", DV_DULL 279 }; 280 281 struct cfattach sximmc_ca = { 282 sizeof(struct sximmc_softc), sximmc_match, sximmc_attach 283 }; 284 285 #define MMC_WRITE(sc, reg, val) \ 286 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 287 #define MMC_READ(sc, reg) \ 288 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 289 290 int sximmc_set_clock(struct sximmc_softc *sc, u_int); 291 292 int 293 sximmc_match(struct device *parent, void *match, void *aux) 294 { 295 struct fdt_attach_args *faa = aux; 296 297 return (OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-mmc") || 298 OF_is_compatible(faa->fa_node, "allwinner,sun5i-a13-mmc") || 299 OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-mmc") || 300 OF_is_compatible(faa->fa_node, "allwinner,sun9i-a80-mmc") || 301 OF_is_compatible(faa->fa_node, "allwinner,sun50i-a64-mmc")); 302 } 303 304 int 305 sximmc_idma_setup(struct sximmc_softc *sc) 306 { 307 int error; 308 309 if (OF_is_compatible(sc->sc_node, "allwinner,sun4i-a10-mmc")) { 310 sc->sc_idma_xferlen = 0x2000; 311 } else { 312 sc->sc_idma_xferlen = 0x10000; 313 } 314 315 sc->sc_idma_ndesc = SXIMMC_NDESC; 316 sc->sc_idma_size = sizeof(struct sximmc_idma_descriptor) * 317 sc->sc_idma_ndesc; 318 error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_idma_size, 0, 319 sc->sc_idma_size, sc->sc_idma_segs, 1, 320 &sc->sc_idma_nsegs, BUS_DMA_WAITOK); 321 if (error) 322 return error; 323 error = bus_dmamem_map(sc->sc_dmat, sc->sc_idma_segs, 324 sc->sc_idma_nsegs, sc->sc_idma_size, 325 &sc->sc_idma_desc, BUS_DMA_WAITOK); 326 if (error) 327 goto free; 328 error = bus_dmamap_create(sc->sc_dmat, sc->sc_idma_size, 1, 329 sc->sc_idma_size, 0, BUS_DMA_WAITOK, &sc->sc_idma_map); 330 if (error) 331 goto unmap; 332 error = bus_dmamap_load(sc->sc_dmat, sc->sc_idma_map, 333 sc->sc_idma_desc, sc->sc_idma_size, NULL, BUS_DMA_WAITOK); 334 if (error) 335 goto destroy; 336 return 0; 337 338 destroy: 339 bus_dmamap_destroy(sc->sc_dmat, sc->sc_idma_map); 340 unmap: 341 bus_dmamem_unmap(sc->sc_dmat, sc->sc_idma_desc, sc->sc_idma_size); 342 free: 343 bus_dmamem_free(sc->sc_dmat, sc->sc_idma_segs, sc->sc_idma_nsegs); 344 return error; 345 } 346 347 void 348 sximmc_attach(struct device *parent, struct device *self, void *aux) 349 { 350 struct sximmc_softc *sc = (struct sximmc_softc *)self; 351 struct fdt_attach_args *faa = aux; 352 struct sdmmcbus_attach_args saa; 353 int node, width; 354 355 if (faa->fa_nreg < 1) 356 return; 357 358 sc->sc_node = faa->fa_node; 359 sc->sc_bst = faa->fa_iot; 360 sc->sc_dmat = faa->fa_dmat; 361 362 if (bus_space_map(sc->sc_bst, faa->fa_reg[0].addr, 363 faa->fa_reg[0].size, 0, &sc->sc_bsh)) { 364 printf(": can't map registers\n"); 365 return; 366 } 367 368 sc->sc_use_dma = 1; 369 370 printf("\n"); 371 372 pinctrl_byname(faa->fa_node, "default"); 373 374 /* enable clock */ 375 clock_enable(faa->fa_node, NULL); 376 delay(5000); 377 378 reset_deassert_all(faa->fa_node); 379 380 /* 381 * The FIFO register is in a different location on the 382 * Allwinner A31 and later generations. Unfortunately the 383 * compatible string wasn't changed, so we need to look at the 384 * root node to pick the right register. 385 * 386 * XXX Should we always use DMA (like Linux does) to avoid 387 * this issue? 388 */ 389 node = OF_finddevice("/"); 390 if (OF_is_compatible(node, "allwinner,sun4i-a10") || 391 OF_is_compatible(node, "allwinner,sun5i-a10s") || 392 OF_is_compatible(node, "allwinner,sun5i-a13") || 393 OF_is_compatible(node, "allwinner,sun7i-a20")) 394 sc->sc_fifo_reg = SXIMMC_FIFO_A10; 395 else 396 sc->sc_fifo_reg = SXIMMC_FIFO_A31; 397 398 if (OF_is_compatible(sc->sc_node, "allwinner,sun9i-a80-mmc")) 399 sc->sc_dma_ftrglevel = SXIMMC_DMA_FTRGLEVEL_A80; 400 else 401 sc->sc_dma_ftrglevel = SXIMMC_DMA_FTRGLEVEL_A20; 402 403 if (sc->sc_use_dma) { 404 if (sximmc_idma_setup(sc) != 0) { 405 printf("%s: failed to setup DMA\n", self->dv_xname); 406 return; 407 } 408 } 409 410 OF_getpropintarray(sc->sc_node, "cd-gpios", sc->sc_gpio, 411 sizeof(sc->sc_gpio)); 412 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT); 413 414 sc->sc_vmmc = OF_getpropint(sc->sc_node, "vmmc-supply", 0); 415 sc->sc_vqmmc = OF_getpropint(sc->sc_node, "vqmmc-supply", 0); 416 sc->sc_pwrseq = OF_getpropint(sc->sc_node, "mmc-pwrseq", 0); 417 418 sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_BIO, 419 sximmc_intr, sc, sc->sc_dev.dv_xname); 420 if (sc->sc_ih == NULL) { 421 printf(": can't to establish interrupt\n"); 422 return; 423 } 424 425 sximmc_bus_width(sc, 1); 426 sximmc_set_clock(sc, 400); 427 sximmc_host_reset(sc); 428 429 memset(&saa, 0, sizeof(saa)); 430 saa.saa_busname = "sdmmc"; 431 saa.sct = &sximmc_chip_functions; 432 saa.sch = sc; 433 #if 0 434 saa.saa_clkmin = 400; 435 saa.saa_clkmax = awin_chip_id() == AWIN_CHIP_ID_A80 ? 48000 : 50000; 436 #endif 437 438 saa.caps = SMC_CAPS_SD_HIGHSPEED | SMC_CAPS_MMC_HIGHSPEED; 439 440 width = OF_getpropint(sc->sc_node, "bus-width", 1); 441 if (width >= 8) 442 saa.caps |= SMC_CAPS_8BIT_MODE; 443 if (width >= 4) 444 saa.caps |= SMC_CAPS_4BIT_MODE; 445 446 if (sc->sc_use_dma) { 447 saa.dmat = sc->sc_dmat; 448 saa.caps |= SMC_CAPS_DMA; 449 } 450 451 sc->sc_sdmmc_dev = config_found(self, &saa, NULL); 452 } 453 454 int 455 sximmc_set_clock(struct sximmc_softc *sc, u_int freq) 456 { 457 if (freq > 0) { 458 if (clock_set_frequency(sc->sc_node, "mmc", freq * 1000)) 459 return EIO; 460 clock_enable(sc->sc_node, "mmc"); 461 delay(20000); 462 } else 463 clock_disable(sc->sc_node, "mmc"); 464 465 return 0; 466 } 467 468 469 int 470 sximmc_intr(void *priv) 471 { 472 struct sximmc_softc *sc = priv; 473 uint32_t idst, rint, mint; 474 475 idst = MMC_READ(sc, SXIMMC_IDST); 476 rint = MMC_READ(sc, SXIMMC_RINT); 477 mint = MMC_READ(sc, SXIMMC_MINT); 478 if (!idst && !rint && !mint) 479 return 0; 480 481 MMC_WRITE(sc, SXIMMC_IDST, idst); 482 MMC_WRITE(sc, SXIMMC_RINT, rint); 483 MMC_WRITE(sc, SXIMMC_MINT, mint); 484 485 #ifdef SXIMMC_DEBUG 486 printf("%s: mmc intr idst=%08X rint=%08X mint=%08X\n", 487 sc->sc_dev.dv_xname, idst, rint, mint); 488 #endif 489 490 if (idst) { 491 sc->sc_idma_idst |= idst; 492 wakeup(&sc->sc_idma_idst); 493 } 494 495 if (rint) { 496 sc->sc_intr_rint |= rint; 497 wakeup(&sc->sc_intr_rint); 498 499 if (rint & SXIMMC_INT_SDIO_INT) { 500 uint32_t imask; 501 502 imask = MMC_READ(sc, SXIMMC_IMASK); 503 imask &= ~SXIMMC_INT_SDIO_INT; 504 MMC_WRITE(sc, SXIMMC_IMASK, imask); 505 sdmmc_card_intr(sc->sc_sdmmc_dev); 506 } 507 } 508 509 return 1; 510 } 511 512 void 513 sximmc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable) 514 { 515 struct sximmc_softc *sc = sch; 516 uint32_t imask; 517 518 imask = MMC_READ(sc, SXIMMC_IMASK); 519 if (enable) 520 imask |= SXIMMC_INT_SDIO_INT; 521 else 522 imask &= ~SXIMMC_INT_SDIO_INT; 523 MMC_WRITE(sc, SXIMMC_IMASK, imask); 524 } 525 526 void 527 sximmc_card_intr_ack(sdmmc_chipset_handle_t sch) 528 { 529 struct sximmc_softc *sc = sch; 530 uint32_t imask; 531 532 MMC_WRITE(sc, SXIMMC_RINT, SXIMMC_INT_SDIO_INT); 533 imask = MMC_READ(sc, SXIMMC_IMASK); 534 imask |= SXIMMC_INT_SDIO_INT; 535 MMC_WRITE(sc, SXIMMC_IMASK, imask); 536 } 537 538 int 539 sximmc_wait_rint(struct sximmc_softc *sc, uint32_t mask, int timeout) 540 { 541 int retry; 542 int error; 543 544 splassert(IPL_BIO); 545 546 if (sc->sc_intr_rint & mask) 547 return 0; 548 549 retry = sc->sc_use_dma ? (timeout / hz) : 10000; 550 551 while (retry > 0) { 552 if (sc->sc_use_dma) { 553 error = tsleep(&sc->sc_intr_rint, PWAIT, "rint", hz); 554 if (error && error != EWOULDBLOCK) 555 return error; 556 if (sc->sc_intr_rint & mask) 557 return 0; 558 } else { 559 sc->sc_intr_rint |= MMC_READ(sc, SXIMMC_RINT); 560 if (sc->sc_intr_rint & mask) 561 return 0; 562 delay(1000); 563 } 564 --retry; 565 } 566 567 return ETIMEDOUT; 568 } 569 570 void 571 sximmc_led(struct sximmc_softc *sc, int on) 572 { 573 } 574 575 int 576 sximmc_host_reset(sdmmc_chipset_handle_t sch) 577 { 578 struct sximmc_softc *sc = sch; 579 int retry = 1000; 580 581 #if 0 582 if (awin_chip_id() == AWIN_CHIP_ID_A80) { 583 if (sc->sc_mmc_port == 2 || sc->sc_mmc_port == 3) { 584 MMC_WRITE(sc, SXIMMC_HWRST, 0); 585 delay(10); 586 MMC_WRITE(sc, SXIMMC_HWRST, 1); 587 delay(300); 588 } 589 } 590 #endif 591 592 MMC_WRITE(sc, SXIMMC_GCTRL, 593 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_RESET); 594 while (--retry > 0) { 595 if (!(MMC_READ(sc, SXIMMC_GCTRL) & SXIMMC_GCTRL_RESET)) 596 break; 597 delay(100); 598 } 599 #ifdef SXIMMC_DEBUG 600 if (retry == 0) 601 printf("%s: host reset failed\n", sc->sc_dev.dv_xname); 602 else 603 printf("%s: host reset succeeded\n", sc->sc_dev.dv_xname); 604 #endif 605 606 /* Allow access to the FIFO by the CPU. */ 607 MMC_WRITE(sc, SXIMMC_GCTRL, 608 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_ACCESS_BY_AHB); 609 610 MMC_WRITE(sc, SXIMMC_TIMEOUT, 0xffffffff); 611 612 MMC_WRITE(sc, SXIMMC_IMASK, 613 SXIMMC_INT_CMD_DONE | SXIMMC_INT_ERROR | 614 SXIMMC_INT_DATA_OVER | SXIMMC_INT_AUTO_CMD_DONE); 615 616 MMC_WRITE(sc, SXIMMC_GCTRL, 617 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_INTEN); 618 619 return 0; 620 } 621 622 uint32_t 623 sximmc_host_ocr(sdmmc_chipset_handle_t sch) 624 { 625 #if 0 626 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | MMC_OCR_HCS; 627 #else 628 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V; 629 #endif 630 } 631 632 int 633 sximmc_host_maxblklen(sdmmc_chipset_handle_t sch) 634 { 635 #if 0 636 return 8192; 637 #else 638 return 512; 639 #endif 640 } 641 642 int 643 sximmc_card_detect(sdmmc_chipset_handle_t sch) 644 { 645 struct sximmc_softc *sc = sch; 646 int inverted, val; 647 648 if (OF_getproplen(sc->sc_node, "non-removable") == 0) 649 return 1; 650 651 val = gpio_controller_get_pin(sc->sc_gpio); 652 653 inverted = (OF_getproplen(sc->sc_node, "cd-inverted") == 0); 654 return inverted ? !val : val; 655 } 656 657 int 658 sximmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 659 { 660 struct sximmc_softc *sc = sch; 661 uint32_t vdd = 0; 662 663 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) 664 vdd = 3300000; 665 666 if (sc->sc_vdd == 0 && vdd > 0) 667 sximmc_pwrseq_pre(sc->sc_pwrseq); 668 669 /* enable mmc power */ 670 if (sc->sc_vmmc && vdd > 0) 671 regulator_enable(sc->sc_vmmc); 672 673 if (sc->sc_vqmmc && vdd > 0) 674 regulator_enable(sc->sc_vqmmc); 675 676 delay(10000); 677 678 if (sc->sc_vdd == 0 && vdd > 0) 679 sximmc_pwrseq_post(sc->sc_pwrseq); 680 681 sc->sc_vdd = vdd; 682 return 0; 683 } 684 685 int 686 sximmc_update_clock(struct sximmc_softc *sc) 687 { 688 uint32_t cmd; 689 int retry; 690 691 #ifdef SXIMMC_DEBUG 692 printf("%s: update clock\n", sc->sc_dev.dv_xname); 693 #endif 694 695 cmd = SXIMMC_CMD_START | 696 SXIMMC_CMD_UPCLK_ONLY | 697 SXIMMC_CMD_WAIT_PRE_OVER; 698 MMC_WRITE(sc, SXIMMC_CMD, cmd); 699 retry = 0xfffff; 700 while (--retry > 0) { 701 if (!(MMC_READ(sc, SXIMMC_CMD) & SXIMMC_CMD_START)) 702 break; 703 delay(10); 704 } 705 706 if (retry == 0) { 707 printf("%s: timeout updating clock\n", sc->sc_dev.dv_xname); 708 #ifdef SXIMMC_DEBUG 709 printf("GCTRL: 0x%08x\n", MMC_READ(sc, SXIMMC_GCTRL)); 710 printf("CLKCR: 0x%08x\n", MMC_READ(sc, SXIMMC_CLKCR)); 711 printf("TIMEOUT: 0x%08x\n", MMC_READ(sc, SXIMMC_TIMEOUT)); 712 printf("WIDTH: 0x%08x\n", MMC_READ(sc, SXIMMC_WIDTH)); 713 printf("CMD: 0x%08x\n", MMC_READ(sc, SXIMMC_CMD)); 714 printf("MINT: 0x%08x\n", MMC_READ(sc, SXIMMC_MINT)); 715 printf("RINT: 0x%08x\n", MMC_READ(sc, SXIMMC_RINT)); 716 printf("STATUS: 0x%08x\n", MMC_READ(sc, SXIMMC_STATUS)); 717 #endif 718 return ETIMEDOUT; 719 } 720 721 return 0; 722 } 723 724 int 725 sximmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, int timing) 726 { 727 struct sximmc_softc *sc = sch; 728 uint32_t clkcr; 729 730 clkcr = MMC_READ(sc, SXIMMC_CLKCR); 731 if (clkcr & SXIMMC_CLKCR_CARDCLKON) { 732 clkcr &= ~SXIMMC_CLKCR_CARDCLKON; 733 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 734 if (sximmc_update_clock(sc) != 0) 735 return 1; 736 } 737 738 if (freq) { 739 clkcr &= ~SXIMMC_CLKCR_DIV; 740 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 741 if (sximmc_update_clock(sc) != 0) 742 return 1; 743 744 if (sximmc_set_clock(sc, freq) != 0) 745 return 1; 746 747 clkcr |= SXIMMC_CLKCR_CARDCLKON; 748 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 749 if (sximmc_update_clock(sc) != 0) 750 return 1; 751 } 752 753 return 0; 754 } 755 756 int 757 sximmc_bus_width(sdmmc_chipset_handle_t sch, int width) 758 { 759 struct sximmc_softc *sc = sch; 760 761 #ifdef SXIMMC_DEBUG 762 printf("%s: width = %d\n", sc->sc_dev.dv_xname, width); 763 #endif 764 765 switch (width) { 766 case 1: 767 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_1); 768 break; 769 case 4: 770 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_4); 771 break; 772 case 8: 773 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_8); 774 break; 775 default: 776 return 1; 777 } 778 779 return 0; 780 } 781 782 int 783 sximmc_pio_wait(struct sximmc_softc *sc, struct sdmmc_command *cmd) 784 { 785 int retry = 0xfffff; 786 uint32_t bit = (cmd->c_flags & SCF_CMD_READ) ? 787 SXIMMC_STATUS_FIFO_EMPTY : SXIMMC_STATUS_FIFO_FULL; 788 789 while (--retry > 0) { 790 uint32_t status = MMC_READ(sc, SXIMMC_STATUS); 791 if (!(status & bit)) 792 return 0; 793 delay(10); 794 } 795 796 return ETIMEDOUT; 797 } 798 799 int 800 sximmc_pio_transfer(struct sximmc_softc *sc, struct sdmmc_command *cmd) 801 { 802 u_char *datap = cmd->c_data; 803 int datalen = cmd->c_resid; 804 805 while (datalen > 3) { 806 if (sximmc_pio_wait(sc, cmd)) 807 return ETIMEDOUT; 808 if (cmd->c_flags & SCF_CMD_READ) { 809 *(uint32_t *)datap = MMC_READ(sc, sc->sc_fifo_reg); 810 } else { 811 MMC_WRITE(sc, sc->sc_fifo_reg, *(uint32_t *)datap); 812 } 813 datap += 4; 814 datalen -= 4; 815 } 816 817 if (datalen > 0 && cmd->c_flags & SCF_CMD_READ) { 818 uint32_t rv = MMC_READ(sc, sc->sc_fifo_reg); 819 do { 820 *datap++ = rv & 0xff; 821 rv = rv >> 8; 822 } while(--datalen > 0); 823 } else if (datalen > 0) { 824 uint32_t rv = *datap++; 825 if (datalen > 1) 826 rv |= *datap++ << 8; 827 if (datalen > 2) 828 rv |= *datap++ << 16; 829 MMC_WRITE(sc, sc->sc_fifo_reg, rv); 830 } 831 832 return 0; 833 } 834 835 int 836 sximmc_dma_prepare(struct sximmc_softc *sc, struct sdmmc_command *cmd) 837 { 838 struct sximmc_idma_descriptor *dma = (void *)sc->sc_idma_desc; 839 bus_addr_t desc_paddr = sc->sc_idma_map->dm_segs[0].ds_addr; 840 bus_size_t off; 841 int desc, resid, seg; 842 uint32_t val; 843 844 desc = 0; 845 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 846 bus_addr_t paddr = cmd->c_dmamap->dm_segs[seg].ds_addr; 847 bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len; 848 resid = min(len, cmd->c_resid); 849 off = 0; 850 while (resid > 0) { 851 if (desc == sc->sc_idma_ndesc) 852 break; 853 len = min(sc->sc_idma_xferlen, resid); 854 dma[desc].dma_buf_size = htole32(len); 855 dma[desc].dma_buf_addr = htole32(paddr + off); 856 dma[desc].dma_config = htole32(SXIMMC_IDMA_CONFIG_CH | 857 SXIMMC_IDMA_CONFIG_OWN); 858 cmd->c_resid -= len; 859 resid -= len; 860 off += len; 861 if (desc == 0) { 862 dma[desc].dma_config |= 863 htole32(SXIMMC_IDMA_CONFIG_FD); 864 } 865 if (cmd->c_resid == 0) { 866 dma[desc].dma_config |= 867 htole32(SXIMMC_IDMA_CONFIG_LD); 868 dma[desc].dma_config |= 869 htole32(SXIMMC_IDMA_CONFIG_ER); 870 dma[desc].dma_next = 0; 871 } else { 872 dma[desc].dma_config |= 873 htole32(SXIMMC_IDMA_CONFIG_DIC); 874 dma[desc].dma_next = htole32( 875 desc_paddr + ((desc+1) * 876 sizeof(struct sximmc_idma_descriptor))); 877 } 878 ++desc; 879 } 880 } 881 if (desc == sc->sc_idma_ndesc) { 882 printf("%s: not enough descriptors for %d byte transfer!\n", 883 sc->sc_dev.dv_xname, cmd->c_datalen); 884 return EIO; 885 } 886 887 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 888 sc->sc_idma_size, BUS_DMASYNC_PREWRITE); 889 890 sc->sc_idma_idst = 0; 891 892 val = MMC_READ(sc, SXIMMC_GCTRL); 893 val |= SXIMMC_GCTRL_DMAEN; 894 val |= SXIMMC_GCTRL_INTEN; 895 MMC_WRITE(sc, SXIMMC_GCTRL, val); 896 val |= SXIMMC_GCTRL_DMARESET; 897 MMC_WRITE(sc, SXIMMC_GCTRL, val); 898 MMC_WRITE(sc, SXIMMC_DMAC, SXIMMC_DMAC_SOFTRESET); 899 MMC_WRITE(sc, SXIMMC_DMAC, 900 SXIMMC_DMAC_IDMA_ON|SXIMMC_DMAC_FIX_BURST); 901 val = MMC_READ(sc, SXIMMC_IDIE); 902 val &= ~(SXIMMC_IDST_RECEIVE_INT|SXIMMC_IDST_TRANSMIT_INT); 903 if (cmd->c_flags & SCF_CMD_READ) 904 val |= SXIMMC_IDST_RECEIVE_INT; 905 else 906 val |= SXIMMC_IDST_TRANSMIT_INT; 907 MMC_WRITE(sc, SXIMMC_IDIE, val); 908 MMC_WRITE(sc, SXIMMC_DLBA, desc_paddr); 909 MMC_WRITE(sc, SXIMMC_FTRGLEVEL, sc->sc_dma_ftrglevel); 910 911 return 0; 912 } 913 914 void 915 sximmc_dma_complete(struct sximmc_softc *sc) 916 { 917 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 918 sc->sc_idma_size, BUS_DMASYNC_POSTWRITE); 919 } 920 921 void 922 sximmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 923 { 924 struct sximmc_softc *sc = sch; 925 uint32_t cmdval = SXIMMC_CMD_START; 926 int retry; 927 int s; 928 929 #ifdef SXIMMC_DEBUG 930 printf("%s: opcode %d flags 0x%x data %p datalen %d blklen %d\n", 931 sc->sc_dev.dv_xname, cmd->c_opcode, cmd->c_flags, 932 cmd->c_data, cmd->c_datalen, cmd->c_blklen); 933 #endif 934 935 s = splbio(); 936 937 if (cmd->c_opcode == 0) 938 cmdval |= SXIMMC_CMD_SEND_INIT_SEQ; 939 if (cmd->c_flags & SCF_RSP_PRESENT) 940 cmdval |= SXIMMC_CMD_RSP_EXP; 941 if (cmd->c_flags & SCF_RSP_136) 942 cmdval |= SXIMMC_CMD_LONG_RSP; 943 if (cmd->c_flags & SCF_RSP_CRC) 944 cmdval |= SXIMMC_CMD_CHECK_RSP_CRC; 945 946 if (cmd->c_datalen > 0) { 947 uint16_t blksize; 948 uint16_t blkcount; 949 950 cmdval |= SXIMMC_CMD_DATA_EXP | SXIMMC_CMD_WAIT_PRE_OVER; 951 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) { 952 cmdval |= SXIMMC_CMD_WRITE; 953 } 954 955 blksize = MIN(cmd->c_datalen, cmd->c_blklen); 956 blkcount = cmd->c_datalen / blksize; 957 if (blkcount > 1 && cmd->c_opcode != SD_IO_RW_EXTENDED) { 958 cmdval |= SXIMMC_CMD_SEND_AUTO_STOP; 959 } 960 961 MMC_WRITE(sc, SXIMMC_BLKSZ, blksize); 962 MMC_WRITE(sc, SXIMMC_BYTECNT, blkcount * blksize); 963 } 964 965 sc->sc_intr_rint = 0; 966 967 #if 0 968 if (awin_chip_id() == AWIN_CHIP_ID_A80) { 969 MMC_WRITE(sc, SXIMMC_A12A, 970 (cmdval & SXIMMC_CMD_SEND_AUTO_STOP) ? 0 : 0xffff); 971 } 972 #endif 973 974 MMC_WRITE(sc, SXIMMC_ARG, cmd->c_arg); 975 976 #ifdef SXIMMC_DEBUG 977 printf("%s: cmdval = %08x\n", sc->sc_dev.dv_xname, cmdval); 978 #endif 979 980 if (cmd->c_datalen == 0) { 981 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 982 } else { 983 cmd->c_resid = cmd->c_datalen; 984 sximmc_led(sc, 0); 985 if (cmd->c_dmamap && sc->sc_use_dma) { 986 cmd->c_error = sximmc_dma_prepare(sc, cmd); 987 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 988 if (cmd->c_error == 0) { 989 cmd->c_error = tsleep(&sc->sc_idma_idst, 990 PWAIT, "idma", hz*10); 991 } 992 sximmc_dma_complete(sc); 993 if (sc->sc_idma_idst & SXIMMC_IDST_ERROR) { 994 cmd->c_error = EIO; 995 } else if (!(sc->sc_idma_idst & SXIMMC_IDST_COMPLETE)) { 996 cmd->c_error = ETIMEDOUT; 997 } 998 } else { 999 splx(s); 1000 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 1001 cmd->c_error = sximmc_pio_transfer(sc, cmd); 1002 s = splbio(); 1003 } 1004 sximmc_led(sc, 1); 1005 if (cmd->c_error) { 1006 #ifdef SXIMMC_DEBUG 1007 printf("%s: xfer failed, error %d\n", 1008 sc->sc_dev.dv_xname, cmd->c_error); 1009 #endif 1010 goto done; 1011 } 1012 } 1013 1014 cmd->c_error = sximmc_wait_rint(sc, 1015 SXIMMC_INT_ERROR|SXIMMC_INT_CMD_DONE, hz * 10); 1016 if (cmd->c_error == 0 && (sc->sc_intr_rint & SXIMMC_INT_ERROR)) { 1017 if (sc->sc_intr_rint & SXIMMC_INT_RESP_TIMEOUT) { 1018 cmd->c_error = ETIMEDOUT; 1019 } else { 1020 cmd->c_error = EIO; 1021 } 1022 } 1023 if (cmd->c_error) { 1024 #ifdef SXIMMC_DEBUG 1025 printf("%s: cmd failed, error %d\n", 1026 sc->sc_dev.dv_xname, cmd->c_error); 1027 #endif 1028 goto done; 1029 } 1030 1031 if (cmd->c_datalen > 0) { 1032 cmd->c_error = sximmc_wait_rint(sc, 1033 SXIMMC_INT_ERROR| 1034 SXIMMC_INT_AUTO_CMD_DONE| 1035 SXIMMC_INT_DATA_OVER, 1036 hz*10); 1037 if (cmd->c_error == 0 && 1038 (sc->sc_intr_rint & SXIMMC_INT_ERROR)) { 1039 cmd->c_error = ETIMEDOUT; 1040 } 1041 if (cmd->c_error) { 1042 #ifdef SXIMMC_DEBUG 1043 printf("%s: data timeout, rint = %08x\n", 1044 sc->sc_dev.dv_xname, sc->sc_intr_rint); 1045 #endif 1046 cmd->c_error = ETIMEDOUT; 1047 goto done; 1048 } 1049 } 1050 1051 if (cmd->c_flags & SCF_RSP_PRESENT) { 1052 if (cmd->c_flags & SCF_RSP_136) { 1053 cmd->c_resp[0] = MMC_READ(sc, SXIMMC_RESP0); 1054 cmd->c_resp[1] = MMC_READ(sc, SXIMMC_RESP1); 1055 cmd->c_resp[2] = MMC_READ(sc, SXIMMC_RESP2); 1056 cmd->c_resp[3] = MMC_READ(sc, SXIMMC_RESP3); 1057 if (cmd->c_flags & SCF_RSP_CRC) { 1058 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 1059 (cmd->c_resp[1] << 24); 1060 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 1061 (cmd->c_resp[2] << 24); 1062 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 1063 (cmd->c_resp[3] << 24); 1064 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 1065 } 1066 } else { 1067 cmd->c_resp[0] = MMC_READ(sc, SXIMMC_RESP0); 1068 } 1069 } 1070 1071 done: 1072 cmd->c_flags |= SCF_ITSDONE; 1073 splx(s); 1074 1075 if (cmd->c_error) { 1076 #ifdef SXIMMC_DEBUG 1077 printf("%s: i/o error %d\n", sc->sc_dev.dv_xname, 1078 cmd->c_error); 1079 #endif 1080 MMC_WRITE(sc, SXIMMC_GCTRL, 1081 MMC_READ(sc, SXIMMC_GCTRL) | 1082 SXIMMC_GCTRL_DMARESET | SXIMMC_GCTRL_FIFORESET); 1083 for (retry = 0; retry < 1000; retry++) { 1084 if (!(MMC_READ(sc, SXIMMC_GCTRL) & SXIMMC_GCTRL_RESET)) 1085 break; 1086 delay(10); 1087 } 1088 sximmc_host_reset(sc); 1089 sximmc_update_clock(sc); 1090 } 1091 1092 if (!cmd->c_dmamap || !sc->sc_use_dma) { 1093 MMC_WRITE(sc, SXIMMC_GCTRL, 1094 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_FIFORESET); 1095 } 1096 } 1097 1098 void 1099 sximmc_pwrseq_pre(uint32_t phandle) 1100 { 1101 uint32_t *gpios, *gpio; 1102 int node; 1103 int len; 1104 1105 node = OF_getnodebyphandle(phandle); 1106 if (node == 0) 1107 return; 1108 1109 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1110 return; 1111 1112 pinctrl_byname(node, "default"); 1113 1114 clock_enable(node, "ext_clock"); 1115 1116 len = OF_getproplen(node, "reset-gpios"); 1117 if (len <= 0) 1118 return; 1119 1120 gpios = malloc(len, M_TEMP, M_WAITOK); 1121 OF_getpropintarray(node, "reset-gpios", gpios, len); 1122 1123 gpio = gpios; 1124 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1125 gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT); 1126 gpio_controller_set_pin(gpio, 1); 1127 gpio = gpio_controller_next_pin(gpio); 1128 } 1129 1130 free(gpios, M_TEMP, len); 1131 } 1132 1133 void 1134 sximmc_pwrseq_post(uint32_t phandle) 1135 { 1136 uint32_t *gpios, *gpio; 1137 int node; 1138 int len; 1139 1140 node = OF_getnodebyphandle(phandle); 1141 if (node == 0) 1142 return; 1143 1144 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1145 return; 1146 1147 len = OF_getproplen(node, "reset-gpios"); 1148 if (len <= 0) 1149 return; 1150 1151 gpios = malloc(len, M_TEMP, M_WAITOK); 1152 OF_getpropintarray(node, "reset-gpios", gpios, len); 1153 1154 gpio = gpios; 1155 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1156 gpio_controller_set_pin(gpio, 0); 1157 gpio = gpio_controller_next_pin(gpio); 1158 } 1159 1160 free(gpios, M_TEMP, len); 1161 } 1162