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@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
48enum {
49	SDHC_PORT_A = 0,
50	SDHC_PORT_B = 1,
51	SDHC_PORT_C = 2
52};
53
54static int	meson_sdhc_match(device_t, cfdata_t, void *);
55static void	meson_sdhc_attach(device_t, device_t, void *);
56static void	meson_sdhc_attach_i(device_t);
57
58static int	meson_sdhc_intr(void *);
59
60struct 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
95CFATTACH_DECL_NEW(meson_sdhc, sizeof(struct meson_sdhc_softc),
96	meson_sdhc_match, meson_sdhc_attach, NULL, NULL);
97
98static int	meson_sdhc_host_reset(sdmmc_chipset_handle_t);
99static uint32_t	meson_sdhc_host_ocr(sdmmc_chipset_handle_t);
100static int	meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t);
101static int	meson_sdhc_card_detect(sdmmc_chipset_handle_t);
102static int	meson_sdhc_write_protect(sdmmc_chipset_handle_t);
103static int	meson_sdhc_bus_power(sdmmc_chipset_handle_t, uint32_t);
104static int	meson_sdhc_bus_clock(sdmmc_chipset_handle_t, int);
105static int	meson_sdhc_bus_width(sdmmc_chipset_handle_t, int);
106static int	meson_sdhc_bus_rod(sdmmc_chipset_handle_t, int);
107static void	meson_sdhc_exec_command(sdmmc_chipset_handle_t,
108				     struct sdmmc_command *);
109static void	meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t, int);
110static void	meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t);
111static int	meson_sdhc_signal_voltage(sdmmc_chipset_handle_t, int);
112static int	meson_sdhc_execute_tuning(sdmmc_chipset_handle_t, int);
113
114static int	meson_sdhc_default_rx_phase(struct meson_sdhc_softc *);
115static int	meson_sdhc_set_clock(struct meson_sdhc_softc *, u_int);
116static int	meson_sdhc_wait_idle(struct meson_sdhc_softc *);
117static int	meson_sdhc_wait_ista(struct meson_sdhc_softc *, uint32_t, int);
118
119static void	meson_sdhc_dmainit(struct meson_sdhc_softc *);
120
121static 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
144static inline void
145meson_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
153static const struct device_compatible_entry compat_data[] = {
154	{ .compat = "amlogic,meson8-sdhc" },
155	{ .compat = "amlogic,meson8b-sdhc" },	/* DTCOMPAT */
156	DEVICE_COMPAT_EOL
157};
158
159static const struct device_compatible_entry slot_compat_data[] = {
160	{ .compat = "mmc-slot" },
161	DEVICE_COMPAT_EOL
162};
163
164static int
165meson_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
172static void
173meson_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
272static void
273meson_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
307static int
308meson_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
331static void
332meson_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
360static int
361meson_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
387static int
388meson_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
437static int
438meson_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
454static int
455meson_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
478static int
479meson_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
532static uint32_t
533meson_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
539static int
540meson_sdhc_host_maxblklen(sdmmc_chipset_handle_t sch)
541{
542	return 512;
543}
544
545static int
546meson_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
563static int
564meson_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
579static int
580meson_sdhc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
581{
582	return 0;
583}
584
585static int
586meson_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
593static int
594meson_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
620static int
621meson_sdhc_bus_rod(sdmmc_chipset_handle_t sch, int on)
622{
623	return ENOTSUP;
624}
625
626static void
627meson_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
789done:
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
816static void
817meson_sdhc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
818{
819}
820
821static void
822meson_sdhc_card_intr_ack(sdmmc_chipset_handle_t sch)
823{
824}
825
826static int
827meson_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
863static int
864meson_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