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