Home | History | Annotate | Line # | Download | only in amlogic
      1 /* $NetBSD: meson_sdhc.c,v 1.6 2021/11/07 17:11:58 jmcneill Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2015-2019 Jared McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: meson_sdhc.c,v 1.6 2021/11/07 17:11:58 jmcneill Exp $");
     31 
     32 #include <sys/param.h>
     33 #include <sys/bus.h>
     34 #include <sys/device.h>
     35 #include <sys/intr.h>
     36 #include <sys/systm.h>
     37 #include <sys/kernel.h>
     38 #include <sys/gpio.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/fdt/fdtvar.h>
     45 
     46 #include <arm/amlogic/meson_sdhcreg.h>
     47 
     48 enum {
     49 	SDHC_PORT_A = 0,
     50 	SDHC_PORT_B = 1,
     51 	SDHC_PORT_C = 2
     52 };
     53 
     54 static int	meson_sdhc_match(device_t, cfdata_t, void *);
     55 static void	meson_sdhc_attach(device_t, device_t, void *);
     56 static void	meson_sdhc_attach_i(device_t);
     57 
     58 static int	meson_sdhc_intr(void *);
     59 
     60 struct meson_sdhc_softc {
     61 	device_t		sc_dev;
     62 	bus_space_tag_t		sc_bst;
     63 	bus_space_handle_t	sc_bsh;
     64 	bus_dma_tag_t		sc_dmat;
     65 	void			*sc_ih;
     66 
     67 	device_t		sc_sdmmc_dev;
     68 	kmutex_t		sc_intr_lock;
     69 	kcondvar_t		sc_intr_cv;
     70 
     71 	uint32_t		sc_intr_ista;
     72 
     73 	bus_dmamap_t		sc_dmamap;
     74 	bus_dma_segment_t	sc_segs[1];
     75 	void			*sc_bbuf;
     76 
     77 	u_int			sc_bus_freq;
     78 
     79 	struct fdtbus_gpio_pin	*sc_gpio_cd;
     80 	int			sc_gpio_cd_inverted;
     81 	struct fdtbus_gpio_pin	*sc_gpio_wp;
     82 	int			sc_gpio_wp_inverted;
     83 
     84 	struct fdtbus_regulator	*sc_reg_vmmc;
     85 	struct fdtbus_regulator	*sc_reg_vqmmc;
     86 
     87 	bool			sc_non_removable;
     88 	bool			sc_broken_cd;
     89 
     90 	int			sc_port;
     91 	int			sc_slot_phandle;
     92 	int			sc_signal_voltage;
     93 };
     94 
     95 CFATTACH_DECL_NEW(meson_sdhc, sizeof(struct meson_sdhc_softc),
     96 	meson_sdhc_match, meson_sdhc_attach, NULL, NULL);
     97 
     98 static int	meson_sdhc_host_reset(sdmmc_chipset_handle_t);
     99 static uint32_t	meson_sdhc_host_ocr(sdmmc_chipset_handle_t);
    100 static int	meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t);
    101 static int	meson_sdhc_card_detect(sdmmc_chipset_handle_t);
    102 static int	meson_sdhc_write_protect(sdmmc_chipset_handle_t);
    103 static int	meson_sdhc_bus_power(sdmmc_chipset_handle_t, uint32_t);
    104 static int	meson_sdhc_bus_clock(sdmmc_chipset_handle_t, int);
    105 static int	meson_sdhc_bus_width(sdmmc_chipset_handle_t, int);
    106 static int	meson_sdhc_bus_rod(sdmmc_chipset_handle_t, int);
    107 static void	meson_sdhc_exec_command(sdmmc_chipset_handle_t,
    108 				     struct sdmmc_command *);
    109 static void	meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t, int);
    110 static void	meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t);
    111 static int	meson_sdhc_signal_voltage(sdmmc_chipset_handle_t, int);
    112 static int	meson_sdhc_execute_tuning(sdmmc_chipset_handle_t, int);
    113 
    114 static int	meson_sdhc_default_rx_phase(struct meson_sdhc_softc *);
    115 static int	meson_sdhc_set_clock(struct meson_sdhc_softc *, u_int);
    116 static int	meson_sdhc_wait_idle(struct meson_sdhc_softc *);
    117 static int	meson_sdhc_wait_ista(struct meson_sdhc_softc *, uint32_t, int);
    118 
    119 static void	meson_sdhc_dmainit(struct meson_sdhc_softc *);
    120 
    121 static struct sdmmc_chip_functions meson_sdhc_chip_functions = {
    122 	.host_reset = meson_sdhc_host_reset,
    123 	.host_ocr = meson_sdhc_host_ocr,
    124 	.host_maxblklen = meson_sdhc_host_maxblklen,
    125 	.card_detect = meson_sdhc_card_detect,
    126 	.write_protect = meson_sdhc_write_protect,
    127 	.bus_power = meson_sdhc_bus_power,
    128 	.bus_clock = meson_sdhc_bus_clock,
    129 	.bus_width = meson_sdhc_bus_width,
    130 	.bus_rod = meson_sdhc_bus_rod,
    131 	.exec_command = meson_sdhc_exec_command,
    132 	.card_enable_intr = meson_sdhc_card_enable_intr,
    133 	.card_intr_ack = meson_sdhc_card_intr_ack,
    134 	.signal_voltage = meson_sdhc_signal_voltage,
    135 	.execute_tuning = meson_sdhc_execute_tuning,
    136 };
    137 
    138 #define SDHC_WRITE(sc, reg, val) \
    139 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
    140 #define SDHC_READ(sc, reg) \
    141 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
    142 #define	SDHC_SET_CLEAR meson_sdhc_set_clear
    143 
    144 static inline void
    145 meson_sdhc_set_clear(struct meson_sdhc_softc *sc, bus_addr_t reg, uint32_t set, uint32_t clr)
    146 {
    147 	const uint32_t old = SDHC_READ(sc, reg);
    148 	const uint32_t new = set | (old & ~clr);
    149 	if (old != new)
    150 		SDHC_WRITE(sc, reg, new);
    151 }
    152 
    153 static const struct device_compatible_entry compat_data[] = {
    154 	{ .compat = "amlogic,meson8-sdhc" },
    155 	{ .compat = "amlogic,meson8b-sdhc" },	/* DTCOMPAT */
    156 	DEVICE_COMPAT_EOL
    157 };
    158 
    159 static const struct device_compatible_entry slot_compat_data[] = {
    160 	{ .compat = "mmc-slot" },
    161 	DEVICE_COMPAT_EOL
    162 };
    163 
    164 static int
    165 meson_sdhc_match(device_t parent, cfdata_t cf, void *aux)
    166 {
    167 	struct fdt_attach_args * const faa = aux;
    168 
    169 	return of_compatible_match(faa->faa_phandle, compat_data);
    170 }
    171 
    172 static void
    173 meson_sdhc_attach(device_t parent, device_t self, void *aux)
    174 {
    175 	struct meson_sdhc_softc * const sc = device_private(self);
    176 	struct fdt_attach_args * const faa = aux;
    177 	const int phandle = faa->faa_phandle;
    178 	char intrstr[128];
    179 	struct clk *clk_clkin, *clk_core;
    180 	bus_addr_t addr, port;
    181 	bus_size_t size;
    182 	int child;
    183 
    184 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
    185 		aprint_error(": couldn't get registers\n");
    186 		return;
    187 	}
    188 
    189 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    190 		aprint_error(": failed to decode interrupt\n");
    191 		return;
    192 	}
    193 
    194 	clk_core = fdtbus_clock_get(phandle, "core");
    195 	if (clk_core == NULL) {
    196 		clk_core = fdtbus_clock_get(phandle, "pclk");
    197 	}
    198 	if (clk_core == NULL || clk_enable(clk_core) != 0) {
    199 		aprint_error(": failed to enable core/pclk clock\n");
    200 		return;
    201 	}
    202 
    203 	clk_clkin = fdtbus_clock_get(phandle, "clkin");
    204 	if (clk_clkin == NULL) {
    205 		clk_clkin = fdtbus_clock_get(phandle, "clkin2");
    206 	}
    207 	if (clk_clkin == NULL || clk_enable(clk_clkin) != 0) {
    208 		aprint_error(": failed to get clkin/clkin2 clock\n");
    209 		return;
    210 	}
    211 
    212 	sc->sc_dev = self;
    213 	sc->sc_bst = faa->faa_bst;
    214 	sc->sc_dmat = faa->faa_dmat;
    215 	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
    216 		aprint_error(": failed to map registers\n");
    217 		return;
    218 	}
    219 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO);
    220 	cv_init(&sc->sc_intr_cv, "sdhcintr");
    221 	sc->sc_signal_voltage = SDMMC_SIGNAL_VOLTAGE_330;
    222 
    223 	sc->sc_port = -1;
    224 	for (child = OF_child(phandle); child; child = OF_peer(child))
    225 		if (of_compatible_match(child, slot_compat_data)) {
    226 			if (fdtbus_get_reg(child, 0, &port, NULL) == 0) {
    227 				sc->sc_slot_phandle = child;
    228 				sc->sc_port = port;
    229 			}
    230 			break;
    231 		}
    232 	if (sc->sc_port == -1) {
    233 		aprint_error(": couldn't get mmc slot\n");
    234 		return;
    235 	}
    236 
    237 	aprint_naive("\n");
    238 	aprint_normal(": SDHC controller (port %c)\n", sc->sc_port + 'A');
    239 
    240 	sc->sc_reg_vmmc = fdtbus_regulator_acquire(sc->sc_slot_phandle, "vmmc-supply");
    241 	sc->sc_reg_vqmmc = fdtbus_regulator_acquire(sc->sc_slot_phandle, "vqmmc-supply");
    242 
    243 	sc->sc_gpio_cd = fdtbus_gpio_acquire(sc->sc_slot_phandle, "cd-gpios",
    244 	    GPIO_PIN_INPUT);
    245 	sc->sc_gpio_wp = fdtbus_gpio_acquire(sc->sc_slot_phandle, "wp-gpios",
    246 	    GPIO_PIN_INPUT);
    247 
    248 	sc->sc_gpio_cd_inverted = of_hasprop(sc->sc_slot_phandle, "cd-inverted");
    249 	sc->sc_gpio_wp_inverted = of_hasprop(sc->sc_slot_phandle, "wp-inverted");
    250 
    251 	sc->sc_non_removable = of_hasprop(sc->sc_slot_phandle, "non-removable");
    252 	sc->sc_broken_cd = of_hasprop(sc->sc_slot_phandle, "broken-cd");
    253 
    254 	sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_BIO, 0,
    255 	    meson_sdhc_intr, sc, device_xname(self));
    256 	if (sc->sc_ih == NULL) {
    257 		aprint_error_dev(self, "couldn't establish interrupt on %s\n",
    258 		    intrstr);
    259 		return;
    260 	}
    261 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
    262 
    263 	sc->sc_bus_freq = clk_get_rate(clk_clkin);
    264 
    265 	aprint_normal_dev(self, "core %u Hz, clkin %u Hz\n", clk_get_rate(clk_core), clk_get_rate(clk_clkin));
    266 
    267 	meson_sdhc_dmainit(sc);
    268 
    269 	config_interrupts(self, meson_sdhc_attach_i);
    270 }
    271 
    272 static void
    273 meson_sdhc_attach_i(device_t self)
    274 {
    275 	struct meson_sdhc_softc *sc = device_private(self);
    276 	struct sdmmcbus_attach_args saa;
    277 	u_int pll_freq;
    278 
    279 	pll_freq = sc->sc_bus_freq / 1000;
    280 
    281 	meson_sdhc_host_reset(sc);
    282 	meson_sdhc_bus_width(sc, 1);
    283 
    284 	memset(&saa, 0, sizeof(saa));
    285 	saa.saa_busname = "sdmmc";
    286 	saa.saa_sct = &meson_sdhc_chip_functions;
    287 	saa.saa_dmat = sc->sc_dmat;
    288 	saa.saa_sch = sc;
    289 	saa.saa_clkmin = 400;
    290 	saa.saa_clkmax = pll_freq;
    291 	/* Do not advertise DMA capabilities, we handle DMA ourselves */
    292 	saa.saa_caps = SMC_CAPS_4BIT_MODE|
    293 		       SMC_CAPS_SD_HIGHSPEED|
    294 		       SMC_CAPS_MMC_HIGHSPEED|
    295 		       SMC_CAPS_UHS_SDR50|
    296 		       SMC_CAPS_UHS_SDR104|
    297 		       SMC_CAPS_AUTO_STOP;
    298 
    299 	if (sc->sc_port == SDHC_PORT_C) {
    300 		saa.saa_caps |= SMC_CAPS_MMC_HS200;
    301 		saa.saa_caps |= SMC_CAPS_8BIT_MODE;
    302 	}
    303 
    304 	sc->sc_sdmmc_dev = config_found(self, &saa, NULL, CFARGS_NONE);
    305 }
    306 
    307 static int
    308 meson_sdhc_intr(void *priv)
    309 {
    310 	struct meson_sdhc_softc *sc = priv;
    311 	uint32_t ista;
    312 
    313 	mutex_enter(&sc->sc_intr_lock);
    314 	ista = SDHC_READ(sc, SD_ISTA_REG);
    315 
    316 	if (!ista) {
    317 		mutex_exit(&sc->sc_intr_lock);
    318 		return 0;
    319 	}
    320 
    321 	SDHC_WRITE(sc, SD_ISTA_REG, ista);
    322 
    323 	sc->sc_intr_ista |= ista;
    324 	cv_broadcast(&sc->sc_intr_cv);
    325 
    326 	mutex_exit(&sc->sc_intr_lock);
    327 
    328 	return 1;
    329 }
    330 
    331 static void
    332 meson_sdhc_dmainit(struct meson_sdhc_softc *sc)
    333 {
    334 	int error, rseg;
    335 
    336 	error = bus_dmamem_alloc(sc->sc_dmat, MAXPHYS, PAGE_SIZE, MAXPHYS,
    337 	    sc->sc_segs, 1, &rseg, BUS_DMA_WAITOK);
    338 	if (error) {
    339 		device_printf(sc->sc_dev, "bus_dmamem_alloc failed: %d\n", error);
    340 		return;
    341 	}
    342 	KASSERT(rseg == 1);
    343 
    344 	error = bus_dmamem_map(sc->sc_dmat, sc->sc_segs, rseg, MAXPHYS,
    345 	    &sc->sc_bbuf, BUS_DMA_WAITOK);
    346 	if (error) {
    347 		device_printf(sc->sc_dev, "bus_dmamem_map failed\n");
    348 		return;
    349 	}
    350 
    351 	error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, 1, MAXPHYS, 0,
    352 	    BUS_DMA_WAITOK, &sc->sc_dmamap);
    353 	if (error) {
    354 		device_printf(sc->sc_dev, "bus_dmamap_create failed\n");
    355 		return;
    356 	}
    357 
    358 }
    359 
    360 static int
    361 meson_sdhc_default_rx_phase(struct meson_sdhc_softc *sc)
    362 {
    363 	const u_int pll_freq = sc->sc_bus_freq / 1000;
    364 	const u_int clkc = SDHC_READ(sc, SD_CLKC_REG);
    365 	const u_int clk_div = __SHIFTOUT(clkc, SD_CLKC_CLK_DIV);
    366 	const u_int act_freq = pll_freq / clk_div;
    367 
    368 	if (act_freq > 90000) {
    369 		return 1;
    370 	} else if (act_freq > 45000) {
    371 		if (sc->sc_signal_voltage == SDMMC_SIGNAL_VOLTAGE_330) {
    372 			return 15;
    373 		} else {
    374 			return 11;
    375 		}
    376 	} else if (act_freq >= 25000) {
    377 		return 15;
    378 	} else if (act_freq > 5000) {
    379 		return 23;
    380 	} else if (act_freq > 1000) {
    381 		return 55;
    382 	} else {
    383 		return 1061;
    384 	}
    385 }
    386 
    387 static int
    388 meson_sdhc_set_clock(struct meson_sdhc_softc *sc, u_int freq)
    389 {
    390 	uint32_t clkc;
    391 	uint32_t clk2;
    392 	u_int pll_freq, clk_div;
    393 
    394 	clkc = SDHC_READ(sc, SD_CLKC_REG);
    395 	clkc &= ~SD_CLKC_TX_CLK_ENABLE;
    396 	clkc &= ~SD_CLKC_RX_CLK_ENABLE;
    397 	clkc &= ~SD_CLKC_SD_CLK_ENABLE;
    398 	SDHC_WRITE(sc, SD_CLKC_REG, clkc);
    399 	clkc &= ~SD_CLKC_MOD_CLK_ENABLE;
    400 	SDHC_WRITE(sc, SD_CLKC_REG, clkc);
    401 
    402 	if (freq == 0)
    403 		return 0;
    404 
    405 	clkc &= ~SD_CLKC_CLK_DIV;
    406 	clkc &= ~SD_CLKC_CLK_IN_SEL;
    407 
    408 	clkc |= __SHIFTIN(SD_CLKC_CLK_IN_SEL_FCLK_DIV3,
    409 			  SD_CLKC_CLK_IN_SEL);
    410 
    411 	pll_freq = sc->sc_bus_freq / 1000;	/* 2.55GHz */
    412 	clk_div = howmany(pll_freq, freq);
    413 
    414 	clkc |= __SHIFTIN(clk_div - 1, SD_CLKC_CLK_DIV);
    415 
    416 	SDHC_WRITE(sc, SD_CLKC_REG, clkc);
    417 
    418 	clkc |= SD_CLKC_MOD_CLK_ENABLE;
    419 	SDHC_WRITE(sc, SD_CLKC_REG, clkc);
    420 
    421 	clkc |= SD_CLKC_TX_CLK_ENABLE;
    422 	clkc |= SD_CLKC_RX_CLK_ENABLE;
    423 	clkc |= SD_CLKC_SD_CLK_ENABLE;
    424 	SDHC_WRITE(sc, SD_CLKC_REG, clkc);
    425 
    426 	clk2 = SDHC_READ(sc, SD_CLK2_REG);
    427 	clk2 &= ~SD_CLK2_SD_CLK_PHASE;
    428 	clk2 |= __SHIFTIN(1, SD_CLK2_SD_CLK_PHASE);
    429 	clk2 &= ~SD_CLK2_RX_CLK_PHASE;
    430 	clk2 |= __SHIFTIN(meson_sdhc_default_rx_phase(sc),
    431 			  SD_CLK2_RX_CLK_PHASE);
    432 	SDHC_WRITE(sc, SD_CLK2_REG, clk2);
    433 
    434 	return 0;
    435 }
    436 
    437 static int
    438 meson_sdhc_wait_idle(struct meson_sdhc_softc *sc)
    439 {
    440 	int i;
    441 
    442 	for (i = 0; i < 1000000; i++) {
    443 		const uint32_t stat = SDHC_READ(sc, SD_STAT_REG);
    444 		const uint32_t esta = SDHC_READ(sc, SD_ESTA_REG);
    445 		if ((stat & SD_STAT_BUSY) == 0 &&
    446 		    (esta & SD_ESTA_BUSY) == 0)
    447 			return 0;
    448 		delay(1);
    449 	}
    450 
    451 	return EBUSY;
    452 }
    453 
    454 static int
    455 meson_sdhc_wait_ista(struct meson_sdhc_softc *sc, uint32_t mask, int timeout)
    456 {
    457 	int retry, error;
    458 
    459 	KASSERT(mutex_owned(&sc->sc_intr_lock));
    460 
    461 	if (sc->sc_intr_ista & mask)
    462 		return 0;
    463 
    464 	retry = timeout / hz;
    465 
    466 	while (retry > 0) {
    467 		error = cv_timedwait(&sc->sc_intr_cv, &sc->sc_intr_lock, hz);
    468 		if (error && error != EWOULDBLOCK)
    469 			return error;
    470 		if (sc->sc_intr_ista & mask)
    471 			return 0;
    472 		--retry;
    473 	}
    474 
    475 	return ETIMEDOUT;
    476 }
    477 
    478 static int
    479 meson_sdhc_host_reset(sdmmc_chipset_handle_t sch)
    480 {
    481 	struct meson_sdhc_softc *sc = sch;
    482 	uint32_t enhc;
    483 
    484 	SDHC_WRITE(sc, SD_SRST_REG,
    485 	    SD_SRST_MAIN_CTRL | SD_SRST_TX_FIFO | SD_SRST_RX_FIFO |
    486 	    SD_SRST_DPHY_TX | SD_SRST_DPHY_RX | SD_SRST_DMA_IF);
    487 
    488 	delay(50);
    489 
    490 	SDHC_WRITE(sc, SD_SRST_REG, 0);
    491 
    492 	delay(10);
    493 
    494 	SDHC_WRITE(sc, SD_CNTL_REG,
    495 	    __SHIFTIN(0x7, SD_CNTL_TX_ENDIAN_CTRL) |
    496 	    __SHIFTIN(0x7, SD_CNTL_RX_ENDIAN_CTRL) |
    497 	    __SHIFTIN(0xf, SD_CNTL_RX_PERIOD) |
    498 	    __SHIFTIN(0x7f, SD_CNTL_RX_TIMEOUT));
    499 
    500 	SDHC_WRITE(sc, SD_CLKC_REG,
    501 	    SDHC_READ(sc, SD_CLKC_REG) & ~SD_CLKC_MEM_PWR);
    502 
    503 	SDHC_WRITE(sc, SD_PDMA_REG,
    504 	    __SHIFTIN(7, SD_PDMA_TX_BURST_LEN) |
    505 	    __SHIFTIN(49, SD_PDMA_TXFIFO_THRESHOLD) |
    506 	    __SHIFTIN(15, SD_PDMA_RX_BURST_LEN) |
    507 	    __SHIFTIN(7, SD_PDMA_RXFIFO_THRESHOLD) |
    508 	    SD_PDMA_DMA_URGENT);
    509 
    510 	SDHC_WRITE(sc, SD_MISC_REG,
    511 	    __SHIFTIN(7, SD_MISC_TXSTART_THRESHOLD) |
    512 	    __SHIFTIN(5, SD_MISC_WCRC_ERR_PATTERN) |
    513 	    __SHIFTIN(2, SD_MISC_WCRC_OK_PATTERN));
    514 
    515 	enhc = SDHC_READ(sc, SD_ENHC_REG);
    516 	enhc &= ~SD_ENHC_RXFIFO_THRESHOLD;
    517 	enhc |= __SHIFTIN(63, SD_ENHC_RXFIFO_THRESHOLD);
    518 	enhc &= ~SD_ENHC_DMA_RX_RESP;
    519 	enhc |= SD_ENHC_DMA_TX_RESP;
    520 	enhc &= ~SD_ENHC_SDIO_IRQ_PERIOD;
    521 	enhc |= __SHIFTIN(12, SD_ENHC_SDIO_IRQ_PERIOD);
    522 	enhc &= ~SD_ENHC_RX_TIMEOUT;
    523 	enhc |= __SHIFTIN(0xff, SD_ENHC_RX_TIMEOUT);
    524 	SDHC_WRITE(sc, SD_ENHC_REG, enhc);
    525 
    526 	SDHC_WRITE(sc, SD_ICTL_REG, 0);
    527 	SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
    528 
    529 	return 0;
    530 }
    531 
    532 static uint32_t
    533 meson_sdhc_host_ocr(sdmmc_chipset_handle_t sch)
    534 {
    535 	return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V |
    536 	       MMC_OCR_HCS | MMC_OCR_S18A;
    537 }
    538 
    539 static int
    540 meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)
    541 {
    542 	return 512;
    543 }
    544 
    545 static int
    546 meson_sdhc_card_detect(sdmmc_chipset_handle_t sch)
    547 {
    548 	struct meson_sdhc_softc *sc = sch;
    549 	int val;
    550 
    551 	if (sc->sc_non_removable || sc->sc_broken_cd) {
    552 		return 1;
    553 	} else if (sc->sc_gpio_cd != NULL) {
    554 		val = fdtbus_gpio_read(sc->sc_gpio_cd);
    555 		if (sc->sc_gpio_cd_inverted)
    556 			val = !val;
    557 		return val;
    558 	} else {
    559 		return 1;
    560 	}
    561 }
    562 
    563 static int
    564 meson_sdhc_write_protect(sdmmc_chipset_handle_t sch)
    565 {
    566 	struct meson_sdhc_softc *sc = sch;
    567 	int val;
    568 
    569 	if (sc->sc_gpio_wp != NULL) {
    570 		val = fdtbus_gpio_read(sc->sc_gpio_wp);
    571 		if (sc->sc_gpio_wp_inverted)
    572 			val = !val;
    573 		return val;
    574 	}
    575 
    576 	return 0;
    577 }
    578 
    579 static int
    580 meson_sdhc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
    581 {
    582 	return 0;
    583 }
    584 
    585 static int
    586 meson_sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
    587 {
    588 	struct meson_sdhc_softc *sc = sch;
    589 
    590 	return meson_sdhc_set_clock(sc, freq);
    591 }
    592 
    593 static int
    594 meson_sdhc_bus_width(sdmmc_chipset_handle_t sch, int width)
    595 {
    596 	struct meson_sdhc_softc *sc = sch;
    597 	uint32_t cntl;
    598 
    599 	cntl = SDHC_READ(sc, SD_CNTL_REG);
    600 	cntl &= ~SD_CNTL_DAT_TYPE;
    601 	switch (width) {
    602 	case 1:
    603 		cntl |= __SHIFTIN(0, SD_CNTL_DAT_TYPE);
    604 		break;
    605 	case 4:
    606 		cntl |= __SHIFTIN(1, SD_CNTL_DAT_TYPE);
    607 		break;
    608 	case 8:
    609 		cntl |= __SHIFTIN(2, SD_CNTL_DAT_TYPE);
    610 		break;
    611 	default:
    612 		return EINVAL;
    613 	}
    614 
    615 	SDHC_WRITE(sc, SD_CNTL_REG, cntl);
    616 
    617 	return 0;
    618 }
    619 
    620 static int
    621 meson_sdhc_bus_rod(sdmmc_chipset_handle_t sch, int on)
    622 {
    623 	return ENOTSUP;
    624 }
    625 
    626 static void
    627 meson_sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
    628 {
    629 	struct meson_sdhc_softc *sc = sch;
    630 	uint32_t cmdval = 0, cntl, srst, pdma, ictl;
    631 	bool use_bbuf = false;
    632 	int i;
    633 
    634 	KASSERT(cmd->c_blklen <= 512);
    635 
    636 	mutex_enter(&sc->sc_intr_lock);
    637 
    638 	/* Filter SDIO commands */
    639 	switch (cmd->c_opcode) {
    640 	case SD_IO_SEND_OP_COND:
    641 	case SD_IO_RW_DIRECT:
    642 	case SD_IO_RW_EXTENDED:
    643 		cmd->c_error = EINVAL;
    644 		goto done;
    645 	}
    646 
    647 	if (cmd->c_opcode == MMC_STOP_TRANSMISSION)
    648 		cmdval |= SD_SEND_DATA_STOP;
    649 	if (cmd->c_flags & SCF_RSP_PRESENT)
    650 		cmdval |= SD_SEND_COMMAND_HAS_RESP;
    651 	if (cmd->c_flags & SCF_RSP_136) {
    652 		cmdval |= SD_SEND_RESPONSE_LENGTH;
    653 		cmdval |= SD_SEND_RESPONSE_NO_CRC;
    654 	}
    655 	if ((cmd->c_flags & SCF_RSP_CRC) == 0)
    656 		cmdval |= SD_SEND_RESPONSE_NO_CRC;
    657 
    658 	SDHC_WRITE(sc, SD_ICTL_REG, 0);
    659 	SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
    660 	sc->sc_intr_ista = 0;
    661 
    662 	ictl = SD_INT_ERROR;
    663 
    664 	cntl = SDHC_READ(sc, SD_CNTL_REG);
    665 	cntl &= ~SD_CNTL_PACK_LEN;
    666 	if (cmd->c_datalen > 0) {
    667 		unsigned int nblks;
    668 
    669 		cmdval |= SD_SEND_COMMAND_HAS_DATA;
    670 		if (!ISSET(cmd->c_flags, SCF_CMD_READ)) {
    671 			cmdval |= SD_SEND_DATA_DIRECTION;
    672 		}
    673 
    674 		nblks = cmd->c_datalen / cmd->c_blklen;
    675 		if (nblks == 0 || (cmd->c_datalen % cmd->c_blklen) != 0)
    676 			++nblks;
    677 
    678 		cntl |= __SHIFTIN(cmd->c_blklen & 0x1ff, SD_CNTL_PACK_LEN);
    679 
    680 		cmdval |= __SHIFTIN(nblks - 1, SD_SEND_TOTAL_PACK);
    681 
    682 		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    683 			ictl |= SD_INT_DATA_COMPLETE;
    684 		} else {
    685 			ictl |= SD_INT_DMA_DONE;
    686 		}
    687 	} else {
    688 		ictl |= SD_INT_RESP_COMPLETE;
    689 	}
    690 
    691 	SDHC_WRITE(sc, SD_ICTL_REG, ictl);
    692 
    693 	SDHC_WRITE(sc, SD_CNTL_REG, cntl);
    694 
    695 	pdma = SDHC_READ(sc, SD_PDMA_REG);
    696 	if (cmd->c_datalen > 0) {
    697 		pdma |= SD_PDMA_DMA_MODE;
    698 	} else {
    699 		pdma &= ~SD_PDMA_DMA_MODE;
    700 	}
    701 	SDHC_WRITE(sc, SD_PDMA_REG, pdma);
    702 
    703 	SDHC_WRITE(sc, SD_ARGU_REG, cmd->c_arg);
    704 
    705 	cmd->c_error = meson_sdhc_wait_idle(sc);
    706 	if (cmd->c_error) {
    707 		goto done;
    708 	}
    709 
    710 	if (cmd->c_datalen > 0) {
    711 		cmd->c_error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap,
    712 		    sc->sc_bbuf, MAXPHYS, NULL, BUS_DMA_WAITOK);
    713 		if (cmd->c_error) {
    714 			device_printf(sc->sc_dev, "bus_dmamap_load failed\n");
    715 			goto done;
    716 		}
    717 		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    718 			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
    719 			    MAXPHYS, BUS_DMASYNC_PREREAD);
    720 		} else {
    721 			memcpy(sc->sc_bbuf, cmd->c_data, cmd->c_datalen);
    722 			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
    723 			    MAXPHYS, BUS_DMASYNC_PREWRITE);
    724 		}
    725 		SDHC_WRITE(sc, SD_ADDR_REG, sc->sc_dmamap->dm_segs[0].ds_addr);
    726 		use_bbuf = true;
    727 	}
    728 
    729 	cmd->c_resid = cmd->c_datalen;
    730 	SDHC_WRITE(sc, SD_SEND_REG, cmdval | cmd->c_opcode);
    731 
    732 	if (cmd->c_datalen > 0) {
    733 		uint32_t wbit = ISSET(cmd->c_flags, SCF_CMD_READ) ?
    734 		    SD_INT_DATA_COMPLETE : SD_INT_DMA_DONE;
    735 		cmd->c_error = meson_sdhc_wait_ista(sc,
    736 		    SD_INT_ERROR | wbit, hz * 10);
    737 		if (cmd->c_error == 0 &&
    738 		    (sc->sc_intr_ista & SD_INT_ERROR)) {
    739 			cmd->c_error = ETIMEDOUT;
    740 		}
    741 		if (cmd->c_error) {
    742 			goto done;
    743 		}
    744 	} else {
    745 		cmd->c_error = meson_sdhc_wait_ista(sc,
    746 		    SD_INT_ERROR | SD_INT_RESP_COMPLETE, hz * 10);
    747 		if (cmd->c_error == 0 && (sc->sc_intr_ista & SD_INT_ERROR)) {
    748 			if (sc->sc_intr_ista & SD_INT_TIMEOUT) {
    749 				cmd->c_error = ETIMEDOUT;
    750 			} else {
    751 				cmd->c_error = EIO;
    752 			}
    753 		}
    754 		if (cmd->c_error) {
    755 			goto done;
    756 		}
    757 	}
    758 
    759 	SDHC_WRITE(sc, SD_ISTA_REG, sc->sc_intr_ista);
    760 
    761 	if (cmd->c_flags & SCF_RSP_PRESENT) {
    762 		pdma = SDHC_READ(sc, SD_PDMA_REG);
    763 		pdma &= ~SD_PDMA_DMA_MODE;
    764 		if (cmd->c_flags & SCF_RSP_136) {
    765 			for (i = 4; i >= 1; i--) {
    766 				pdma &= ~SD_PDMA_PIO_RDRESP;
    767 				pdma |= __SHIFTIN(i, SD_PDMA_PIO_RDRESP);
    768 				SDHC_WRITE(sc, SD_PDMA_REG, pdma);
    769 				cmd->c_resp[i - 1] = SDHC_READ(sc, SD_ARGU_REG);
    770 
    771 			}
    772 			if (cmd->c_flags & SCF_RSP_CRC) {
    773 				cmd->c_resp[0] = (cmd->c_resp[0] >> 8) |
    774 				    (cmd->c_resp[1] << 24);
    775 				cmd->c_resp[1] = (cmd->c_resp[1] >> 8) |
    776 				    (cmd->c_resp[2] << 24);
    777 				cmd->c_resp[2] = (cmd->c_resp[2] >> 8) |
    778 				    (cmd->c_resp[3] << 24);
    779 				cmd->c_resp[3] = (cmd->c_resp[3] >> 8);
    780 			}
    781 		} else {
    782 			pdma &= ~SD_PDMA_PIO_RDRESP;
    783 			pdma |= __SHIFTIN(0, SD_PDMA_PIO_RDRESP);
    784 			SDHC_WRITE(sc, SD_PDMA_REG, pdma);
    785 			cmd->c_resp[0] = SDHC_READ(sc, SD_ARGU_REG);
    786 		}
    787 	}
    788 
    789 done:
    790 	if (use_bbuf) {
    791 		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    792 			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
    793 			    MAXPHYS, BUS_DMASYNC_POSTREAD);
    794 		} else {
    795 			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
    796 			    MAXPHYS, BUS_DMASYNC_POSTWRITE);
    797 		}
    798 		bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap);
    799 		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
    800 			memcpy(cmd->c_data, sc->sc_bbuf, cmd->c_datalen);
    801 		}
    802 	}
    803 
    804 	cmd->c_flags |= SCF_ITSDONE;
    805 
    806 	SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
    807 	SDHC_WRITE(sc, SD_ICTL_REG, 0);
    808 
    809 	srst = SDHC_READ(sc, SD_SRST_REG);
    810 	srst |= (SD_SRST_TX_FIFO | SD_SRST_RX_FIFO);
    811 	SDHC_WRITE(sc, SD_SRST_REG, srst);
    812 
    813 	mutex_exit(&sc->sc_intr_lock);
    814 }
    815 
    816 static void
    817 meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
    818 {
    819 }
    820 
    821 static void
    822 meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
    823 {
    824 }
    825 
    826 static int
    827 meson_sdhc_signal_voltage(sdmmc_chipset_handle_t sch, int signal_voltage)
    828 {
    829 	struct meson_sdhc_softc *sc = sch;
    830 	u_int uvol;
    831 	int error;
    832 
    833 	if (sc->sc_reg_vqmmc == NULL)
    834 		return 0;
    835 
    836 	switch (signal_voltage) {
    837 	case SDMMC_SIGNAL_VOLTAGE_330:
    838 		uvol = 3300000;
    839 		break;
    840 	case SDMMC_SIGNAL_VOLTAGE_180:
    841 		uvol = 1800000;
    842 		break;
    843 	default:
    844 		return EINVAL;
    845 	}
    846 
    847 	error = fdtbus_regulator_supports_voltage(sc->sc_reg_vqmmc, uvol, uvol);
    848 	if (error != 0)
    849 		return 0;
    850 
    851 	error = fdtbus_regulator_set_voltage(sc->sc_reg_vqmmc, uvol, uvol);
    852 	if (error != 0)
    853 		return error;
    854 
    855 	error = fdtbus_regulator_enable(sc->sc_reg_vqmmc);
    856 	if (error != 0)
    857 		return error;
    858 
    859 	sc->sc_signal_voltage = signal_voltage;
    860 	return 0;
    861 }
    862 
    863 static int
    864 meson_sdhc_execute_tuning(sdmmc_chipset_handle_t sch, int timing)
    865 {
    866 	static const uint8_t tuning_blk_8bit[] = {
    867 		0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
    868 		0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
    869 		0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
    870 		0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
    871 		0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
    872 		0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
    873 		0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
    874 		0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
    875 		0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
    876 		0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
    877 		0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
    878 		0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
    879 		0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
    880 		0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
    881 		0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
    882 		0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
    883 	};
    884 	static const uint8_t tuning_blk_4bit[] = {
    885 		0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
    886 		0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
    887 		0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
    888 		0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
    889 		0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
    890 		0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
    891 		0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
    892 		0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
    893 	};
    894 
    895 	struct meson_sdhc_softc *sc = sch;
    896 	struct sdmmc_command cmd;
    897 	uint8_t data[sizeof(tuning_blk_8bit)];
    898 	const uint8_t *tblk;
    899 	size_t tsize;
    900 	struct window_s {
    901 		int start;
    902 		u_int size;
    903 	} best = { .start = -1, .size = 0 },
    904 	  curr = { .start = -1, .size = 0 },
    905 	  wrap = { .start =  0, .size = 0 };
    906 	u_int ph, rx_phase, clk_div;
    907 	int opcode;
    908 
    909 	switch (timing) {
    910 	case SDMMC_TIMING_MMC_HS200:
    911 		tblk = tuning_blk_8bit;
    912 		tsize = sizeof(tuning_blk_8bit);
    913 		opcode = MMC_SEND_TUNING_BLOCK_HS200;
    914 		break;
    915 	case SDMMC_TIMING_UHS_SDR50:
    916 	case SDMMC_TIMING_UHS_SDR104:
    917 		tblk = tuning_blk_4bit;
    918 		tsize = sizeof(tuning_blk_4bit);
    919 		opcode = MMC_SEND_TUNING_BLOCK;
    920 		break;
    921 	default:
    922 		return EINVAL;
    923 	}
    924 
    925 	const uint32_t clkc = SDHC_READ(sc, SD_CLKC_REG);
    926 	clk_div = __SHIFTOUT(clkc, SD_CLKC_CLK_DIV);
    927 
    928 	for (ph = 0; ph <= clk_div; ph++) {
    929 		SDHC_SET_CLEAR(sc, SD_CLK2_REG,
    930 		    __SHIFTIN(ph, SD_CLK2_RX_CLK_PHASE), SD_CLK2_RX_CLK_PHASE);
    931 		delay(10);
    932 
    933 		u_int nmatch = 0;
    934 #define NUMTRIES 10
    935 		for (u_int i = 0; i < NUMTRIES; i++) {
    936 			memset(data, 0, tsize);
    937 			memset(&cmd, 0, sizeof(cmd));
    938 			cmd.c_data = data;
    939 			cmd.c_datalen = cmd.c_blklen = tsize;
    940 			cmd.c_opcode = opcode;
    941 			cmd.c_arg = 0;
    942 			cmd.c_flags = SCF_CMD_ADTC | SCF_CMD_READ | SCF_RSP_R1;
    943 			meson_sdhc_exec_command(sc, &cmd);
    944 			if (cmd.c_error == 0 && memcmp(data, tblk, tsize) == 0)
    945 				nmatch++;
    946 		}
    947 		if (nmatch == NUMTRIES) {	/* good phase value */
    948 			if (wrap.start == 0)
    949 				wrap.size++;
    950 			if (curr.start == -1)
    951 				curr.start = ph;
    952 			curr.size++;
    953 		} else {
    954 			wrap.start = -1;
    955 			if (curr.start != -1) {	/* end of current window */
    956 				if (best.start == -1 || best.size < curr.size)
    957 					best = curr;
    958 				curr = (struct window_s)
    959 				    { .start = -1, .size = 0 };
    960 			}
    961 		}
    962 #undef NUMTRIES
    963 	}
    964 
    965 	if (curr.start != -1) {	/* the current window wraps around */
    966 		curr.size += wrap.size;
    967 		if (curr.size > ph)
    968 			curr.size = ph;
    969 		if (best.start == -1 || best.size < curr.size)
    970 			best = curr;
    971 	}
    972 
    973 	if (best.start == -1) {	/* no window - use default rx_phase */
    974 		rx_phase = meson_sdhc_default_rx_phase(sc);
    975 	} else {
    976 		rx_phase = best.start + best.size / 2;
    977 		if (rx_phase >= ph)
    978 			rx_phase -= ph;
    979 	}
    980 
    981 	SDHC_SET_CLEAR(sc, SD_CLK2_REG,
    982 	    __SHIFTIN(rx_phase, SD_CLK2_RX_CLK_PHASE), SD_CLK2_RX_CLK_PHASE);
    983 
    984 	return 0;
    985 }
    986