2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/systm.h>
35 #include <sys/endian.h>
36 #include <sys/kernel.h>
37 #include <sys/kthread.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>
46 #include <sys/timetc.h>
47 #include <sys/watchdog.h>
51 #include <machine/bus.h>
52 #include <machine/cpu.h>
53 #include <machine/cpufunc.h>
54 #include <machine/resource.h>
55 #include <machine/intr.h>
57 #include <dev/ofw/ofw_bus.h>
58 #include <dev/ofw/ofw_bus_subr.h>
60 #include <dev/mmc/bridge.h>
61 #include <dev/mmc/mmcreg.h>
62 #include <dev/mmc/mmcbrvar.h>
64 #include <arm/lpc/lpcreg.h>
65 #include <arm/lpc/lpcvar.h>
68 #define debugf(fmt, args...) do { printf("%s(): ", __func__); \
69 printf(fmt,##args); } while (0)
71 #define debugf(fmt, args...)
74 struct lpc_mmc_dmamap_arg
{
75 bus_addr_t lm_dma_busaddr
;
78 struct lpc_mmc_softc
{
81 struct resource
* lm_mem_res
;
82 struct resource
* lm_irq_res
;
83 bus_space_tag_t lm_bst
;
84 bus_space_handle_t lm_bsh
;
86 struct mmc_host lm_host
;
87 struct mmc_request
* lm_req
;
88 struct mmc_data
* lm_data
;
90 #define LPC_SD_FLAGS_IGNORECRC (1 << 0)
91 int lm_xfer_direction
;
92 #define DIRECTION_READ 0
93 #define DIRECTION_WRITE 1
96 bus_dma_tag_t lm_dma_tag
;
97 bus_dmamap_t lm_dma_map
;
98 bus_addr_t lm_buffer_phys
;
102 #define LPC_SD_MAX_BLOCKSIZE 1024
104 #define LPC_MMC_DMACH_READ 1
105 #define LPC_MMC_DMACH_WRITE 0
108 static int lpc_mmc_probe(device_t
);
109 static int lpc_mmc_attach(device_t
);
110 static int lpc_mmc_detach(device_t
);
111 static void lpc_mmc_intr(void *);
113 static void lpc_mmc_cmd(struct lpc_mmc_softc
*, struct mmc_command
*);
114 static void lpc_mmc_setup_xfer(struct lpc_mmc_softc
*, struct mmc_data
*);
116 static int lpc_mmc_update_ios(device_t
, device_t
);
117 static int lpc_mmc_request(device_t
, device_t
, struct mmc_request
*);
118 static int lpc_mmc_get_ro(device_t
, device_t
);
119 static int lpc_mmc_acquire_host(device_t
, device_t
);
120 static int lpc_mmc_release_host(device_t
, device_t
);
122 static void lpc_mmc_dma_rxfinish(void *);
123 static void lpc_mmc_dma_rxerror(void *);
124 static void lpc_mmc_dma_txfinish(void *);
125 static void lpc_mmc_dma_txerror(void *);
127 static void lpc_mmc_dmamap_cb(void *, bus_dma_segment_t
*, int, int);
129 #define lpc_mmc_lock(_sc) \
130 mtx_lock(&_sc->lm_mtx);
131 #define lpc_mmc_unlock(_sc) \
132 mtx_unlock(&_sc->lm_mtx);
133 #define lpc_mmc_read_4(_sc, _reg) \
134 bus_space_read_4(_sc->lm_bst, _sc->lm_bsh, _reg)
135 #define lpc_mmc_write_4(_sc, _reg, _value) \
136 bus_space_write_4(_sc->lm_bst, _sc->lm_bsh, _reg, _value)
138 static struct lpc_dmac_channel_config lpc_mmc_dma_rxconf
= {
139 .ldc_fcntl
= LPC_DMAC_FLOW_D_P2M
,
140 .ldc_src_periph
= LPC_DMAC_SD_ID
,
141 .ldc_src_width
= LPC_DMAC_CH_CONTROL_WIDTH_4
,
143 .ldc_src_burst
= LPC_DMAC_CH_CONTROL_BURST_8
,
144 .ldc_dst_periph
= LPC_DMAC_SD_ID
,
145 .ldc_dst_width
= LPC_DMAC_CH_CONTROL_WIDTH_4
,
147 .ldc_dst_burst
= LPC_DMAC_CH_CONTROL_BURST_8
,
148 .ldc_success_handler
= lpc_mmc_dma_rxfinish
,
149 .ldc_error_handler
= lpc_mmc_dma_rxerror
,
152 static struct lpc_dmac_channel_config lpc_mmc_dma_txconf
= {
153 .ldc_fcntl
= LPC_DMAC_FLOW_P_M2P
,
154 .ldc_src_periph
= LPC_DMAC_SD_ID
,
155 .ldc_src_width
= LPC_DMAC_CH_CONTROL_WIDTH_4
,
157 .ldc_src_burst
= LPC_DMAC_CH_CONTROL_BURST_8
,
158 .ldc_dst_periph
= LPC_DMAC_SD_ID
,
159 .ldc_dst_width
= LPC_DMAC_CH_CONTROL_WIDTH_4
,
161 .ldc_dst_burst
= LPC_DMAC_CH_CONTROL_BURST_8
,
162 .ldc_success_handler
= lpc_mmc_dma_txfinish
,
163 .ldc_error_handler
= lpc_mmc_dma_txerror
,
167 lpc_mmc_probe(device_t dev
)
170 if (!ofw_bus_status_okay(dev
))
173 if (!ofw_bus_is_compatible(dev
, "lpc,mmc"))
176 device_set_desc(dev
, "LPC32x0 MMC/SD controller");
177 return (BUS_PROBE_DEFAULT
);
181 lpc_mmc_attach(device_t dev
)
183 struct lpc_mmc_softc
*sc
= device_get_softc(dev
);
184 struct lpc_mmc_dmamap_arg ctx
;
191 mtx_init(&sc
->lm_mtx
, "lpcmmc", "mmc", MTX_DEF
);
194 sc
->lm_mem_res
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
, &rid
,
196 if (!sc
->lm_mem_res
) {
197 device_printf(dev
, "cannot allocate memory window\n");
201 sc
->lm_bst
= rman_get_bustag(sc
->lm_mem_res
);
202 sc
->lm_bsh
= rman_get_bushandle(sc
->lm_mem_res
);
204 debugf("virtual register space: 0x%08lx\n", sc
->lm_bsh
);
207 sc
->lm_irq_res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
,
209 if (!sc
->lm_irq_res
) {
210 device_printf(dev
, "cannot allocate interrupt\n");
211 bus_release_resource(dev
, SYS_RES_MEMORY
, 0, sc
->lm_mem_res
);
215 if (bus_setup_intr(dev
, sc
->lm_irq_res
, INTR_TYPE_MISC
| INTR_MPSAFE
,
216 NULL
, lpc_mmc_intr
, sc
, &sc
->lm_intrhand
))
218 bus_release_resource(dev
, SYS_RES_MEMORY
, 0, sc
->lm_mem_res
);
219 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->lm_irq_res
);
220 device_printf(dev
, "cannot setup interrupt handler\n");
224 sc
->lm_host
.f_min
= 312500;
225 sc
->lm_host
.f_max
= 2500000;
226 sc
->lm_host
.host_ocr
= MMC_OCR_300_310
| MMC_OCR_310_320
|
227 MMC_OCR_320_330
| MMC_OCR_330_340
;
229 sc
->lm_host
.caps
= MMC_CAP_4_BIT_DATA
;
232 lpc_pwr_write(dev
, LPC_CLKPWR_MS_CTRL
,
233 LPC_CLKPWR_MS_CTRL_CLOCK_EN
| LPC_CLKPWR_MS_CTRL_SD_CLOCK
| 1);
234 lpc_mmc_write_4(sc
, LPC_SD_POWER
, LPC_SD_POWER_CTRL_ON
);
236 device_set_ivars(dev
, &sc
->lm_host
);
238 child
= device_add_child(dev
, "mmc", -1);
240 device_printf(dev
, "attaching MMC bus failed!\n");
241 bus_teardown_intr(dev
, sc
->lm_irq_res
, sc
->lm_intrhand
);
242 bus_release_resource(dev
, SYS_RES_MEMORY
, 0, sc
->lm_mem_res
);
243 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->lm_irq_res
);
247 /* Alloc DMA memory */
248 err
= bus_dma_tag_create(
249 bus_get_dma_tag(sc
->lm_dev
),
250 4, 0, /* alignment, boundary */
251 BUS_SPACE_MAXADDR_32BIT
, /* lowaddr */
252 BUS_SPACE_MAXADDR
, /* highaddr */
253 NULL
, NULL
, /* filter, filterarg */
254 LPC_SD_MAX_BLOCKSIZE
, 1, /* maxsize, nsegments */
255 LPC_SD_MAX_BLOCKSIZE
, 0, /* maxsegsize, flags */
256 NULL
, NULL
, /* lockfunc, lockarg */
259 err
= bus_dmamem_alloc(sc
->lm_dma_tag
, (void **)&sc
->lm_buffer
,
262 device_printf(dev
, "cannot allocate framebuffer\n");
266 err
= bus_dmamap_load(sc
->lm_dma_tag
, sc
->lm_dma_map
, sc
->lm_buffer
,
267 LPC_SD_MAX_BLOCKSIZE
, lpc_mmc_dmamap_cb
, &ctx
, BUS_DMA_NOWAIT
);
269 device_printf(dev
, "cannot load DMA map\n");
273 sc
->lm_buffer_phys
= ctx
.lm_dma_busaddr
;
275 lpc_mmc_dma_rxconf
.ldc_handler_arg
= (void *)sc
;
276 err
= lpc_dmac_config_channel(dev
, LPC_MMC_DMACH_READ
, &lpc_mmc_dma_rxconf
);
278 device_printf(dev
, "cannot allocate RX DMA channel\n");
283 lpc_mmc_dma_txconf
.ldc_handler_arg
= (void *)sc
;
284 err
= lpc_dmac_config_channel(dev
, LPC_MMC_DMACH_WRITE
, &lpc_mmc_dma_txconf
);
286 device_printf(dev
, "cannot allocate TX DMA channel\n");
290 bus_generic_probe(dev
);
291 bus_generic_attach(dev
);
297 bus_teardown_intr(dev
, sc
->lm_irq_res
, sc
->lm_intrhand
);
299 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->lm_irq_res
);
301 bus_release_resource(dev
, SYS_RES_MEMORY
, 0, sc
->lm_mem_res
);
306 lpc_mmc_detach(device_t dev
)
312 lpc_mmc_intr(void *arg
)
314 struct lpc_mmc_softc
*sc
= (struct lpc_mmc_softc
*)arg
;
315 struct mmc_command
*cmd
;
318 status
= lpc_mmc_read_4(sc
, LPC_SD_STATUS
);
320 debugf("interrupt: 0x%08x\n", status
);
322 if (status
& LPC_SD_STATUS_CMDCRCFAIL
) {
323 cmd
= sc
->lm_req
->cmd
;
324 cmd
->error
= sc
->lm_flags
& LPC_SD_FLAGS_IGNORECRC
325 ? MMC_ERR_NONE
: MMC_ERR_BADCRC
;
326 cmd
->resp
[0] = lpc_mmc_read_4(sc
, LPC_SD_RESP0
);
327 sc
->lm_req
->done(sc
->lm_req
);
329 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_CMDCRCFAIL
);
332 if (status
& LPC_SD_STATUS_CMDACTIVE
)
334 debugf("command active\n");
335 cmd
= sc
->lm_req
->cmd
;
336 cmd
->resp
[0] = lpc_mmc_read_4(sc
, LPC_SD_RESP0
);
337 sc
->lm_req
->done(sc
->lm_req
);
341 if (status
& LPC_SD_STATUS_DATATIMEOUT
) {
342 device_printf(sc
->lm_dev
, "data timeout\n");
343 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_DATATIMEOUT
);
346 if (status
& LPC_SD_STATUS_TXUNDERRUN
) {
347 device_printf(sc
->lm_dev
, "TX underrun\n");
348 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_TXUNDERRUN
);
351 if (status
& LPC_SD_STATUS_CMDRESPEND
) {
352 debugf("command response\n");
353 cmd
= sc
->lm_req
->cmd
;
355 if (cmd
->flags
& MMC_RSP_136
) {
356 cmd
->resp
[3] = lpc_mmc_read_4(sc
, LPC_SD_RESP3
);
357 cmd
->resp
[2] = lpc_mmc_read_4(sc
, LPC_SD_RESP2
);
358 cmd
->resp
[1] = lpc_mmc_read_4(sc
, LPC_SD_RESP1
);
361 cmd
->resp
[0] = lpc_mmc_read_4(sc
, LPC_SD_RESP0
);
362 cmd
->error
= MMC_ERR_NONE
;
364 if (cmd
->data
&& (cmd
->data
->flags
& MMC_DATA_WRITE
))
365 lpc_mmc_setup_xfer(sc
, sc
->lm_req
->cmd
->data
);
368 sc
->lm_req
->done(sc
->lm_req
);
372 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_CMDRESPEND
);
375 if (status
& LPC_SD_STATUS_CMDSENT
) {
376 debugf("command sent\n");
377 cmd
= sc
->lm_req
->cmd
;
378 cmd
->error
= MMC_ERR_NONE
;
379 sc
->lm_req
->done(sc
->lm_req
);
381 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_CMDSENT
);
384 if (status
& LPC_SD_STATUS_DATAEND
) {
385 if (sc
->lm_xfer_direction
== DIRECTION_READ
)
386 lpc_dmac_start_burst(sc
->lm_dev
, LPC_DMAC_SD_ID
);
388 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_DATAEND
);
391 if (status
& LPC_SD_STATUS_CMDTIMEOUT
) {
392 device_printf(sc
->lm_dev
, "command response timeout\n");
393 cmd
= sc
->lm_req
->cmd
;
394 cmd
->error
= MMC_ERR_TIMEOUT
;
395 sc
->lm_req
->done(sc
->lm_req
);
397 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_CMDTIMEOUT
);
401 if (status
& LPC_SD_STATUS_STARTBITERR
) {
402 device_printf(sc
->lm_dev
, "start bit error\n");
403 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_STARTBITERR
);
406 if (status
& LPC_SD_STATUS_DATACRCFAIL
) {
407 device_printf(sc
->lm_dev
, "data CRC error\n");
408 debugf("data buffer: %p\n", sc
->lm_buffer
);
409 cmd
= sc
->lm_req
->cmd
;
410 cmd
->error
= MMC_ERR_BADCRC
;
411 sc
->lm_req
->done(sc
->lm_req
);
414 if (sc
->lm_xfer_direction
== DIRECTION_READ
)
415 lpc_dmac_start_burst(sc
->lm_dev
, LPC_DMAC_SD_ID
);
417 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_DATACRCFAIL
);
420 if (status
& LPC_SD_STATUS_DATABLOCKEND
) {
421 debugf("data block end\n");
422 if (sc
->lm_xfer_direction
== DIRECTION_READ
)
423 memcpy(sc
->lm_data
->data
, sc
->lm_buffer
, sc
->lm_data
->len
);
425 if (sc
->lm_xfer_direction
== DIRECTION_WRITE
) {
426 lpc_dmac_disable_channel(sc
->lm_dev
, LPC_MMC_DMACH_WRITE
);
427 lpc_mmc_write_4(sc
, LPC_SD_DATACTRL
, 0);
430 sc
->lm_req
->done(sc
->lm_req
);
432 lpc_mmc_write_4(sc
, LPC_SD_CLEAR
, LPC_SD_STATUS_DATABLOCKEND
);
439 lpc_mmc_request(device_t bus
, device_t child
, struct mmc_request
*req
)
441 struct lpc_mmc_softc
*sc
= device_get_softc(bus
);
443 debugf("request: %p\n", req
);
451 if (req
->cmd
->data
&& req
->cmd
->data
->flags
& MMC_DATA_WRITE
) {
452 memcpy(sc
->lm_buffer
, req
->cmd
->data
->data
, req
->cmd
->data
->len
);
453 lpc_mmc_cmd(sc
, req
->cmd
);
459 lpc_mmc_setup_xfer(sc
, req
->cmd
->data
);
461 lpc_mmc_cmd(sc
, req
->cmd
);
468 lpc_mmc_cmd(struct lpc_mmc_softc
*sc
, struct mmc_command
*cmd
)
472 debugf("cmd: %d arg: 0x%08x\n", cmd
->opcode
, cmd
->arg
);
474 if (lpc_mmc_read_4(sc
, LPC_SD_COMMAND
) & LPC_SD_COMMAND_ENABLE
) {
475 lpc_mmc_write_4(sc
, LPC_SD_COMMAND
, 0);
479 sc
->lm_flags
&= ~LPC_SD_FLAGS_IGNORECRC
;
481 if (cmd
->flags
& MMC_RSP_PRESENT
)
482 cmdreg
|= LPC_SD_COMMAND_RESPONSE
;
484 if (MMC_RSP(cmd
->flags
) == MMC_RSP_R2
)
485 cmdreg
|= LPC_SD_COMMAND_LONGRSP
;
487 if (MMC_RSP(cmd
->flags
) == MMC_RSP_R3
)
488 sc
->lm_flags
|= LPC_SD_FLAGS_IGNORECRC
;
490 cmdreg
|= LPC_SD_COMMAND_ENABLE
;
491 cmdreg
|= (cmd
->opcode
& LPC_SD_COMMAND_CMDINDEXMASK
);
493 lpc_mmc_write_4(sc
, LPC_SD_MASK0
, 0xffffffff);
494 lpc_mmc_write_4(sc
, LPC_SD_MASK1
, 0xffffffff);
495 lpc_mmc_write_4(sc
, LPC_SD_ARGUMENT
, cmd
->arg
);
496 lpc_mmc_write_4(sc
, LPC_SD_COMMAND
, cmdreg
);
500 lpc_mmc_setup_xfer(struct lpc_mmc_softc
*sc
, struct mmc_data
*data
)
502 uint32_t datactrl
= 0;
503 int data_words
= data
->len
/ 4;
506 sc
->lm_xfer_done
= 0;
508 debugf("data: %p, len: %d, %s\n", data
,
509 data
->len
, (data
->flags
& MMC_DATA_READ
) ? "read" : "write");
511 if (data
->flags
& MMC_DATA_READ
) {
512 sc
->lm_xfer_direction
= DIRECTION_READ
;
513 lpc_dmac_setup_transfer(sc
->lm_dev
, LPC_MMC_DMACH_READ
,
514 LPC_SD_PHYS_BASE
+ LPC_SD_FIFO
, sc
->lm_buffer_phys
,
518 if (data
->flags
& MMC_DATA_WRITE
) {
519 sc
->lm_xfer_direction
= DIRECTION_WRITE
;
520 lpc_dmac_setup_transfer(sc
->lm_dev
, LPC_MMC_DMACH_WRITE
,
521 sc
->lm_buffer_phys
, LPC_SD_PHYS_BASE
+ LPC_SD_FIFO
,
525 datactrl
|= (sc
->lm_xfer_direction
526 ? LPC_SD_DATACTRL_WRITE
527 : LPC_SD_DATACTRL_READ
);
529 datactrl
|= LPC_SD_DATACTRL_DMAENABLE
| LPC_SD_DATACTRL_ENABLE
;
530 datactrl
|= (ffs(data
->len
) - 1) << 4;
532 debugf("datactrl: 0x%08x\n", datactrl
);
534 lpc_mmc_write_4(sc
, LPC_SD_DATATIMER
, 0xFFFF0000);
535 lpc_mmc_write_4(sc
, LPC_SD_DATALENGTH
, data
->len
);
536 lpc_mmc_write_4(sc
, LPC_SD_DATACTRL
, datactrl
);
540 lpc_mmc_read_ivar(device_t bus
, device_t child
, int which
,
543 struct lpc_mmc_softc
*sc
= device_get_softc(bus
);
548 case MMCBR_IVAR_BUS_MODE
:
549 *(int *)result
= sc
->lm_host
.ios
.bus_mode
;
551 case MMCBR_IVAR_BUS_WIDTH
:
552 *(int *)result
= sc
->lm_host
.ios
.bus_width
;
554 case MMCBR_IVAR_CHIP_SELECT
:
555 *(int *)result
= sc
->lm_host
.ios
.chip_select
;
557 case MMCBR_IVAR_CLOCK
:
558 *(int *)result
= sc
->lm_host
.ios
.clock
;
560 case MMCBR_IVAR_F_MIN
:
561 *(int *)result
= sc
->lm_host
.f_min
;
563 case MMCBR_IVAR_F_MAX
:
564 *(int *)result
= sc
->lm_host
.f_max
;
566 case MMCBR_IVAR_HOST_OCR
:
567 *(int *)result
= sc
->lm_host
.host_ocr
;
569 case MMCBR_IVAR_MODE
:
570 *(int *)result
= sc
->lm_host
.mode
;
573 *(int *)result
= sc
->lm_host
.ocr
;
575 case MMCBR_IVAR_POWER_MODE
:
576 *(int *)result
= sc
->lm_host
.ios
.power_mode
;
579 *(int *)result
= sc
->lm_host
.ios
.vdd
;
581 case MMCBR_IVAR_CAPS
:
582 *(int *)result
= sc
->lm_host
.caps
;
584 case MMCBR_IVAR_MAX_DATA
:
593 lpc_mmc_write_ivar(device_t bus
, device_t child
, int which
,
596 struct lpc_mmc_softc
*sc
= device_get_softc(bus
);
601 case MMCBR_IVAR_BUS_MODE
:
602 sc
->lm_host
.ios
.bus_mode
= value
;
604 case MMCBR_IVAR_BUS_WIDTH
:
605 sc
->lm_host
.ios
.bus_width
= value
;
607 case MMCBR_IVAR_CHIP_SELECT
:
608 sc
->lm_host
.ios
.chip_select
= value
;
610 case MMCBR_IVAR_CLOCK
:
611 sc
->lm_host
.ios
.clock
= value
;
613 case MMCBR_IVAR_MODE
:
614 sc
->lm_host
.mode
= value
;
617 sc
->lm_host
.ocr
= value
;
619 case MMCBR_IVAR_POWER_MODE
:
620 sc
->lm_host
.ios
.power_mode
= value
;
623 sc
->lm_host
.ios
.vdd
= value
;
625 /* These are read-only */
626 case MMCBR_IVAR_CAPS
:
627 case MMCBR_IVAR_HOST_OCR
:
628 case MMCBR_IVAR_F_MIN
:
629 case MMCBR_IVAR_F_MAX
:
630 case MMCBR_IVAR_MAX_DATA
:
637 lpc_mmc_update_ios(device_t bus
, device_t child
)
639 struct lpc_mmc_softc
*sc
= device_get_softc(bus
);
640 struct mmc_ios
*ios
= &sc
->lm_host
.ios
;
641 uint32_t clkdiv
= 0, pwr
= 0;
643 if (ios
->bus_width
== bus_width_4
)
644 clkdiv
|= LPC_SD_CLOCK_WIDEBUS
;
646 /* Calculate clock divider */
647 clkdiv
= (LPC_SD_CLK
/ (2 * ios
->clock
)) - 1;
649 /* Clock rate should not exceed rate requested in ios */
650 if ((LPC_SD_CLK
/ (2 * (clkdiv
+ 1))) > ios
->clock
)
653 debugf("clock: %dHz, clkdiv: %d\n", ios
->clock
, clkdiv
);
655 if (ios
->bus_width
== bus_width_4
) {
656 debugf("using wide bus mode\n");
657 clkdiv
|= LPC_SD_CLOCK_WIDEBUS
;
660 lpc_mmc_write_4(sc
, LPC_SD_CLOCK
, clkdiv
| LPC_SD_CLOCK_ENABLE
);
662 switch (ios
->power_mode
) {
664 pwr
|= LPC_SD_POWER_CTRL_OFF
;
667 pwr
|= LPC_SD_POWER_CTRL_UP
;
670 pwr
|= LPC_SD_POWER_CTRL_ON
;
674 if (ios
->bus_mode
== opendrain
)
675 pwr
|= LPC_SD_POWER_OPENDRAIN
;
677 lpc_mmc_write_4(sc
, LPC_SD_POWER
, pwr
);
683 lpc_mmc_get_ro(device_t bus
, device_t child
)
690 lpc_mmc_acquire_host(device_t bus
, device_t child
)
692 struct lpc_mmc_softc
*sc
= device_get_softc(bus
);
696 while (sc
->lm_bus_busy
)
697 error
= mtx_sleep(sc
, &sc
->lm_mtx
, PZERO
, "mmcah", 0);
705 lpc_mmc_release_host(device_t bus
, device_t child
)
707 struct lpc_mmc_softc
*sc
= device_get_softc(bus
);
716 static void lpc_mmc_dma_rxfinish(void *arg
)
720 static void lpc_mmc_dma_rxerror(void *arg
)
722 struct lpc_mmc_softc
*sc
= (struct lpc_mmc_softc
*)arg
;
723 device_printf(sc
->lm_dev
, "DMA RX error\n");
726 static void lpc_mmc_dma_txfinish(void *arg
)
730 static void lpc_mmc_dma_txerror(void *arg
)
732 struct lpc_mmc_softc
*sc
= (struct lpc_mmc_softc
*)arg
;
733 device_printf(sc
->lm_dev
, "DMA TX error\n");
737 lpc_mmc_dmamap_cb(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int err
)
739 struct lpc_mmc_dmamap_arg
*ctx
;
744 ctx
= (struct lpc_mmc_dmamap_arg
*)arg
;
745 ctx
->lm_dma_busaddr
= segs
[0].ds_addr
;
748 static device_method_t lpc_mmc_methods
[] = {
749 /* Device interface */
750 DEVMETHOD(device_probe
, lpc_mmc_probe
),
751 DEVMETHOD(device_attach
, lpc_mmc_attach
),
752 DEVMETHOD(device_detach
, lpc_mmc_detach
),
755 DEVMETHOD(bus_read_ivar
, lpc_mmc_read_ivar
),
756 DEVMETHOD(bus_write_ivar
, lpc_mmc_write_ivar
),
757 DEVMETHOD(bus_print_child
, bus_generic_print_child
),
759 /* MMC bridge interface */
760 DEVMETHOD(mmcbr_update_ios
, lpc_mmc_update_ios
),
761 DEVMETHOD(mmcbr_request
, lpc_mmc_request
),
762 DEVMETHOD(mmcbr_get_ro
, lpc_mmc_get_ro
),
763 DEVMETHOD(mmcbr_acquire_host
, lpc_mmc_acquire_host
),
764 DEVMETHOD(mmcbr_release_host
, lpc_mmc_release_host
),
769 static devclass_t lpc_mmc_devclass
;
771 static driver_t lpc_mmc_driver
= {
774 sizeof(struct lpc_mmc_softc
),
777 DRIVER_MODULE(lpcmmc
, simplebus
, lpc_mmc_driver
, lpc_mmc_devclass
, 0, 0);
778 DRIVER_MODULE(mmc
, lpcmmc
, mmc_driver
, mmc_devclass
, NULL
, NULL
);
779 MODULE_DEPEND(lpcmmc
, mmc
, 1, 1, 1);