1 /* $OpenBSD: sximmc.c,v 1.9 2019/02/10 11:56:26 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 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(&sc->sc_intr_rint, PWAIT, "rint", hz); 555 if (error && error != EWOULDBLOCK) 556 return error; 557 if (sc->sc_intr_rint & mask) 558 return 0; 559 } else { 560 sc->sc_intr_rint |= MMC_READ(sc, SXIMMC_RINT); 561 if (sc->sc_intr_rint & mask) 562 return 0; 563 delay(1000); 564 } 565 --retry; 566 } 567 568 return ETIMEDOUT; 569 } 570 571 void 572 sximmc_led(struct sximmc_softc *sc, int on) 573 { 574 } 575 576 int 577 sximmc_host_reset(sdmmc_chipset_handle_t sch) 578 { 579 struct sximmc_softc *sc = sch; 580 int retry = 1000; 581 582 #if 0 583 if (awin_chip_id() == AWIN_CHIP_ID_A80) { 584 if (sc->sc_mmc_port == 2 || sc->sc_mmc_port == 3) { 585 MMC_WRITE(sc, SXIMMC_HWRST, 0); 586 delay(10); 587 MMC_WRITE(sc, SXIMMC_HWRST, 1); 588 delay(300); 589 } 590 } 591 #endif 592 593 MMC_WRITE(sc, SXIMMC_GCTRL, 594 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_RESET); 595 while (--retry > 0) { 596 if (!(MMC_READ(sc, SXIMMC_GCTRL) & SXIMMC_GCTRL_RESET)) 597 break; 598 delay(100); 599 } 600 #ifdef SXIMMC_DEBUG 601 if (retry == 0) 602 printf("%s: host reset failed\n", sc->sc_dev.dv_xname); 603 else 604 printf("%s: host reset succeeded\n", sc->sc_dev.dv_xname); 605 #endif 606 607 /* Allow access to the FIFO by the CPU. */ 608 MMC_WRITE(sc, SXIMMC_GCTRL, 609 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_ACCESS_BY_AHB); 610 611 MMC_WRITE(sc, SXIMMC_TIMEOUT, 0xffffffff); 612 613 MMC_WRITE(sc, SXIMMC_IMASK, 614 SXIMMC_INT_CMD_DONE | SXIMMC_INT_ERROR | 615 SXIMMC_INT_DATA_OVER | SXIMMC_INT_AUTO_CMD_DONE); 616 617 MMC_WRITE(sc, SXIMMC_GCTRL, 618 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_INTEN); 619 620 return 0; 621 } 622 623 uint32_t 624 sximmc_host_ocr(sdmmc_chipset_handle_t sch) 625 { 626 #if 0 627 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V | MMC_OCR_HCS; 628 #else 629 return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V; 630 #endif 631 } 632 633 int 634 sximmc_host_maxblklen(sdmmc_chipset_handle_t sch) 635 { 636 #if 0 637 return 8192; 638 #else 639 return 512; 640 #endif 641 } 642 643 int 644 sximmc_card_detect(sdmmc_chipset_handle_t sch) 645 { 646 struct sximmc_softc *sc = sch; 647 int inverted, val; 648 649 /* XXX treat broken-cd as non-removable */ 650 if (OF_getproplen(sc->sc_node, "non-removable") == 0 || 651 OF_getproplen(sc->sc_node, "broken-cd") == 0) 652 return 1; 653 654 val = gpio_controller_get_pin(sc->sc_gpio); 655 656 inverted = (OF_getproplen(sc->sc_node, "cd-inverted") == 0); 657 return inverted ? !val : val; 658 } 659 660 int 661 sximmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 662 { 663 struct sximmc_softc *sc = sch; 664 uint32_t vdd = 0; 665 666 if (ISSET(ocr, MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) 667 vdd = 3300000; 668 669 if (sc->sc_vdd == 0 && vdd > 0) 670 sximmc_pwrseq_pre(sc->sc_pwrseq); 671 672 /* enable mmc power */ 673 if (sc->sc_vmmc && vdd > 0) 674 regulator_enable(sc->sc_vmmc); 675 676 if (sc->sc_vqmmc && vdd > 0) 677 regulator_enable(sc->sc_vqmmc); 678 679 delay(10000); 680 681 if (sc->sc_vdd == 0 && vdd > 0) 682 sximmc_pwrseq_post(sc->sc_pwrseq); 683 684 sc->sc_vdd = vdd; 685 return 0; 686 } 687 688 int 689 sximmc_update_clock(struct sximmc_softc *sc) 690 { 691 uint32_t cmd; 692 int retry; 693 694 #ifdef SXIMMC_DEBUG 695 printf("%s: update clock\n", sc->sc_dev.dv_xname); 696 #endif 697 698 cmd = SXIMMC_CMD_START | 699 SXIMMC_CMD_UPCLK_ONLY | 700 SXIMMC_CMD_WAIT_PRE_OVER; 701 MMC_WRITE(sc, SXIMMC_CMD, cmd); 702 retry = 0xfffff; 703 while (--retry > 0) { 704 if (!(MMC_READ(sc, SXIMMC_CMD) & SXIMMC_CMD_START)) 705 break; 706 delay(10); 707 } 708 709 if (retry == 0) { 710 printf("%s: timeout updating clock\n", sc->sc_dev.dv_xname); 711 #ifdef SXIMMC_DEBUG 712 printf("GCTRL: 0x%08x\n", MMC_READ(sc, SXIMMC_GCTRL)); 713 printf("CLKCR: 0x%08x\n", MMC_READ(sc, SXIMMC_CLKCR)); 714 printf("TIMEOUT: 0x%08x\n", MMC_READ(sc, SXIMMC_TIMEOUT)); 715 printf("WIDTH: 0x%08x\n", MMC_READ(sc, SXIMMC_WIDTH)); 716 printf("CMD: 0x%08x\n", MMC_READ(sc, SXIMMC_CMD)); 717 printf("MINT: 0x%08x\n", MMC_READ(sc, SXIMMC_MINT)); 718 printf("RINT: 0x%08x\n", MMC_READ(sc, SXIMMC_RINT)); 719 printf("STATUS: 0x%08x\n", MMC_READ(sc, SXIMMC_STATUS)); 720 #endif 721 return ETIMEDOUT; 722 } 723 724 return 0; 725 } 726 727 int 728 sximmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, int timing) 729 { 730 struct sximmc_softc *sc = sch; 731 uint32_t clkcr; 732 733 clkcr = MMC_READ(sc, SXIMMC_CLKCR); 734 if (clkcr & SXIMMC_CLKCR_CARDCLKON) { 735 clkcr &= ~SXIMMC_CLKCR_CARDCLKON; 736 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 737 if (sximmc_update_clock(sc) != 0) 738 return 1; 739 } 740 741 if (freq) { 742 clkcr &= ~SXIMMC_CLKCR_DIV; 743 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 744 if (sximmc_update_clock(sc) != 0) 745 return 1; 746 747 if (sximmc_set_clock(sc, freq) != 0) 748 return 1; 749 750 clkcr |= SXIMMC_CLKCR_CARDCLKON; 751 MMC_WRITE(sc, SXIMMC_CLKCR, clkcr); 752 if (sximmc_update_clock(sc) != 0) 753 return 1; 754 } 755 756 return 0; 757 } 758 759 int 760 sximmc_bus_width(sdmmc_chipset_handle_t sch, int width) 761 { 762 struct sximmc_softc *sc = sch; 763 764 #ifdef SXIMMC_DEBUG 765 printf("%s: width = %d\n", sc->sc_dev.dv_xname, width); 766 #endif 767 768 switch (width) { 769 case 1: 770 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_1); 771 break; 772 case 4: 773 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_4); 774 break; 775 case 8: 776 MMC_WRITE(sc, SXIMMC_WIDTH, SXIMMC_WIDTH_8); 777 break; 778 default: 779 return 1; 780 } 781 782 return 0; 783 } 784 785 int 786 sximmc_pio_wait(struct sximmc_softc *sc, struct sdmmc_command *cmd) 787 { 788 int retry = 0xfffff; 789 uint32_t bit = (cmd->c_flags & SCF_CMD_READ) ? 790 SXIMMC_STATUS_FIFO_EMPTY : SXIMMC_STATUS_FIFO_FULL; 791 792 while (--retry > 0) { 793 uint32_t status = MMC_READ(sc, SXIMMC_STATUS); 794 if (!(status & bit)) 795 return 0; 796 delay(10); 797 } 798 799 return ETIMEDOUT; 800 } 801 802 int 803 sximmc_pio_transfer(struct sximmc_softc *sc, struct sdmmc_command *cmd) 804 { 805 u_char *datap = cmd->c_data; 806 int datalen = cmd->c_resid; 807 808 while (datalen > 3) { 809 if (sximmc_pio_wait(sc, cmd)) 810 return ETIMEDOUT; 811 if (cmd->c_flags & SCF_CMD_READ) { 812 *(uint32_t *)datap = MMC_READ(sc, sc->sc_fifo_reg); 813 } else { 814 MMC_WRITE(sc, sc->sc_fifo_reg, *(uint32_t *)datap); 815 } 816 datap += 4; 817 datalen -= 4; 818 } 819 820 if (datalen > 0 && cmd->c_flags & SCF_CMD_READ) { 821 uint32_t rv = MMC_READ(sc, sc->sc_fifo_reg); 822 do { 823 *datap++ = rv & 0xff; 824 rv = rv >> 8; 825 } while(--datalen > 0); 826 } else if (datalen > 0) { 827 uint32_t rv = *datap++; 828 if (datalen > 1) 829 rv |= *datap++ << 8; 830 if (datalen > 2) 831 rv |= *datap++ << 16; 832 MMC_WRITE(sc, sc->sc_fifo_reg, rv); 833 } 834 835 return 0; 836 } 837 838 int 839 sximmc_dma_prepare(struct sximmc_softc *sc, struct sdmmc_command *cmd) 840 { 841 struct sximmc_idma_descriptor *dma = (void *)sc->sc_idma_desc; 842 bus_addr_t desc_paddr = sc->sc_idma_map->dm_segs[0].ds_addr; 843 uint32_t val; 844 int seg; 845 846 if (sc->sc_idma_ndesc < cmd->c_dmamap->dm_nsegs) { 847 printf("%s: not enough descriptors for %d byte transfer!\n", 848 sc->sc_dev.dv_xname, cmd->c_datalen); 849 return EIO; 850 } 851 852 for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) { 853 bus_addr_t paddr = cmd->c_dmamap->dm_segs[seg].ds_addr; 854 bus_size_t len = cmd->c_dmamap->dm_segs[seg].ds_len; 855 dma[seg].dma_buf_size = htole32(len); 856 dma[seg].dma_buf_addr = htole32(paddr); 857 dma[seg].dma_config = htole32(SXIMMC_IDMA_CONFIG_CH | 858 SXIMMC_IDMA_CONFIG_OWN); 859 if (seg == 0) { 860 dma[seg].dma_config |= 861 htole32(SXIMMC_IDMA_CONFIG_FD); 862 } 863 if (seg == cmd->c_dmamap->dm_nsegs - 1) { 864 dma[seg].dma_config |= 865 htole32(SXIMMC_IDMA_CONFIG_LD); 866 dma[seg].dma_config |= 867 htole32(SXIMMC_IDMA_CONFIG_ER); 868 dma[seg].dma_next = 0; 869 } else { 870 dma[seg].dma_config |= 871 htole32(SXIMMC_IDMA_CONFIG_DIC); 872 dma[seg].dma_next = htole32( 873 desc_paddr + ((seg + 1) * 874 sizeof(struct sximmc_idma_descriptor))); 875 } 876 } 877 878 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 879 sc->sc_idma_size, BUS_DMASYNC_PREWRITE); 880 881 sc->sc_idma_idst = 0; 882 883 val = MMC_READ(sc, SXIMMC_GCTRL); 884 val |= SXIMMC_GCTRL_DMAEN; 885 val |= SXIMMC_GCTRL_INTEN; 886 MMC_WRITE(sc, SXIMMC_GCTRL, val); 887 val |= SXIMMC_GCTRL_DMARESET; 888 MMC_WRITE(sc, SXIMMC_GCTRL, val); 889 MMC_WRITE(sc, SXIMMC_DMAC, SXIMMC_DMAC_SOFTRESET); 890 MMC_WRITE(sc, SXIMMC_DMAC, 891 SXIMMC_DMAC_IDMA_ON|SXIMMC_DMAC_FIX_BURST); 892 val = MMC_READ(sc, SXIMMC_IDIE); 893 val &= ~(SXIMMC_IDST_RECEIVE_INT|SXIMMC_IDST_TRANSMIT_INT); 894 if (cmd->c_flags & SCF_CMD_READ) 895 val |= SXIMMC_IDST_RECEIVE_INT; 896 else 897 val |= SXIMMC_IDST_TRANSMIT_INT; 898 MMC_WRITE(sc, SXIMMC_IDIE, val); 899 MMC_WRITE(sc, SXIMMC_DLBA, desc_paddr); 900 MMC_WRITE(sc, SXIMMC_FTRGLEVEL, sc->sc_dma_ftrglevel); 901 902 return 0; 903 } 904 905 void 906 sximmc_dma_complete(struct sximmc_softc *sc) 907 { 908 bus_dmamap_sync(sc->sc_dmat, sc->sc_idma_map, 0, 909 sc->sc_idma_size, BUS_DMASYNC_POSTWRITE); 910 } 911 912 void 913 sximmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) 914 { 915 struct sximmc_softc *sc = sch; 916 uint32_t cmdval = SXIMMC_CMD_START; 917 int retry; 918 int s; 919 920 #ifdef SXIMMC_DEBUG 921 printf("%s: opcode %d flags 0x%x data %p datalen %d blklen %d\n", 922 sc->sc_dev.dv_xname, cmd->c_opcode, cmd->c_flags, 923 cmd->c_data, cmd->c_datalen, cmd->c_blklen); 924 #endif 925 926 s = splbio(); 927 928 if (cmd->c_opcode == 0) 929 cmdval |= SXIMMC_CMD_SEND_INIT_SEQ; 930 if (cmd->c_flags & SCF_RSP_PRESENT) 931 cmdval |= SXIMMC_CMD_RSP_EXP; 932 if (cmd->c_flags & SCF_RSP_136) 933 cmdval |= SXIMMC_CMD_LONG_RSP; 934 if (cmd->c_flags & SCF_RSP_CRC) 935 cmdval |= SXIMMC_CMD_CHECK_RSP_CRC; 936 937 if (cmd->c_datalen > 0) { 938 uint16_t blksize; 939 uint16_t blkcount; 940 941 cmdval |= SXIMMC_CMD_DATA_EXP | SXIMMC_CMD_WAIT_PRE_OVER; 942 if (!ISSET(cmd->c_flags, SCF_CMD_READ)) { 943 cmdval |= SXIMMC_CMD_WRITE; 944 } 945 946 blksize = MIN(cmd->c_datalen, cmd->c_blklen); 947 blkcount = cmd->c_datalen / blksize; 948 if (blkcount > 1 && cmd->c_opcode != SD_IO_RW_EXTENDED) { 949 cmdval |= SXIMMC_CMD_SEND_AUTO_STOP; 950 } 951 952 MMC_WRITE(sc, SXIMMC_BLKSZ, blksize); 953 MMC_WRITE(sc, SXIMMC_BYTECNT, blkcount * blksize); 954 } 955 956 sc->sc_intr_rint = 0; 957 958 #if 0 959 if (awin_chip_id() == AWIN_CHIP_ID_A80) { 960 MMC_WRITE(sc, SXIMMC_A12A, 961 (cmdval & SXIMMC_CMD_SEND_AUTO_STOP) ? 0 : 0xffff); 962 } 963 #endif 964 965 MMC_WRITE(sc, SXIMMC_ARG, cmd->c_arg); 966 967 #ifdef SXIMMC_DEBUG 968 printf("%s: cmdval = %08x\n", sc->sc_dev.dv_xname, cmdval); 969 #endif 970 971 if (cmd->c_datalen == 0) { 972 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 973 } else { 974 cmd->c_resid = cmd->c_datalen; 975 sximmc_led(sc, 0); 976 if (cmd->c_dmamap && sc->sc_use_dma) { 977 cmd->c_error = sximmc_dma_prepare(sc, cmd); 978 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 979 if (cmd->c_error == 0) { 980 cmd->c_error = tsleep(&sc->sc_idma_idst, 981 PWAIT, "idma", hz*10); 982 } 983 sximmc_dma_complete(sc); 984 if (sc->sc_idma_idst & SXIMMC_IDST_ERROR) { 985 cmd->c_error = EIO; 986 } else if (!(sc->sc_idma_idst & SXIMMC_IDST_COMPLETE)) { 987 cmd->c_error = ETIMEDOUT; 988 } 989 } else { 990 splx(s); 991 MMC_WRITE(sc, SXIMMC_CMD, cmdval | cmd->c_opcode); 992 cmd->c_error = sximmc_pio_transfer(sc, cmd); 993 s = splbio(); 994 } 995 sximmc_led(sc, 1); 996 if (cmd->c_error) { 997 #ifdef SXIMMC_DEBUG 998 printf("%s: xfer failed, error %d\n", 999 sc->sc_dev.dv_xname, cmd->c_error); 1000 #endif 1001 goto done; 1002 } 1003 } 1004 1005 cmd->c_error = sximmc_wait_rint(sc, 1006 SXIMMC_INT_ERROR|SXIMMC_INT_CMD_DONE, hz * 10); 1007 if (cmd->c_error == 0 && (sc->sc_intr_rint & SXIMMC_INT_ERROR)) { 1008 if (sc->sc_intr_rint & SXIMMC_INT_RESP_TIMEOUT) { 1009 cmd->c_error = ETIMEDOUT; 1010 } else { 1011 cmd->c_error = EIO; 1012 } 1013 } 1014 if (cmd->c_error) { 1015 #ifdef SXIMMC_DEBUG 1016 printf("%s: cmd failed, error %d\n", 1017 sc->sc_dev.dv_xname, cmd->c_error); 1018 #endif 1019 goto done; 1020 } 1021 1022 if (cmd->c_datalen > 0) { 1023 cmd->c_error = sximmc_wait_rint(sc, 1024 SXIMMC_INT_ERROR| 1025 SXIMMC_INT_AUTO_CMD_DONE| 1026 SXIMMC_INT_DATA_OVER, 1027 hz*10); 1028 if (cmd->c_error == 0 && 1029 (sc->sc_intr_rint & SXIMMC_INT_ERROR)) { 1030 cmd->c_error = ETIMEDOUT; 1031 } 1032 if (cmd->c_error) { 1033 #ifdef SXIMMC_DEBUG 1034 printf("%s: data timeout, rint = %08x\n", 1035 sc->sc_dev.dv_xname, sc->sc_intr_rint); 1036 #endif 1037 cmd->c_error = ETIMEDOUT; 1038 goto done; 1039 } 1040 } 1041 1042 if (cmd->c_flags & SCF_RSP_PRESENT) { 1043 if (cmd->c_flags & SCF_RSP_136) { 1044 cmd->c_resp[0] = MMC_READ(sc, SXIMMC_RESP0); 1045 cmd->c_resp[1] = MMC_READ(sc, SXIMMC_RESP1); 1046 cmd->c_resp[2] = MMC_READ(sc, SXIMMC_RESP2); 1047 cmd->c_resp[3] = MMC_READ(sc, SXIMMC_RESP3); 1048 if (cmd->c_flags & SCF_RSP_CRC) { 1049 cmd->c_resp[0] = (cmd->c_resp[0] >> 8) | 1050 (cmd->c_resp[1] << 24); 1051 cmd->c_resp[1] = (cmd->c_resp[1] >> 8) | 1052 (cmd->c_resp[2] << 24); 1053 cmd->c_resp[2] = (cmd->c_resp[2] >> 8) | 1054 (cmd->c_resp[3] << 24); 1055 cmd->c_resp[3] = (cmd->c_resp[3] >> 8); 1056 } 1057 } else { 1058 cmd->c_resp[0] = MMC_READ(sc, SXIMMC_RESP0); 1059 } 1060 } 1061 1062 done: 1063 cmd->c_flags |= SCF_ITSDONE; 1064 splx(s); 1065 1066 if (cmd->c_error) { 1067 #ifdef SXIMMC_DEBUG 1068 printf("%s: i/o error %d\n", sc->sc_dev.dv_xname, 1069 cmd->c_error); 1070 #endif 1071 MMC_WRITE(sc, SXIMMC_GCTRL, 1072 MMC_READ(sc, SXIMMC_GCTRL) | 1073 SXIMMC_GCTRL_DMARESET | SXIMMC_GCTRL_FIFORESET); 1074 for (retry = 0; retry < 1000; retry++) { 1075 if (!(MMC_READ(sc, SXIMMC_GCTRL) & SXIMMC_GCTRL_RESET)) 1076 break; 1077 delay(10); 1078 } 1079 sximmc_host_reset(sc); 1080 sximmc_update_clock(sc); 1081 } 1082 1083 if (!cmd->c_dmamap || !sc->sc_use_dma) { 1084 MMC_WRITE(sc, SXIMMC_GCTRL, 1085 MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_FIFORESET); 1086 } 1087 } 1088 1089 void 1090 sximmc_pwrseq_pre(uint32_t phandle) 1091 { 1092 uint32_t *gpios, *gpio; 1093 int node; 1094 int len; 1095 1096 node = OF_getnodebyphandle(phandle); 1097 if (node == 0) 1098 return; 1099 1100 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1101 return; 1102 1103 pinctrl_byname(node, "default"); 1104 1105 clock_enable(node, "ext_clock"); 1106 1107 len = OF_getproplen(node, "reset-gpios"); 1108 if (len <= 0) 1109 return; 1110 1111 gpios = malloc(len, M_TEMP, M_WAITOK); 1112 OF_getpropintarray(node, "reset-gpios", gpios, len); 1113 1114 gpio = gpios; 1115 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1116 gpio_controller_config_pin(gpio, GPIO_CONFIG_OUTPUT); 1117 gpio_controller_set_pin(gpio, 1); 1118 gpio = gpio_controller_next_pin(gpio); 1119 } 1120 1121 free(gpios, M_TEMP, len); 1122 } 1123 1124 void 1125 sximmc_pwrseq_post(uint32_t phandle) 1126 { 1127 uint32_t *gpios, *gpio; 1128 int node; 1129 int len; 1130 1131 node = OF_getnodebyphandle(phandle); 1132 if (node == 0) 1133 return; 1134 1135 if (!OF_is_compatible(node, "mmc-pwrseq-simple")) 1136 return; 1137 1138 len = OF_getproplen(node, "reset-gpios"); 1139 if (len <= 0) 1140 return; 1141 1142 gpios = malloc(len, M_TEMP, M_WAITOK); 1143 OF_getpropintarray(node, "reset-gpios", gpios, len); 1144 1145 gpio = gpios; 1146 while (gpio && gpio < gpios + (len / sizeof(uint32_t))) { 1147 gpio_controller_set_pin(gpio, 0); 1148 gpio = gpio_controller_next_pin(gpio); 1149 } 1150 1151 free(gpios, M_TEMP, len); 1152 } 1153