fsl_sdhc.c revision 318198
1/*-
2 * Copyright (c) 2011-2012 Semihalf
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 * Driver for Freescale integrated eSDHC controller.
29 * Limitations:
30 * 	- No support for multi-block transfers.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: stable/10/sys/powerpc/mpc85xx/fsl_sdhc.c 318198 2017-05-11 21:01:02Z marius $");
35
36#include <sys/param.h>
37#include <sys/bus.h>
38#include <sys/kernel.h>
39#include <sys/lock.h>
40#include <sys/module.h>
41#include <sys/mutex.h>
42#include <sys/rman.h>
43#include <sys/sysctl.h>
44#include <sys/systm.h>
45#include <sys/taskqueue.h>
46
47#include <machine/bus.h>
48#include <machine/vmparam.h>
49
50#include <dev/fdt/fdt_common.h>
51#include <dev/ofw/ofw_bus.h>
52#include <dev/ofw/ofw_bus_subr.h>
53
54#include <dev/mmc/bridge.h>
55#include <dev/mmc/mmcreg.h>
56#include <dev/mmc/mmcvar.h>
57#include <dev/mmc/mmcbrvar.h>
58
59#include <powerpc/mpc85xx/mpc85xx.h>
60
61#include "opt_platform.h"
62
63#include "mmcbr_if.h"
64
65#include "fsl_sdhc.h"
66
67#ifdef DEBUG
68#define	DPRINTF(fmt, arg...)	printf("DEBUG %s(): " fmt, __FUNCTION__, ##arg)
69#else
70#define	DPRINTF(fmt, arg...)
71#endif
72
73
74/*****************************************************************************
75 * Register the driver
76 *****************************************************************************/
77/* Forward declarations */
78static int	fsl_sdhc_probe(device_t);
79static int	fsl_sdhc_attach(device_t);
80static int	fsl_sdhc_detach(device_t);
81
82static int	fsl_sdhc_read_ivar(device_t, device_t, int, uintptr_t *);
83static int	fsl_sdhc_write_ivar(device_t, device_t, int, uintptr_t);
84
85static int	fsl_sdhc_update_ios(device_t, device_t);
86static int	fsl_sdhc_request(device_t, device_t, struct mmc_request *);
87static int	fsl_sdhc_get_ro(device_t, device_t);
88static int	fsl_sdhc_acquire_host(device_t, device_t);
89static int	fsl_sdhc_release_host(device_t, device_t);
90
91static device_method_t fsl_sdhc_methods[] = {
92	/* device_if */
93	DEVMETHOD(device_probe, fsl_sdhc_probe),
94	DEVMETHOD(device_attach, fsl_sdhc_attach),
95	DEVMETHOD(device_detach, fsl_sdhc_detach),
96
97	/* Bus interface */
98	DEVMETHOD(bus_read_ivar, fsl_sdhc_read_ivar),
99	DEVMETHOD(bus_write_ivar, fsl_sdhc_write_ivar),
100
101	/* OFW bus interface */
102	DEVMETHOD(ofw_bus_get_compat,   ofw_bus_gen_get_compat),
103	DEVMETHOD(ofw_bus_get_model,    ofw_bus_gen_get_model),
104	DEVMETHOD(ofw_bus_get_name,     ofw_bus_gen_get_name),
105	DEVMETHOD(ofw_bus_get_node,     ofw_bus_gen_get_node),
106	DEVMETHOD(ofw_bus_get_type,     ofw_bus_gen_get_type),
107
108	/* mmcbr_if */
109	DEVMETHOD(mmcbr_update_ios, fsl_sdhc_update_ios),
110	DEVMETHOD(mmcbr_request, fsl_sdhc_request),
111	DEVMETHOD(mmcbr_get_ro, fsl_sdhc_get_ro),
112	DEVMETHOD(mmcbr_acquire_host, fsl_sdhc_acquire_host),
113	DEVMETHOD(mmcbr_release_host, fsl_sdhc_release_host),
114
115	{0, 0},
116};
117
118/* kobj_class definition */
119static driver_t fsl_sdhc_driver = {
120	"sdhci",
121	fsl_sdhc_methods,
122	sizeof(struct fsl_sdhc_softc)
123};
124
125static devclass_t fsl_sdhc_devclass;
126
127DRIVER_MODULE(sdhci, simplebus, fsl_sdhc_driver, fsl_sdhc_devclass, 0, 0);
128DRIVER_MODULE(mmc, sdhci_fsl, mmc_driver, mmc_devclass, NULL, NULL);
129MODULE_DEPEND(sdhci_fsl, mmc, 1, 1, 1);
130
131/*****************************************************************************
132 * Private methods
133 *****************************************************************************/
134static inline int
135read4(struct fsl_sdhc_softc *sc, unsigned int offset)
136{
137
138	return bus_space_read_4(sc->bst, sc->bsh, offset);
139}
140
141static inline void
142write4(struct fsl_sdhc_softc *sc, unsigned int offset, int value)
143{
144
145	bus_space_write_4(sc->bst, sc->bsh, offset, value);
146}
147
148static inline void
149set_bit(struct fsl_sdhc_softc *sc, uint32_t offset, uint32_t mask)
150{
151	uint32_t x = read4(sc, offset);
152
153	write4(sc, offset, x | mask);
154}
155
156static inline void
157clear_bit(struct fsl_sdhc_softc *sc, uint32_t offset, uint32_t mask)
158{
159	uint32_t x = read4(sc, offset);
160
161	write4(sc, offset, x & ~mask);
162}
163
164static int
165wait_for_bit_clear(struct fsl_sdhc_softc *sc, enum sdhc_reg_off reg,
166    uint32_t bit)
167{
168	uint32_t timeout = 10;
169	uint32_t stat;
170
171	stat = read4(sc, reg);
172	while (stat & bit) {
173		if (timeout == 0) {
174			return (-1);
175		}
176		--timeout;
177		DELAY(1000);
178		stat = read4(sc, reg);
179	}
180
181	return (0);
182}
183
184static int
185wait_for_free_line(struct fsl_sdhc_softc *sc, enum sdhc_line line)
186{
187	uint32_t timeout = 100;
188	uint32_t stat;
189
190	stat = read4(sc, SDHC_PRSSTAT);
191	while (stat & line) {
192		if (timeout == 0) {
193			return (-1);
194		}
195		--timeout;
196		DELAY(1000);
197		stat = read4(sc, SDHC_PRSSTAT);
198	}
199
200	return (0);
201}
202
203static uint32_t
204get_platform_clock(struct fsl_sdhc_softc *sc)
205{
206	device_t self, parent;
207	phandle_t node;
208	uint32_t clock;
209
210	self = sc->self;
211	node = ofw_bus_get_node(self);
212
213	/* Get sdhci node properties */
214	if((OF_getprop(node, "clock-frequency", (void *)&clock,
215	    sizeof(clock)) <= 0) || (clock == 0)) {
216
217		/*
218		 * Trying to get clock from parent device (soc) if correct
219		 * clock cannot be acquired from sdhci node.
220		 */
221		parent = device_get_parent(self);
222		node = ofw_bus_get_node(parent);
223
224		/* Get soc properties */
225		if ((OF_getprop(node, "bus-frequency", (void *)&clock,
226		    sizeof(clock)) <= 0) || (clock == 0)) {
227			device_printf(self,"Cannot acquire correct sdhci "
228			    "frequency from DTS.\n");
229
230			return (0);
231		}
232	}
233
234	DPRINTF("Acquired clock: %d from DTS\n", clock);
235
236	return (clock);
237}
238
239/**
240 * Set clock driving card.
241 * @param sc
242 * @param clock Desired clock frequency in Hz
243 */
244static void
245set_clock(struct fsl_sdhc_softc *sc, uint32_t clock)
246{
247	uint32_t base_clock;
248	uint32_t divisor, prescaler = 1;
249	uint32_t round = 0;
250
251	if (clock == sc->slot.clock)
252		return;
253
254	if (clock == 0) {
255		clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL | SYSCTL_PEREN |
256		    SYSCTL_HCKEN | SYSCTL_IPGEN);
257		return;
258	}
259
260	base_clock = sc->platform_clock;
261	round = base_clock & 0x2;
262	base_clock >>= 2;
263	base_clock += round;
264	round = 0;
265
266	/* SD specification 1.1 doesn't allow frequences above 50 MHz */
267	if (clock > FSL_SDHC_MAX_CLOCK)
268		clock = FSL_SDHC_MAX_CLOCK;
269
270	/*
271	 * divisor = ceil(base_clock / clock)
272	 * TODO: Reconsider symmetric rounding here instead of ceiling.
273	 */
274	divisor = (base_clock + clock - 1) / clock;
275
276	while (divisor > 16) {
277		round = divisor & 0x1;
278		divisor >>= 1;
279
280		prescaler <<= 1;
281	}
282	divisor += round - 1;
283
284	/* Turn off the clock. */
285	clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL);
286
287	/* Write clock settings. */
288	set_bit(sc, SDHC_SYSCTL, (prescaler << SHIFT_SDCLKFS) |
289	    (divisor << SHIFT_DVS));
290
291	/*
292	 * Turn on clocks.
293	 * TODO: This actually disables clock automatic gating off feature of
294	 * the controller which eventually should be enabled but as for now
295	 * it prevents controller from generating card insertion/removal
296	 * interrupts correctly.
297	 */
298	set_bit(sc, SDHC_SYSCTL, SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN);
299
300	sc->slot.clock = clock;
301
302	DPRINTF("given clock = %d, computed clock = %d\n", clock,
303	    (base_clock / prescaler) / (divisor + 1));
304}
305
306static inline void
307send_80_clock_ticks(struct fsl_sdhc_softc *sc)
308{
309	int err;
310
311	err = wait_for_free_line(sc, SDHC_CMD_LINE | SDHC_DAT_LINE);
312	if (err != 0) {
313		device_printf(sc->self, "Can't acquire data/cmd lines\n");
314		return;
315	}
316
317	set_bit(sc, SDHC_SYSCTL, SYSCTL_INITA);
318	err = wait_for_bit_clear(sc, SDHC_SYSCTL, SYSCTL_INITA);
319	if (err != 0) {
320		device_printf(sc->self, "Can't send 80 clocks to the card.\n");
321	}
322}
323
324static void
325set_bus_width(struct fsl_sdhc_softc *sc, enum mmc_bus_width width)
326{
327
328	DPRINTF("setting bus width to %d\n", width);
329	switch (width) {
330	case bus_width_1:
331		set_bit(sc, SDHC_PROCTL, DTW_1);
332		break;
333	case bus_width_4:
334		set_bit(sc, SDHC_PROCTL, DTW_4);
335		break;
336	case bus_width_8:
337		set_bit(sc, SDHC_PROCTL, DTW_8);
338		break;
339	default:
340		device_printf(sc->self, "Unsupported bus width\n");
341	}
342}
343
344static void
345reset_controller_all(struct fsl_sdhc_softc *sc)
346{
347	uint32_t count = 5;
348
349	set_bit(sc, SDHC_SYSCTL, SYSCTL_RSTA);
350	while (read4(sc, SDHC_SYSCTL) & SYSCTL_RSTA) {
351		DELAY(FSL_SDHC_RESET_DELAY);
352		--count;
353		if (count == 0) {
354			device_printf(sc->self,
355			    "Can't reset the controller\n");
356			return;
357		}
358	}
359}
360
361static void
362reset_controller_dat_cmd(struct fsl_sdhc_softc *sc)
363{
364	int err;
365
366	set_bit(sc, SDHC_SYSCTL, SYSCTL_RSTD | SYSCTL_RSTC);
367	err = wait_for_bit_clear(sc, SDHC_SYSCTL, SYSCTL_RSTD | SYSCTL_RSTC);
368	if (err != 0) {
369		device_printf(sc->self, "Can't reset data & command part!\n");
370		return;
371	}
372}
373
374static void
375init_controller(struct fsl_sdhc_softc *sc)
376{
377
378	/* Enable interrupts. */
379#ifdef FSL_SDHC_NO_DMA
380	write4(sc, SDHC_IRQSTATEN, MASK_IRQ_ALL & ~IRQ_DINT & ~IRQ_DMAE);
381	write4(sc, SDHC_IRQSIGEN, MASK_IRQ_ALL & ~IRQ_DINT & ~IRQ_DMAE);
382#else
383	write4(sc, SDHC_IRQSTATEN, MASK_IRQ_ALL & ~IRQ_BRR & ~IRQ_BWR);
384	write4(sc, SDHC_IRQSIGEN, MASK_IRQ_ALL & ~IRQ_BRR & ~IRQ_BWR);
385
386	/* Write DMA address */
387	write4(sc, SDHC_DSADDR, sc->dma_phys);
388
389	/* Enable snooping and fix for AHB2MAG bypass. */
390	write4(sc, SDHC_DCR, DCR_SNOOP | DCR_AHB2MAG_BYPASS);
391#endif
392	/* Set data timeout. */
393	set_bit(sc, SDHC_SYSCTL, 0xe << SHIFT_DTOCV);
394
395	/* Set water-mark levels (FIFO buffer size). */
396	write4(sc, SDHC_WML, (FSL_SDHC_FIFO_BUF_WORDS << 16) |
397	    FSL_SDHC_FIFO_BUF_WORDS);
398}
399
400static void
401init_mmc_host_struct(struct fsl_sdhc_softc *sc)
402{
403	struct mmc_host *host = &sc->mmc_host;
404
405	/* Clear host structure. */
406	bzero(host, sizeof(struct mmc_host));
407
408	/* Calculate minimum and maximum operating frequencies. */
409	host->f_min = sc->platform_clock / FSL_SDHC_MAX_DIV;
410	host->f_max = FSL_SDHC_MAX_CLOCK;
411
412	/* Set operation conditions (voltage). */
413	host->host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
414
415	/* Set additional host controller capabilities. */
416	host->caps = MMC_CAP_4_BIT_DATA;
417
418	/* Set mode. */
419	host->mode = mode_sd;
420}
421
422static void
423card_detect_task(void *arg, int pending)
424{
425	struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg;
426	int err;
427	int insert;
428
429	insert = read4(sc, SDHC_PRSSTAT) & PRSSTAT_CINS;
430
431	mtx_lock(&sc->mtx);
432
433	if (insert) {
434		if (sc->child != NULL) {
435			mtx_unlock(&sc->mtx);
436			return;
437		}
438
439		sc->child = device_add_child(sc->self, "mmc", -1);
440		if (sc->child == NULL) {
441			device_printf(sc->self, "Couldn't add MMC bus!\n");
442			mtx_unlock(&sc->mtx);
443			return;
444		}
445
446		/* Initialize MMC bus host structure. */
447		init_mmc_host_struct(sc);
448		device_set_ivars(sc->child, &sc->mmc_host);
449
450	} else {
451		if (sc->child == NULL) {
452			mtx_unlock(&sc->mtx);
453			return;
454		}
455	}
456
457	mtx_unlock(&sc->mtx);
458
459	if (insert) {
460		if ((err = device_probe_and_attach(sc->child)) != 0) {
461			device_printf(sc->self, "MMC bus failed on probe "
462			    "and attach! error %d\n", err);
463			device_delete_child(sc->self, sc->child);
464			sc->child = NULL;
465		}
466	} else {
467		if (device_delete_child(sc->self, sc->child) != 0)
468			device_printf(sc->self, "Could not delete MMC bus!\n");
469		sc->child = NULL;
470	}
471}
472
473static void
474card_detect_delay(void *arg)
475{
476	struct fsl_sdhc_softc *sc = arg;
477
478	taskqueue_enqueue(taskqueue_swi_giant, &sc->card_detect_task);
479}
480
481static void
482finalize_request(struct fsl_sdhc_softc *sc)
483{
484
485	DPRINTF("finishing request %x\n", sc->request);
486
487	sc->request->done(sc->request);
488	sc->request = NULL;
489}
490
491/**
492 * Read response from card.
493 * @todo Implement Auto-CMD responses being held in R3 for multi-block xfers.
494 * @param sc
495 */
496static void
497get_response(struct fsl_sdhc_softc *sc)
498{
499	struct mmc_command *cmd = sc->request->cmd;
500	int i;
501	uint32_t val;
502	uint8_t ext = 0;
503
504	if (cmd->flags & MMC_RSP_136) {
505		/* CRC is stripped, need to shift one byte left. */
506		for (i = 0; i < 4; i++) {
507			val = read4(sc, SDHC_CMDRSP0 + i * 4);
508			cmd->resp[3 - i] = (val << 8) + ext;
509			ext = val >> 24;
510		}
511	} else {
512		cmd->resp[0] = read4(sc, SDHC_CMDRSP0);
513	}
514}
515
516#ifdef FSL_SDHC_NO_DMA
517/**
518 * Read all content of a fifo buffer.
519 * @warning Assumes data buffer is 32-bit aligned.
520 * @param sc
521 */
522static void
523read_block_pio(struct fsl_sdhc_softc *sc)
524{
525	struct mmc_data *data = sc->request->cmd->data;
526	size_t left = min(FSL_SDHC_FIFO_BUF_SIZE, data->len);
527	uint8_t *buf = data->data;
528	uint32_t word;
529
530	buf += sc->data_offset;
531	bus_space_read_multi_4(sc->bst, sc->bsh, SDHC_DATPORT, (uint32_t *)buf,
532	    left >> 2);
533
534	sc->data_offset += left;
535
536	/* Handle 32-bit unaligned size case. */
537	left &= 0x3;
538	if (left > 0) {
539		buf = (uint8_t *)data->data + (sc->data_offset & ~0x3);
540		word = read4(sc, SDHC_DATPORT);
541		while (left > 0) {
542			*(buf++) = word;
543			word >>= 8;
544			--left;
545		}
546	}
547}
548
549/**
550 * Write a fifo buffer.
551 * @warning Assumes data buffer size is 32-bit aligned.
552 * @param sc
553 */
554static void
555write_block_pio(struct fsl_sdhc_softc *sc)
556{
557	struct mmc_data *data = sc->request->cmd->data;
558	size_t left = min(FSL_SDHC_FIFO_BUF_SIZE, data->len);
559	uint8_t *buf = data->data;
560	uint32_t word = 0;
561
562	DPRINTF("sc->data_offset %d\n", sc->data_offset);
563
564	buf += sc->data_offset;
565	bus_space_write_multi_4(sc->bst, sc->bsh, SDHC_DATPORT, (uint32_t *)buf,
566	    left >> 2);
567
568	sc->data_offset += left;
569
570	/* Handle 32-bit unaligned size case. */
571	left &= 0x3;
572	if (left > 0) {
573		buf = (uint8_t *)data->data + (sc->data_offset & ~0x3);
574		while (left > 0) {
575			word += *(buf++);
576			word <<= 8;
577			--left;
578		}
579		write4(sc, SDHC_DATPORT, word);
580	}
581}
582
583static void
584pio_read_transfer(struct fsl_sdhc_softc *sc)
585{
586
587	while (read4(sc, SDHC_PRSSTAT) & PRSSTAT_BREN) {
588		read_block_pio(sc);
589
590		/*
591		 * TODO: should we check here whether data_offset >= data->len?
592		 */
593	}
594}
595
596static void
597pio_write_transfer(struct fsl_sdhc_softc *sc)
598{
599
600	while (read4(sc, SDHC_PRSSTAT) & PRSSTAT_BWEN) {
601		write_block_pio(sc);
602
603		/*
604		 * TODO: should we check here whether data_offset >= data->len?
605		 */
606	}
607}
608#endif /* FSL_SDHC_USE_DMA */
609
610static inline void
611handle_command_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat)
612{
613	struct mmc_command *cmd = sc->request->cmd;
614
615	/* Handle errors. */
616	if (irq_stat & IRQ_CTOE) {
617		cmd->error = MMC_ERR_TIMEOUT;
618	} else if (irq_stat & IRQ_CCE) {
619		cmd->error = MMC_ERR_BADCRC;
620	} else if (irq_stat & (IRQ_CEBE | IRQ_CIE)) {
621		cmd->error = MMC_ERR_FIFO;
622	}
623
624	if (cmd->error) {
625		device_printf(sc->self, "Error interrupt occured\n");
626		reset_controller_dat_cmd(sc);
627		return;
628	}
629
630	if (sc->command_done)
631		return;
632
633	if (irq_stat & IRQ_CC) {
634		sc->command_done = 1;
635
636		if (cmd->flags & MMC_RSP_PRESENT)
637			get_response(sc);
638	}
639}
640
641static inline void
642handle_data_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat)
643{
644	struct mmc_command *cmd = sc->request->cmd;
645
646	/* Handle errors. */
647	if (irq_stat & IRQ_DTOE) {
648		cmd->error = MMC_ERR_TIMEOUT;
649	} else if (irq_stat & (IRQ_DCE | IRQ_DEBE)) {
650		cmd->error = MMC_ERR_BADCRC;
651	} else if (irq_stat & IRQ_ERROR_DATA_MASK) {
652		cmd->error = MMC_ERR_FAILED;
653	}
654
655	if (cmd->error) {
656		device_printf(sc->self, "Error interrupt occured\n");
657		sc->data_done = 1;
658		reset_controller_dat_cmd(sc);
659		return;
660	}
661
662	if (sc->data_done)
663		return;
664
665#ifdef FSL_SDHC_NO_DMA
666	if (irq_stat & IRQ_BRR) {
667		pio_read_transfer(sc);
668	}
669
670	if (irq_stat & IRQ_BWR) {
671		pio_write_transfer(sc);
672	}
673#else
674	if (irq_stat & IRQ_DINT) {
675		struct mmc_data *data = sc->request->cmd->data;
676
677		/* Synchronize DMA. */
678		if (data->flags & MMC_DATA_READ) {
679			bus_dmamap_sync(sc->dma_tag, sc->dma_map,
680			    BUS_DMASYNC_POSTREAD);
681			memcpy(data->data, sc->dma_mem, data->len);
682		} else {
683			bus_dmamap_sync(sc->dma_tag, sc->dma_map,
684			    BUS_DMASYNC_POSTWRITE);
685		}
686
687		/*
688		 * TODO: For multiple block transfers, address of dma memory
689		 * in DSADDR register should be set to the beginning of the
690		 * segment here. Also offset to data pointer should be handled.
691		 */
692	}
693#endif
694
695	if (irq_stat & IRQ_TC)
696		sc->data_done = 1;
697}
698
699static void
700interrupt_handler(void *arg)
701{
702	struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg;
703	uint32_t irq_stat;
704
705	mtx_lock(&sc->mtx);
706
707	irq_stat = read4(sc, SDHC_IRQSTAT);
708
709	/* Card interrupt. */
710	if (irq_stat & IRQ_CINT) {
711		DPRINTF("Card interrupt recievied\n");
712
713	}
714
715	/* Card insertion interrupt. */
716	if (irq_stat & IRQ_CINS) {
717		clear_bit(sc, SDHC_IRQSIGEN, IRQ_CINS);
718		clear_bit(sc, SDHC_IRQSTATEN, IRQ_CINS);
719		set_bit(sc, SDHC_IRQSIGEN, IRQ_CRM);
720		set_bit(sc, SDHC_IRQSTATEN, IRQ_CRM);
721
722		callout_reset(&sc->card_detect_callout, hz / 2,
723		    card_detect_delay, sc);
724	}
725
726	/* Card removal interrupt. */
727	if (irq_stat & IRQ_CRM) {
728		clear_bit(sc, SDHC_IRQSIGEN, IRQ_CRM);
729		clear_bit(sc, SDHC_IRQSTATEN, IRQ_CRM);
730		set_bit(sc, SDHC_IRQSIGEN, IRQ_CINS);
731		set_bit(sc, SDHC_IRQSTATEN, IRQ_CINS);
732
733		callout_stop(&sc->card_detect_callout);
734		taskqueue_enqueue(taskqueue_swi_giant, &sc->card_detect_task);
735	}
736
737	/* Handle request interrupts. */
738	if (sc->request) {
739		handle_command_intr(sc, irq_stat);
740		handle_data_intr(sc, irq_stat);
741
742		/*
743		 * Finalize request when transfer is done successfully
744		 * or was interrupted due to error.
745		 */
746		if ((sc->data_done && sc->command_done) ||
747		    (sc->request->cmd->error))
748			finalize_request(sc);
749	}
750
751	/* Clear status register. */
752	write4(sc, SDHC_IRQSTAT, irq_stat);
753
754	mtx_unlock(&sc->mtx);
755}
756
757#ifndef FSL_SDHC_NO_DMA
758static void
759dma_get_phys_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
760{
761
762	if (error != 0)
763		return;
764
765	/* Get first segment's physical address. */
766	*(bus_addr_t *)arg = segs->ds_addr;
767}
768
769static int
770init_dma(struct fsl_sdhc_softc *sc)
771{
772	device_t self = sc->self;
773	int err;
774
775	err = bus_dma_tag_create(bus_get_dma_tag(self),
776	    FSL_SDHC_DMA_BLOCK_SIZE, 0, BUS_SPACE_MAXADDR_32BIT,
777	    BUS_SPACE_MAXADDR, NULL, NULL, FSL_SDHC_DMA_BLOCK_SIZE, 1,
778	    FSL_SDHC_DMA_BLOCK_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL,
779	    &sc->dma_tag);
780
781	if (err) {
782		device_printf(self, "Could not create DMA tag!\n");
783		return (-1);
784	}
785
786	err = bus_dmamem_alloc(sc->dma_tag, (void **)&(sc->dma_mem),
787	    BUS_DMA_NOWAIT | BUS_DMA_NOCACHE, &sc->dma_map);
788	if (err) {
789		device_printf(self, "Could not allocate DMA memory!\n");
790		goto fail1;
791	}
792
793	err = bus_dmamap_load(sc->dma_tag, sc->dma_map, (void *)sc->dma_mem,
794	    FSL_SDHC_DMA_BLOCK_SIZE, dma_get_phys_addr, &sc->dma_phys, 0);
795	if (err) {
796		device_printf(self, "Could not load DMA map!\n");
797		goto fail2;
798	}
799
800	return (0);
801
802fail2:
803	bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map);
804fail1:
805	bus_dma_tag_destroy(sc->dma_tag);
806
807	return (-1);
808}
809#endif /* FSL_SDHC_NO_DMA */
810
811static uint32_t
812set_xfertyp_register(const struct mmc_command *cmd)
813{
814	uint32_t xfertyp = 0;
815
816	/* Set command index. */
817	xfertyp |= cmd->opcode << CMDINX_SHIFT;
818
819	/* Set command type. */
820	if (cmd->opcode == MMC_STOP_TRANSMISSION)
821		xfertyp |= CMDTYP_ABORT;
822
823	/* Set data preset select. */
824	if (cmd->data) {
825		xfertyp |= XFERTYP_DPSEL;
826
827		/* Set transfer direction. */
828		if (cmd->data->flags & MMC_DATA_READ)
829			xfertyp |= XFERTYP_DTDSEL;
830	}
831
832	/* Set command index check. */
833	if (cmd->flags & MMC_RSP_OPCODE)
834		xfertyp |= XFERTYP_CICEN;
835
836	/* Set command CRC check. */
837	if (cmd->flags & MMC_RSP_CRC)
838		xfertyp |= XFERTYP_CCCEN;
839
840	/* Set response type */
841	if (!(cmd->flags & MMC_RSP_PRESENT))
842		xfertyp |= RSPTYP_NONE;
843	else if (cmd->flags & MMC_RSP_136)
844		xfertyp |= RSPTYP_136;
845	else if (cmd->flags & MMC_RSP_BUSY)
846		xfertyp |= RSPTYP_48_BUSY;
847	else
848		xfertyp |= RSPTYP_48;
849
850#ifndef FSL_SDHC_NO_DMA
851	/* Enable DMA */
852	xfertyp |= XFERTYP_DMAEN;
853#endif
854
855	return (xfertyp);
856}
857
858static uint32_t
859set_blkattr_register(const struct mmc_data *data)
860{
861
862	if (data->len <= FSL_SDHC_MAX_BLOCK_SIZE) {
863		/* One block transfer. */
864		return (BLKATTR_BLOCK_COUNT(1) | ((data->len) &
865		    BLKATTR_BLKSZE));
866	}
867
868	/* TODO: Write code here for multi-block transfers. */
869	return (0);
870}
871
872/**
873 * Initiate data transfer. Interrupt handler will finalize it.
874 * @todo Implement multi-block transfers.
875 * @param sc
876 * @param cmd
877 */
878static int
879start_data(struct fsl_sdhc_softc *sc, struct mmc_data *data)
880{
881	uint32_t reg;
882
883	if ((uint32_t)data->data & 0x3) {
884		device_printf(sc->self, "32-bit unaligned data pointer in "
885		    "request\n");
886		return (-1);
887	}
888
889	sc->data_done = 0;
890
891#ifdef FSL_SDHC_NO_DMA
892	sc->data_ptr = data->data;
893	sc->data_offset = 0;
894#else
895	/* Write DMA address register. */
896	write4(sc, SDHC_DSADDR, sc->dma_phys);
897
898	/* Synchronize DMA. */
899	if (data->flags & MMC_DATA_READ) {
900		bus_dmamap_sync(sc->dma_tag, sc->dma_map,
901		    BUS_DMASYNC_PREREAD);
902	} else {
903		memcpy(sc->dma_mem, data->data, data->len);
904		bus_dmamap_sync(sc->dma_tag, sc->dma_map,
905		    BUS_DMASYNC_PREWRITE);
906	}
907#endif
908	/* Set block size and count. */
909	reg = set_blkattr_register(data);
910	if (reg == 0) {
911		device_printf(sc->self, "Requested unsupported multi-block "
912		    "transfer.\n");
913		return (-1);
914	}
915	write4(sc, SDHC_BLKATTR, reg);
916
917	return (0);
918}
919
920static int
921start_command(struct fsl_sdhc_softc *sc, struct mmc_command *cmd)
922{
923	struct mmc_request *req = sc->request;
924	uint32_t mask;
925	uint32_t xfertyp;
926	int err;
927
928	DPRINTF("opcode %d, flags 0x%08x\n", cmd->opcode, cmd->flags);
929	DPRINTF("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT));
930
931	sc->command_done = 0;
932
933	cmd->error = MMC_ERR_NONE;
934
935	/* TODO: should we check here for card presence and clock settings? */
936
937	/* Always wait for free CMD line. */
938	mask = SDHC_CMD_LINE;
939	/* Wait for free DAT if we have data or busy signal. */
940	if (cmd->data || (cmd->flags & MMC_RSP_BUSY))
941		mask |= SDHC_DAT_LINE;
942	/* We shouldn't wait for DAT for stop commands. */
943	if (cmd == req->stop)
944		mask &= ~SDHC_DAT_LINE;
945	err = wait_for_free_line(sc, mask);
946	if (err != 0) {
947		device_printf(sc->self, "Controller never released inhibit "
948		    "bit(s).\n");
949		reset_controller_dat_cmd(sc);
950		cmd->error = MMC_ERR_FAILED;
951		sc->request = NULL;
952		req->done(req);
953		return (-1);
954	}
955
956	xfertyp = set_xfertyp_register(cmd);
957
958	if (cmd->data != NULL) {
959		err = start_data(sc, cmd->data);
960		if (err != 0) {
961			device_printf(sc->self,
962			    "Data transfer request failed\n");
963			reset_controller_dat_cmd(sc);
964			cmd->error = MMC_ERR_FAILED;
965			sc->request = NULL;
966			req->done(req);
967			return (-1);
968		}
969	}
970
971	write4(sc, SDHC_CMDARG, cmd->arg);
972	write4(sc, SDHC_XFERTYP, xfertyp);
973
974	DPRINTF("XFERTYP = 0x%08x\n", xfertyp);
975	DPRINTF("CMDARG = 0x%08x\n", cmd->arg);
976
977	return (0);
978}
979
980#ifdef DEBUG
981static void
982dump_registers(struct fsl_sdhc_softc *sc)
983{
984	printf("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT));
985	printf("PROCTL = 0x%08x\n", read4(sc, SDHC_PROCTL));
986	printf("PMUXCR = 0x%08x\n", ccsr_read4(OCP85XX_PMUXCR));
987	printf("HOSTCAPBLT = 0x%08x\n", read4(sc, SDHC_HOSTCAPBLT));
988	printf("IRQSTAT = 0x%08x\n", read4(sc, SDHC_IRQSTAT));
989	printf("IRQSTATEN = 0x%08x\n", read4(sc, SDHC_IRQSTATEN));
990	printf("IRQSIGEN = 0x%08x\n", read4(sc, SDHC_IRQSIGEN));
991	printf("WML = 0x%08x\n", read4(sc, SDHC_WML));
992	printf("DSADDR = 0x%08x\n", read4(sc, SDHC_DSADDR));
993	printf("XFERTYP = 0x%08x\n", read4(sc, SDHC_XFERTYP));
994	printf("ECMCR = 0x%08x\n", ccsr_read4(OCP85XX_ECMCR));
995	printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR));
996}
997#endif
998
999/*****************************************************************************
1000 * Public methods
1001 *****************************************************************************/
1002/*
1003 * Device interface methods.
1004 */
1005static int
1006fsl_sdhc_probe(device_t self)
1007{
1008	static const char *desc =
1009	    "Freescale Enhanced Secure Digital Host Controller";
1010
1011	if (!ofw_bus_is_compatible(self, "fsl,p2020-esdhc") &&
1012	    !ofw_bus_is_compatible(self, "fsl,esdhc"))
1013		return (ENXIO);
1014
1015	device_set_desc(self, desc);
1016
1017	return (BUS_PROBE_VENDOR);
1018}
1019
1020static int
1021fsl_sdhc_attach(device_t self)
1022{
1023	struct fsl_sdhc_softc *sc;
1024
1025	sc = device_get_softc(self);
1026
1027	sc->self = self;
1028
1029	mtx_init(&sc->mtx, device_get_nameunit(self), NULL, MTX_DEF);
1030
1031	/* Setup memory resource */
1032	sc->mem_rid = 0;
1033	sc->mem_resource = bus_alloc_resource_any(self, SYS_RES_MEMORY,
1034	    &sc->mem_rid, RF_ACTIVE);
1035	if (sc->mem_resource == NULL) {
1036		device_printf(self, "Could not allocate memory.\n");
1037		goto fail;
1038	}
1039	sc->bst = rman_get_bustag(sc->mem_resource);
1040	sc->bsh = rman_get_bushandle(sc->mem_resource);
1041
1042	/* Setup interrupt resource. */
1043	sc->irq_rid = 0;
1044	sc->irq_resource = bus_alloc_resource_any(self, SYS_RES_IRQ,
1045	    &sc->irq_rid, RF_ACTIVE);
1046	if (sc->irq_resource == NULL) {
1047		device_printf(self, "Could not allocate interrupt.\n");
1048		goto fail;
1049	}
1050	if (bus_setup_intr(self, sc->irq_resource, INTR_TYPE_MISC |
1051	    INTR_MPSAFE, NULL, interrupt_handler, sc, &sc->ihl) != 0) {
1052		device_printf(self, "Could not setup interrupt.\n");
1053		goto fail;
1054	}
1055
1056	/* Setup DMA. */
1057#ifndef FSL_SDHC_NO_DMA
1058	if (init_dma(sc) != 0) {
1059		device_printf(self, "Could not setup DMA\n");
1060	}
1061#endif
1062	sc->bus_busy = 0;
1063	sc->platform_clock = get_platform_clock(sc);
1064	if (sc->platform_clock == 0) {
1065		device_printf(self, "Could not get platform clock.\n");
1066		goto fail;
1067	}
1068	sc->command_done = 1;
1069	sc->data_done = 1;
1070
1071	/* Init card detection task. */
1072	TASK_INIT(&sc->card_detect_task, 0, card_detect_task, sc);
1073	callout_init(&sc->card_detect_callout, 1);
1074
1075	reset_controller_all(sc);
1076	init_controller(sc);
1077	set_clock(sc, 400000);
1078	send_80_clock_ticks(sc);
1079
1080#ifdef DEBUG
1081	dump_registers(sc);
1082#endif
1083
1084	return (0);
1085
1086fail:
1087	fsl_sdhc_detach(self);
1088	return (ENXIO);
1089}
1090
1091static int
1092fsl_sdhc_detach(device_t self)
1093{
1094	struct fsl_sdhc_softc *sc = device_get_softc(self);
1095	int err;
1096
1097	if (sc->child)
1098		device_delete_child(self, sc->child);
1099
1100	taskqueue_drain(taskqueue_swi_giant, &sc->card_detect_task);
1101
1102#ifndef FSL_SDHC_NO_DMA
1103	bus_dmamap_unload(sc->dma_tag, sc->dma_map);
1104	bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map);
1105	bus_dma_tag_destroy(sc->dma_tag);
1106#endif
1107
1108	if (sc->ihl != NULL) {
1109		err = bus_teardown_intr(self, sc->irq_resource, sc->ihl);
1110		if (err)
1111			return (err);
1112	}
1113	if (sc->irq_resource != NULL) {
1114		err = bus_release_resource(self, SYS_RES_IRQ, sc->irq_rid,
1115		    sc->irq_resource);
1116		if (err)
1117			return (err);
1118
1119	}
1120	if (sc->mem_resource != NULL) {
1121		err = bus_release_resource(self, SYS_RES_MEMORY, sc->mem_rid,
1122		    sc->mem_resource);
1123		if (err)
1124			return (err);
1125	}
1126
1127	mtx_destroy(&sc->mtx);
1128
1129	return (0);
1130}
1131
1132
1133/*
1134 * Bus interface methods.
1135 */
1136static int
1137fsl_sdhc_read_ivar(device_t self, device_t child, int index,
1138    uintptr_t *result)
1139{
1140	struct mmc_host *host = device_get_ivars(child);
1141
1142	switch (index) {
1143	case MMCBR_IVAR_BUS_MODE:
1144		*(int *)result = host->ios.bus_mode;
1145		break;
1146	case MMCBR_IVAR_BUS_WIDTH:
1147		*(int *)result = host->ios.bus_width;
1148		break;
1149	case MMCBR_IVAR_CHIP_SELECT:
1150		*(int *)result = host->ios.chip_select;
1151		break;
1152	case MMCBR_IVAR_CLOCK:
1153		*(int *)result = host->ios.clock;
1154		break;
1155	case MMCBR_IVAR_F_MIN:
1156		*(int *)result = host->f_min;
1157		break;
1158	case MMCBR_IVAR_F_MAX:
1159		*(int *)result = host->f_max;
1160		break;
1161	case MMCBR_IVAR_HOST_OCR:
1162		*(int *)result = host->host_ocr;
1163		break;
1164	case MMCBR_IVAR_MODE:
1165		*(int *)result = host->mode;
1166		break;
1167	case MMCBR_IVAR_OCR:
1168		*(int *)result = host->ocr;
1169		break;
1170	case MMCBR_IVAR_POWER_MODE:
1171		*(int *)result = host->ios.power_mode;
1172		break;
1173	case MMCBR_IVAR_VDD:
1174		*(int *)result = host->ios.vdd;
1175		break;
1176	default:
1177		return (EINVAL);
1178	}
1179
1180	return (0);
1181}
1182
1183static int
1184fsl_sdhc_write_ivar(device_t self, device_t child, int index,
1185    uintptr_t value)
1186{
1187	struct mmc_host *host = device_get_ivars(child);
1188
1189	switch (index) {
1190	case MMCBR_IVAR_BUS_MODE:
1191		host->ios.bus_mode = value;
1192		break;
1193	case MMCBR_IVAR_BUS_WIDTH:
1194		host->ios.bus_width = value;
1195		break;
1196	case MMCBR_IVAR_CHIP_SELECT:
1197		host->ios.chip_select = value;
1198		break;
1199	case MMCBR_IVAR_CLOCK:
1200		host->ios.clock = value;
1201		break;
1202	case MMCBR_IVAR_MODE:
1203		host->mode = value;
1204		break;
1205	case MMCBR_IVAR_OCR:
1206		host->ocr = value;
1207		break;
1208	case MMCBR_IVAR_POWER_MODE:
1209		host->ios.power_mode = value;
1210		break;
1211	case MMCBR_IVAR_VDD:
1212		host->ios.vdd = value;
1213		break;
1214	case MMCBR_IVAR_HOST_OCR:
1215	case MMCBR_IVAR_F_MIN:
1216	case MMCBR_IVAR_F_MAX:
1217	default:
1218		/* Instance variable not writable. */
1219		return (EINVAL);
1220	}
1221
1222	return (0);
1223}
1224
1225
1226/*
1227 * MMC bridge methods.
1228 */
1229static int
1230fsl_sdhc_update_ios(device_t self, device_t reqdev)
1231{
1232	struct fsl_sdhc_softc *sc = device_get_softc(self);
1233	struct mmc_host *host = device_get_ivars(reqdev);
1234	struct mmc_ios *ios = &host->ios;
1235
1236	mtx_lock(&sc->mtx);
1237
1238	/* Full reset on bus power down to clear from any state. */
1239	if (ios->power_mode == power_off) {
1240		reset_controller_all(sc);
1241		init_controller(sc);
1242	}
1243
1244	set_clock(sc, ios->clock);
1245	set_bus_width(sc, ios->bus_width);
1246
1247	mtx_unlock(&sc->mtx);
1248
1249	return (0);
1250}
1251
1252static int
1253fsl_sdhc_request(device_t self, device_t reqdev, struct mmc_request *req)
1254{
1255	struct fsl_sdhc_softc *sc = device_get_softc(self);
1256	int err;
1257
1258	mtx_lock(&sc->mtx);
1259
1260	sc->request = req;
1261	err = start_command(sc, req->cmd);
1262
1263	mtx_unlock(&sc->mtx);
1264
1265	return (err);
1266}
1267
1268static int
1269fsl_sdhc_get_ro(device_t self, device_t reqdev)
1270{
1271	struct fsl_sdhc_softc *sc = device_get_softc(self);
1272
1273	/* Wouldn't it be faster using branching (if {}) ?? */
1274	return (((read4(sc, SDHC_PRSSTAT) & PRSSTAT_WPSPL) >> 19) ^ 0x1);
1275}
1276
1277static int
1278fsl_sdhc_acquire_host(device_t self, device_t reqdev)
1279{
1280	struct fsl_sdhc_softc *sc = device_get_softc(self);
1281	int retval = 0;
1282
1283	mtx_lock(&sc->mtx);
1284
1285	while (sc->bus_busy)
1286		retval = mtx_sleep(sc, &sc->mtx, PZERO, "sdhcah", 0);
1287	++(sc->bus_busy);
1288
1289	mtx_unlock(&sc->mtx);
1290
1291	return (retval);
1292}
1293
1294static int
1295fsl_sdhc_release_host(device_t self, device_t reqdev)
1296{
1297	struct fsl_sdhc_softc *sc = device_get_softc(self);
1298
1299	mtx_lock(&sc->mtx);
1300	--(sc->bus_busy);
1301	mtx_unlock(&sc->mtx);
1302	wakeup(sc);
1303
1304	return (0);
1305}
1306