aml8726_sdxc-m8.c revision 318197
1/*-
2 * Copyright 2015 John Wehle <john@feith.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Amlogic aml8726-m8 (and later) SDXC host controller driver.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/11/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c 318197 2017-05-11 20:55:11Z marius $");
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/bus.h>
37#include <sys/kernel.h>
38#include <sys/module.h>
39#include <sys/lock.h>
40#include <sys/mutex.h>
41#include <sys/resource.h>
42#include <sys/rman.h>
43
44#include <sys/gpio.h>
45
46#include <machine/bus.h>
47#include <machine/cpu.h>
48
49#include <dev/fdt/fdt_common.h>
50#include <dev/ofw/ofw_bus.h>
51#include <dev/ofw/ofw_bus_subr.h>
52
53#include <dev/mmc/bridge.h>
54#include <dev/mmc/mmcreg.h>
55#include <dev/mmc/mmcbrvar.h>
56
57#include <arm/amlogic/aml8726/aml8726_soc.h>
58#include <arm/amlogic/aml8726/aml8726_sdxc-m8.h>
59
60#include "gpio_if.h"
61#include "mmcbr_if.h"
62
63/*
64 * The table is sorted from highest to lowest and
65 * last entry in the table is mark by freq == 0.
66 */
67struct {
68	uint32_t	voltage;
69	uint32_t	freq;
70	uint32_t	rx_phase;
71} aml8726_sdxc_clk_phases[] = {
72	{
73		MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340,
74		100000000,
75		1
76	},
77	{
78		MMC_OCR_320_330 | MMC_OCR_330_340,
79		45000000,
80		15
81	},
82	{
83		MMC_OCR_LOW_VOLTAGE,
84		45000000,
85		11
86	},
87	{
88		MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340,
89		24999999,
90		15
91	},
92	{
93		MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340,
94		5000000,
95		23
96	},
97	{
98		MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340,
99		1000000,
100		55
101	},
102	{
103		MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340,
104		0,
105		1061
106	},
107};
108
109struct aml8726_sdxc_gpio {
110	device_t	dev;
111	uint32_t	pin;
112	uint32_t	pol;
113};
114
115struct aml8726_sdxc_softc {
116	device_t		dev;
117	boolean_t		auto_fill_flush;
118	struct resource		*res[2];
119	struct mtx		mtx;
120	struct callout		ch;
121	unsigned int		ref_freq;
122	struct aml8726_sdxc_gpio pwr_en;
123	int			voltages[2];
124	struct aml8726_sdxc_gpio vselect;
125	struct aml8726_sdxc_gpio card_rst;
126	bus_dma_tag_t		dmatag;
127	bus_dmamap_t		dmamap;
128	void			*ih_cookie;
129	struct mmc_host		host;
130	int			bus_busy;
131	struct {
132		uint32_t	time;
133		uint32_t	error;
134	} busy;
135	struct mmc_command 	*cmd;
136};
137
138static struct resource_spec aml8726_sdxc_spec[] = {
139	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
140	{ SYS_RES_IRQ,		0,	RF_ACTIVE },
141	{ -1, 0 }
142};
143
144#define	AML_SDXC_LOCK(sc)		mtx_lock(&(sc)->mtx)
145#define	AML_SDXC_UNLOCK(sc)		mtx_unlock(&(sc)->mtx)
146#define	AML_SDXC_LOCK_ASSERT(sc)	mtx_assert(&(sc)->mtx, MA_OWNED)
147#define	AML_SDXC_LOCK_INIT(sc)		\
148    mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev),	\
149    "sdxc", MTX_DEF)
150#define	AML_SDXC_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->mtx);
151
152#define	CSR_WRITE_4(sc, reg, val)	bus_write_4((sc)->res[0], reg, (val))
153#define	CSR_READ_4(sc, reg)		bus_read_4((sc)->res[0], reg)
154#define	CSR_BARRIER(sc, reg)		bus_barrier((sc)->res[0], reg, 4, \
155    (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE))
156
157#define	PIN_ON_FLAG(pol)		((pol) == 0 ? \
158    GPIO_PIN_LOW : GPIO_PIN_HIGH)
159#define	PIN_OFF_FLAG(pol)		((pol) == 0 ? \
160    GPIO_PIN_HIGH : GPIO_PIN_LOW)
161
162#define	msecs_to_ticks(ms)		(((ms)*hz)/1000 + 1)
163
164static void aml8726_sdxc_timeout(void *arg);
165
166static void
167aml8726_sdxc_mapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error)
168{
169	bus_addr_t *busaddrp;
170
171	/*
172	 * There should only be one bus space address since
173	 * bus_dma_tag_create was called with nsegments = 1.
174	 */
175
176	 busaddrp = (bus_addr_t *)arg;
177	 *busaddrp = segs->ds_addr;
178}
179
180static int
181aml8726_sdxc_power_off(struct aml8726_sdxc_softc *sc)
182{
183
184	if (sc->pwr_en.dev == NULL)
185		return (0);
186
187	return (GPIO_PIN_SET(sc->pwr_en.dev, sc->pwr_en.pin,
188	    PIN_OFF_FLAG(sc->pwr_en.pol)));
189}
190
191static int
192aml8726_sdxc_power_on(struct aml8726_sdxc_softc *sc)
193{
194
195	if (sc->pwr_en.dev == NULL)
196		return (0);
197
198	return (GPIO_PIN_SET(sc->pwr_en.dev, sc->pwr_en.pin,
199	    PIN_ON_FLAG(sc->pwr_en.pol)));
200}
201
202static void
203aml8726_sdxc_soft_reset(struct aml8726_sdxc_softc *sc)
204{
205
206	CSR_WRITE_4(sc, AML_SDXC_SOFT_RESET_REG, AML_SDXC_SOFT_RESET);
207	CSR_BARRIER(sc, AML_SDXC_SOFT_RESET_REG);
208	DELAY(5);
209}
210
211static void
212aml8726_sdxc_engage_dma(struct aml8726_sdxc_softc *sc)
213{
214	int i;
215	uint32_t pdmar;
216	uint32_t sr;
217	struct mmc_data *data;
218
219	data = sc->cmd->data;
220
221	if (data == NULL || data->len == 0)
222		return;
223
224	/*
225	 * Engaging the DMA hardware is recommended before writing
226	 * to AML_SDXC_SEND_REG so that the FIFOs are ready to go.
227	 *
228	 * Presumably AML_SDXC_CNTRL_REG and AML_SDXC_DMA_ADDR_REG
229	 * must be set up prior to this happening.
230	 */
231
232	pdmar = CSR_READ_4(sc, AML_SDXC_PDMA_REG);
233
234	pdmar &= ~AML_SDXC_PDMA_RX_FLUSH_MODE_SW;
235	pdmar |= AML_SDXC_PDMA_DMA_EN;
236
237	if (sc->auto_fill_flush == true) {
238		CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
239		CSR_BARRIER(sc, AML_SDXC_PDMA_REG);
240		return;
241	}
242
243	if ((data->flags & MMC_DATA_READ) != 0) {
244		pdmar |= AML_SDXC_PDMA_RX_FLUSH_MODE_SW;
245		CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
246		CSR_BARRIER(sc, AML_SDXC_PDMA_REG);
247	} else {
248		pdmar |= AML_SDXC_PDMA_TX_FILL;
249		CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
250		CSR_BARRIER(sc, AML_SDXC_PDMA_REG);
251
252		/*
253		 * Wait up to 100us for data to show up.
254		 */
255		for (i = 0; i < 100; i++) {
256			sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG);
257			if ((sr & AML_SDXC_STATUS_TX_CNT_MASK) != 0)
258				break;
259			DELAY(1);
260		}
261		if (i >= 100)
262			device_printf(sc->dev, "TX FIFO fill timeout\n");
263	}
264}
265
266static void
267aml8726_sdxc_disengage_dma(struct aml8726_sdxc_softc *sc)
268{
269	int i;
270	uint32_t pdmar;
271	uint32_t sr;
272	struct mmc_data *data;
273
274	data = sc->cmd->data;
275
276	if (data == NULL || data->len == 0)
277		return;
278
279	pdmar = CSR_READ_4(sc, AML_SDXC_PDMA_REG);
280
281	if (sc->auto_fill_flush == true) {
282		pdmar &= ~AML_SDXC_PDMA_DMA_EN;
283		CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
284		CSR_BARRIER(sc, AML_SDXC_PDMA_REG);
285		return;
286	}
287
288	if ((data->flags & MMC_DATA_READ) != 0) {
289		pdmar |= AML_SDXC_PDMA_RX_FLUSH_NOW;
290		CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
291		CSR_BARRIER(sc, AML_SDXC_PDMA_REG);
292
293		/*
294		 * Wait up to 100us for data to drain.
295		 */
296		for (i = 0; i < 100; i++) {
297			sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG);
298			if ((sr & AML_SDXC_STATUS_RX_CNT_MASK) == 0)
299				break;
300			DELAY(1);
301		}
302		if (i >= 100)
303			device_printf(sc->dev, "RX FIFO drain timeout\n");
304	}
305
306	pdmar &= ~(AML_SDXC_PDMA_DMA_EN | AML_SDXC_PDMA_RX_FLUSH_MODE_SW);
307
308	CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
309	CSR_BARRIER(sc, AML_SDXC_PDMA_REG);
310}
311
312static int
313aml8726_sdxc_start_command(struct aml8726_sdxc_softc *sc,
314    struct mmc_command *cmd)
315{
316	bus_addr_t baddr;
317	uint32_t block_size;
318	uint32_t ctlr;
319	uint32_t ier;
320	uint32_t sndr;
321	uint32_t timeout;
322	int error;
323	struct mmc_data *data;
324
325	AML_SDXC_LOCK_ASSERT(sc);
326
327	if (cmd->opcode > 0x3f)
328		return (MMC_ERR_INVALID);
329
330	/*
331	 * Ensure the hardware state machine is in a known state.
332	 */
333	aml8726_sdxc_soft_reset(sc);
334
335	sndr = cmd->opcode;
336
337	if ((cmd->flags & MMC_RSP_136) != 0) {
338		sndr |= AML_SDXC_SEND_CMD_HAS_RESP;
339		sndr |= AML_SDXC_SEND_RESP_136;
340		/*
341		 * According to the SD spec the 136 bit response is
342		 * used for getting the CID or CSD in which case the
343		 * CRC7 is embedded in the contents rather than being
344		 * calculated over the entire response (the controller
345		 * always checks the CRC7 over the entire response).
346		 */
347		sndr |= AML_SDXC_SEND_RESP_NO_CRC7_CHECK;
348	} else if ((cmd->flags & MMC_RSP_PRESENT) != 0)
349		sndr |= AML_SDXC_SEND_CMD_HAS_RESP;
350
351	if ((cmd->flags & MMC_RSP_CRC) == 0)
352		sndr |= AML_SDXC_SEND_RESP_NO_CRC7_CHECK;
353
354	if (cmd->opcode == MMC_STOP_TRANSMISSION)
355		sndr |= AML_SDXC_SEND_DATA_STOP;
356
357	data = cmd->data;
358
359	baddr = 0;
360	ctlr = CSR_READ_4(sc, AML_SDXC_CNTRL_REG);
361	ier = AML_SDXC_IRQ_ENABLE_STANDARD;
362	timeout = AML_SDXC_CMD_TIMEOUT;
363
364	ctlr &= ~AML_SDXC_CNTRL_PKG_LEN_MASK;
365
366	if (data && data->len &&
367	    (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) {
368		block_size = data->len;
369
370		if ((data->flags & MMC_DATA_MULTI) != 0) {
371			block_size = MMC_SECTOR_SIZE;
372			if ((data->len % block_size) != 0)
373				return (MMC_ERR_INVALID);
374		}
375
376		if (block_size > 512)
377			return (MMC_ERR_INVALID);
378
379		sndr |= AML_SDXC_SEND_CMD_HAS_DATA;
380		sndr |= ((data->flags & MMC_DATA_WRITE) != 0) ?
381		    AML_SDXC_SEND_DATA_WRITE : 0;
382		sndr |= (((data->len / block_size) - 1) <<
383		    AML_SDXC_SEND_REP_PKG_CNT_SHIFT);
384
385		ctlr |= ((block_size < 512) ? block_size : 0) <<
386		    AML_SDXC_CNTRL_PKG_LEN_SHIFT;
387
388		ier &= ~AML_SDXC_IRQ_ENABLE_RESP_OK;
389		ier |= (sc->auto_fill_flush == true ||
390		    (data->flags & MMC_DATA_WRITE) != 0) ?
391		    AML_SDXC_IRQ_ENABLE_DMA_DONE :
392		    AML_SDXC_IRQ_ENABLE_TRANSFER_DONE_OK;
393
394		error = bus_dmamap_load(sc->dmatag, sc->dmamap,
395		    data->data, data->len, aml8726_sdxc_mapmem, &baddr,
396		    BUS_DMA_NOWAIT);
397		if (error)
398			return (MMC_ERR_NO_MEMORY);
399
400		if ((data->flags & MMC_DATA_READ) != 0) {
401			bus_dmamap_sync(sc->dmatag, sc->dmamap,
402			    BUS_DMASYNC_PREREAD);
403			timeout = AML_SDXC_READ_TIMEOUT *
404			    (data->len / block_size);
405		} else {
406			bus_dmamap_sync(sc->dmatag, sc->dmamap,
407			    BUS_DMASYNC_PREWRITE);
408			timeout = AML_SDXC_WRITE_TIMEOUT *
409			    (data->len / block_size);
410		}
411	}
412
413	sc->cmd = cmd;
414
415	cmd->error = MMC_ERR_NONE;
416
417	sc->busy.time = 0;
418	sc->busy.error = MMC_ERR_NONE;
419
420	if (timeout > AML_SDXC_MAX_TIMEOUT)
421		timeout = AML_SDXC_MAX_TIMEOUT;
422
423	callout_reset(&sc->ch, msecs_to_ticks(timeout),
424	    aml8726_sdxc_timeout, sc);
425
426	CSR_WRITE_4(sc, AML_SDXC_IRQ_ENABLE_REG, ier);
427
428	CSR_WRITE_4(sc, AML_SDXC_CNTRL_REG, ctlr);
429	CSR_WRITE_4(sc, AML_SDXC_DMA_ADDR_REG, (uint32_t)baddr);
430	CSR_WRITE_4(sc, AML_SDXC_CMD_ARGUMENT_REG, cmd->arg);
431
432	aml8726_sdxc_engage_dma(sc);
433
434	CSR_WRITE_4(sc, AML_SDXC_SEND_REG, sndr);
435	CSR_BARRIER(sc, AML_SDXC_SEND_REG);
436
437	return (MMC_ERR_NONE);
438}
439
440static void
441aml8726_sdxc_finish_command(struct aml8726_sdxc_softc *sc, int mmc_error)
442{
443	int mmc_stop_error;
444	struct mmc_command *cmd;
445	struct mmc_command *stop_cmd;
446	struct mmc_data *data;
447
448	AML_SDXC_LOCK_ASSERT(sc);
449
450	/* Clear all interrupts since the request is no longer in flight. */
451	CSR_WRITE_4(sc, AML_SDXC_IRQ_STATUS_REG, AML_SDXC_IRQ_STATUS_CLEAR);
452	CSR_BARRIER(sc, AML_SDXC_IRQ_STATUS_REG);
453
454	/* In some cases (e.g. finish called via timeout) this is a NOP. */
455	callout_stop(&sc->ch);
456
457	cmd = sc->cmd;
458	sc->cmd = NULL;
459
460	cmd->error = mmc_error;
461
462	data = cmd->data;
463
464	if (data && data->len
465	    && (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) {
466		if ((data->flags & MMC_DATA_READ) != 0)
467			bus_dmamap_sync(sc->dmatag, sc->dmamap,
468			    BUS_DMASYNC_POSTREAD);
469		else
470			bus_dmamap_sync(sc->dmatag, sc->dmamap,
471			    BUS_DMASYNC_POSTWRITE);
472		bus_dmamap_unload(sc->dmatag, sc->dmamap);
473	}
474
475	/*
476	 * If there's a linked stop command, then start the stop command.
477	 * In order to establish a known state attempt the stop command
478	 * even if the original request encountered an error.
479	 */
480
481	stop_cmd = (cmd->mrq->stop != cmd) ? cmd->mrq->stop : NULL;
482
483	if (stop_cmd != NULL) {
484
485		/*
486		 * If the original command executed successfully, then
487		 * the hardware will also have automatically executed
488		 * a stop command so don't bother with the one supplied
489		 * with the original request.
490		 */
491
492		if (mmc_error == MMC_ERR_NONE) {
493			stop_cmd->error = MMC_ERR_NONE;
494			stop_cmd->resp[0] = cmd->resp[0];
495			stop_cmd->resp[1] = cmd->resp[1];
496			stop_cmd->resp[2] = cmd->resp[2];
497			stop_cmd->resp[3] = cmd->resp[3];
498		} else {
499			mmc_stop_error = aml8726_sdxc_start_command(sc,
500			    stop_cmd);
501			if (mmc_stop_error == MMC_ERR_NONE) {
502				AML_SDXC_UNLOCK(sc);
503				return;
504			}
505			stop_cmd->error = mmc_stop_error;
506		}
507	}
508
509	AML_SDXC_UNLOCK(sc);
510
511	/* Execute the callback after dropping the lock. */
512	if (cmd->mrq != NULL)
513		cmd->mrq->done(cmd->mrq);
514}
515
516static void
517aml8726_sdxc_timeout(void *arg)
518{
519	struct aml8726_sdxc_softc *sc = (struct aml8726_sdxc_softc *)arg;
520
521	/*
522	 * The command failed to complete in time so forcefully
523	 * terminate it.
524	 */
525	aml8726_sdxc_soft_reset(sc);
526
527	/*
528	 * Ensure the command has terminated before continuing on
529	 * to things such as bus_dmamap_sync / bus_dmamap_unload.
530	 */
531	while ((CSR_READ_4(sc, AML_SDXC_STATUS_REG) &
532	    AML_SDXC_STATUS_BUSY) != 0)
533		cpu_spinwait();
534
535	aml8726_sdxc_finish_command(sc, MMC_ERR_TIMEOUT);
536}
537
538static void
539aml8726_sdxc_busy_check(void *arg)
540{
541	struct aml8726_sdxc_softc *sc = (struct aml8726_sdxc_softc *)arg;
542	uint32_t sr;
543
544	sc->busy.time += AML_SDXC_BUSY_POLL_INTVL;
545
546	sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG);
547
548	if ((sr & AML_SDXC_STATUS_DAT0) == 0) {
549		if (sc->busy.time < AML_SDXC_BUSY_TIMEOUT) {
550			callout_reset(&sc->ch,
551			    msecs_to_ticks(AML_SDXC_BUSY_POLL_INTVL),
552			    aml8726_sdxc_busy_check, sc);
553			AML_SDXC_UNLOCK(sc);
554			return;
555		}
556		if (sc->busy.error == MMC_ERR_NONE)
557			sc->busy.error = MMC_ERR_TIMEOUT;
558	}
559
560	aml8726_sdxc_finish_command(sc, sc->busy.error);
561}
562
563static void
564aml8726_sdxc_intr(void *arg)
565{
566	struct aml8726_sdxc_softc *sc = (struct aml8726_sdxc_softc *)arg;
567	uint32_t isr;
568	uint32_t pdmar;
569	uint32_t sndr;
570	uint32_t sr;
571	int i;
572	int mmc_error;
573	int start;
574	int stop;
575
576	AML_SDXC_LOCK(sc);
577
578	isr = CSR_READ_4(sc, AML_SDXC_IRQ_STATUS_REG);
579	sndr = CSR_READ_4(sc, AML_SDXC_SEND_REG);
580	sr = CSR_READ_4(sc, AML_SDXC_STATUS_REG);
581
582	if (sc->cmd == NULL)
583		goto spurious;
584
585	mmc_error = MMC_ERR_NONE;
586
587	if ((isr & (AML_SDXC_IRQ_STATUS_TX_FIFO_EMPTY |
588	    AML_SDXC_IRQ_STATUS_RX_FIFO_FULL)) != 0)
589		mmc_error = MMC_ERR_FIFO;
590	else if ((isr & (AML_SDXC_IRQ_ENABLE_A_PKG_CRC_ERR |
591	    AML_SDXC_IRQ_ENABLE_RESP_CRC_ERR)) != 0)
592		mmc_error = MMC_ERR_BADCRC;
593	else if ((isr & (AML_SDXC_IRQ_ENABLE_A_PKG_TIMEOUT_ERR |
594	    AML_SDXC_IRQ_ENABLE_RESP_TIMEOUT_ERR)) != 0)
595		mmc_error = MMC_ERR_TIMEOUT;
596	else if ((isr & (AML_SDXC_IRQ_STATUS_RESP_OK |
597	    AML_SDXC_IRQ_STATUS_DMA_DONE |
598	    AML_SDXC_IRQ_STATUS_TRANSFER_DONE_OK)) != 0) {
599		;
600	}
601	else {
602spurious:
603		/*
604		 * Clear spurious interrupts while leaving intacted any
605		 * interrupts that may have occurred after we read the
606		 * interrupt status register.
607		 */
608
609		CSR_WRITE_4(sc, AML_SDXC_IRQ_STATUS_REG,
610		    (AML_SDXC_IRQ_STATUS_CLEAR & isr));
611		CSR_BARRIER(sc, AML_SDXC_IRQ_STATUS_REG);
612		AML_SDXC_UNLOCK(sc);
613		return;
614	}
615
616	aml8726_sdxc_disengage_dma(sc);
617
618	if ((sndr & AML_SDXC_SEND_CMD_HAS_RESP) != 0) {
619		start = 0;
620		stop = 1;
621		if ((sndr & AML_SDXC_SEND_RESP_136) != 0) {
622			start = 1;
623			stop = start + 4;
624		}
625		for (i = start; i < stop; i++) {
626			pdmar = CSR_READ_4(sc, AML_SDXC_PDMA_REG);
627			pdmar &= ~(AML_SDXC_PDMA_DMA_EN |
628			    AML_SDXC_PDMA_RESP_INDEX_MASK);
629			pdmar |= i << AML_SDXC_PDMA_RESP_INDEX_SHIFT;
630			CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
631			sc->cmd->resp[(stop - 1) - i] = CSR_READ_4(sc,
632			    AML_SDXC_CMD_ARGUMENT_REG);
633		}
634	}
635
636	if ((sr & AML_SDXC_STATUS_BUSY) != 0 &&
637	    /*
638	     * A multiblock operation may keep the hardware
639	     * busy until stop transmission is executed.
640	     */
641	    (isr & (AML_SDXC_IRQ_STATUS_DMA_DONE |
642	    AML_SDXC_IRQ_STATUS_TRANSFER_DONE_OK)) == 0) {
643		if (mmc_error == MMC_ERR_NONE)
644			mmc_error = MMC_ERR_FAILED;
645
646		/*
647		 * Issue a soft reset to terminate the command.
648		 *
649		 * Ensure the command has terminated before continuing on
650		 * to things such as bus_dmamap_sync / bus_dmamap_unload.
651		 */
652
653		aml8726_sdxc_soft_reset(sc);
654
655		while ((CSR_READ_4(sc, AML_SDXC_STATUS_REG) &
656		    AML_SDXC_STATUS_BUSY) != 0)
657			cpu_spinwait();
658	}
659
660	/*
661	 * The stop command can be generated either manually or
662	 * automatically by the hardware if MISC_MANUAL_STOP_MODE
663	 * has not been set.  In either case check for busy.
664	 */
665
666	if (((sc->cmd->flags & MMC_RSP_BUSY) != 0 ||
667	    (sndr & AML_SDXC_SEND_INDEX_MASK) == MMC_STOP_TRANSMISSION) &&
668	    (sr & AML_SDXC_STATUS_DAT0) == 0) {
669		sc->busy.error = mmc_error;
670		callout_reset(&sc->ch,
671		    msecs_to_ticks(AML_SDXC_BUSY_POLL_INTVL),
672		    aml8726_sdxc_busy_check, sc);
673		CSR_WRITE_4(sc, AML_SDXC_IRQ_STATUS_REG,
674		    (AML_SDXC_IRQ_STATUS_CLEAR & isr));
675		CSR_BARRIER(sc, AML_SDXC_IRQ_STATUS_REG);
676		AML_SDXC_UNLOCK(sc);
677		return;
678	}
679
680	aml8726_sdxc_finish_command(sc, mmc_error);
681}
682
683static int
684aml8726_sdxc_probe(device_t dev)
685{
686
687	if (!ofw_bus_status_okay(dev))
688		return (ENXIO);
689
690	if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-sdxc-m8"))
691		return (ENXIO);
692
693	device_set_desc(dev, "Amlogic aml8726-m8 SDXC");
694
695	return (BUS_PROBE_DEFAULT);
696}
697
698static int
699aml8726_sdxc_attach(device_t dev)
700{
701	struct aml8726_sdxc_softc *sc = device_get_softc(dev);
702	char *voltages;
703	char *voltage;
704	int error;
705	int nvoltages;
706	pcell_t prop[3];
707	phandle_t node;
708	ssize_t len;
709	device_t child;
710	uint32_t ectlr;
711	uint32_t miscr;
712	uint32_t pdmar;
713
714	sc->dev = dev;
715
716	sc->auto_fill_flush = false;
717
718	pdmar = AML_SDXC_PDMA_DMA_URGENT |
719	    (49 << AML_SDXC_PDMA_TX_THOLD_SHIFT) |
720	    (7 << AML_SDXC_PDMA_RX_THOLD_SHIFT) |
721	    (15 << AML_SDXC_PDMA_RD_BURST_SHIFT) |
722	    (7 << AML_SDXC_PDMA_WR_BURST_SHIFT);
723
724	miscr = (2 << AML_SDXC_MISC_WCRC_OK_PAT_SHIFT) |
725	    (5 << AML_SDXC_MISC_WCRC_ERR_PAT_SHIFT);
726
727	ectlr = (12 << AML_SDXC_ENH_CNTRL_SDIO_IRQ_PERIOD_SHIFT);
728
729	/*
730	 * Certain bitfields are dependent on the hardware revision.
731	 */
732	switch (aml8726_soc_hw_rev) {
733	case AML_SOC_HW_REV_M8:
734		switch (aml8726_soc_metal_rev) {
735		case AML_SOC_M8_METAL_REV_M2_A:
736			sc->auto_fill_flush = true;
737			miscr |= (6 << AML_SDXC_MISC_TXSTART_THOLD_SHIFT);
738			ectlr |= (64 << AML_SDXC_ENH_CNTRL_RX_FULL_THOLD_SHIFT) |
739			    AML_SDXC_ENH_CNTRL_WR_RESP_MODE_SKIP_M8M2;
740			break;
741		default:
742			miscr |= (7 << AML_SDXC_MISC_TXSTART_THOLD_SHIFT);
743			ectlr |= (63 << AML_SDXC_ENH_CNTRL_RX_FULL_THOLD_SHIFT) |
744			    AML_SDXC_ENH_CNTRL_DMA_NO_WR_RESP_CHECK_M8 |
745			    (255 << AML_SDXC_ENH_CNTRL_RX_TIMEOUT_SHIFT_M8);
746
747			break;
748		}
749		break;
750	case AML_SOC_HW_REV_M8B:
751		miscr |= (7 << AML_SDXC_MISC_TXSTART_THOLD_SHIFT);
752		ectlr |= (63 << AML_SDXC_ENH_CNTRL_RX_FULL_THOLD_SHIFT) |
753		    AML_SDXC_ENH_CNTRL_DMA_NO_WR_RESP_CHECK_M8 |
754		    (255 << AML_SDXC_ENH_CNTRL_RX_TIMEOUT_SHIFT_M8);
755		break;
756	default:
757		device_printf(dev, "unsupported SoC\n");
758		return (ENXIO);
759		/* NOTREACHED */
760	}
761
762	node = ofw_bus_get_node(dev);
763
764	len = OF_getencprop(node, "clock-frequency", prop, sizeof(prop));
765	if ((len / sizeof(prop[0])) != 1 || prop[0] == 0) {
766		device_printf(dev,
767		    "missing clock-frequency attribute in FDT\n");
768		return (ENXIO);
769	}
770
771	sc->ref_freq = prop[0];
772
773	sc->pwr_en.dev = NULL;
774
775	len = OF_getencprop(node, "mmc-pwr-en", prop, sizeof(prop));
776	if (len > 0) {
777		if ((len / sizeof(prop[0])) == 3) {
778			sc->pwr_en.dev = OF_device_from_xref(prop[0]);
779			sc->pwr_en.pin = prop[1];
780			sc->pwr_en.pol = prop[2];
781		}
782
783		if (sc->pwr_en.dev == NULL) {
784			device_printf(dev,
785			    "unable to process mmc-pwr-en attribute in FDT\n");
786			return (ENXIO);
787		}
788
789		/* Turn off power and then configure the output driver. */
790		if (aml8726_sdxc_power_off(sc) != 0 ||
791		    GPIO_PIN_SETFLAGS(sc->pwr_en.dev, sc->pwr_en.pin,
792		    GPIO_PIN_OUTPUT) != 0) {
793			device_printf(dev,
794			    "could not use gpio to control power\n");
795			return (ENXIO);
796		}
797	}
798
799	len = OF_getprop_alloc(node, "mmc-voltages",
800	    sizeof(char), (void **)&voltages);
801
802	if (len < 0) {
803		device_printf(dev, "missing mmc-voltages attribute in FDT\n");
804		return (ENXIO);
805	}
806
807	sc->voltages[0] = 0;
808	sc->voltages[1] = 0;
809
810	voltage = voltages;
811	nvoltages = 0;
812
813	while (len && nvoltages < 2) {
814		if (strncmp("1.8", voltage, len) == 0)
815			sc->voltages[nvoltages] = MMC_OCR_LOW_VOLTAGE;
816		else if (strncmp("3.3", voltage, len) == 0)
817			sc->voltages[nvoltages] = MMC_OCR_320_330 |
818			    MMC_OCR_330_340;
819		else {
820			device_printf(dev,
821			    "unknown voltage attribute %.*s in FDT\n",
822			    len, voltage);
823			OF_prop_free(voltages);
824			return (ENXIO);
825		}
826
827		nvoltages++;
828
829		/* queue up next string */
830		while (*voltage && len) {
831			voltage++;
832			len--;
833		}
834		if (len) {
835			voltage++;
836			len--;
837		}
838	}
839
840	OF_prop_free(voltages);
841
842	sc->vselect.dev = NULL;
843
844	len = OF_getencprop(node, "mmc-vselect", prop, sizeof(prop));
845	if (len > 0) {
846		if ((len / sizeof(prop[0])) == 2) {
847			sc->vselect.dev = OF_device_from_xref(prop[0]);
848			sc->vselect.pin = prop[1];
849			sc->vselect.pol = 1;
850		}
851
852		if (sc->vselect.dev == NULL) {
853			device_printf(dev,
854			    "unable to process mmc-vselect attribute in FDT\n");
855			return (ENXIO);
856		}
857
858		/*
859		 * With the power off select voltage 0 and then
860		 * configure the output driver.
861		 */
862		if (GPIO_PIN_SET(sc->vselect.dev, sc->vselect.pin, 0) != 0 ||
863		    GPIO_PIN_SETFLAGS(sc->vselect.dev, sc->vselect.pin,
864		    GPIO_PIN_OUTPUT) != 0) {
865			device_printf(dev,
866			    "could not use gpio to set voltage\n");
867			return (ENXIO);
868		}
869	}
870
871	if (nvoltages == 0) {
872		device_printf(dev, "no voltages in FDT\n");
873		return (ENXIO);
874	} else if (nvoltages == 1 && sc->vselect.dev != NULL) {
875		device_printf(dev, "only one voltage in FDT\n");
876		return (ENXIO);
877	} else if (nvoltages == 2 && sc->vselect.dev == NULL) {
878		device_printf(dev, "too many voltages in FDT\n");
879		return (ENXIO);
880	}
881
882	sc->card_rst.dev = NULL;
883
884	len = OF_getencprop(node, "mmc-rst", prop, sizeof(prop));
885	if (len > 0) {
886		if ((len / sizeof(prop[0])) == 3) {
887			sc->card_rst.dev = OF_device_from_xref(prop[0]);
888			sc->card_rst.pin = prop[1];
889			sc->card_rst.pol = prop[2];
890		}
891
892		if (sc->card_rst.dev == NULL) {
893			device_printf(dev,
894			    "unable to process mmc-rst attribute in FDT\n");
895			return (ENXIO);
896		}
897	}
898
899	if (bus_alloc_resources(dev, aml8726_sdxc_spec, sc->res)) {
900		device_printf(dev, "could not allocate resources for device\n");
901		return (ENXIO);
902	}
903
904	AML_SDXC_LOCK_INIT(sc);
905
906	error = bus_dma_tag_create(bus_get_dma_tag(dev), AML_SDXC_ALIGN_DMA, 0,
907	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
908	    AML_SDXC_MAX_DMA, 1, AML_SDXC_MAX_DMA, 0, NULL, NULL, &sc->dmatag);
909	if (error)
910		goto fail;
911
912	error = bus_dmamap_create(sc->dmatag, 0, &sc->dmamap);
913
914	if (error)
915		goto fail;
916
917	error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
918	    NULL, aml8726_sdxc_intr, sc, &sc->ih_cookie);
919	if (error) {
920		device_printf(dev, "could not setup interrupt handler\n");
921		goto fail;
922	}
923
924	callout_init_mtx(&sc->ch, &sc->mtx, CALLOUT_RETURNUNLOCKED);
925
926	sc->host.f_min = 200000;
927	sc->host.f_max = 100000000;
928	sc->host.host_ocr = sc->voltages[0] | sc->voltages[1];
929	sc->host.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
930	    MMC_CAP_HSPEED;
931
932	aml8726_sdxc_soft_reset(sc);
933
934	CSR_WRITE_4(sc, AML_SDXC_PDMA_REG, pdmar);
935
936	CSR_WRITE_4(sc, AML_SDXC_MISC_REG, miscr);
937
938	CSR_WRITE_4(sc, AML_SDXC_ENH_CNTRL_REG, ectlr);
939
940	child = device_add_child(dev, "mmc", -1);
941
942	if (!child) {
943		device_printf(dev, "could not add mmc\n");
944		error = ENXIO;
945		goto fail;
946	}
947
948	error = device_probe_and_attach(child);
949
950	if (error) {
951		device_printf(dev, "could not attach mmc\n");
952		goto fail;
953	}
954
955	return (0);
956
957fail:
958	if (sc->ih_cookie)
959		bus_teardown_intr(dev, sc->res[1], sc->ih_cookie);
960
961	if (sc->dmamap)
962		bus_dmamap_destroy(sc->dmatag, sc->dmamap);
963
964	if (sc->dmatag)
965		bus_dma_tag_destroy(sc->dmatag);
966
967	AML_SDXC_LOCK_DESTROY(sc);
968
969	(void)aml8726_sdxc_power_off(sc);
970
971	bus_release_resources(dev, aml8726_sdxc_spec, sc->res);
972
973	return (error);
974}
975
976static int
977aml8726_sdxc_detach(device_t dev)
978{
979	struct aml8726_sdxc_softc *sc = device_get_softc(dev);
980
981	AML_SDXC_LOCK(sc);
982
983	if (sc->cmd != NULL) {
984		AML_SDXC_UNLOCK(sc);
985		return (EBUSY);
986	}
987
988	/*
989	 * Turn off the power, reset the hardware state machine,
990	 * and disable the interrupts.
991	 */
992	aml8726_sdxc_power_off(sc);
993	aml8726_sdxc_soft_reset(sc);
994	CSR_WRITE_4(sc, AML_SDXC_IRQ_ENABLE_REG, 0);
995
996	AML_SDXC_UNLOCK(sc);
997
998	bus_generic_detach(dev);
999
1000	bus_teardown_intr(dev, sc->res[1], sc->ih_cookie);
1001
1002	bus_dmamap_destroy(sc->dmatag, sc->dmamap);
1003
1004	bus_dma_tag_destroy(sc->dmatag);
1005
1006	AML_SDXC_LOCK_DESTROY(sc);
1007
1008	bus_release_resources(dev, aml8726_sdxc_spec, sc->res);
1009
1010	return (0);
1011}
1012
1013static int
1014aml8726_sdxc_shutdown(device_t dev)
1015{
1016	struct aml8726_sdxc_softc *sc = device_get_softc(dev);
1017
1018	/*
1019	 * Turn off the power, reset the hardware state machine,
1020	 * and disable the interrupts.
1021	 */
1022	aml8726_sdxc_power_off(sc);
1023	aml8726_sdxc_soft_reset(sc);
1024	CSR_WRITE_4(sc, AML_SDXC_IRQ_ENABLE_REG, 0);
1025
1026	return (0);
1027}
1028
1029static int
1030aml8726_sdxc_update_ios(device_t bus, device_t child)
1031{
1032	struct aml8726_sdxc_softc *sc = device_get_softc(bus);
1033	struct mmc_ios *ios = &sc->host.ios;
1034	unsigned int divisor;
1035	int error;
1036	int i;
1037	uint32_t cctlr;
1038	uint32_t clk2r;
1039	uint32_t ctlr;
1040	uint32_t freq;
1041
1042	ctlr = (7 << AML_SDXC_CNTRL_TX_ENDIAN_SHIFT) |
1043	    (7 << AML_SDXC_CNTRL_RX_ENDIAN_SHIFT) |
1044	    (0xf << AML_SDXC_CNTRL_RX_PERIOD_SHIFT) |
1045	    (0x7f << AML_SDXC_CNTRL_RX_TIMEOUT_SHIFT);
1046
1047	switch (ios->bus_width) {
1048	case bus_width_8:
1049		ctlr |= AML_SDXC_CNTRL_BUS_WIDTH_8;
1050		break;
1051	case bus_width_4:
1052		ctlr |= AML_SDXC_CNTRL_BUS_WIDTH_4;
1053		break;
1054	case bus_width_1:
1055		ctlr |= AML_SDXC_CNTRL_BUS_WIDTH_1;
1056		break;
1057	default:
1058		return (EINVAL);
1059	}
1060
1061	CSR_WRITE_4(sc, AML_SDXC_CNTRL_REG, ctlr);
1062
1063	/*
1064	 * Disable clocks and then clock module prior to setting desired values.
1065	 */
1066	cctlr = CSR_READ_4(sc, AML_SDXC_CLK_CNTRL_REG);
1067	cctlr &= ~(AML_SDXC_CLK_CNTRL_TX_CLK_EN | AML_SDXC_CLK_CNTRL_RX_CLK_EN |
1068	    AML_SDXC_CLK_CNTRL_SD_CLK_EN);
1069	CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr);
1070	CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG);
1071	cctlr &= ~AML_SDXC_CLK_CNTRL_CLK_MODULE_EN;
1072	CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr);
1073	CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG);
1074
1075	/*
1076	 *                  aml8726-m8
1077	 *
1078	 * Clock select 1   fclk_div2 (1.275 GHz)
1079	 */
1080	cctlr &= ~AML_SDXC_CLK_CNTRL_CLK_SEL_MASK;
1081	cctlr |= (1 << AML_SDXC_CLK_CNTRL_CLK_SEL_SHIFT);
1082
1083	divisor = sc->ref_freq / ios->clock - 1;
1084	if (divisor == 0 || divisor == -1)
1085		divisor = 1;
1086	if ((sc->ref_freq / (divisor + 1)) > ios->clock)
1087		divisor += 1;
1088	if (divisor > (AML_SDXC_CLK_CNTRL_CLK_DIV_MASK >>
1089	    AML_SDXC_CLK_CNTRL_CLK_DIV_SHIFT))
1090		divisor = AML_SDXC_CLK_CNTRL_CLK_DIV_MASK >>
1091		    AML_SDXC_CLK_CNTRL_CLK_DIV_SHIFT;
1092
1093	cctlr &= ~AML_SDXC_CLK_CNTRL_CLK_DIV_MASK;
1094	cctlr |= divisor << AML_SDXC_CLK_CNTRL_CLK_DIV_SHIFT;
1095
1096	cctlr &= ~AML_SDXC_CLK_CNTRL_MEM_PWR_MASK;
1097	cctlr |= AML_SDXC_CLK_CNTRL_MEM_PWR_ON;
1098
1099	CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr);
1100	CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG);
1101
1102	/*
1103	 * Enable clock module and then clocks after setting desired values.
1104	 */
1105	cctlr |= AML_SDXC_CLK_CNTRL_CLK_MODULE_EN;
1106	CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr);
1107	CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG);
1108	cctlr |= AML_SDXC_CLK_CNTRL_TX_CLK_EN | AML_SDXC_CLK_CNTRL_RX_CLK_EN |
1109	    AML_SDXC_CLK_CNTRL_SD_CLK_EN;
1110	CSR_WRITE_4(sc, AML_SDXC_CLK_CNTRL_REG, cctlr);
1111	CSR_BARRIER(sc, AML_SDXC_CLK_CNTRL_REG);
1112
1113	freq = sc->ref_freq / divisor;
1114
1115	for (i = 0; aml8726_sdxc_clk_phases[i].voltage; i++) {
1116		if ((aml8726_sdxc_clk_phases[i].voltage &
1117		    (1 << ios->vdd)) != 0 &&
1118		    freq > aml8726_sdxc_clk_phases[i].freq)
1119			break;
1120		if (aml8726_sdxc_clk_phases[i].freq == 0)
1121			break;
1122	}
1123
1124	clk2r = (1 << AML_SDXC_CLK2_SD_PHASE_SHIFT) |
1125	    (aml8726_sdxc_clk_phases[i].rx_phase <<
1126	    AML_SDXC_CLK2_RX_PHASE_SHIFT);
1127	CSR_WRITE_4(sc, AML_SDXC_CLK2_REG, clk2r);
1128	CSR_BARRIER(sc, AML_SDXC_CLK2_REG);
1129
1130	error = 0;
1131
1132	switch (ios->power_mode) {
1133	case power_up:
1134		/*
1135		 * Configure and power on the regulator so that the
1136		 * voltage stabilizes prior to powering on the card.
1137		 */
1138		if (sc->vselect.dev != NULL) {
1139			for (i = 0; i < 2; i++)
1140				if ((sc->voltages[i] & (1 << ios->vdd)) != 0)
1141					break;
1142			if (i >= 2)
1143				return (EINVAL);
1144			error = GPIO_PIN_SET(sc->vselect.dev,
1145			    sc->vselect.pin, i);
1146		}
1147		break;
1148	case power_on:
1149		error = aml8726_sdxc_power_on(sc);
1150		if (error)
1151			break;
1152
1153		if (sc->card_rst.dev != NULL) {
1154			if (GPIO_PIN_SET(sc->card_rst.dev, sc->card_rst.pin,
1155			    PIN_ON_FLAG(sc->card_rst.pol)) != 0 ||
1156			    GPIO_PIN_SETFLAGS(sc->card_rst.dev,
1157			    sc->card_rst.pin,
1158			    GPIO_PIN_OUTPUT) != 0)
1159				error = ENXIO;
1160
1161			DELAY(5);
1162
1163			if (GPIO_PIN_SET(sc->card_rst.dev, sc->card_rst.pin,
1164			    PIN_OFF_FLAG(sc->card_rst.pol)) != 0)
1165				error = ENXIO;
1166
1167			DELAY(5);
1168
1169			if (error) {
1170				device_printf(sc->dev,
1171				    "could not use gpio to reset card\n");
1172				break;
1173			}
1174		}
1175		break;
1176	case power_off:
1177		error = aml8726_sdxc_power_off(sc);
1178		break;
1179	default:
1180		return (EINVAL);
1181	}
1182
1183	return (error);
1184}
1185
1186static int
1187aml8726_sdxc_request(device_t bus, device_t child, struct mmc_request *req)
1188{
1189	struct aml8726_sdxc_softc *sc = device_get_softc(bus);
1190	int mmc_error;
1191
1192	AML_SDXC_LOCK(sc);
1193
1194	if (sc->cmd != NULL) {
1195		AML_SDXC_UNLOCK(sc);
1196		return (EBUSY);
1197	}
1198
1199	mmc_error = aml8726_sdxc_start_command(sc, req->cmd);
1200
1201	AML_SDXC_UNLOCK(sc);
1202
1203	/* Execute the callback after dropping the lock. */
1204	if (mmc_error != MMC_ERR_NONE) {
1205		req->cmd->error = mmc_error;
1206		req->done(req);
1207	}
1208
1209	return (0);
1210}
1211
1212static int
1213aml8726_sdxc_read_ivar(device_t bus, device_t child,
1214    int which, uintptr_t *result)
1215{
1216	struct aml8726_sdxc_softc *sc = device_get_softc(bus);
1217
1218	switch (which) {
1219	case MMCBR_IVAR_BUS_MODE:
1220		*(int *)result = sc->host.ios.bus_mode;
1221		break;
1222	case MMCBR_IVAR_BUS_WIDTH:
1223		*(int *)result = sc->host.ios.bus_width;
1224		break;
1225	case MMCBR_IVAR_CHIP_SELECT:
1226		*(int *)result = sc->host.ios.chip_select;
1227		break;
1228	case MMCBR_IVAR_CLOCK:
1229		*(int *)result = sc->host.ios.clock;
1230		break;
1231	case MMCBR_IVAR_F_MIN:
1232		*(int *)result = sc->host.f_min;
1233		break;
1234	case MMCBR_IVAR_F_MAX:
1235		*(int *)result = sc->host.f_max;
1236		break;
1237	case MMCBR_IVAR_HOST_OCR:
1238		*(int *)result = sc->host.host_ocr;
1239		break;
1240	case MMCBR_IVAR_MODE:
1241		*(int *)result = sc->host.mode;
1242		break;
1243	case MMCBR_IVAR_OCR:
1244		*(int *)result = sc->host.ocr;
1245		break;
1246	case MMCBR_IVAR_POWER_MODE:
1247		*(int *)result = sc->host.ios.power_mode;
1248		break;
1249	case MMCBR_IVAR_VDD:
1250		*(int *)result = sc->host.ios.vdd;
1251		break;
1252	case MMCBR_IVAR_CAPS:
1253		*(int *)result = sc->host.caps;
1254		break;
1255	case MMCBR_IVAR_MAX_DATA:
1256		*(int *)result = AML_SDXC_MAX_DMA / MMC_SECTOR_SIZE;
1257		break;
1258	default:
1259		return (EINVAL);
1260	}
1261
1262	return (0);
1263}
1264
1265static int
1266aml8726_sdxc_write_ivar(device_t bus, device_t child,
1267    int which, uintptr_t value)
1268{
1269	struct aml8726_sdxc_softc *sc = device_get_softc(bus);
1270
1271	switch (which) {
1272	case MMCBR_IVAR_BUS_MODE:
1273		sc->host.ios.bus_mode = value;
1274		break;
1275	case MMCBR_IVAR_BUS_WIDTH:
1276		sc->host.ios.bus_width = value;
1277		break;
1278	case MMCBR_IVAR_CHIP_SELECT:
1279		sc->host.ios.chip_select = value;
1280		break;
1281	case MMCBR_IVAR_CLOCK:
1282		sc->host.ios.clock = value;
1283		break;
1284	case MMCBR_IVAR_MODE:
1285		sc->host.mode = value;
1286		break;
1287	case MMCBR_IVAR_OCR:
1288		sc->host.ocr = value;
1289		break;
1290	case MMCBR_IVAR_POWER_MODE:
1291		sc->host.ios.power_mode = value;
1292		break;
1293	case MMCBR_IVAR_VDD:
1294		sc->host.ios.vdd = value;
1295		break;
1296	/* These are read-only */
1297	case MMCBR_IVAR_CAPS:
1298	case MMCBR_IVAR_HOST_OCR:
1299	case MMCBR_IVAR_F_MIN:
1300	case MMCBR_IVAR_F_MAX:
1301	case MMCBR_IVAR_MAX_DATA:
1302	default:
1303		return (EINVAL);
1304	}
1305
1306	return (0);
1307}
1308
1309static int
1310aml8726_sdxc_get_ro(device_t bus, device_t child)
1311{
1312
1313	return (0);
1314}
1315
1316static int
1317aml8726_sdxc_acquire_host(device_t bus, device_t child)
1318{
1319	struct aml8726_sdxc_softc *sc = device_get_softc(bus);
1320
1321	AML_SDXC_LOCK(sc);
1322
1323	while (sc->bus_busy)
1324		mtx_sleep(sc, &sc->mtx, PZERO, "sdxc", hz / 5);
1325	sc->bus_busy++;
1326
1327	AML_SDXC_UNLOCK(sc);
1328
1329	return (0);
1330}
1331
1332static int
1333aml8726_sdxc_release_host(device_t bus, device_t child)
1334{
1335	struct aml8726_sdxc_softc *sc = device_get_softc(bus);
1336
1337	AML_SDXC_LOCK(sc);
1338
1339	sc->bus_busy--;
1340	wakeup(sc);
1341
1342	AML_SDXC_UNLOCK(sc);
1343
1344	return (0);
1345}
1346
1347static device_method_t aml8726_sdxc_methods[] = {
1348	/* Device interface */
1349	DEVMETHOD(device_probe,		aml8726_sdxc_probe),
1350	DEVMETHOD(device_attach,	aml8726_sdxc_attach),
1351	DEVMETHOD(device_detach,	aml8726_sdxc_detach),
1352	DEVMETHOD(device_shutdown,	aml8726_sdxc_shutdown),
1353
1354	/* Bus interface */
1355	DEVMETHOD(bus_read_ivar,	aml8726_sdxc_read_ivar),
1356	DEVMETHOD(bus_write_ivar,	aml8726_sdxc_write_ivar),
1357
1358	/* MMC bridge interface */
1359	DEVMETHOD(mmcbr_update_ios,	aml8726_sdxc_update_ios),
1360	DEVMETHOD(mmcbr_request,	aml8726_sdxc_request),
1361	DEVMETHOD(mmcbr_get_ro,		aml8726_sdxc_get_ro),
1362	DEVMETHOD(mmcbr_acquire_host,	aml8726_sdxc_acquire_host),
1363	DEVMETHOD(mmcbr_release_host,	aml8726_sdxc_release_host),
1364
1365	DEVMETHOD_END
1366};
1367
1368static driver_t aml8726_sdxc_driver = {
1369	"aml8726_sdxc",
1370	aml8726_sdxc_methods,
1371	sizeof(struct aml8726_sdxc_softc),
1372};
1373
1374static devclass_t aml8726_sdxc_devclass;
1375
1376DRIVER_MODULE(aml8726_sdxc, simplebus, aml8726_sdxc_driver,
1377    aml8726_sdxc_devclass, NULL, NULL);
1378MODULE_DEPEND(aml8726_sdxc, aml8726_gpio, 1, 1, 1);
1379MMC_DECLARE_BRIDGE(aml8726_sdxc);
1380