1 /* $OpenBSD: sximmc.c,v 1.11 2020/01/11 01:18:29 cheloha 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 bus_dma_segment_t sc_idma_segs[1]; 259 int sc_idma_nsegs; 260 bus_size_t sc_idma_size; 261 bus_dmamap_t sc_idma_map; 262 int sc_idma_ndesc; 263 char *sc_idma_desc; 264 265 uint32_t sc_intr_rint; 266 uint32_t sc_intr_mint; 267 uint32_t sc_idma_idst; 268 269 uint32_t sc_gpio[4]; 270 uint32_t sc_vmmc; 271 uint32_t sc_vqmmc; 272 uint32_t sc_pwrseq; 273 uint32_t sc_vdd; 274 }; 275 276 struct cfdriver sximmc_cd = { 277 NULL, "sximmc", DV_DULL 278 }; 279 280 struct cfattach sximmc_ca = { 281 sizeof(struct sximmc_softc), sximmc_match, sximmc_attach 282 }; 283 284 #define MMC_WRITE(sc, reg, val) \ 285 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 286 #define MMC_READ(sc, reg) \ 287 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 288 289 int sximmc_set_clock(struct sximmc_softc *sc, u_int); 290 291 int 292 sximmc_match(struct device *parent, void *match, void *aux) 293 { 294 struct fdt_attach_args *faa = aux; 295 296 return (OF_is_compatible(faa->fa_node, "allwinner,sun4i-a10-mmc") || 297 OF_is_compatible(faa->fa_node, "allwinner,sun5i-a13-mmc") || 298 OF_is_compatible(faa->fa_node, "allwinner,sun7i-a20-mmc") || 299 OF_is_compatible(faa->fa_node, "allwinner,sun9i-a80-mmc") || 300 OF_is_compatible(faa->fa_node, "allwinner,sun50i-a64-mmc") || 301 OF_is_compatible(faa->fa_node, "allwinner,sun50i-a64-emmc")); 302 } 303 304 int 305 sximmc_idma_setup(struct sximmc_softc *sc) 306 { 307 int error; 308 309 sc->sc_idma_ndesc = SXIMMC_NDESC; 310 sc->sc_idma_size = sizeof(struct sximmc_idma_descriptor) * 311 sc->sc_idma_ndesc; 312 error = bus_dmamem_alloc(sc->sc_dmat, sc->sc_idma_size, 0, 313 sc->sc_idma_size, sc->sc_idma_segs, 1, 314 &sc->sc_idma_nsegs, BUS_DMA_WAITOK); 315 if (error) 316 return error; 317 error = bus_dmamem_map(sc->sc_dmat, sc->sc_idma_segs, 318 sc->sc_idma_nsegs, sc->sc_idma_size, 319 &sc->sc_idma_desc, BUS_DMA_WAITOK); 320 if (error) 321 goto free; 322 error = bus_dmamap_create(sc->sc_dmat, sc->sc_idma_size, 1, 323 sc->sc_idma_size, 0, BUS_DMA_WAITOK, &sc->sc_idma_map); 324 if (error) 325 goto unmap; 326 error = bus_dmamap_load(sc->sc_dmat, sc->sc_idma_map, 327 sc->sc_idma_desc, sc->sc_idma_size, NULL, BUS_DMA_WAITOK); 328 if (error) 329 goto destroy; 330 return 0; 331 332 destroy: 333 bus_dmamap_destroy(sc->sc_dmat, sc->sc_idma_map); 334 unmap: 335 bus_dmamem_unmap(sc->sc_dmat, sc->sc_idma_desc, sc->sc_idma_size); 336 free: 337 bus_dmamem_free(sc->sc_dmat, sc->sc_idma_segs, sc->sc_idma_nsegs); 338 return error; 339 } 340 341 void 342 sximmc_attach(struct device *parent, struct device *self, void *aux) 343 { 344 struct sximmc_softc *sc = (struct sximmc_softc *)self; 345 struct fdt_attach_args *faa = aux; 346 struct sdmmcbus_attach_args saa; 347 int node, width; 348 349 if (faa->fa_nreg < 1) 350 return; 351 352 sc->sc_node = faa->fa_node; 353 sc->sc_bst = faa->fa_iot; 354 sc->sc_dmat = faa->fa_dmat; 355 356 if (bus_space_map(sc->sc_bst, faa->fa_reg[0].addr, 357 faa->fa_reg[0].size, 0, &sc->sc_bsh)) { 358 printf(": can't map registers\n"); 359 return; 360 } 361 362 sc->sc_use_dma = 1; 363 364 printf("\n"); 365 366 pinctrl_byname(faa->fa_node, "default"); 367 368 /* enable clock */ 369 clock_enable(faa->fa_node, NULL); 370 delay(5000); 371 372 reset_deassert_all(faa->fa_node); 373 374 /* 375 * The FIFO register is in a different location on the 376 * Allwinner A31 and later generations. Unfortunately the 377 * compatible string wasn't changed, so we need to look at the 378 * root node to pick the right register. 379 * 380 * XXX Should we always use DMA (like Linux does) to avoid 381 * this issue? 382 */ 383 node = OF_finddevice("/"); 384 if (OF_is_compatible(node, "allwinner,sun4i-a10") || 385 OF_is_compatible(node, "allwinner,sun5i-a10s") || 386 OF_is_compatible(node, "allwinner,sun5i-a13") || 387 OF_is_compatible(node, "allwinner,sun7i-a20")) 388 sc->sc_fifo_reg = SXIMMC_FIFO_A10; 389 else 390 sc->sc_fifo_reg = SXIMMC_FIFO_A31; 391 392 if (OF_is_compatible(sc->sc_node, "allwinner,sun9i-a80-mmc")) 393 sc->sc_dma_ftrglevel = SXIMMC_DMA_FTRGLEVEL_A80; 394 else 395 sc->sc_dma_ftrglevel = SXIMMC_DMA_FTRGLEVEL_A20; 396 397 if (sc->sc_use_dma) { 398 if (sximmc_idma_setup(sc) != 0) { 399 printf("%s: failed to setup DMA\n", self->dv_xname); 400 return; 401 } 402 } 403 404 OF_getpropintarray(sc->sc_node, "cd-gpios", sc->sc_gpio, 405 sizeof(sc->sc_gpio)); 406 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT); 407 408 sc->sc_vmmc = OF_getpropint(sc->sc_node, "vmmc-supply", 0); 409 sc->sc_vqmmc = OF_getpropint(sc->sc_node, "vqmmc-supply", 0); 410 sc->sc_pwrseq = OF_getpropint(sc->sc_node, "mmc-pwrseq", 0); 411 412 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_BIO, 413 sximmc_intr, sc, sc->sc_dev.dv_xname); 414 if (sc->sc_ih == NULL) { 415 printf(": can't establish interrupt\n"); 416 return; 417 } 418 419 sximmc_bus_width(sc, 1); 420 sximmc_set_clock(sc, 400); 421 sximmc_host_reset(sc); 422 423 memset(&saa, 0, sizeof(saa)); 424 saa.saa_busname = "sdmmc"; 425 saa.sct = &sximmc_chip_functions; 426 saa.sch = sc; 427 #if 0 428 saa.saa_clkmin = 400; 429 saa.saa_clkmax = awin_chip_id() == AWIN_CHIP_ID_A80 ? 48000 : 50000; 430 #endif 431 432 saa.caps = SMC_CAPS_SD_HIGHSPEED | SMC_CAPS_MMC_HIGHSPEED; 433 434 width = OF_getpropint(sc->sc_node, "bus-width", 1); 435 if (width >= 8) 436 saa.caps |= SMC_CAPS_8BIT_MODE; 437 if (width >= 4) 438 saa.caps |= SMC_CAPS_4BIT_MODE; 439 440 if (sc->sc_use_dma) { 441 saa.dmat = sc->sc_dmat; 442 saa.caps |= SMC_CAPS_DMA; 443 } 444 445 if (OF_is_compatible(sc->sc_node, "allwinner,sun4i-a10-mmc") || 446 OF_is_compatible(sc->sc_node, "allwinner,sun50i-a64-emmc")) { 447 saa.max_seg = 0x2000; 448 } else { 449 saa.max_seg = 0x10000; 450 } 451 452 sc->sc_sdmmc_dev = config_found(self, &saa, NULL); 453 } 454 455 int 456 sximmc_set_clock(struct sximmc_softc *sc, u_int freq) 457 { 458 if (freq > 0) { 459 if (clock_set_frequency(sc->sc_node, "mmc", freq * 1000)) 460 return EIO; 461 clock_enable(sc->sc_node, "mmc"); 462 delay(20000); 463 } else 464 clock_disable(sc->sc_node, "mmc"); 465 466 return 0; 467 } 468 469 470 int 471 sximmc_intr(void *priv) 472 { 473 struct sximmc_softc *sc = priv; 474 uint32_t idst, rint, mint; 475 476 idst = MMC_READ(sc, SXIMMC_IDST); 477 rint = MMC_READ(sc, SXIMMC_RINT); 478 mint = MMC_READ(sc, SXIMMC_MINT); 479 if (!idst && !rint && !mint) 480 return 0; 481 482 MMC_WRITE(sc, SXIMMC_IDST, idst); 483 MMC_WRITE(sc, SXIMMC_RINT, rint); 484 MMC_WRITE(sc, SXIMMC_MINT, mint); 485 486 #ifdef SXIMMC_DEBUG 487 printf("%s: mmc intr idst=%08X rint=%08X mint=%08X\n", 488 sc->sc_dev.dv_xname, idst, rint, mint); 489 #endif 490 491 if (idst) { 492 sc->sc_idma_idst |= idst; 493 wakeup(&sc->sc_idma_idst); 494 } 495 496 if (rint) { 497 sc->sc_intr_rint |= rint; 498 wakeup(&sc->sc_intr_rint); 499 500 if (rint & SXIMMC_INT_SDIO_INT) { 501 uint32_t imask; 502 503 imask = MMC_READ(sc, SXIMMC_IMASK); 504 imask &= ~SXIMMC_INT_SDIO_INT; 505 MMC_WRITE(sc, SXIMMC_IMASK, imask); 506 sdmmc_card_intr(sc->sc_sdmmc_dev); 507 } 508 } 509 510 return 1; 511 } 512 513 void 514 sximmc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable) 515 { 516 struct sximmc_softc *sc = sch; 517 uint32_t imask; 518 519 imask = MMC_READ(sc, SXIMMC_IMASK); 520 if (enable) 521 imask |= SXIMMC_INT_SDIO_INT; 522 else 523 imask &= ~SXIMMC_INT_SDIO_INT; 524 MMC_WRITE(sc, SXIMMC_IMASK, imask); 525 } 526 527 void 528 sximmc_card_intr_ack(sdmmc_chipset_handle_t sch) 529 { 530 struct sximmc_softc *sc = sch; 531 uint32_t imask; 532 533 MMC_WRITE(sc, SXIMMC_RINT, SXIMMC_INT_SDIO_INT); 534 imask = MMC_READ(sc, SXIMMC_IMASK); 535 imask |= SXIMMC_INT_SDIO_INT; 536 MMC_WRITE(sc, SXIMMC_IMASK, imask); 537 } 538 539 int 540 sximmc_wait_rint(struct sximmc_softc *sc, uint32_t mask, int timeout) 541 { 542 int retry; 543 int error; 544 545 splassert(IPL_BIO); 546 547 if (sc->sc_intr_rint & mask) 548 return 0; 549 550 retry = sc->sc_use_dma ? (timeout / hz) : 10000; 551 552 while (retry > 0) { 553 if (sc->sc_use_dma) { 554 error = tsleep_nsec(&sc->sc_intr_rint, PWAIT, "rint", 555 SEC_TO_NSEC(1)); 556 if (error && error != EWOULDBLOCK) 557 return error; 558 if (sc->sc_intr_rint & mask) 559 return 0; 560 } else { 561 sc->sc_intr_rint |= MMC_READ(sc, SXIMMC_RINT); 562 if (sc->sc_intr_rint & mask) 563 return 0; 564 delay(1000); 565 } 566 --retry; 567 } 568 569 return ETIMEDOUT; 570 } 571 572 void 573 sximmc_led(struct sximmc_softc *sc, int on) 574 { 575 } 576 577 int 578 sximmc_host_reset(sdmmc_chipset_handle_t sch) 579 { 580 struct sximmc_softc *sc = sch; 581 int retry = 1000; 582 583 #if 0 584 if (awin_chip_id() == AWIN_CHIP_ID_A80) { 585 if (sc->sc_mmc_port == 2 || sc->sc_mmc_port == 3) { 586 MMC_WRITE(sc, SXIMMC_HWRST, 0); 587 delay(10); 588 MMC_WRITE(sc, SXIMMC_HWRST, 1); 589 delay(300); 590 } 591 } 592 #endif 593 594 MMC_WRITE(sc, SXIMMC_GCTRL, 595 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_RESET); 596 while (--retry > 0) { 597 if (!(MMC_READ(sc, SXIMMC_GCTRL) & SXIMMC_GCTRL_RESET)) 598 break; 599 delay(100); 600 } 601 #ifdef SXIMMC_DEBUG 602 if (retry == 0) 603 printf("%s: host reset failed\n", sc->sc_dev.dv_xname); 604 else 605 printf("%s: host reset succeeded\n", sc->sc_dev.dv_xname); 606 #endif 607 608 /* Allow access to the FIFO by the CPU. */ 609 MMC_WRITE(sc, SXIMMC_GCTRL, 610 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_ACCESS_BY_AHB); 611 612 MMC_WRITE(sc, SXIMMC_TIMEOUT, 0xffffffff); 613 614 MMC_WRITE(sc, SXIMMC_IMASK, 615 SXIMMC_INT_CMD_DONE | SXIMMC_INT_ERROR | 616 SXIMMC_INT_DATA_OVER | SXIMMC_INT_AUTO_CMD_DONE); 617 618 MMC_WRITE(sc, SXIMMC_GCTRL, 619 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_INTEN); 620 621 return 0; 622 } 623 624 uint32_t 625 sximmc_host_ocr(sdmmc_chipset_handle_t sch) 626 { 627 #if 0 628 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | MMC_OCR_HCS; 629 #else 630 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V; 631 #endif 632 } 633 634 int 635 sximmc_host_maxblklen(sdmmc_chipset_handle_t sch) 636 { 637 #if 0 638 return 8192; 639 #else 640 return 512; 641 #endif 642 } 643 644 int 645 sximmc_card_detect(sdmmc_chipset_handle_t sch) 646 { 647 struct sximmc_softc *sc = sch; 648 int inverted, val; 649 650 /* XXX treat broken-cd as non-removable */ 651 if (OF_getproplen(sc->sc_node, "non-removable") == 0 || 652 OF_getproplen(sc->sc_node, "broken-cd") == 0) 653 return 1; 654 655 val = gpio_controller_get_pin(sc->sc_gpio); 656 657 inverted = (OF_getproplen(sc->sc_node, "cd-inverted") == 0); 658 return inverted ? !val : val; 659 } 660 661 int 662 sximmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 663 { 664 struct sximmc_softc *sc = sch; 665 uint32_t vdd = 0; 666 667 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) 668 vdd = 3300000; 669 670 if (sc->sc_vdd == 0 && vdd > 0) 671 sximmc_pwrseq_pre(sc->sc_pwrseq); 672 673 /* enable mmc power */ 674 if (sc->sc_vmmc && vdd > 0) 675 regulator_enable(sc->sc_vmmc); 676 677 if (sc->sc_vqmmc && vdd > 0) 678 regulator_enable(sc->sc_vqmmc); 679 680 delay(10000); 681 682 if (sc->sc_vdd == 0 && vdd > 0) 683 sximmc_pwrseq_post(sc->sc_pwrseq); 684 685 sc->sc_vdd = vdd; 686 return 0; 687 } 688 689 int 690 sximmc_update_clock(struct sximmc_softc *sc) 691 { 692 uint32_t cmd; 693 int retry; 694 695 #ifdef SXIMMC_DEBUG 696 printf("%s: update clock\n", sc->sc_dev.dv_xname); 697 #endif 698 699 cmd = SXIMMC_CMD_START | 700 SXIMMC_CMD_UPCLK_ONLY | 701 SXIMMC_CMD_WAIT_PRE_OVER; 702 MMC_WRITE(sc, SXIMMC_CMD, cmd); 703 retry = 0xfffff; 704 while (--retry > 0) { 705 if (!(MMC_READ(sc, SXIMMC_CMD) & SXIMMC_CMD_START)) 706 break; 707 delay(10); 708 } 709 710 if (retry == 0) { 711 printf("%s: timeout updating clock\n", sc->sc_dev.dv_xname); 712 #ifdef SXIMMC_DEBUG 713 printf("GCTRL: 0x%08x\n", MMC_READ(sc, SXIMMC_GCTRL)); 714 printf("CLKCR: 0x%08x\n", MMC_READ(sc, SXIMMC_CLKCR)); 715 printf("TIMEOUT: 0x%08x\n", MMC_READ(sc, SXIMMC_TIMEOUT)); 716 printf("WIDTH: 0x%08x\n", MMC_READ(sc, SXIMMC_WIDTH)); 717 printf("CMD: 0x%08x\n", MMC_READ(sc, SXIMMC_CMD)); 718 printf("MINT: 0x%08x\n", MMC_READ(sc, SXIMMC_MINT)); 719 printf("RINT: 0x%08x\n", MMC_READ(sc, SXIMMC_RINT)); 720 printf("STATUS: 0x%08x\n", MMC_READ(sc, SXIMMC_STATUS)); 721 #endif 722 return ETIMEDOUT; 723 } 724 725 return 0; 726 } 727 728 int 729 sximmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, int timing) 730 { 731 struct sximmc_softc *sc = sch; 732 uint32_t clkcr; 733 734 clkcr = MMC_READ(sc, SXIMMC_CLKCR); 735 if (clkcr & SXIMMC_CLKCR_CARDCLKON) { 736 clkcr &= ~SXIMMC_CLKCR_CARDCLKON; 737 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 738 if (sximmc_update_clock(sc) != 0) 739 return 1; 740 } 741 742 if (freq) { 743 clkcr &= ~SXIMMC_CLKCR_DIV; 744 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 745 if (sximmc_update_clock(sc) != 0) 746 return 1; 747 748 if (sximmc_set_clock(sc, freq) != 0) 749 return 1; 750 751 clkcr |= SXIMMC_CLKCR_CARDCLKON; 752 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 753 if (sximmc_update_clock(sc) != 0) 754 return 1; 755 } 756 757 return 0; 758 } 759 760 int 761 sximmc_bus_width(sdmmc_chipset_handle_t sch, int width) 762 { 763 struct sximmc_softc *sc = sch; 764 765 #ifdef SXIMMC_DEBUG 766 printf("%s: width = %d\n", sc->sc_dev.dv_xname, width); 767 #endif 768 769 switch (width) { 770 case 1: 771 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_1); 772 break; 773 case 4: 774 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_4); 775 break; 776 case 8: 777 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_8); 778 break; 779 default: 780 return 1; 781 } 782 783 return 0; 784 } 785 786 int 787 sximmc_pio_wait(struct sximmc_softc *sc, struct sdmmc_command *cmd) 788 { 789 int retry = 0xfffff; 790 uint32_t bit = (cmd->c_flags & SCF_CMD_READ) ? 791 SXIMMC_STATUS_FIFO_EMPTY : SXIMMC_STATUS_FIFO_FULL; 792 793 while (--retry > 0) { 794 uint32_t status = MMC_READ(sc, SXIMMC_STATUS); 795 if (!(status & bit)) 796 return 0; 797 delay(10); 798 } 799 800 return ETIMEDOUT; 801 } 802 803 int 804 sximmc_pio_transfer(struct sximmc_softc *sc, struct sdmmc_command *cmd) 805 { 806 u_char *datap = cmd->c_data; 807 int datalen = cmd->c_resid; 808 809 while (datalen > 3) { 810 if (sximmc_pio_wait(sc, cmd)) 811 return ETIMEDOUT; 812 if (cmd->c_flags & SCF_CMD_READ) { 813 *(uint32_t *)datap = MMC_READ(sc, sc->sc_fifo_reg); 814 } else { 815 MMC_WRITE(sc, sc->sc_fifo_reg, *(uint32_t *)datap); 816 } 817 datap += 4; 818 datalen -= 4; 819 } 820 821 if (datalen > 0 && cmd->c_flags & SCF_CMD_READ) { 822 uint32_t rv = MMC_READ(sc, sc->sc_fifo_reg); 823 do { 824 *datap++ = rv & 0xff; 825 rv = rv >> 8; 826 } while(--datalen > 0); 827 } else if (datalen > 0) { 828 uint32_t rv = *datap++; 829 if (datalen > 1) 830 rv |= *datap++ << 8; 831 if (datalen > 2) 832 rv |= *datap++ << 16; 833 MMC_WRITE(sc, sc->sc_fifo_reg, rv); 834 } 835 836 return 0; 837 } 838 839 int 840 sximmc_dma_prepare(struct sximmc_softc *sc, struct sdmmc_command *cmd) 841 { 842 struct sximmc_idma_descriptor *dma = (void *)sc->sc_idma_desc; 843 bus_addr_t desc_paddr = sc->sc_idma_map->dm_segs[0].ds_addr; 844 uint32_t val; 845 int seg; 846 847 if (sc->sc_idma_ndesc < cmd->c_dmamap->dm_nsegs) { 848 printf("%s: not enough descriptors for %d byte transfer!\n", 849 sc->sc_dev.dv_xname, cmd->c_datalen); 850 return EIO; 851 } 852 853 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 854 bus_addr_t paddr = cmd->c_dmamap->dm_segs[seg].ds_addr; 855 bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len; 856 dma[seg].dma_buf_size = htole32(len); 857 dma[seg].dma_buf_addr = htole32(paddr); 858 dma[seg].dma_config = htole32(SXIMMC_IDMA_CONFIG_CH | 859 SXIMMC_IDMA_CONFIG_OWN); 860 if (seg == 0) { 861 dma[seg].dma_config |= 862 htole32(SXIMMC_IDMA_CONFIG_FD); 863 } 864 if (seg == cmd->c_dmamap->dm_nsegs - 1) { 865 dma[seg].dma_config |= 866 htole32(SXIMMC_IDMA_CONFIG_LD); 867 dma[seg].dma_config |= 868 htole32(SXIMMC_IDMA_CONFIG_ER); 869 dma[seg].dma_next = 0; 870 } else { 871 dma[seg].dma_config |= 872 htole32(SXIMMC_IDMA_CONFIG_DIC); 873 dma[seg].dma_next = htole32( 874 desc_paddr + ((seg + 1) * 875 sizeof(struct sximmc_idma_descriptor))); 876 } 877 } 878 879 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 880 sc->sc_idma_size, BUS_DMASYNC_PREWRITE); 881 882 sc->sc_idma_idst = 0; 883 884 val = MMC_READ(sc, SXIMMC_GCTRL); 885 val |= SXIMMC_GCTRL_DMAEN; 886 val |= SXIMMC_GCTRL_INTEN; 887 MMC_WRITE(sc, SXIMMC_GCTRL, val); 888 val |= SXIMMC_GCTRL_DMARESET; 889 MMC_WRITE(sc, SXIMMC_GCTRL, val); 890 MMC_WRITE(sc, SXIMMC_DMAC, SXIMMC_DMAC_SOFTRESET); 891 MMC_WRITE(sc, SXIMMC_DMAC, 892 SXIMMC_DMAC_IDMA_ON|SXIMMC_DMAC_FIX_BURST); 893 val = MMC_READ(sc, SXIMMC_IDIE); 894 val &= ~(SXIMMC_IDST_RECEIVE_INT|SXIMMC_IDST_TRANSMIT_INT); 895 if (cmd->c_flags & SCF_CMD_READ) 896 val |= SXIMMC_IDST_RECEIVE_INT; 897 else 898 val |= SXIMMC_IDST_TRANSMIT_INT; 899 MMC_WRITE(sc, SXIMMC_IDIE, val); 900 MMC_WRITE(sc, SXIMMC_DLBA, desc_paddr); 901 MMC_WRITE(sc, SXIMMC_FTRGLEVEL, sc->sc_dma_ftrglevel); 902 903 return 0; 904 } 905 906 void 907 sximmc_dma_complete(struct sximmc_softc *sc) 908 { 909 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 910 sc->sc_idma_size, BUS_DMASYNC_POSTWRITE); 911 } 912 913 void 914 sximmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 915 { 916 struct sximmc_softc *sc = sch; 917 uint32_t cmdval = SXIMMC_CMD_START; 918 int retry; 919 int s; 920 921 #ifdef SXIMMC_DEBUG 922 printf("%s: opcode %d flags 0x%x data %p datalen %d blklen %d\n", 923 sc->sc_dev.dv_xname, cmd->c_opcode, cmd->c_flags, 924 cmd->c_data, cmd->c_datalen, cmd->c_blklen); 925 #endif 926 927 s = splbio(); 928 929 if (cmd->c_opcode == 0) 930 cmdval |= SXIMMC_CMD_SEND_INIT_SEQ; 931 if (cmd->c_flags & SCF_RSP_PRESENT) 932 cmdval |= SXIMMC_CMD_RSP_EXP; 933 if (cmd->c_flags & SCF_RSP_136) 934 cmdval |= SXIMMC_CMD_LONG_RSP; 935 if (cmd->c_flags & SCF_RSP_CRC) 936 cmdval |= SXIMMC_CMD_CHECK_RSP_CRC; 937 938 if (cmd->c_datalen > 0) { 939 uint16_t blksize; 940 uint16_t blkcount; 941 942 cmdval |= SXIMMC_CMD_DATA_EXP | SXIMMC_CMD_WAIT_PRE_OVER; 943 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) { 944 cmdval |= SXIMMC_CMD_WRITE; 945 } 946 947 blksize = MIN(cmd->c_datalen, cmd->c_blklen); 948 blkcount = cmd->c_datalen / blksize; 949 if (blkcount > 1 && cmd->c_opcode != SD_IO_RW_EXTENDED) { 950 cmdval |= SXIMMC_CMD_SEND_AUTO_STOP; 951 } 952 953 MMC_WRITE(sc, SXIMMC_BLKSZ, blksize); 954 MMC_WRITE(sc, SXIMMC_BYTECNT, blkcount * blksize); 955 } 956 957 sc->sc_intr_rint = 0; 958 959 #if 0 960 if (awin_chip_id() == AWIN_CHIP_ID_A80) { 961 MMC_WRITE(sc, SXIMMC_A12A, 962 (cmdval & SXIMMC_CMD_SEND_AUTO_STOP) ? 0 : 0xffff); 963 } 964 #endif 965 966 MMC_WRITE(sc, SXIMMC_ARG, cmd->c_arg); 967 968 #ifdef SXIMMC_DEBUG 969 printf("%s: cmdval = %08x\n", sc->sc_dev.dv_xname, cmdval); 970 #endif 971 972 if (cmd->c_datalen == 0) { 973 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 974 } else { 975 cmd->c_resid = cmd->c_datalen; 976 sximmc_led(sc, 0); 977 if (cmd->c_dmamap && sc->sc_use_dma) { 978 cmd->c_error = sximmc_dma_prepare(sc, cmd); 979 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 980 if (cmd->c_error == 0) { 981 cmd->c_error = tsleep_nsec(&sc->sc_idma_idst, 982 PWAIT, "idma", SEC_TO_NSEC(10)); 983 } 984 sximmc_dma_complete(sc); 985 if (sc->sc_idma_idst & SXIMMC_IDST_ERROR) { 986 cmd->c_error = EIO; 987 } else if (!(sc->sc_idma_idst & SXIMMC_IDST_COMPLETE)) { 988 cmd->c_error = ETIMEDOUT; 989 } 990 } else { 991 splx(s); 992 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 993 cmd->c_error = sximmc_pio_transfer(sc, cmd); 994 s = splbio(); 995 } 996 sximmc_led(sc, 1); 997 if (cmd->c_error) { 998 #ifdef SXIMMC_DEBUG 999 printf("%s: xfer failed, error %d\n", 1000 sc->sc_dev.dv_xname, cmd->c_error); 1001 #endif 1002 goto done; 1003 } 1004 } 1005 1006 cmd->c_error = sximmc_wait_rint(sc, 1007 SXIMMC_INT_ERROR|SXIMMC_INT_CMD_DONE, hz * 10); 1008 if (cmd->c_error == 0 && (sc->sc_intr_rint & SXIMMC_INT_ERROR)) { 1009 if (sc->sc_intr_rint & SXIMMC_INT_RESP_TIMEOUT) { 1010 cmd->c_error = ETIMEDOUT; 1011 } else { 1012 cmd->c_error = EIO; 1013 } 1014 } 1015 if (cmd->c_error) { 1016 #ifdef SXIMMC_DEBUG 1017 printf("%s: cmd failed, error %d\n", 1018 sc->sc_dev.dv_xname, cmd->c_error); 1019 #endif 1020 goto done; 1021 } 1022 1023 if (cmd->c_datalen > 0) { 1024 cmd->c_error = sximmc_wait_rint(sc, 1025 SXIMMC_INT_ERROR| 1026 SXIMMC_INT_AUTO_CMD_DONE| 1027 SXIMMC_INT_DATA_OVER, 1028 hz*10); 1029 if (cmd->c_error == 0 && 1030 (sc->sc_intr_rint & SXIMMC_INT_ERROR)) { 1031 cmd->c_error = ETIMEDOUT; 1032 } 1033 if (cmd->c_error) { 1034 #ifdef SXIMMC_DEBUG 1035 printf("%s: data timeout, rint = %08x\n", 1036 sc->sc_dev.dv_xname, sc->sc_intr_rint); 1037 #endif 1038 cmd->c_error = ETIMEDOUT; 1039 goto done; 1040 } 1041 } 1042 1043 if (cmd->c_flags & SCF_RSP_PRESENT) { 1044 if (cmd->c_flags & SCF_RSP_136) { 1045 cmd->c_resp[0] = MMC_READ(sc, SXIMMC_RESP0); 1046 cmd->c_resp[1] = MMC_READ(sc, SXIMMC_RESP1); 1047 cmd->c_resp[2] = MMC_READ(sc, SXIMMC_RESP2); 1048 cmd->c_resp[3] = MMC_READ(sc, SXIMMC_RESP3); 1049 if (cmd->c_flags & SCF_RSP_CRC) { 1050 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 1051 (cmd->c_resp[1] << 24); 1052 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 1053 (cmd->c_resp[2] << 24); 1054 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 1055 (cmd->c_resp[3] << 24); 1056 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 1057 } 1058 } else { 1059 cmd->c_resp[0] = MMC_READ(sc, SXIMMC_RESP0); 1060 } 1061 } 1062 1063 done: 1064 cmd->c_flags |= SCF_ITSDONE; 1065 splx(s); 1066 1067 if (cmd->c_error) { 1068 #ifdef SXIMMC_DEBUG 1069 printf("%s: i/o error %d\n", sc->sc_dev.dv_xname, 1070 cmd->c_error); 1071 #endif 1072 MMC_WRITE(sc, SXIMMC_GCTRL, 1073 MMC_READ(sc, SXIMMC_GCTRL) | 1074 SXIMMC_GCTRL_DMARESET | SXIMMC_GCTRL_FIFORESET); 1075 for (retry = 0; retry < 1000; retry++) { 1076 if (!(MMC_READ(sc, SXIMMC_GCTRL) & SXIMMC_GCTRL_RESET)) 1077 break; 1078 delay(10); 1079 } 1080 sximmc_host_reset(sc); 1081 sximmc_update_clock(sc); 1082 } 1083 1084 if (!cmd->c_dmamap || !sc->sc_use_dma) { 1085 MMC_WRITE(sc, SXIMMC_GCTRL, 1086 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_FIFORESET); 1087 } 1088 } 1089 1090 void 1091 sximmc_pwrseq_pre(uint32_t phandle) 1092 { 1093 uint32_t *gpios, *gpio; 1094 int node; 1095 int len; 1096 1097 node = OF_getnodebyphandle(phandle); 1098 if (node == 0) 1099 return; 1100 1101 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1102 return; 1103 1104 pinctrl_byname(node, "default"); 1105 1106 clock_enable(node, "ext_clock"); 1107 1108 len = OF_getproplen(node, "reset-gpios"); 1109 if (len <= 0) 1110 return; 1111 1112 gpios = malloc(len, M_TEMP, M_WAITOK); 1113 OF_getpropintarray(node, "reset-gpios", gpios, len); 1114 1115 gpio = gpios; 1116 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1117 gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT); 1118 gpio_controller_set_pin(gpio, 1); 1119 gpio = gpio_controller_next_pin(gpio); 1120 } 1121 1122 free(gpios, M_TEMP, len); 1123 } 1124 1125 void 1126 sximmc_pwrseq_post(uint32_t phandle) 1127 { 1128 uint32_t *gpios, *gpio; 1129 int node; 1130 int len; 1131 1132 node = OF_getnodebyphandle(phandle); 1133 if (node == 0) 1134 return; 1135 1136 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1137 return; 1138 1139 len = OF_getproplen(node, "reset-gpios"); 1140 if (len <= 0) 1141 return; 1142 1143 gpios = malloc(len, M_TEMP, M_WAITOK); 1144 OF_getpropintarray(node, "reset-gpios", gpios, len); 1145 1146 gpio = gpios; 1147 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1148 gpio_controller_set_pin(gpio, 0); 1149 gpio = gpio_controller_next_pin(gpio); 1150 } 1151 1152 free(gpios, M_TEMP, len); 1153 } 1154