bcm2835_sdhci.c revision 278703
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 278703 2015-02-13 20:38:39Z 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_DONT_SET_HISPD_BIT
236		| SDHCI_QUIRK_MISSING_CAPS;
237
238	sdhci_init_slot(dev, &sc->sc_slot, 0);
239
240	sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST1);
241	if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
242		sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST2);
243	if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
244		sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_ANY);
245	if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
246		goto fail;
247
248	bcm_dma_setup_intr(sc->sc_dma_ch, bcm_sdhci_dma_intr, sc);
249
250	/* Allocate bus_dma resources. */
251	err = bus_dma_tag_create(bus_get_dma_tag(dev),
252	    1, 0, BUS_SPACE_MAXADDR_32BIT,
253	    BUS_SPACE_MAXADDR, NULL, NULL,
254	    BCM_SDHCI_BUFFER_SIZE, NUM_DMA_SEGS, BCM_SDHCI_BUFFER_SIZE,
255	    BUS_DMA_ALLOCNOW, NULL, NULL,
256	    &sc->sc_dma_tag);
257
258	if (err) {
259		device_printf(dev, "failed allocate DMA tag");
260		goto fail;
261	}
262
263	err = bus_dmamap_create(sc->sc_dma_tag, 0, &sc->sc_dma_map);
264	if (err) {
265		device_printf(dev, "bus_dmamap_create failed\n");
266		goto fail;
267	}
268
269	sc->sc_sdhci_buffer_phys = BUS_SPACE_PHYSADDR(sc->sc_mem_res,
270	    SDHCI_BUFFER);
271
272	bus_generic_probe(dev);
273	bus_generic_attach(dev);
274
275	sdhci_start_slot(&sc->sc_slot);
276
277	return (0);
278
279fail:
280	if (sc->sc_intrhand)
281		bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
282	if (sc->sc_irq_res)
283		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
284	if (sc->sc_mem_res)
285		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
286
287	return (err);
288}
289
290static int
291bcm_sdhci_detach(device_t dev)
292{
293
294	return (EBUSY);
295}
296
297static void
298bcm_sdhci_intr(void *arg)
299{
300	struct bcm_sdhci_softc *sc = arg;
301
302	sdhci_generic_intr(&sc->sc_slot);
303}
304
305static int
306bcm_sdhci_get_ro(device_t bus, device_t child)
307{
308
309	return (0);
310}
311
312static inline uint32_t
313RD4(struct bcm_sdhci_softc *sc, bus_size_t off)
314{
315	uint32_t val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, off);
316	return val;
317}
318
319static inline void
320WR4(struct bcm_sdhci_softc *sc, bus_size_t off, uint32_t val)
321{
322	bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val);
323
324	if ((off != SDHCI_BUFFER && off != SDHCI_INT_STATUS && off != SDHCI_CLOCK_CONTROL))
325	{
326		int timeout = 100000;
327		while (val != bus_space_read_4(sc->sc_bst, sc->sc_bsh, off)
328		    && --timeout > 0)
329			continue;
330
331		if (timeout <= 0)
332			printf("sdhci_brcm: writing 0x%X to reg 0x%X "
333				"always gives 0x%X\n",
334				val, (uint32_t)off,
335				bus_space_read_4(sc->sc_bst, sc->sc_bsh, off));
336	}
337}
338
339static uint8_t
340bcm_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
341{
342	struct bcm_sdhci_softc *sc = device_get_softc(dev);
343	uint32_t val = RD4(sc, off & ~3);
344
345	return ((val >> (off & 3)*8) & 0xff);
346}
347
348static uint16_t
349bcm_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
350{
351	struct bcm_sdhci_softc *sc = device_get_softc(dev);
352	uint32_t val = RD4(sc, off & ~3);
353
354	/*
355	 * Standard 32-bit handling of command and transfer mode.
356	 */
357	if (off == SDHCI_TRANSFER_MODE) {
358		return (sc->cmd_and_mode >> 16);
359	} else if (off == SDHCI_COMMAND_FLAGS) {
360		return (sc->cmd_and_mode & 0x0000ffff);
361	}
362	return ((val >> (off & 3)*8) & 0xffff);
363}
364
365static uint32_t
366bcm_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
367{
368	struct bcm_sdhci_softc *sc = device_get_softc(dev);
369
370	return RD4(sc, off);
371}
372
373static void
374bcm_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
375    uint32_t *data, bus_size_t count)
376{
377	struct bcm_sdhci_softc *sc = device_get_softc(dev);
378
379	bus_space_read_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count);
380}
381
382static void
383bcm_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint8_t val)
384{
385	struct bcm_sdhci_softc *sc = device_get_softc(dev);
386	uint32_t val32 = RD4(sc, off & ~3);
387	val32 &= ~(0xff << (off & 3)*8);
388	val32 |= (val << (off & 3)*8);
389	WR4(sc, off & ~3, val32);
390}
391
392static void
393bcm_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint16_t val)
394{
395	struct bcm_sdhci_softc *sc = device_get_softc(dev);
396	uint32_t val32;
397	if (off == SDHCI_COMMAND_FLAGS)
398		val32 = sc->cmd_and_mode;
399	else
400		val32 = RD4(sc, off & ~3);
401	val32 &= ~(0xffff << (off & 3)*8);
402	val32 |= (val << (off & 3)*8);
403	if (off == SDHCI_TRANSFER_MODE)
404		sc->cmd_and_mode = val32;
405	else {
406		WR4(sc, off & ~3, val32);
407		if (off == SDHCI_COMMAND_FLAGS)
408			sc->cmd_and_mode = val32;
409	}
410}
411
412static void
413bcm_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, uint32_t val)
414{
415	struct bcm_sdhci_softc *sc = device_get_softc(dev);
416	WR4(sc, off, val);
417}
418
419static void
420bcm_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
421    uint32_t *data, bus_size_t count)
422{
423	struct bcm_sdhci_softc *sc = device_get_softc(dev);
424
425	bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count);
426}
427
428static uint32_t
429bcm_sdhci_min_freq(device_t dev, struct sdhci_slot *slot)
430{
431
432	return bcm2835_sdhci_min_freq;
433}
434
435static void
436bcm_sdhci_start_dma_seg(struct bcm_sdhci_softc *sc)
437{
438	struct sdhci_slot *slot;
439	vm_paddr_t pdst, psrc;
440	int err, idx, len, sync_op;
441
442	slot = &sc->sc_slot;
443	idx = sc->dmamap_seg_index++;
444	len = sc->dmamap_seg_sizes[idx];
445	slot->offset += len;
446
447	if (slot->curcmd->data->flags & MMC_DATA_READ) {
448		bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
449		    BCM_DMA_SAME_ADDR, BCM_DMA_32BIT);
450		bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
451		    BCM_DMA_INC_ADDR,
452		    (len & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
453		psrc = sc->sc_sdhci_buffer_phys;
454		pdst = sc->dmamap_seg_addrs[idx];
455		sync_op = BUS_DMASYNC_PREREAD;
456	} else {
457		bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
458		    BCM_DMA_INC_ADDR,
459		    (len & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
460		bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
461		    BCM_DMA_SAME_ADDR, BCM_DMA_32BIT);
462		psrc = sc->dmamap_seg_addrs[idx];
463		pdst = sc->sc_sdhci_buffer_phys;
464		sync_op = BUS_DMASYNC_PREWRITE;
465	}
466
467	/*
468	 * When starting a new DMA operation do the busdma sync operation, and
469	 * disable SDCHI data interrrupts because we'll be driven by DMA
470	 * interrupts (or SDHCI error interrupts) until the IO is done.
471	 */
472	if (idx == 0) {
473		bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
474		slot->intmask &= ~(SDHCI_INT_DATA_AVAIL |
475		    SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END);
476		bcm_sdhci_write_4(sc->sc_dev, &sc->sc_slot, SDHCI_SIGNAL_ENABLE,
477		    slot->intmask);
478	}
479
480	/*
481	 * Start the DMA transfer.  Only programming errors (like failing to
482	 * allocate a channel) cause a non-zero return from bcm_dma_start().
483	 */
484	err = bcm_dma_start(sc->sc_dma_ch, psrc, pdst, len);
485	KASSERT((err == 0), ("bcm2835_sdhci: failed DMA start"));
486}
487
488static void
489bcm_sdhci_dma_intr(int ch, void *arg)
490{
491	struct bcm_sdhci_softc *sc = (struct bcm_sdhci_softc *)arg;
492	struct sdhci_slot *slot = &sc->sc_slot;
493	uint32_t reg, mask;
494	int left, sync_op;
495
496	mtx_lock(&slot->mtx);
497
498	/*
499	 * If there are more segments for the current dma, start the next one.
500	 * Otherwise unload the dma map and decide what to do next based on the
501	 * status of the sdhci controller and whether there's more data left.
502	 */
503	if (sc->dmamap_seg_index < sc->dmamap_seg_count) {
504		bcm_sdhci_start_dma_seg(sc);
505		mtx_unlock(&slot->mtx);
506		return;
507	}
508
509	if (slot->curcmd->data->flags & MMC_DATA_READ) {
510		sync_op = BUS_DMASYNC_POSTREAD;
511		mask = SDHCI_INT_DATA_AVAIL;
512	} else {
513		sync_op = BUS_DMASYNC_POSTWRITE;
514		mask = SDHCI_INT_SPACE_AVAIL;
515	}
516	bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map, sync_op);
517	bus_dmamap_unload(sc->sc_dma_tag, sc->sc_dma_map);
518
519	sc->dmamap_seg_count = 0;
520	sc->dmamap_seg_index = 0;
521
522	left = min(BCM_SDHCI_BUFFER_SIZE,
523	    slot->curcmd->data->len - slot->offset);
524
525	/* DATA END? */
526	reg = bcm_sdhci_read_4(slot->bus, slot, SDHCI_INT_STATUS);
527
528	if (reg & SDHCI_INT_DATA_END) {
529		/* ACK for all outstanding interrupts */
530		bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS, reg);
531
532		/* enable INT */
533		slot->intmask |= SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL
534		    | SDHCI_INT_DATA_END;
535		bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
536		    slot->intmask);
537
538		/* finish this data */
539		sdhci_finish_data(slot);
540	}
541	else {
542		/* already available? */
543		if (reg & mask) {
544
545			/* ACK for DATA_AVAIL or SPACE_AVAIL */
546			bcm_sdhci_write_4(slot->bus, slot,
547			    SDHCI_INT_STATUS, mask);
548
549			/* continue next DMA transfer */
550			if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map,
551			    (uint8_t *)slot->curcmd->data->data +
552			    slot->offset, left, bcm_sdhci_dmacb, sc,
553			    BUS_DMA_NOWAIT) != 0 || sc->dmamap_status != 0) {
554				slot->curcmd->error = MMC_ERR_NO_MEMORY;
555				sdhci_finish_data(slot);
556			} else {
557				bcm_sdhci_start_dma_seg(sc);
558			}
559		} else {
560			/* wait for next data by INT */
561
562			/* enable INT */
563			slot->intmask |= SDHCI_INT_DATA_AVAIL |
564			    SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END;
565			bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
566			    slot->intmask);
567		}
568	}
569
570	mtx_unlock(&slot->mtx);
571}
572
573static void
574bcm_sdhci_read_dma(device_t dev, struct sdhci_slot *slot)
575{
576	struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
577	size_t left;
578
579	if (sc->dmamap_seg_count != 0) {
580		device_printf(sc->sc_dev, "DMA in use\n");
581		return;
582	}
583
584	left = min(BCM_SDHCI_BUFFER_SIZE,
585	    slot->curcmd->data->len - slot->offset);
586
587	KASSERT((left & 3) == 0,
588	    ("%s: len = %d, not word-aligned", __func__, left));
589
590	if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map,
591	    (uint8_t *)slot->curcmd->data->data + slot->offset, left,
592	    bcm_sdhci_dmacb, sc, BUS_DMA_NOWAIT) != 0 ||
593	    sc->dmamap_status != 0) {
594		slot->curcmd->error = MMC_ERR_NO_MEMORY;
595		return;
596	}
597
598	/* DMA start */
599	bcm_sdhci_start_dma_seg(sc);
600}
601
602static void
603bcm_sdhci_write_dma(device_t dev, struct sdhci_slot *slot)
604{
605	struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
606	size_t left;
607
608	if (sc->dmamap_seg_count != 0) {
609		device_printf(sc->sc_dev, "DMA in use\n");
610		return;
611	}
612
613	left = min(BCM_SDHCI_BUFFER_SIZE,
614	    slot->curcmd->data->len - slot->offset);
615
616	KASSERT((left & 3) == 0,
617	    ("%s: len = %d, not word-aligned", __func__, left));
618
619	if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map,
620	    (uint8_t *)slot->curcmd->data->data + slot->offset, left,
621	    bcm_sdhci_dmacb, sc, BUS_DMA_NOWAIT) != 0 ||
622	    sc->dmamap_status != 0) {
623		slot->curcmd->error = MMC_ERR_NO_MEMORY;
624		return;
625	}
626
627	/* DMA start */
628	bcm_sdhci_start_dma_seg(sc);
629}
630
631static int
632bcm_sdhci_will_handle_transfer(device_t dev, struct sdhci_slot *slot)
633{
634	size_t left;
635
636	/*
637	 * Do not use DMA for transfers less than block size or with a length
638	 * that is not a multiple of four.
639	 */
640	left = min(BCM_DMA_BLOCK_SIZE,
641	    slot->curcmd->data->len - slot->offset);
642	if (left < BCM_DMA_BLOCK_SIZE)
643		return (0);
644	if (left & 0x03)
645		return (0);
646
647	return (1);
648}
649
650static void
651bcm_sdhci_start_transfer(device_t dev, struct sdhci_slot *slot,
652    uint32_t *intmask)
653{
654
655	/* DMA transfer FIFO 1KB */
656	if (slot->curcmd->data->flags & MMC_DATA_READ)
657		bcm_sdhci_read_dma(dev, slot);
658	else
659		bcm_sdhci_write_dma(dev, slot);
660}
661
662static void
663bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
664{
665
666	sdhci_finish_data(slot);
667}
668
669static device_method_t bcm_sdhci_methods[] = {
670	/* Device interface */
671	DEVMETHOD(device_probe,		bcm_sdhci_probe),
672	DEVMETHOD(device_attach,	bcm_sdhci_attach),
673	DEVMETHOD(device_detach,	bcm_sdhci_detach),
674
675	/* Bus interface */
676	DEVMETHOD(bus_read_ivar,	sdhci_generic_read_ivar),
677	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
678	DEVMETHOD(bus_print_child,	bus_generic_print_child),
679
680	/* MMC bridge interface */
681	DEVMETHOD(mmcbr_update_ios,	sdhci_generic_update_ios),
682	DEVMETHOD(mmcbr_request,	sdhci_generic_request),
683	DEVMETHOD(mmcbr_get_ro,		bcm_sdhci_get_ro),
684	DEVMETHOD(mmcbr_acquire_host,	sdhci_generic_acquire_host),
685	DEVMETHOD(mmcbr_release_host,	sdhci_generic_release_host),
686
687	DEVMETHOD(sdhci_min_freq,	bcm_sdhci_min_freq),
688	/* Platform transfer methods */
689	DEVMETHOD(sdhci_platform_will_handle,		bcm_sdhci_will_handle_transfer),
690	DEVMETHOD(sdhci_platform_start_transfer,	bcm_sdhci_start_transfer),
691	DEVMETHOD(sdhci_platform_finish_transfer,	bcm_sdhci_finish_transfer),
692	/* SDHCI registers accessors */
693	DEVMETHOD(sdhci_read_1,		bcm_sdhci_read_1),
694	DEVMETHOD(sdhci_read_2,		bcm_sdhci_read_2),
695	DEVMETHOD(sdhci_read_4,		bcm_sdhci_read_4),
696	DEVMETHOD(sdhci_read_multi_4,	bcm_sdhci_read_multi_4),
697	DEVMETHOD(sdhci_write_1,	bcm_sdhci_write_1),
698	DEVMETHOD(sdhci_write_2,	bcm_sdhci_write_2),
699	DEVMETHOD(sdhci_write_4,	bcm_sdhci_write_4),
700	DEVMETHOD(sdhci_write_multi_4,	bcm_sdhci_write_multi_4),
701
702	{ 0, 0 }
703};
704
705static devclass_t bcm_sdhci_devclass;
706
707static driver_t bcm_sdhci_driver = {
708	"sdhci_bcm",
709	bcm_sdhci_methods,
710	sizeof(struct bcm_sdhci_softc),
711};
712
713DRIVER_MODULE(sdhci_bcm, simplebus, bcm_sdhci_driver, bcm_sdhci_devclass, 0, 0);
714MODULE_DEPEND(sdhci_bcm, sdhci, 1, 1, 1);
715