bcm2835_sdhci.c revision 278689
1/*-
2 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
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#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: stable/10/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c 278689 2015-02-13 18:16:08Z ian $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bio.h>
33#include <sys/bus.h>
34#include <sys/conf.h>
35#include <sys/endian.h>
36#include <sys/kernel.h>
37#include <sys/kthread.h>
38#include <sys/lock.h>
39#include <sys/malloc.h>
40#include <sys/module.h>
41#include <sys/mutex.h>
42#include <sys/queue.h>
43#include <sys/resource.h>
44#include <sys/rman.h>
45#include <sys/sysctl.h>
46#include <sys/taskqueue.h>
47#include <sys/time.h>
48#include <sys/timetc.h>
49#include <sys/watchdog.h>
50
51#include <sys/kdb.h>
52
53#include <machine/bus.h>
54#include <machine/cpu.h>
55#include <machine/cpufunc.h>
56#include <machine/resource.h>
57#include <machine/intr.h>
58
59#include <dev/fdt/fdt_common.h>
60#include <dev/ofw/ofw_bus.h>
61#include <dev/ofw/ofw_bus_subr.h>
62
63#include <dev/mmc/bridge.h>
64#include <dev/mmc/mmcreg.h>
65#include <dev/mmc/mmcbrvar.h>
66
67#include <dev/sdhci/sdhci.h>
68#include "sdhci_if.h"
69
70#include "bcm2835_dma.h"
71#include "bcm2835_vcbus.h"
72
73#define	BCM2835_DEFAULT_SDHCI_FREQ	50
74
75#define	BCM_SDHCI_BUFFER_SIZE		512
76#define	NUM_DMA_SEGS			2
77
78#ifdef DEBUG
79#define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
80    printf(fmt,##args); } while (0)
81#else
82#define dprintf(fmt, args...)
83#endif
84
85/*
86 * Arasan HC seems to have problem with Data CRC on lower frequencies.
87 * Use this tunable to cap initialization sequence frequency at higher
88 * value. Default is standard 400kHz
89 */
90static int bcm2835_sdhci_min_freq = 400000;
91static int bcm2835_sdhci_hs = 1;
92static int bcm2835_sdhci_pio_mode = 0;
93
94TUNABLE_INT("hw.bcm2835.sdhci.min_freq", &bcm2835_sdhci_min_freq);
95TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs);
96TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode);
97
98struct bcm_sdhci_softc {
99	device_t		sc_dev;
100	struct mtx		sc_mtx;
101	struct resource *	sc_mem_res;
102	struct resource *	sc_irq_res;
103	bus_space_tag_t		sc_bst;
104	bus_space_handle_t	sc_bsh;
105	void *			sc_intrhand;
106	struct mmc_request *	sc_req;
107	struct mmc_data *	sc_data;
108	uint32_t		sc_flags;
109#define	LPC_SD_FLAGS_IGNORECRC		(1 << 0)
110	int			sc_xfer_direction;
111#define	DIRECTION_READ		0
112#define	DIRECTION_WRITE		1
113	int			sc_xfer_done;
114	int			sc_bus_busy;
115	struct sdhci_slot	sc_slot;
116	int			sc_dma_inuse;
117	int			sc_dma_ch;
118	bus_dma_tag_t		sc_dma_tag;
119	bus_dmamap_t		sc_dma_map;
120	vm_paddr_t		sc_sdhci_buffer_phys;
121	uint32_t		cmd_and_mode;
122	bus_addr_t		dmamap_seg_addrs[NUM_DMA_SEGS];
123	bus_size_t		dmamap_seg_sizes[NUM_DMA_SEGS];
124	int			dmamap_seg_count;
125	int			dmamap_seg_index;
126	int			dmamap_status;
127};
128
129static int bcm_sdhci_probe(device_t);
130static int bcm_sdhci_attach(device_t);
131static int bcm_sdhci_detach(device_t);
132static void bcm_sdhci_intr(void *);
133
134static int bcm_sdhci_get_ro(device_t, device_t);
135static void bcm_sdhci_dma_intr(int ch, void *arg);
136
137#define	bcm_sdhci_lock(_sc)						\
138    mtx_lock(&_sc->sc_mtx);
139#define	bcm_sdhci_unlock(_sc)						\
140    mtx_unlock(&_sc->sc_mtx);
141
142static void
143bcm_sdhci_dmacb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
144{
145	struct bcm_sdhci_softc *sc = arg;
146	int i;
147
148	sc->dmamap_status = err;
149	sc->dmamap_seg_count = nseg;
150
151	/* Note nseg is guaranteed to be zero if err is non-zero. */
152	for (i = 0; i < nseg; i++) {
153		sc->dmamap_seg_addrs[i] = segs[i].ds_addr;
154		sc->dmamap_seg_sizes[i] = segs[i].ds_len;
155	}
156}
157
158static int
159bcm_sdhci_probe(device_t dev)
160{
161
162	if (!ofw_bus_status_okay(dev))
163		return (ENXIO);
164
165	if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-sdhci"))
166		return (ENXIO);
167
168	device_set_desc(dev, "Broadcom 2708 SDHCI controller");
169	return (BUS_PROBE_DEFAULT);
170}
171
172static int
173bcm_sdhci_attach(device_t dev)
174{
175	struct bcm_sdhci_softc *sc = device_get_softc(dev);
176	int rid, err;
177	phandle_t node;
178	pcell_t cell;
179	int default_freq;
180
181	sc->sc_dev = dev;
182	sc->sc_req = NULL;
183	err = 0;
184
185	default_freq = BCM2835_DEFAULT_SDHCI_FREQ;
186	node = ofw_bus_get_node(sc->sc_dev);
187	if ((OF_getprop(node, "clock-frequency", &cell, sizeof(cell))) > 0)
188		default_freq = (int)fdt32_to_cpu(cell)/1000000;
189
190	dprintf("SDHCI frequency: %dMHz\n", default_freq);
191
192	mtx_init(&sc->sc_mtx, "bcm sdhci", "sdhci", MTX_DEF);
193
194	rid = 0;
195	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
196	    RF_ACTIVE);
197	if (!sc->sc_mem_res) {
198		device_printf(dev, "cannot allocate memory window\n");
199		err = ENXIO;
200		goto fail;
201	}
202
203	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
204	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
205
206	rid = 0;
207	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
208	    RF_ACTIVE);
209	if (!sc->sc_irq_res) {
210		device_printf(dev, "cannot allocate interrupt\n");
211		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
212		err = ENXIO;
213		goto fail;
214	}
215
216	if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
217	    NULL, bcm_sdhci_intr, sc, &sc->sc_intrhand))
218	{
219		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
220		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
221		device_printf(dev, "cannot setup interrupt handler\n");
222		err = ENXIO;
223		goto fail;
224	}
225
226	if (!bcm2835_sdhci_pio_mode)
227		sc->sc_slot.opt = SDHCI_PLATFORM_TRANSFER;
228
229	sc->sc_slot.caps = SDHCI_CAN_VDD_330 | SDHCI_CAN_VDD_180;
230	if (bcm2835_sdhci_hs)
231		sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD;
232	sc->sc_slot.caps |= (default_freq << SDHCI_CLOCK_BASE_SHIFT);
233	sc->sc_slot.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
234		| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
235		| SDHCI_QUIRK_MISSING_CAPS;
236
237	sdhci_init_slot(dev, &sc->sc_slot, 0);
238
239	sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST1);
240	if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
241		sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST2);
242	if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
243		sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_ANY);
244	if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
245		goto fail;
246
247	bcm_dma_setup_intr(sc->sc_dma_ch, bcm_sdhci_dma_intr, sc);
248
249	/* Allocate bus_dma resources. */
250	err = bus_dma_tag_create(bus_get_dma_tag(dev),
251	    1, 0, BUS_SPACE_MAXADDR_32BIT,
252	    BUS_SPACE_MAXADDR, NULL, NULL,
253	    BCM_SDHCI_BUFFER_SIZE, NUM_DMA_SEGS, BCM_SDHCI_BUFFER_SIZE,
254	    BUS_DMA_ALLOCNOW, NULL, NULL,
255	    &sc->sc_dma_tag);
256
257	if (err) {
258		device_printf(dev, "failed allocate DMA tag");
259		goto fail;
260	}
261
262	err = bus_dmamap_create(sc->sc_dma_tag, 0, &sc->sc_dma_map);
263	if (err) {
264		device_printf(dev, "bus_dmamap_create failed\n");
265		goto fail;
266	}
267
268	sc->sc_sdhci_buffer_phys = BUS_SPACE_PHYSADDR(sc->sc_mem_res,
269	    SDHCI_BUFFER);
270
271	bus_generic_probe(dev);
272	bus_generic_attach(dev);
273
274	sdhci_start_slot(&sc->sc_slot);
275
276	return (0);
277
278fail:
279	if (sc->sc_intrhand)
280		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
281	if (sc->sc_irq_res)
282		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
283	if (sc->sc_mem_res)
284		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
285
286	return (err);
287}
288
289static int
290bcm_sdhci_detach(device_t dev)
291{
292
293	return (EBUSY);
294}
295
296static void
297bcm_sdhci_intr(void *arg)
298{
299	struct bcm_sdhci_softc *sc = arg;
300
301	sdhci_generic_intr(&sc->sc_slot);
302}
303
304static int
305bcm_sdhci_get_ro(device_t bus, device_t child)
306{
307
308	return (0);
309}
310
311static inline uint32_t
312RD4(struct bcm_sdhci_softc *sc, bus_size_t off)
313{
314	uint32_t val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off);
315	return val;
316}
317
318static inline void
319WR4(struct bcm_sdhci_softc *sc, bus_size_t off, uint32_t val)
320{
321	bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val);
322
323	if ((off != SDHCI_BUFFER && off != SDHCI_INT_STATUS && off != SDHCI_CLOCK_CONTROL))
324	{
325		int timeout = 100000;
326		while (val != bus_space_read_4(sc->sc_bst, sc->sc_bsh, off)
327		    && --timeout > 0)
328			continue;
329
330		if (timeout <= 0)
331			printf("sdhci_brcm: writing 0x%X to reg 0x%X "
332				"always gives 0x%X\n",
333				val, (uint32_t)off,
334				bus_space_read_4(sc->sc_bst, sc->sc_bsh, off));
335	}
336}
337
338static uint8_t
339bcm_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
340{
341	struct bcm_sdhci_softc *sc = device_get_softc(dev);
342	uint32_t val = RD4(sc, off & ~3);
343
344	return ((val >> (off & 3)*8) & 0xff);
345}
346
347static uint16_t
348bcm_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
349{
350	struct bcm_sdhci_softc *sc = device_get_softc(dev);
351	uint32_t val = RD4(sc, off & ~3);
352
353	/*
354	 * Standard 32-bit handling of command and transfer mode.
355	 */
356	if (off == SDHCI_TRANSFER_MODE) {
357		return (sc->cmd_and_mode >> 16);
358	} else if (off == SDHCI_COMMAND_FLAGS) {
359		return (sc->cmd_and_mode & 0x0000ffff);
360	}
361	return ((val >> (off & 3)*8) & 0xffff);
362}
363
364static uint32_t
365bcm_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
366{
367	struct bcm_sdhci_softc *sc = device_get_softc(dev);
368
369	return RD4(sc, off);
370}
371
372static void
373bcm_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
374    uint32_t *data, bus_size_t count)
375{
376	struct bcm_sdhci_softc *sc = device_get_softc(dev);
377
378	bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count);
379}
380
381static void
382bcm_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
383{
384	struct bcm_sdhci_softc *sc = device_get_softc(dev);
385	uint32_t val32 = RD4(sc, off & ~3);
386	val32 &= ~(0xff << (off & 3)*8);
387	val32 |= (val << (off & 3)*8);
388	WR4(sc, off & ~3, val32);
389}
390
391static void
392bcm_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
393{
394	struct bcm_sdhci_softc *sc = device_get_softc(dev);
395	uint32_t val32;
396	if (off == SDHCI_COMMAND_FLAGS)
397		val32 = sc->cmd_and_mode;
398	else
399		val32 = RD4(sc, off & ~3);
400	val32 &= ~(0xffff << (off & 3)*8);
401	val32 |= (val << (off & 3)*8);
402	if (off == SDHCI_TRANSFER_MODE)
403		sc->cmd_and_mode = val32;
404	else
405		WR4(sc, off & ~3, val32);
406}
407
408static void
409bcm_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
410{
411	struct bcm_sdhci_softc *sc = device_get_softc(dev);
412	WR4(sc, off, val);
413}
414
415static void
416bcm_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
417    uint32_t *data, bus_size_t count)
418{
419	struct bcm_sdhci_softc *sc = device_get_softc(dev);
420
421	bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count);
422}
423
424static uint32_t
425bcm_sdhci_min_freq(device_t dev, struct sdhci_slot *slot)
426{
427
428	return bcm2835_sdhci_min_freq;
429}
430
431static void
432bcm_sdhci_start_dma_seg(struct bcm_sdhci_softc *sc)
433{
434	struct sdhci_slot *slot;
435	vm_paddr_t pdst, psrc;
436	int err, idx, len, sync_op;
437
438	slot = &sc->sc_slot;
439	idx = sc->dmamap_seg_index++;
440	len = sc->dmamap_seg_sizes[idx];
441	slot->offset += len;
442
443	if (slot->curcmd->data->flags & MMC_DATA_READ) {
444		bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
445		    BCM_DMA_SAME_ADDR, BCM_DMA_32BIT);
446		bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
447		    BCM_DMA_INC_ADDR,
448		    (len & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
449		psrc = sc->sc_sdhci_buffer_phys;
450		pdst = sc->dmamap_seg_addrs[idx];
451		sync_op = BUS_DMASYNC_PREREAD;
452	} else {
453		bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
454		    BCM_DMA_INC_ADDR,
455		    (len & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
456		bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
457		    BCM_DMA_SAME_ADDR, BCM_DMA_32BIT);
458		psrc = sc->dmamap_seg_addrs[idx];
459		pdst = sc->sc_sdhci_buffer_phys;
460		sync_op = BUS_DMASYNC_PREWRITE;
461	}
462
463	/*
464	 * When starting a new DMA operation do the busdma sync operation, and
465	 * disable SDCHI data interrrupts because we'll be driven by DMA
466	 * interrupts (or SDHCI error interrupts) until the IO is done.
467	 */
468	if (idx == 0) {
469		bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
470		slot->intmask &= ~(SDHCI_INT_DATA_AVAIL |
471		    SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END);
472		bcm_sdhci_write_4(sc->sc_dev, &sc->sc_slot, SDHCI_SIGNAL_ENABLE,
473		    slot->intmask);
474	}
475
476	/*
477	 * Start the DMA transfer.  Only programming errors (like failing to
478	 * allocate a channel) cause a non-zero return from bcm_dma_start().
479	 */
480	err = bcm_dma_start(sc->sc_dma_ch, psrc, pdst, len);
481	KASSERT((err == 0), ("bcm2835_sdhci: failed DMA start"));
482}
483
484static void
485bcm_sdhci_dma_intr(int ch, void *arg)
486{
487	struct bcm_sdhci_softc *sc = (struct bcm_sdhci_softc *)arg;
488	struct sdhci_slot *slot = &sc->sc_slot;
489	uint32_t reg, mask;
490	int left, sync_op;
491
492	mtx_lock(&slot->mtx);
493
494	/*
495	 * If there are more segments for the current dma, start the next one.
496	 * Otherwise unload the dma map and decide what to do next based on the
497	 * status of the sdhci controller and whether there's more data left.
498	 */
499	if (sc->dmamap_seg_index < sc->dmamap_seg_count) {
500		bcm_sdhci_start_dma_seg(sc);
501		mtx_unlock(&slot->mtx);
502		return;
503	}
504
505	if (slot->curcmd->data->flags & MMC_DATA_READ) {
506		sync_op = BUS_DMASYNC_POSTREAD;
507		mask = SDHCI_INT_DATA_AVAIL;
508	} else {
509		sync_op = BUS_DMASYNC_POSTWRITE;
510		mask = SDHCI_INT_SPACE_AVAIL;
511	}
512	bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
513	bus_dmamap_unload(sc->sc_dma_tag, sc->sc_dma_map);
514
515	sc->dmamap_seg_count = 0;
516	sc->dmamap_seg_index = 0;
517
518	left = min(BCM_SDHCI_BUFFER_SIZE,
519	    slot->curcmd->data->len - slot->offset);
520
521	/* DATA END? */
522	reg = bcm_sdhci_read_4(slot->bus, slot, SDHCI_INT_STATUS);
523
524	if (reg & SDHCI_INT_DATA_END) {
525		/* ACK for all outstanding interrupts */
526		bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS, reg);
527
528		/* enable INT */
529		slot->intmask |= SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL
530		    | SDHCI_INT_DATA_END;
531		bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
532		    slot->intmask);
533
534		/* finish this data */
535		sdhci_finish_data(slot);
536	}
537	else {
538		/* already available? */
539		if (reg & mask) {
540
541			/* ACK for DATA_AVAIL or SPACE_AVAIL */
542			bcm_sdhci_write_4(slot->bus, slot,
543			    SDHCI_INT_STATUS, mask);
544
545			/* continue next DMA transfer */
546			if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map,
547			    (uint8_t *)slot->curcmd->data->data +
548			    slot->offset, left, bcm_sdhci_dmacb, sc,
549			    BUS_DMA_NOWAIT) != 0 || sc->dmamap_status != 0) {
550				slot->curcmd->error = MMC_ERR_NO_MEMORY;
551				sdhci_finish_data(slot);
552			} else {
553				bcm_sdhci_start_dma_seg(sc);
554			}
555		} else {
556			/* wait for next data by INT */
557
558			/* enable INT */
559			slot->intmask |= SDHCI_INT_DATA_AVAIL |
560			    SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END;
561			bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
562			    slot->intmask);
563		}
564	}
565
566	mtx_unlock(&slot->mtx);
567}
568
569static void
570bcm_sdhci_read_dma(device_t dev, struct sdhci_slot *slot)
571{
572	struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
573	size_t left;
574
575	if (sc->dmamap_seg_count != 0) {
576		device_printf(sc->sc_dev, "DMA in use\n");
577		return;
578	}
579
580	left = min(BCM_SDHCI_BUFFER_SIZE,
581	    slot->curcmd->data->len - slot->offset);
582
583	KASSERT((left & 3) == 0,
584	    ("%s: len = %d, not word-aligned", __func__, left));
585
586	if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map,
587	    (uint8_t *)slot->curcmd->data->data + slot->offset, left,
588	    bcm_sdhci_dmacb, sc, BUS_DMA_NOWAIT) != 0 ||
589	    sc->dmamap_status != 0) {
590		slot->curcmd->error = MMC_ERR_NO_MEMORY;
591		return;
592	}
593
594	/* DMA start */
595	bcm_sdhci_start_dma_seg(sc);
596}
597
598static void
599bcm_sdhci_write_dma(device_t dev, struct sdhci_slot *slot)
600{
601	struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
602	size_t left;
603
604	if (sc->dmamap_seg_count != 0) {
605		device_printf(sc->sc_dev, "DMA in use\n");
606		return;
607	}
608
609	left = min(BCM_SDHCI_BUFFER_SIZE,
610	    slot->curcmd->data->len - slot->offset);
611
612	KASSERT((left & 3) == 0,
613	    ("%s: len = %d, not word-aligned", __func__, left));
614
615	if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map,
616	    (uint8_t *)slot->curcmd->data->data + slot->offset, left,
617	    bcm_sdhci_dmacb, sc, BUS_DMA_NOWAIT) != 0 ||
618	    sc->dmamap_status != 0) {
619		slot->curcmd->error = MMC_ERR_NO_MEMORY;
620		return;
621	}
622
623	/* DMA start */
624	bcm_sdhci_start_dma_seg(sc);
625}
626
627static int
628bcm_sdhci_will_handle_transfer(device_t dev, struct sdhci_slot *slot)
629{
630	size_t left;
631
632	/*
633	 * Do not use DMA for transfers less than block size or with a length
634	 * that is not a multiple of four.
635	 */
636	left = min(BCM_DMA_BLOCK_SIZE,
637	    slot->curcmd->data->len - slot->offset);
638	if (left < BCM_DMA_BLOCK_SIZE)
639		return (0);
640	if (left & 0x03)
641		return (0);
642
643	return (1);
644}
645
646static void
647bcm_sdhci_start_transfer(device_t dev, struct sdhci_slot *slot,
648    uint32_t *intmask)
649{
650
651	/* DMA transfer FIFO 1KB */
652	if (slot->curcmd->data->flags & MMC_DATA_READ)
653		bcm_sdhci_read_dma(dev, slot);
654	else
655		bcm_sdhci_write_dma(dev, slot);
656}
657
658static void
659bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
660{
661
662	sdhci_finish_data(slot);
663}
664
665static device_method_t bcm_sdhci_methods[] = {
666	/* Device interface */
667	DEVMETHOD(device_probe,		bcm_sdhci_probe),
668	DEVMETHOD(device_attach,	bcm_sdhci_attach),
669	DEVMETHOD(device_detach,	bcm_sdhci_detach),
670
671	/* Bus interface */
672	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
673	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
674	DEVMETHOD(bus_print_child,	bus_generic_print_child),
675
676	/* MMC bridge interface */
677	DEVMETHOD(mmcbr_update_ios,	sdhci_generic_update_ios),
678	DEVMETHOD(mmcbr_request,	sdhci_generic_request),
679	DEVMETHOD(mmcbr_get_ro,		bcm_sdhci_get_ro),
680	DEVMETHOD(mmcbr_acquire_host,	sdhci_generic_acquire_host),
681	DEVMETHOD(mmcbr_release_host,	sdhci_generic_release_host),
682
683	DEVMETHOD(sdhci_min_freq,	bcm_sdhci_min_freq),
684	/* Platform transfer methods */
685	DEVMETHOD(sdhci_platform_will_handle,		bcm_sdhci_will_handle_transfer),
686	DEVMETHOD(sdhci_platform_start_transfer,	bcm_sdhci_start_transfer),
687	DEVMETHOD(sdhci_platform_finish_transfer,	bcm_sdhci_finish_transfer),
688	/* SDHCI registers accessors */
689	DEVMETHOD(sdhci_read_1,		bcm_sdhci_read_1),
690	DEVMETHOD(sdhci_read_2,		bcm_sdhci_read_2),
691	DEVMETHOD(sdhci_read_4,		bcm_sdhci_read_4),
692	DEVMETHOD(sdhci_read_multi_4,	bcm_sdhci_read_multi_4),
693	DEVMETHOD(sdhci_write_1,	bcm_sdhci_write_1),
694	DEVMETHOD(sdhci_write_2,	bcm_sdhci_write_2),
695	DEVMETHOD(sdhci_write_4,	bcm_sdhci_write_4),
696	DEVMETHOD(sdhci_write_multi_4,	bcm_sdhci_write_multi_4),
697
698	{ 0, 0 }
699};
700
701static devclass_t bcm_sdhci_devclass;
702
703static driver_t bcm_sdhci_driver = {
704	"sdhci_bcm",
705	bcm_sdhci_methods,
706	sizeof(struct bcm_sdhci_softc),
707};
708
709DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass, 0, 0);
710MODULE_DEPEND(sdhci_bcm, sdhci, 1, 1, 1);
711