Home | History | Annotate | Line # | Download | only in ti
      1 /* $NetBSD: am18xx_sdmmc.c,v 1.1 2026/08/19 09:28:39 yurix Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2026 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Yuri Honegger.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Driver for the sd card port on the TI AM18XX.
     34  */
     35 
     36 #include <sys/param.h>
     37 #include <sys/bus.h>
     38 #include <sys/cdefs.h>
     39 #include <sys/device.h>
     40 #include <sys/mutex.h>
     41 
     42 #include <dev/fdt/fdtvar.h>
     43 #include <dev/sdmmc/sdmmcchip.h>
     44 #include <dev/sdmmc/sdmmcreg.h>
     45 #include <dev/sdmmc/sdmmcvar.h>
     46 
     47 struct am18xx_sdmmc_softc {
     48 	/* bus_space io */
     49 	bus_space_tag_t sc_bst;
     50 	bus_space_handle_t sc_bsh;
     51 
     52 	device_t sc_dev;
     53 	device_t sc_sdmmc;
     54 
     55 	/* driver internals */
     56 	kmutex_t sc_lock;
     57 	kcondvar_t sc_intr_cv;
     58 	struct sdmmc_command *sc_cmd;
     59 	struct clk *sc_clk;
     60 
     61 	/* edma */
     62 	bus_addr_t sc_phys_base_addr;
     63 	struct fdtbus_dma *sc_rx_dma;
     64 	struct fdtbus_dma *sc_tx_dma;
     65 	struct fdtbus_dma_req sc_dma_req;
     66 
     67 	/* status flags */
     68 	bool sc_irq_wait;
     69 	bool sc_command_done;
     70 	bool sc_transfer_done;
     71 	bool sc_dma_done;
     72 	bool sc_opendrain;
     73 	bool sc_firstcmd;
     74 	bool sc_use_dma;
     75 	bool sc_have_dma;
     76 };
     77 
     78 static int	am18xx_sdmmc_match(device_t, cfdata_t, void *);
     79 static void	am18xx_sdmmc_attach(device_t, device_t, void *);
     80 static void	am18xx_sdmmc_init(struct am18xx_sdmmc_softc *);
     81 static int	am18xx_sdmmc_host_reset(sdmmc_chipset_handle_t);
     82 static uint32_t	am18xx_sdmmc_host_ocr(sdmmc_chipset_handle_t);
     83 static int	am18xx_sdmmc_host_maxblklen(sdmmc_chipset_handle_t);
     84 static int	am18xx_sdmmc_card_detect(sdmmc_chipset_handle_t);
     85 static int	am18xx_sdmmc_write_protect(sdmmc_chipset_handle_t);
     86 static int	am18xx_sdmmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
     87 static int	am18xx_sdmmc_bus_clock(sdmmc_chipset_handle_t, int);
     88 static int	am18xx_sdmmc_bus_width(sdmmc_chipset_handle_t, int);
     89 static int	am18xx_sdmmc_bus_rod(sdmmc_chipset_handle_t, int);
     90 static void	am18xx_sdmmc_exec_command(sdmmc_chipset_handle_t,
     91     struct sdmmc_command *);
     92 static int 	am18xx_sdmmc_initiate_command(struct am18xx_sdmmc_softc *,
     93     struct sdmmc_command *);
     94 static void	am18xx_sdmmc_check_completion(struct am18xx_sdmmc_softc *,
     95     bool);
     96 static void	am18xx_sdmmc_card_enable_intr(sdmmc_chipset_handle_t, int);
     97 static void	am18xx_sdmmc_card_intr_ack(sdmmc_chipset_handle_t);
     98 static void	am18xx_sdmmc_cpu_data_transfer(struct am18xx_sdmmc_softc *sc);
     99 static int	am18xx_sdmmc_intr(void *);
    100 static void	am18xx_sdmmc_dma_callback(void *priv);
    101 
    102 #define	SDMMC_READ(sc, reg)					\
    103 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, reg)
    104 #define	SDMMC_WRITE(sc, reg, val)				\
    105 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, reg, val)
    106 
    107 #define AM18XX_SDMMC_MMCCTL	0x0
    108 #define AM18XX_SDMMC_MMCCLK	0x4
    109 #define AM18XX_SDMMC_MMCST0	0x8
    110 #define AM18XX_SDMMC_MMCST1	0xC
    111 #define AM18XX_SDMMC_MMCIM	0x10
    112 #define AM18XX_SDMMC_MMCTOR	0x14
    113 #define AM18XX_SDMMC_MMCTOD	0x18
    114 #define AM18XX_SDMMC_MMCBLEN	0x1C
    115 #define AM18XX_SDMMC_MMCNBLK	0x20
    116 #define AM18XX_SDMMC_MMCDRR	0x28
    117 #define AM18XX_SDMMC_MMCDXR	0x2C
    118 #define AM18XX_SDMMC_MMCCMD	0x30
    119 #define AM18XX_SDMMC_MMCARGHL	0x34
    120 #define AM18XX_SDMMC_MMCRSP01	0x38
    121 #define AM18XX_SDMMC_MMCRSP23	0x3C
    122 #define AM18XX_SDMMC_MMCRSP45	0x40
    123 #define AM18XX_SDMMC_MMCRSP67	0x44
    124 #define AM18XX_SDMMC_FIFOCTL	0x74
    125 
    126 #define AM18XX_SDMMC_MMCCTL_DATARST	__BIT(0)
    127 #define AM18XX_SDMMC_MMCCTL_CMDRST	__BIT(1)
    128 #define AM18XX_SDMMC_MMCCTL_WIDTH0	__BIT(2)
    129 #define AM18XX_SDMMC_MMCCTL_DATEG	__BITS(7,6)
    130 #define AM18XX_SDMMC_MMCCTL_WIDTH1	__BIT(8)
    131 #define AM18XX_SDMMC_MMCCTL_PERMDR	__BIT(9)
    132 #define AM18XX_SDMMC_MMCCTL_PERMDX	__BIT(10)
    133 
    134 #define AM18XX_SDMMC_MMCCLK_CLKRT	__BITS(7,0)
    135 #define AM18XX_SDMMC_MMCCLK_CLKEN	__BIT(8)
    136 #define AM18XX_SDMMC_MMCCLK_DIV4	__BIT(9)
    137 
    138 #define AM18XX_SDMMC_MMCST0_DATDNE	__BIT(0)
    139 #define AM18XX_SDMMC_MMCST0_BSYDNE	__BIT(1)
    140 #define AM18XX_SDMMC_MMCST0_RSPDNE	__BIT(2)
    141 #define AM18XX_SDMMC_MMCST0_TOUTRD	__BIT(3)
    142 #define AM18XX_SDMMC_MMCST0_TOUTRS	__BIT(4)
    143 #define AM18XX_SDMMC_MMCST0_CRCWR	__BIT(5)
    144 #define AM18XX_SDMMC_MMCST0_CRCRD	__BIT(6)
    145 #define AM18XX_SDMMC_MMCST0_CRCRS	__BIT(7)
    146 #define AM18XX_SDMMC_MMCST0_DXRDY	__BIT(9)
    147 #define AM18XX_SDMMC_MMCST0_DRRDY	__BIT(10)
    148 #define AM18XX_SDMMC_MMCST0_TRNDNE	__BIT(12)
    149 
    150 #define AM18XX_SDMMC_MMCST0_ERRMASK	(AM18XX_SDMMC_MMCST0_TOUTRD | \
    151 					 AM18XX_SDMMC_MMCST0_TOUTRS | \
    152 					 AM18XX_SDMMC_MMCST0_CRCWR  | \
    153 					 AM18XX_SDMMC_MMCST0_CRCRD  | \
    154 					 AM18XX_SDMMC_MMCST0_CRCRS)
    155 
    156 #define AM18XX_SDMMC_MMCST1_BUSY	__BIT(0)
    157 
    158 #define AM18XX_SDMMC_MMCIM_EDATDNE	__BIT(0)
    159 #define AM18XX_SDMMC_MMCIM_ERSPDNE	__BIT(2)
    160 #define AM18XX_SDMMC_MMCIM_ETOUTRD	__BIT(3)
    161 #define AM18XX_SDMMC_MMCIM_ETOUTRS	__BIT(4)
    162 #define AM18XX_SDMMC_MMCIM_ECRCWR	__BIT(5)
    163 #define AM18XX_SDMMC_MMCIM_ECRCRD	__BIT(6)
    164 #define AM18XX_SDMMC_MMCIM_ECRCRS	__BIT(7)
    165 #define AM18XX_SDMMC_MMCIM_EDXRDY	__BIT(9)
    166 #define AM18XX_SDMMC_MMCIM_EDRRDY	__BIT(10)
    167 
    168 #define AM18XX_SDMMC_MMCCMD_CMD		__BITS(5,0)
    169 #define AM18XX_SDMMC_MMCCMD_PPLEN	__BIT(7)
    170 #define AM18XX_SDMMC_MMCCMD_BSYEXP	__BIT(8)
    171 #define AM18XX_SDMMC_MMCCMD_RSPFMT	__BITS(10,9)
    172 #define AM18XX_SDMMC_MMCCMD_DTRW	__BIT(11)
    173 #define AM18XX_SDMMC_MMCCMD_WDATX	__BIT(13)
    174 #define AM18XX_SDMMC_MMCCMD_INITCK	__BIT(14)
    175 #define AM18XX_SDMMC_MMCCMD_DMATRIG	__BIT(16)
    176 
    177 #define AM18XX_SDMMC_MMCCMD_RSPFMT_R0		0
    178 #define AM18XX_SDMMC_MMCCMD_RSPFMT_R1456	1
    179 #define AM18XX_SDMMC_MMCCMD_RSPFMT_R2		2
    180 #define AM18XX_SDMMC_MMCCMD_RSPFMT_R3		3
    181 
    182 #define AM18XX_SDMMC_FIFOCTL_FIFORST	__BIT(0)
    183 #define AM18XX_SDMMC_FIFOCTL_FIFODIRW	__BIT(1)
    184 #define AM18XX_SDMMC_FIFOCTL_FIFOLEV64 	__BIT(2)
    185 
    186 #define AM18XX_SDMMC_MAX_CLOCK_DIVIDER (2 * (0xFF + 1))
    187 #define AM18XX_SDMMC_MIN_CLOCK_DIVIDER (2 * (0x00 + 1))
    188 
    189 CFATTACH_DECL_NEW(am18xxsdmmc, sizeof(struct am18xx_sdmmc_softc),
    190     am18xx_sdmmc_match, am18xx_sdmmc_attach, NULL, NULL);
    191 
    192 static const struct device_compatible_entry compat_data[] = {
    193 	{.compat = "ti,da830-mmc"}, DEVICE_COMPAT_EOL};
    194 
    195 static struct sdmmc_chip_functions am18xx_sdmmc_functions = {
    196 	.host_reset	= am18xx_sdmmc_host_reset,
    197 	.host_ocr	= am18xx_sdmmc_host_ocr,
    198 	.host_maxblklen	= am18xx_sdmmc_host_maxblklen,
    199 	.card_detect	= am18xx_sdmmc_card_detect,
    200 	.write_protect	= am18xx_sdmmc_write_protect,
    201 	.bus_power	= am18xx_sdmmc_bus_power,
    202 	.bus_clock	= am18xx_sdmmc_bus_clock,
    203 	.bus_width	= am18xx_sdmmc_bus_width,
    204 	.bus_rod	= am18xx_sdmmc_bus_rod,
    205 	.exec_command	= am18xx_sdmmc_exec_command,
    206 	.card_enable_intr = am18xx_sdmmc_card_enable_intr,
    207 	.card_intr_ack	= am18xx_sdmmc_card_intr_ack
    208 };
    209 
    210 static int
    211 am18xx_sdmmc_host_reset(sdmmc_chipset_handle_t sch)
    212 {
    213 	struct am18xx_sdmmc_softc *sc = sch;
    214 
    215 	am18xx_sdmmc_init(sc);
    216 
    217 	return 0;
    218 }
    219 
    220 static uint32_t
    221 am18xx_sdmmc_host_ocr(sdmmc_chipset_handle_t sch)
    222 {
    223 	return MMC_OCR_3_2V_3_3V;
    224 }
    225 
    226 static int
    227 am18xx_sdmmc_host_maxblklen(sdmmc_chipset_handle_t sch)
    228 {
    229 	return 2048;
    230 }
    231 
    232 static int
    233 am18xx_sdmmc_card_detect(sdmmc_chipset_handle_t sch)
    234 {
    235 	return 1;
    236 }
    237 
    238 static int
    239 am18xx_sdmmc_write_protect(sdmmc_chipset_handle_t sch)
    240 {
    241 	return 0;
    242 }
    243 
    244 static int
    245 am18xx_sdmmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
    246 {
    247 	/* do nothing */
    248 	return 0;
    249 }
    250 
    251 static int
    252 am18xx_sdmmc_bus_clock(sdmmc_chipset_handle_t sch, int clock)
    253 {
    254 	struct am18xx_sdmmc_softc *sc = sch;
    255 
    256 	if (clock > 0) {
    257 		int ref_clk = clk_get_rate(sc->sc_clk);
    258 
    259 		/* calculate divider */
    260 		int divider = (ref_clk / (2 * 1000 * clock)) - 1;
    261 		if (divider < 0) {
    262 			divider = 0;
    263 		}
    264 
    265 		/* round divider */
    266 		int effective_rate = ref_clk / (2 * (divider + 1));
    267 		if (effective_rate > clock * 1000) {
    268 			divider++;
    269 		}
    270 		if (divider > 255) {
    271 			divider = 255;
    272 		}
    273 
    274 		device_printf(sc->sc_dev, "requested %d Hz, using %d Hz\n",
    275 		    1000 * clock, ref_clk / (2 * (divider + 1)));
    276 
    277 		SDMMC_WRITE(sc, AM18XX_SDMMC_MMCCLK,
    278 		    divider | AM18XX_SDMMC_MMCCLK_CLKEN);
    279 	} else {
    280 		device_printf(sc->sc_dev, "clocks off\n");
    281 		SDMMC_WRITE(sc, AM18XX_SDMMC_MMCCLK, 0);
    282 	}
    283 
    284 	return 0;
    285 }
    286 
    287 static int
    288 am18xx_sdmmc_bus_width(sdmmc_chipset_handle_t sch, int width)
    289 {
    290 	struct am18xx_sdmmc_softc *sc = sch;
    291 
    292 	/* compute bit flags for new width */
    293 	uint32_t val;
    294 	switch (width) {
    295 	case 1:
    296 		val = 0;
    297 		break;
    298 	case 4:
    299 		val = AM18XX_SDMMC_MMCCTL_WIDTH0;
    300 		break;
    301 	case 8:
    302 		val = AM18XX_SDMMC_MMCCTL_WIDTH1;
    303 		break;
    304 	default:
    305 		return 1;
    306 	}
    307 
    308 	/* change bus bit width bits in MMCCTL */
    309 	uint32_t regval = SDMMC_READ(sc, AM18XX_SDMMC_MMCCTL);
    310 	regval = val | (regval & (~(AM18XX_SDMMC_MMCCTL_WIDTH0 |
    311 				    AM18XX_SDMMC_MMCCTL_WIDTH1)));
    312 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCCTL, regval);
    313 
    314 	return 0;
    315 }
    316 
    317 static int
    318 am18xx_sdmmc_bus_rod(sdmmc_chipset_handle_t sch, int rod)
    319 {
    320 	struct am18xx_sdmmc_softc *sc = sch;
    321 
    322 	mutex_enter(&sc->sc_lock);
    323 	if (rod) {
    324 		sc->sc_opendrain = true;
    325 	} else {
    326 		sc->sc_opendrain = false;
    327 	}
    328 	mutex_exit(&sc->sc_lock);
    329 
    330 	return 0;
    331 }
    332 
    333 static void
    334 am18xx_sdmmc_card_enable_intr(sdmmc_chipset_handle_t sch, int irq)
    335 {
    336 	struct am18xx_sdmmc_softc *sc = sch;
    337 	device_printf(sc->sc_dev, "SDIO interrupts not implemented\n");
    338 }
    339 
    340 static void
    341 am18xx_sdmmc_card_intr_ack(sdmmc_chipset_handle_t sch)
    342 {
    343 	struct am18xx_sdmmc_softc *sc = sch;
    344 	device_printf(sc->sc_dev, "SDIO interrupts not implemented\n");
    345 }
    346 
    347 static void
    348 am18xx_sdmmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
    349 {
    350 	struct am18xx_sdmmc_softc *sc = sch;
    351 	int err;
    352 
    353 	mutex_enter(&sc->sc_lock);
    354 	KASSERT(sc->sc_cmd == NULL);
    355 	sc->sc_cmd = cmd;
    356 
    357 	/* wait for the card to be ready */
    358 	int timeout = 1000000;
    359 	while (SDMMC_READ(sc, AM18XX_SDMMC_MMCST1) & AM18XX_SDMMC_MMCST1_BUSY) {
    360 		delay(10);
    361 		if (timeout-- == 0) {
    362 			device_printf(sc->sc_dev, "mmcst1 timeout\n");
    363 			cmd->c_error = ETIMEDOUT;
    364 			goto out;
    365 		}
    366 	}
    367 
    368 	/* send the command to the controller */
    369 	err = am18xx_sdmmc_initiate_command(sc, cmd);
    370 	if (err != 0) {
    371 		cmd->c_error = err;
    372 		goto out;
    373 	}
    374 
    375 	/* wait for a response */
    376 	err = 0;
    377 	while (sc->sc_irq_wait) {
    378 		err = cv_timedwait(&sc->sc_intr_cv, &sc->sc_lock, mstohz(1000));
    379 		if (err == EWOULDBLOCK) {
    380 			device_printf(sc->sc_dev, "command timeout\n");
    381 			cmd->c_error = ETIMEDOUT;
    382 			break;
    383 		}
    384 	}
    385 	sc->sc_irq_wait = false;
    386 
    387 	/* halt the dma transaction */
    388 	if (sc->sc_use_dma) {
    389 		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    390 			fdtbus_dma_halt(sc->sc_rx_dma);
    391 		} else {
    392 			fdtbus_dma_halt(sc->sc_tx_dma);
    393 		}
    394 	}
    395 
    396 	if (cmd->c_error) {
    397 		goto out;
    398 	}
    399 
    400 	/* read the command response */
    401 	if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
    402 		if (cmd->c_flags & SCF_RSP_136) {
    403 			cmd->c_resp[3] = SDMMC_READ(sc, AM18XX_SDMMC_MMCRSP67);
    404 			cmd->c_resp[2] = SDMMC_READ(sc, AM18XX_SDMMC_MMCRSP45);
    405 			cmd->c_resp[1] = SDMMC_READ(sc, AM18XX_SDMMC_MMCRSP23);
    406 			cmd->c_resp[0] = SDMMC_READ(sc, AM18XX_SDMMC_MMCRSP01);
    407 
    408 			cmd->c_resp[0] >>= 8; /* Remove CRC7 + LSB. */
    409 			cmd->c_resp[0] |= (0x000000FF & cmd->c_resp[1]) << 24;
    410 			cmd->c_resp[1] >>= 8;
    411 			cmd->c_resp[1] |= (0x000000FF & cmd->c_resp[2]) << 24;
    412 			cmd->c_resp[2] >>= 8;
    413 			cmd->c_resp[2] |= (0x000000FF & cmd->c_resp[3]) << 24;
    414 			cmd->c_resp[3] >>= 8;
    415 		} else {
    416 			cmd->c_resp[0] = SDMMC_READ(sc, AM18XX_SDMMC_MMCRSP67);
    417 		}
    418 	}
    419 
    420 	sc->sc_firstcmd = false;
    421 out:
    422 	sc->sc_cmd = NULL;
    423 	mutex_exit(&sc->sc_lock);
    424 }
    425 
    426 static int am18xx_sdmmc_initiate_command(struct am18xx_sdmmc_softc *sc,
    427     struct sdmmc_command *cmd)
    428 {
    429 	sc->sc_use_dma = cmd->c_data != NULL && cmd->c_datalen >= 64 &&
    430 			 sc->sc_have_dma;
    431 
    432 	/* write block size settings */
    433 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCBLEN, cmd->c_blklen);
    434 	if (cmd->c_blklen != 0) {
    435 		SDMMC_WRITE(sc, AM18XX_SDMMC_MMCNBLK,
    436 		    cmd->c_datalen / cmd->c_blklen);
    437 	} else {
    438 		SDMMC_WRITE(sc, AM18XX_SDMMC_MMCNBLK, 0);
    439 	}
    440 
    441 	/* write command */
    442 	uint32_t command = __SHIFTIN(cmd->c_opcode, AM18XX_SDMMC_MMCCMD_CMD);
    443 	uint32_t command_type;
    444 	if (!ISSET(cmd->c_flags, SCF_RSP_PRESENT)) {
    445 		/* no response */
    446 		command_type = AM18XX_SDMMC_MMCCMD_RSPFMT_R0;
    447 	} else if (ISSET(cmd->c_flags, SCF_RSP_136)) {
    448 		/* 136 bits, CRC */
    449 		command_type = AM18XX_SDMMC_MMCCMD_RSPFMT_R2;
    450 	} else if (ISSET(cmd->c_flags, SCF_RSP_CRC)) {
    451 		/* 48 bits, CRC */
    452 		command_type = AM18XX_SDMMC_MMCCMD_RSPFMT_R1456;
    453 	} else {
    454 		/* 48 bits, no CRC */
    455 		command_type = AM18XX_SDMMC_MMCCMD_RSPFMT_R3;
    456 	}
    457 	command |= __SHIFTIN(command_type, AM18XX_SDMMC_MMCCMD_RSPFMT);
    458 	if (sc->sc_opendrain) {
    459 		command |= AM18XX_SDMMC_MMCCMD_PPLEN;
    460 	}
    461 	if (ISSET(cmd->c_flags, SCF_RSP_BSY)) {
    462 		command |= AM18XX_SDMMC_MMCCMD_BSYEXP;
    463 	}
    464 	if (!ISSET(cmd->c_flags, SCF_CMD_READ)) {
    465 		command |= AM18XX_SDMMC_MMCCMD_DTRW;
    466 	}
    467 	if (cmd->c_data != NULL && cmd->c_datalen > 0) {
    468 		/* command has data transfer */
    469 		command |= AM18XX_SDMMC_MMCCMD_WDATX;
    470 		command |= AM18XX_SDMMC_MMCCMD_DMATRIG;
    471 	}
    472 	if (sc->sc_firstcmd) {
    473 		command |= AM18XX_SDMMC_MMCCMD_INITCK;
    474 	}
    475 
    476 	/* configure FIFO register */
    477 	if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    478 		/* read */
    479 		SDMMC_WRITE(sc, AM18XX_SDMMC_FIFOCTL,
    480 		    AM18XX_SDMMC_FIFOCTL_FIFOLEV64 |
    481 			AM18XX_SDMMC_FIFOCTL_FIFORST);
    482 		SDMMC_WRITE(sc, AM18XX_SDMMC_FIFOCTL,
    483 		    AM18XX_SDMMC_FIFOCTL_FIFOLEV64);
    484 	} else {
    485 		/* write */
    486 		SDMMC_WRITE(sc, AM18XX_SDMMC_FIFOCTL,
    487 		    AM18XX_SDMMC_FIFOCTL_FIFOLEV64 |
    488 			AM18XX_SDMMC_FIFOCTL_FIFODIRW |
    489 			AM18XX_SDMMC_FIFOCTL_FIFORST);
    490 		SDMMC_WRITE(sc, AM18XX_SDMMC_FIFOCTL,
    491 		    AM18XX_SDMMC_FIFOCTL_FIFOLEV64 |
    492 			AM18XX_SDMMC_FIFOCTL_FIFODIRW);
    493 	}
    494 
    495 	sc->sc_command_done = false;
    496 	sc->sc_transfer_done = cmd->c_datalen == 0 || cmd->c_data == NULL;
    497 	sc->sc_dma_done = !sc->sc_use_dma;
    498 
    499 	if (sc->sc_use_dma) {
    500 		cmd->c_resid = 0;
    501 
    502 		/* data access is a multiple of fifo size */
    503 		KASSERT((cmd->c_datalen & 0x3f) == 0);
    504 		/* transfer needs to be bigger than the FIFO size */
    505 		KASSERT(cmd->c_datalen >= 64);
    506 
    507 		/* initiate DMA transfer */
    508 		sc->sc_dma_req.dreq_segs = cmd->c_dmamap->dm_segs;
    509 		sc->sc_dma_req.dreq_nsegs = cmd->c_dmamap->dm_nsegs;
    510 
    511 		int err;
    512 		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    513 			sc->sc_dma_req.dreq_dev_phys =
    514 			    sc->sc_phys_base_addr + AM18XX_SDMMC_MMCDRR;
    515 			sc->sc_dma_req.dreq_dir = FDT_DMA_READ;
    516 			err = fdtbus_dma_transfer(sc->sc_rx_dma,
    517 						  &sc->sc_dma_req);
    518 		} else {
    519 			sc->sc_dma_req.dreq_dev_phys =
    520 			    sc->sc_phys_base_addr + AM18XX_SDMMC_MMCDXR;
    521 			sc->sc_dma_req.dreq_dir = FDT_DMA_WRITE;
    522 			err = fdtbus_dma_transfer(sc->sc_tx_dma,
    523 						  &sc->sc_dma_req);
    524 		}
    525 
    526 		if (err) {
    527 			return err;
    528 		}
    529 
    530 	} else if (cmd->c_data != NULL) {
    531 		/* transfer size must be multiple of fifo port width */
    532 		KASSERT((cmd->c_datalen & 0x3) == 0);
    533 
    534 		cmd->c_buf = cmd->c_data;
    535 		cmd->c_resid = cmd->c_datalen;
    536 
    537 		/* writes: shovel first load of data */
    538 		if (!ISSET(cmd->c_flags, SCF_CMD_READ) && cmd->c_datalen > 0) {
    539 			am18xx_sdmmc_cpu_data_transfer(sc);
    540 		}
    541 	}
    542 
    543 	/* write command arguments */
    544 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCTOR, 0x1FFF);
    545 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCARGHL, cmd->c_arg);
    546 
    547 	/* send the command */
    548 	sc->sc_irq_wait = true;
    549 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCCMD, command);
    550 
    551 	return 0;
    552 }
    553 
    554 static void am18xx_sdmmc_init(struct am18xx_sdmmc_softc *sc)
    555 {
    556 	/* reset the controller */
    557 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCCTL, AM18XX_SDMMC_MMCCTL_DATARST |
    558 					     AM18XX_SDMMC_MMCCTL_CMDRST);
    559 	SDMMC_READ(sc, AM18XX_SDMMC_MMCST0);
    560 	SDMMC_READ(sc, AM18XX_SDMMC_MMCST1);
    561 	delay(10);
    562 
    563 	/* clocks off */
    564 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCCLK, 0);
    565 
    566 	/* disable all interrupts */
    567 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCIM, 0);
    568 	/* write timeout values to maximum */
    569 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCTOR, 0x3FFFF);
    570 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCTOD, 0xFFFF);
    571 
    572 	sc->sc_irq_wait = false;
    573 	sc->sc_opendrain = true;
    574 	sc->sc_firstcmd = true;
    575 	sc->sc_cmd = NULL;
    576 
    577 	/* take the controller out of reset */
    578 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCCTL, 0);
    579 
    580 	/* enable the clock */
    581 	am18xx_sdmmc_bus_clock(sc, 400);
    582 
    583 	/* enable interrupts */
    584 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCIM, AM18XX_SDMMC_MMCIM_EDATDNE |
    585 						AM18XX_SDMMC_MMCIM_ERSPDNE |
    586 						AM18XX_SDMMC_MMCIM_ETOUTRD |
    587 						AM18XX_SDMMC_MMCIM_ETOUTRS |
    588 						AM18XX_SDMMC_MMCIM_ECRCWR |
    589 						AM18XX_SDMMC_MMCIM_ECRCRD |
    590 						AM18XX_SDMMC_MMCIM_ECRCRS |
    591 						AM18XX_SDMMC_MMCIM_EDXRDY |
    592 						AM18XX_SDMMC_MMCIM_EDRRDY);
    593 }
    594 
    595 static void
    596 am18xx_sdmmc_cpu_data_transfer(struct am18xx_sdmmc_softc *sc)
    597 {
    598 	/* process one FIFOfull of data */
    599 	for (int i = 0; i < (64 / 4) && sc->sc_cmd->c_resid > 0; i++) {
    600 		KASSERT((sc->sc_cmd->c_resid & 0x3) == 0);
    601 
    602 		if (ISSET(sc->sc_cmd->c_flags, SCF_CMD_READ)) {
    603 			*((uint32_t *)sc->sc_cmd->c_buf) = SDMMC_READ(
    604 			    sc, AM18XX_SDMMC_MMCDRR);
    605 		} else {
    606 			SDMMC_WRITE(sc, AM18XX_SDMMC_MMCDXR,
    607 			    *((uint32_t *)sc->sc_cmd->c_buf));
    608 		}
    609 
    610 		sc->sc_cmd->c_resid -= 4;
    611 		sc->sc_cmd->c_buf += 4;
    612 	}
    613 }
    614 
    615 static int
    616 am18xx_sdmmc_intr(void *arg)
    617 {
    618 	bool cmd_failed = false;
    619 	struct am18xx_sdmmc_softc *sc = arg;
    620 
    621 	uint32_t cause = SDMMC_READ(sc, AM18XX_SDMMC_MMCST0);
    622 	if (cause == 0)
    623 		return 1;
    624 
    625 	mutex_enter(&sc->sc_lock);
    626 
    627 	if (!sc->sc_irq_wait) {
    628 		mutex_exit(&sc->sc_lock);
    629 		device_printf(sc->sc_dev, "spurious interrupt\n");
    630 		return 1;
    631 	}
    632 
    633 	/*
    634 	 * Disable interrupts during cpu transfer. This allows us to capture new
    635 	 * interrupts and handle them in this interrupt instead of generating a
    636 	 * second interrupt.
    637 	 */
    638 	uint32_t mmcim = SDMMC_READ(sc, AM18XX_SDMMC_MMCIM);
    639 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCIM, 0);
    640 
    641 	/*
    642 	 * 1. Service the FIFO until it is empty/full (depending on if we are
    643 	 * reading or writing). We can complete multiple FIFO loads in one
    644 	 * interrupts if the FIFO clears fast enough. After servicing the
    645 	 * FIFO, am18xx_sdmmc_cpu_data_transfer checks for new interrupt
    646 	 * requests like CRC errors or command completion events so we can
    647 	 * deal with them without generating a second interrupt. We service
    648 	 * the FIFO first so we can deal with these new events later on.
    649 	 */
    650 	if (cause & (AM18XX_SDMMC_MMCST0_DRRDY | AM18XX_SDMMC_MMCST0_DXRDY)) {
    651 		/* transfer one fido load for as long as there is space */
    652 		uint32_t status = 0;
    653 		do {
    654 			am18xx_sdmmc_cpu_data_transfer(sc);
    655 			status = SDMMC_READ(sc, AM18XX_SDMMC_MMCST0);
    656 			cause |= status;
    657 		} while (status & (AM18XX_SDMMC_MMCST0_DRRDY
    658 				      | AM18XX_SDMMC_MMCST0_DXRDY));
    659 	}
    660 
    661 	/*
    662 	 * 2. DATDNE indicates the data transfer is complete. If the data size
    663 	 * is not a multiple of the FIFO, we don't get a DXRDY|DRRDY irq,
    664 	 * but the data will be ready to transfer.
    665 	 * This step is the second because the FIFO transfer might still
    666 	 * generate events like CRC errors.
    667 	 */
    668 	if (cause & AM18XX_SDMMC_MMCST0_DATDNE) {
    669 		if (sc->sc_cmd->c_resid > 0) {
    670 			/* transfer remaining outstanding data */
    671 			am18xx_sdmmc_cpu_data_transfer(sc);
    672 			cause |= SDMMC_READ(sc, AM18XX_SDMMC_MMCST0);
    673 		}
    674 		sc->sc_transfer_done = true;
    675 	}
    676 
    677 	/*
    678 	 * 3. Check if any operation failed (CRC errors, timeouts). By now, all
    679 	 * FIFO transfers that could generate new events have happened.
    680 	 */
    681 	if (cause & AM18XX_SDMMC_MMCST0_ERRMASK) {
    682 		if (cause & (AM18XX_SDMMC_MMCST0_TOUTRS
    683 				| AM18XX_SDMMC_MMCST0_TOUTRD)) {
    684 			sc->sc_cmd->c_error = ETIMEDOUT;
    685 		} else {
    686 			sc->sc_cmd->c_error = EIO;
    687 		}
    688 
    689 		cmd_failed = true;
    690 	}
    691 
    692 	/* 4. Check if the command has been fully transmitted. */
    693 	if (cause & AM18XX_SDMMC_MMCST0_RSPDNE) {
    694 		sc->sc_command_done = true;
    695 	}
    696 
    697 	/* re-enable data receive/transmit interrupts */
    698 	SDMMC_WRITE(sc, AM18XX_SDMMC_MMCIM, mmcim);
    699 
    700 	/* signal the main thread if we are done */
    701 	am18xx_sdmmc_check_completion(sc, cmd_failed);
    702 
    703 	mutex_exit(&sc->sc_lock);
    704 	return 1; /* acknowledge IRQ */
    705 }
    706 
    707 static void
    708 am18xx_sdmmc_dma_callback(void *priv)
    709 {
    710 	struct am18xx_sdmmc_softc *sc = priv;
    711 
    712 	/* ensure we have the lock while touching the softcore */
    713 	mutex_enter(&sc->sc_lock);
    714 
    715 	sc->sc_dma_done = true;
    716 	am18xx_sdmmc_check_completion(sc, false);
    717 
    718 	mutex_exit(&sc->sc_lock);
    719 }
    720 
    721 static void
    722 am18xx_sdmmc_check_completion(struct am18xx_sdmmc_softc *sc, bool has_err)
    723 {
    724 	bool completed = sc->sc_command_done
    725 			 && sc->sc_transfer_done
    726 			 && sc->sc_dma_done;
    727 
    728 	if (completed || has_err) {
    729 		KASSERT(sc->sc_cmd->c_resid == 0 || has_err);
    730 		sc->sc_irq_wait = false;
    731 		cv_signal(&sc->sc_intr_cv);
    732 	}
    733 }
    734 
    735 int
    736 am18xx_sdmmc_match(device_t parent, cfdata_t cf, void *aux)
    737 {
    738 	struct fdt_attach_args *const faa = aux;
    739 
    740 	return of_compatible_match(faa->faa_phandle, compat_data);
    741 }
    742 
    743 void
    744 am18xx_sdmmc_attach(device_t parent, device_t self, void *aux)
    745 {
    746 	struct am18xx_sdmmc_softc *const sc = device_private(self);
    747 	struct fdt_attach_args *const faa = aux;
    748 	const int phandle = faa->faa_phandle;
    749 	struct sdmmcbus_attach_args saa;
    750 	bus_addr_t addr;
    751 	bus_size_t size;
    752 	char intrstr[128];
    753 
    754 	sc->sc_bst = faa->faa_bst;
    755 	sc->sc_dev = self;
    756 
    757 	/* we need a spin mutex for intr->lwp synchronization */
    758 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
    759 	cv_init(&sc->sc_intr_cv, "sdmmc_intr");
    760 
    761 	/* enable host controller clock */
    762 	sc->sc_clk = fdtbus_clock_get_index(phandle, 0);
    763 	if (sc->sc_clk == NULL) {
    764 		aprint_error(": failed to get sdmmc clk\n");
    765 		return;
    766 	}
    767 	if (clk_enable(sc->sc_clk) != 0) {
    768 		aprint_error(": failed to enable sdmmc clk\n");
    769 		return;
    770 	}
    771 	u_int clk_rate = clk_get_rate(sc->sc_clk);
    772 
    773 	/* map bus space */
    774 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
    775 		aprint_error(": couldn't get registers\n");
    776 		return;
    777 	}
    778 	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh)) {
    779 		aprint_error(": couldn't map registers\n");
    780 		return;
    781 	}
    782 	sc->sc_phys_base_addr = addr;
    783 
    784 	/* establish interrupt */
    785 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    786 		aprint_error(": failed to decode interrupt\n");
    787 		return;
    788 	}
    789 	void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_SDMMC, IST_LEVEL,
    790 	    am18xx_sdmmc_intr, sc, device_xname(self));
    791 	if (ih == NULL) {
    792 		aprint_error(": couldn't install interrupt\n");
    793 		return;
    794 	}
    795 
    796 
    797 	/* prepare DMA request */
    798 	memset(&sc->sc_dma_req, 0, sizeof(sc->sc_dma_req));
    799 	sc->sc_dma_req.dreq_block_irq = 1;
    800 	sc->sc_dma_req.dreq_block_multi = 0;
    801 	sc->sc_dma_req.dreq_dev_opt.opt_bus_width = 4;
    802 	sc->sc_dma_req.dreq_dev_opt.opt_burst_len = 64;
    803 	/* rx dma channels */
    804 	sc->sc_rx_dma = fdtbus_dma_get(phandle, "rx",
    805 	    am18xx_sdmmc_dma_callback, sc);
    806 	if (sc->sc_rx_dma == NULL) {
    807 		aprint_error(": couldn't get rx dma handle\n");
    808 	}
    809 	/* tx dma channels */
    810 	sc->sc_tx_dma = fdtbus_dma_get(phandle, "tx",
    811 	    am18xx_sdmmc_dma_callback, sc);
    812 	if (sc->sc_tx_dma == NULL) {
    813 		aprint_error(": couldn't get tx dma handle\n");
    814 	}
    815 	sc->sc_have_dma = sc->sc_rx_dma != NULL && sc->sc_tx_dma != NULL;
    816 
    817 	aprint_normal("\n");
    818 
    819 	/* reset the controller */
    820 	am18xx_sdmmc_init(sc);
    821 
    822 	/* attach us as an sdmmc device */
    823 	memset(&saa, 0, sizeof(saa));
    824 	saa.saa_busname = "sdmmc";
    825 	saa.saa_sct	= &am18xx_sdmmc_functions;
    826 	saa.saa_spi_sct	= NULL;
    827 	saa.saa_sch	= sc;
    828 	saa.saa_dmat	= faa->faa_dmat;
    829 	saa.saa_clkmin	= clk_rate / AM18XX_SDMMC_MAX_CLOCK_DIVIDER / 1000;
    830 	u_int clkmax;
    831 	if (of_getprop_uint32(phandle, "max-frequency", &clkmax) == 0) {
    832 		saa.saa_clkmax = clkmax / 1000; /* Hz to kHz */
    833 	} else {
    834 		saa.saa_clkmax = 25000; /* 25MHz is always okay */
    835 	}
    836 	saa.saa_caps = SMC_CAPS_DMA;
    837 
    838 	if (of_hasprop(phandle, "cap-sd-highspeed")) {
    839 		saa.saa_caps |= SMC_CAPS_SD_HIGHSPEED;
    840 	}
    841 	if (of_hasprop(phandle, "cap-mmc-highspeed")) {
    842 		saa.saa_caps |= SMC_CAPS_MMC_HIGHSPEED;
    843 	}
    844 
    845 	uint32_t bus_width;
    846 	if (of_getprop_uint32(phandle, "bus-width", &bus_width)) {
    847 		bus_width = 1;
    848 	}
    849 	switch (bus_width) {
    850 	case 8:
    851 		saa.saa_caps |= SMC_CAPS_8BIT_MODE;
    852 		break;
    853 	case 4:
    854 		saa.saa_caps |= SMC_CAPS_4BIT_MODE;
    855 		break;
    856 	default:
    857 		/* use 1-bit mode */
    858 		break;
    859 	}
    860 
    861 	sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL, CFARGS_NONE);
    862 	if (sc->sc_sdmmc == NULL) {
    863 		aprint_error_dev(sc->sc_dev, "unable to attach sdmmc\n");
    864 		return;
    865 	}
    866 }
    867