]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/lpc/lpc_mmc.c
Upgrade to OpenPAM Radula.
[FreeBSD/FreeBSD.git] / sys / arm / lpc / lpc_mmc.c
1 /*-
2  * Copyright (c) 2011 Jakub Wojciech Klama <jceel@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$");
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/time.h>
46 #include <sys/timetc.h>
47 #include <sys/watchdog.h>
48
49 #include <sys/kdb.h>
50
51 #include <machine/bus.h>
52 #include <machine/resource.h>
53 #include <machine/intr.h>
54
55 #include <dev/ofw/ofw_bus.h>
56 #include <dev/ofw/ofw_bus_subr.h>
57
58 #include <dev/mmc/bridge.h>
59 #include <dev/mmc/mmcreg.h>
60 #include <dev/mmc/mmcbrvar.h>
61
62 #include <arm/lpc/lpcreg.h>
63 #include <arm/lpc/lpcvar.h>
64
65 #ifdef DEBUG
66 #define debugf(fmt, args...) do { printf("%s(): ", __func__);   \
67     printf(fmt,##args); } while (0)
68 #else
69 #define debugf(fmt, args...)
70 #endif
71
72 struct lpc_mmc_dmamap_arg {
73         bus_addr_t              lm_dma_busaddr;
74 };
75
76 struct lpc_mmc_softc {
77         device_t                lm_dev;
78         struct mtx              lm_mtx;
79         struct resource *       lm_mem_res;
80         struct resource *       lm_irq_res;
81         bus_space_tag_t         lm_bst;
82         bus_space_handle_t      lm_bsh;
83         void *                  lm_intrhand;
84         struct mmc_host         lm_host;
85         struct mmc_request *    lm_req;
86         struct mmc_data *       lm_data;
87         uint32_t                lm_flags;
88 #define LPC_SD_FLAGS_IGNORECRC          (1 << 0)
89         int                     lm_xfer_direction;
90 #define DIRECTION_READ          0
91 #define DIRECTION_WRITE         1
92         int                     lm_xfer_done;
93         int                     lm_bus_busy;
94         bus_dma_tag_t           lm_dma_tag;
95         bus_dmamap_t            lm_dma_map;
96         bus_addr_t              lm_buffer_phys;
97         void *                  lm_buffer;
98 };
99
100 #define LPC_SD_MAX_BLOCKSIZE    1024
101 /* XXX */
102 #define LPC_MMC_DMACH_READ      1
103 #define LPC_MMC_DMACH_WRITE     0
104
105
106 static int lpc_mmc_probe(device_t);
107 static int lpc_mmc_attach(device_t);
108 static int lpc_mmc_detach(device_t);
109 static void lpc_mmc_intr(void *);
110
111 static void lpc_mmc_cmd(struct lpc_mmc_softc *, struct mmc_command *);
112 static void lpc_mmc_setup_xfer(struct lpc_mmc_softc *, struct mmc_data *);
113
114 static int lpc_mmc_update_ios(device_t, device_t);
115 static int lpc_mmc_request(device_t, device_t, struct mmc_request *);
116 static int lpc_mmc_get_ro(device_t, device_t);
117 static int lpc_mmc_acquire_host(device_t, device_t);
118 static int lpc_mmc_release_host(device_t, device_t);
119
120 static void lpc_mmc_dma_rxfinish(void *);
121 static void lpc_mmc_dma_rxerror(void *);
122 static void lpc_mmc_dma_txfinish(void *);
123 static void lpc_mmc_dma_txerror(void *);
124
125 static void lpc_mmc_dmamap_cb(void *, bus_dma_segment_t *, int, int);
126
127 #define lpc_mmc_lock(_sc)                                               \
128     mtx_lock(&_sc->lm_mtx);
129 #define lpc_mmc_unlock(_sc)                                             \
130     mtx_unlock(&_sc->lm_mtx);
131 #define lpc_mmc_read_4(_sc, _reg)                                       \
132     bus_space_read_4(_sc->lm_bst, _sc->lm_bsh, _reg)
133 #define lpc_mmc_write_4(_sc, _reg, _value)                              \
134     bus_space_write_4(_sc->lm_bst, _sc->lm_bsh, _reg, _value)
135
136 static struct lpc_dmac_channel_config lpc_mmc_dma_rxconf = {
137         .ldc_fcntl = LPC_DMAC_FLOW_D_P2M,
138         .ldc_src_periph = LPC_DMAC_SD_ID,
139         .ldc_src_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
140         .ldc_src_incr = 0,
141         .ldc_src_burst = LPC_DMAC_CH_CONTROL_BURST_8,
142         .ldc_dst_periph = LPC_DMAC_SD_ID,
143         .ldc_dst_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
144         .ldc_dst_incr = 1,
145         .ldc_dst_burst = LPC_DMAC_CH_CONTROL_BURST_8,
146         .ldc_success_handler = lpc_mmc_dma_rxfinish,
147         .ldc_error_handler = lpc_mmc_dma_rxerror,
148 };
149
150 static struct lpc_dmac_channel_config lpc_mmc_dma_txconf = {
151         .ldc_fcntl = LPC_DMAC_FLOW_P_M2P,
152         .ldc_src_periph = LPC_DMAC_SD_ID,
153         .ldc_src_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
154         .ldc_src_incr = 1,
155         .ldc_src_burst = LPC_DMAC_CH_CONTROL_BURST_8,
156         .ldc_dst_periph = LPC_DMAC_SD_ID,
157         .ldc_dst_width = LPC_DMAC_CH_CONTROL_WIDTH_4,
158         .ldc_dst_incr = 0,
159         .ldc_dst_burst = LPC_DMAC_CH_CONTROL_BURST_8,
160         .ldc_success_handler = lpc_mmc_dma_txfinish,
161         .ldc_error_handler = lpc_mmc_dma_txerror,
162 };
163
164 static int
165 lpc_mmc_probe(device_t dev)
166 {
167
168         if (!ofw_bus_status_okay(dev))
169                 return (ENXIO);
170
171         if (!ofw_bus_is_compatible(dev, "lpc,mmc"))
172                 return (ENXIO);
173
174         device_set_desc(dev, "LPC32x0 MMC/SD controller");
175         return (BUS_PROBE_DEFAULT);
176 }
177
178 static int
179 lpc_mmc_attach(device_t dev)
180 {
181         struct lpc_mmc_softc *sc = device_get_softc(dev);
182         struct lpc_mmc_dmamap_arg ctx;
183         device_t child;
184         int rid, err;
185
186         sc->lm_dev = dev;
187         sc->lm_req = NULL;
188
189         mtx_init(&sc->lm_mtx, "lpcmmc", "mmc", MTX_DEF);
190
191         rid = 0;
192         sc->lm_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
193             RF_ACTIVE);
194         if (!sc->lm_mem_res) {
195                 device_printf(dev, "cannot allocate memory window\n");
196                 return (ENXIO);
197         }
198
199         sc->lm_bst = rman_get_bustag(sc->lm_mem_res);
200         sc->lm_bsh = rman_get_bushandle(sc->lm_mem_res);
201
202         debugf("virtual register space: 0x%08lx\n", sc->lm_bsh);
203
204         rid = 0;
205         sc->lm_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
206             RF_ACTIVE);
207         if (!sc->lm_irq_res) {
208                 device_printf(dev, "cannot allocate interrupt\n");
209                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
210                 return (ENXIO);
211         }
212
213         if (bus_setup_intr(dev, sc->lm_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
214             NULL, lpc_mmc_intr, sc, &sc->lm_intrhand))
215         {
216                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
217                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res);
218                 device_printf(dev, "cannot setup interrupt handler\n");
219                 return (ENXIO);
220         }
221
222         sc->lm_host.f_min = 312500;
223         sc->lm_host.f_max = 2500000;
224         sc->lm_host.host_ocr = MMC_OCR_300_310 | MMC_OCR_310_320 |
225             MMC_OCR_320_330 | MMC_OCR_330_340;
226 #if 0
227         sc->lm_host.caps = MMC_CAP_4_BIT_DATA;
228 #endif
229
230         lpc_pwr_write(dev, LPC_CLKPWR_MS_CTRL,
231             LPC_CLKPWR_MS_CTRL_CLOCK_EN | LPC_CLKPWR_MS_CTRL_SD_CLOCK | 1);
232         lpc_mmc_write_4(sc, LPC_SD_POWER, LPC_SD_POWER_CTRL_ON);
233
234         device_set_ivars(dev, &sc->lm_host);
235
236         child = device_add_child(dev, "mmc", -1);
237         if (!child) {
238                 device_printf(dev, "attaching MMC bus failed!\n");
239                 bus_teardown_intr(dev, sc->lm_irq_res, sc->lm_intrhand);
240                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
241                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res);
242                 return (ENXIO);
243         }
244
245         /* Alloc DMA memory */
246         err = bus_dma_tag_create(
247             bus_get_dma_tag(sc->lm_dev),
248             4, 0,                       /* alignment, boundary */
249             BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
250             BUS_SPACE_MAXADDR,          /* highaddr */
251             NULL, NULL,                 /* filter, filterarg */
252             LPC_SD_MAX_BLOCKSIZE, 1,    /* maxsize, nsegments */
253             LPC_SD_MAX_BLOCKSIZE, 0,    /* maxsegsize, flags */
254             NULL, NULL,                 /* lockfunc, lockarg */
255             &sc->lm_dma_tag);
256
257         err = bus_dmamem_alloc(sc->lm_dma_tag, (void **)&sc->lm_buffer,
258             0, &sc->lm_dma_map);
259         if (err) {
260                 device_printf(dev, "cannot allocate framebuffer\n");
261                 goto fail;
262         }
263
264         err = bus_dmamap_load(sc->lm_dma_tag, sc->lm_dma_map, sc->lm_buffer,
265             LPC_SD_MAX_BLOCKSIZE, lpc_mmc_dmamap_cb, &ctx, BUS_DMA_NOWAIT);
266         if (err) {
267                 device_printf(dev, "cannot load DMA map\n");
268                 goto fail;
269         }
270
271         sc->lm_buffer_phys = ctx.lm_dma_busaddr;
272
273         lpc_mmc_dma_rxconf.ldc_handler_arg = (void *)sc;
274         err = lpc_dmac_config_channel(dev, LPC_MMC_DMACH_READ, &lpc_mmc_dma_rxconf);
275         if (err) {
276                 device_printf(dev, "cannot allocate RX DMA channel\n");
277                 goto fail;
278         }
279
280
281         lpc_mmc_dma_txconf.ldc_handler_arg = (void *)sc;
282         err = lpc_dmac_config_channel(dev, LPC_MMC_DMACH_WRITE, &lpc_mmc_dma_txconf);   
283         if (err) {
284                 device_printf(dev, "cannot allocate TX DMA channel\n");
285                 goto fail;
286         }
287
288         bus_generic_probe(dev);
289         bus_generic_attach(dev);
290
291         return (0);
292
293 fail:
294         if (sc->lm_intrhand)
295                 bus_teardown_intr(dev, sc->lm_irq_res, sc->lm_intrhand);
296         if (sc->lm_irq_res)
297                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lm_irq_res);
298         if (sc->lm_mem_res)
299                 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->lm_mem_res);
300         return (err);
301 }
302
303 static int
304 lpc_mmc_detach(device_t dev)
305 {
306         return (EBUSY);
307 }
308
309 static void
310 lpc_mmc_intr(void *arg)
311 {
312         struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg;
313         struct mmc_command *cmd;
314         uint32_t status;
315
316         status = lpc_mmc_read_4(sc, LPC_SD_STATUS);
317
318         debugf("interrupt: 0x%08x\n", status);
319
320         if (status & LPC_SD_STATUS_CMDCRCFAIL) {
321                 cmd = sc->lm_req->cmd;
322                 cmd->error = sc->lm_flags & LPC_SD_FLAGS_IGNORECRC
323                     ? MMC_ERR_NONE : MMC_ERR_BADCRC;
324                 cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0);
325                 sc->lm_req->done(sc->lm_req);
326                 sc->lm_req = NULL;
327                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDCRCFAIL);    
328         }
329
330         if (status & LPC_SD_STATUS_CMDACTIVE)
331         {
332                 debugf("command active\n");
333                 cmd = sc->lm_req->cmd;
334                 cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0);
335                 sc->lm_req->done(sc->lm_req);
336                 sc->lm_req = NULL;
337         }
338         
339         if (status & LPC_SD_STATUS_DATATIMEOUT) {
340                 device_printf(sc->lm_dev, "data timeout\n");
341                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATATIMEOUT);
342         }
343
344         if (status & LPC_SD_STATUS_TXUNDERRUN) {
345                 device_printf(sc->lm_dev, "TX underrun\n");
346                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_TXUNDERRUN);
347         }
348         
349         if (status & LPC_SD_STATUS_CMDRESPEND) {
350                 debugf("command response\n");
351                 cmd = sc->lm_req->cmd;
352                 
353                 if (cmd->flags & MMC_RSP_136) {
354                         cmd->resp[3] = lpc_mmc_read_4(sc, LPC_SD_RESP3);
355                         cmd->resp[2] = lpc_mmc_read_4(sc, LPC_SD_RESP2);
356                         cmd->resp[1] = lpc_mmc_read_4(sc, LPC_SD_RESP1);
357                 }
358
359                 cmd->resp[0] = lpc_mmc_read_4(sc, LPC_SD_RESP0);
360                 cmd->error = MMC_ERR_NONE;
361         
362                 if (cmd->data && (cmd->data->flags & MMC_DATA_WRITE))
363                         lpc_mmc_setup_xfer(sc, sc->lm_req->cmd->data);
364
365                 if (!cmd->data) {       
366                         sc->lm_req->done(sc->lm_req);
367                         sc->lm_req = NULL;
368                 }
369
370                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDRESPEND);
371         }
372
373         if (status & LPC_SD_STATUS_CMDSENT) {
374                 debugf("command sent\n");
375                 cmd = sc->lm_req->cmd;
376                 cmd->error = MMC_ERR_NONE;
377                 sc->lm_req->done(sc->lm_req);
378                 sc->lm_req = NULL;
379                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDSENT);
380         }
381         
382         if (status & LPC_SD_STATUS_DATAEND) {
383                 if (sc->lm_xfer_direction == DIRECTION_READ)
384                         lpc_dmac_start_burst(sc->lm_dev, LPC_DMAC_SD_ID);
385
386                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATAEND);
387         }
388
389         if (status & LPC_SD_STATUS_CMDTIMEOUT) {
390                 device_printf(sc->lm_dev, "command response timeout\n");
391                 cmd = sc->lm_req->cmd;
392                 cmd->error = MMC_ERR_TIMEOUT;
393                 sc->lm_req->done(sc->lm_req);
394                 sc->lm_req = NULL;
395                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_CMDTIMEOUT);
396                 return;
397         }
398
399         if (status & LPC_SD_STATUS_STARTBITERR) {
400                 device_printf(sc->lm_dev, "start bit error\n");
401                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_STARTBITERR);
402         }
403
404         if (status & LPC_SD_STATUS_DATACRCFAIL) {               
405                 device_printf(sc->lm_dev, "data CRC error\n");
406                 debugf("data buffer: %p\n", sc->lm_buffer);
407                 cmd = sc->lm_req->cmd;
408                 cmd->error = MMC_ERR_BADCRC;
409                 sc->lm_req->done(sc->lm_req);
410                 sc->lm_req = NULL;
411
412                 if (sc->lm_xfer_direction == DIRECTION_READ)
413                         lpc_dmac_start_burst(sc->lm_dev, LPC_DMAC_SD_ID);
414
415                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATACRCFAIL);
416         }
417
418         if (status & LPC_SD_STATUS_DATABLOCKEND) {
419                 debugf("data block end\n");
420                 if (sc->lm_xfer_direction == DIRECTION_READ)
421                         memcpy(sc->lm_data->data, sc->lm_buffer, sc->lm_data->len);
422
423                 if (sc->lm_xfer_direction == DIRECTION_WRITE) {
424                         lpc_dmac_disable_channel(sc->lm_dev, LPC_MMC_DMACH_WRITE);
425                         lpc_mmc_write_4(sc, LPC_SD_DATACTRL, 0);
426                 }
427         
428                 sc->lm_req->done(sc->lm_req);
429                 sc->lm_req = NULL;
430                 lpc_mmc_write_4(sc, LPC_SD_CLEAR, LPC_SD_STATUS_DATABLOCKEND);
431         }
432
433         debugf("done\n");
434 }
435
436 static int
437 lpc_mmc_request(device_t bus, device_t child, struct mmc_request *req)
438 {
439         struct lpc_mmc_softc *sc = device_get_softc(bus);
440
441         debugf("request: %p\n", req);
442
443         lpc_mmc_lock(sc);
444         if (sc->lm_req)
445                 return (EBUSY);
446
447         sc->lm_req = req;
448
449         if (req->cmd->data && req->cmd->data->flags & MMC_DATA_WRITE) {
450                 memcpy(sc->lm_buffer, req->cmd->data->data, req->cmd->data->len);
451                 lpc_mmc_cmd(sc, req->cmd);
452                 lpc_mmc_unlock(sc);
453                 return (0);
454         }
455
456         if (req->cmd->data)
457                 lpc_mmc_setup_xfer(sc, req->cmd->data);
458
459         lpc_mmc_cmd(sc, req->cmd);
460         lpc_mmc_unlock(sc);
461
462         return (0);
463 }
464
465 static void
466 lpc_mmc_cmd(struct lpc_mmc_softc *sc, struct mmc_command *cmd)
467 {
468         uint32_t cmdreg = 0;
469
470         debugf("cmd: %d arg: 0x%08x\n", cmd->opcode, cmd->arg);
471
472         if (lpc_mmc_read_4(sc, LPC_SD_COMMAND) & LPC_SD_COMMAND_ENABLE) {
473                 lpc_mmc_write_4(sc, LPC_SD_COMMAND, 0);
474                 DELAY(1000);
475         }
476
477         sc->lm_flags &= ~LPC_SD_FLAGS_IGNORECRC;
478
479         if (cmd->flags & MMC_RSP_PRESENT)
480                 cmdreg |= LPC_SD_COMMAND_RESPONSE;
481
482         if (MMC_RSP(cmd->flags) == MMC_RSP_R2)
483                 cmdreg |= LPC_SD_COMMAND_LONGRSP;
484
485         if (MMC_RSP(cmd->flags) == MMC_RSP_R3)
486                 sc->lm_flags |= LPC_SD_FLAGS_IGNORECRC;
487
488         cmdreg |= LPC_SD_COMMAND_ENABLE;
489         cmdreg |= (cmd->opcode & LPC_SD_COMMAND_CMDINDEXMASK);
490
491         lpc_mmc_write_4(sc, LPC_SD_MASK0, 0xffffffff);
492         lpc_mmc_write_4(sc, LPC_SD_MASK1, 0xffffffff);
493         lpc_mmc_write_4(sc, LPC_SD_ARGUMENT, cmd->arg);
494         lpc_mmc_write_4(sc, LPC_SD_COMMAND, cmdreg);
495 }
496
497 static void
498 lpc_mmc_setup_xfer(struct lpc_mmc_softc *sc, struct mmc_data *data)
499 {
500         uint32_t datactrl = 0;
501         int data_words = data->len / 4;
502
503         sc->lm_data = data;
504         sc->lm_xfer_done = 0;
505
506         debugf("data: %p, len: %d, %s\n", data,
507             data->len, (data->flags & MMC_DATA_READ) ? "read" : "write");
508
509         if (data->flags & MMC_DATA_READ) {
510                 sc->lm_xfer_direction = DIRECTION_READ;
511                 lpc_dmac_setup_transfer(sc->lm_dev, LPC_MMC_DMACH_READ,
512                     LPC_SD_PHYS_BASE + LPC_SD_FIFO, sc->lm_buffer_phys,
513                     data_words, 0);
514         }
515
516         if (data->flags & MMC_DATA_WRITE) {
517                 sc->lm_xfer_direction = DIRECTION_WRITE;
518                 lpc_dmac_setup_transfer(sc->lm_dev, LPC_MMC_DMACH_WRITE,
519                     sc->lm_buffer_phys, LPC_SD_PHYS_BASE + LPC_SD_FIFO,
520                     data_words, 0);
521         }
522
523         datactrl |= (sc->lm_xfer_direction 
524             ? LPC_SD_DATACTRL_WRITE 
525             : LPC_SD_DATACTRL_READ);
526
527         datactrl |= LPC_SD_DATACTRL_DMAENABLE | LPC_SD_DATACTRL_ENABLE;
528         datactrl |= (ffs(data->len) - 1) << 4;
529
530         debugf("datactrl: 0x%08x\n", datactrl);
531
532         lpc_mmc_write_4(sc, LPC_SD_DATATIMER, 0xFFFF0000);
533         lpc_mmc_write_4(sc, LPC_SD_DATALENGTH, data->len);
534         lpc_mmc_write_4(sc, LPC_SD_DATACTRL, datactrl);
535 }
536
537 static int
538 lpc_mmc_read_ivar(device_t bus, device_t child, int which, 
539     uintptr_t *result)
540 {
541         struct lpc_mmc_softc *sc = device_get_softc(bus);
542
543         switch (which) {
544         default:
545                 return (EINVAL);
546         case MMCBR_IVAR_BUS_MODE:
547                 *(int *)result = sc->lm_host.ios.bus_mode;
548                 break;
549         case MMCBR_IVAR_BUS_WIDTH:
550                 *(int *)result = sc->lm_host.ios.bus_width;
551                 break;
552         case MMCBR_IVAR_CHIP_SELECT:
553                 *(int *)result = sc->lm_host.ios.chip_select;
554                 break;
555         case MMCBR_IVAR_CLOCK:
556                 *(int *)result = sc->lm_host.ios.clock;
557                 break;
558         case MMCBR_IVAR_F_MIN:
559                 *(int *)result = sc->lm_host.f_min;
560                 break;
561         case MMCBR_IVAR_F_MAX:
562                 *(int *)result = sc->lm_host.f_max;
563                 break;
564         case MMCBR_IVAR_HOST_OCR:
565                 *(int *)result = sc->lm_host.host_ocr;
566                 break;
567         case MMCBR_IVAR_MODE:
568                 *(int *)result = sc->lm_host.mode;
569                 break;
570         case MMCBR_IVAR_OCR:
571                 *(int *)result = sc->lm_host.ocr;
572                 break;
573         case MMCBR_IVAR_POWER_MODE:
574                 *(int *)result = sc->lm_host.ios.power_mode;
575                 break;
576         case MMCBR_IVAR_VDD:
577                 *(int *)result = sc->lm_host.ios.vdd;
578                 break;
579         case MMCBR_IVAR_CAPS:
580                 *(int *)result = sc->lm_host.caps;
581                 break;
582         case MMCBR_IVAR_MAX_DATA:
583                 *(int *)result = 1;
584                 break;
585         }
586
587         return (0);
588 }
589
590 static int
591 lpc_mmc_write_ivar(device_t bus, device_t child, int which,
592     uintptr_t value)
593 {
594         struct lpc_mmc_softc *sc = device_get_softc(bus);
595
596         switch (which) {
597         default:
598                 return (EINVAL);
599         case MMCBR_IVAR_BUS_MODE:
600                 sc->lm_host.ios.bus_mode = value;
601                 break;
602         case MMCBR_IVAR_BUS_WIDTH:
603                 sc->lm_host.ios.bus_width = value;
604                 break;
605         case MMCBR_IVAR_CHIP_SELECT:
606                 sc->lm_host.ios.chip_select = value;
607                 break;
608         case MMCBR_IVAR_CLOCK:
609                 sc->lm_host.ios.clock = value;
610                 break;
611         case MMCBR_IVAR_MODE:
612                 sc->lm_host.mode = value;
613                 break;
614         case MMCBR_IVAR_OCR:
615                 sc->lm_host.ocr = value;
616                 break;
617         case MMCBR_IVAR_POWER_MODE:
618                 sc->lm_host.ios.power_mode = value;
619                 break;
620         case MMCBR_IVAR_VDD:
621                 sc->lm_host.ios.vdd = value;
622                 break;
623         /* These are read-only */
624         case MMCBR_IVAR_CAPS:
625         case MMCBR_IVAR_HOST_OCR:
626         case MMCBR_IVAR_F_MIN:
627         case MMCBR_IVAR_F_MAX:
628         case MMCBR_IVAR_MAX_DATA:
629                 return (EINVAL);
630         }
631         return (0);
632 }
633
634 static int
635 lpc_mmc_update_ios(device_t bus, device_t child)
636 {
637         struct lpc_mmc_softc *sc = device_get_softc(bus);
638         struct mmc_ios *ios = &sc->lm_host.ios;
639         uint32_t clkdiv = 0, pwr = 0;
640
641         if (ios->bus_width == bus_width_4)
642                 clkdiv |= LPC_SD_CLOCK_WIDEBUS;
643
644         /* Calculate clock divider */
645         clkdiv = (LPC_SD_CLK / (2 * ios->clock)) - 1;
646
647         /* Clock rate should not exceed rate requested in ios */
648         if ((LPC_SD_CLK / (2 * (clkdiv + 1))) > ios->clock)
649                 clkdiv++;
650
651         debugf("clock: %dHz, clkdiv: %d\n", ios->clock, clkdiv);
652
653         if (ios->bus_width == bus_width_4) {
654                 debugf("using wide bus mode\n");
655                 clkdiv |= LPC_SD_CLOCK_WIDEBUS;
656         }
657
658         lpc_mmc_write_4(sc, LPC_SD_CLOCK, clkdiv | LPC_SD_CLOCK_ENABLE);
659
660         switch (ios->power_mode) {
661         case power_off:
662                 pwr |= LPC_SD_POWER_CTRL_OFF;
663                 break;
664         case power_up:
665                 pwr |= LPC_SD_POWER_CTRL_UP;
666                 break;
667         case power_on:
668                 pwr |= LPC_SD_POWER_CTRL_ON;
669                 break;
670         }
671
672         if (ios->bus_mode == opendrain)
673                 pwr |= LPC_SD_POWER_OPENDRAIN;
674
675         lpc_mmc_write_4(sc, LPC_SD_POWER, pwr);
676
677         return (0);
678 }
679
680 static int
681 lpc_mmc_get_ro(device_t bus, device_t child)
682 {
683
684         return (0);
685 }
686
687 static int
688 lpc_mmc_acquire_host(device_t bus, device_t child)
689 {
690         struct lpc_mmc_softc *sc = device_get_softc(bus);
691         int error = 0;
692
693         lpc_mmc_lock(sc);
694         while (sc->lm_bus_busy)
695                 error = mtx_sleep(sc, &sc->lm_mtx, PZERO, "mmcah", 0);
696
697         sc->lm_bus_busy++;
698         lpc_mmc_unlock(sc);
699         return (error);
700 }
701
702 static int
703 lpc_mmc_release_host(device_t bus, device_t child)
704 {
705         struct lpc_mmc_softc *sc = device_get_softc(bus);
706
707         lpc_mmc_lock(sc);
708         sc->lm_bus_busy--;
709         wakeup(sc);
710         lpc_mmc_unlock(sc);
711         return (0);
712 }
713
714 static void lpc_mmc_dma_rxfinish(void *arg)
715 {
716 }
717
718 static void lpc_mmc_dma_rxerror(void *arg)
719 {
720         struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg;
721         device_printf(sc->lm_dev, "DMA RX error\n");
722 }
723
724 static void lpc_mmc_dma_txfinish(void *arg)
725 {
726 }
727
728 static void lpc_mmc_dma_txerror(void *arg)
729 {
730         struct lpc_mmc_softc *sc = (struct lpc_mmc_softc *)arg;
731         device_printf(sc->lm_dev, "DMA TX error\n");
732 }
733
734 static void
735 lpc_mmc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
736 {
737         struct lpc_mmc_dmamap_arg *ctx;
738
739         if (err)
740                 return;
741
742         ctx = (struct lpc_mmc_dmamap_arg *)arg;
743         ctx->lm_dma_busaddr = segs[0].ds_addr;
744 }
745
746 static device_method_t lpc_mmc_methods[] = {
747         /* Device interface */
748         DEVMETHOD(device_probe,         lpc_mmc_probe),
749         DEVMETHOD(device_attach,        lpc_mmc_attach),
750         DEVMETHOD(device_detach,        lpc_mmc_detach),
751
752         /* Bus interface */
753         DEVMETHOD(bus_read_ivar,        lpc_mmc_read_ivar),
754         DEVMETHOD(bus_write_ivar,       lpc_mmc_write_ivar),
755         DEVMETHOD(bus_print_child,      bus_generic_print_child),
756
757         /* MMC bridge interface */
758         DEVMETHOD(mmcbr_update_ios,     lpc_mmc_update_ios),
759         DEVMETHOD(mmcbr_request,        lpc_mmc_request),
760         DEVMETHOD(mmcbr_get_ro,         lpc_mmc_get_ro),
761         DEVMETHOD(mmcbr_acquire_host,   lpc_mmc_acquire_host),
762         DEVMETHOD(mmcbr_release_host,   lpc_mmc_release_host),
763
764         { 0, 0 }
765 };
766
767 static devclass_t lpc_mmc_devclass;
768
769 static driver_t lpc_mmc_driver = {
770         "lpcmmc",
771         lpc_mmc_methods,
772         sizeof(struct lpc_mmc_softc),
773 };
774
775 DRIVER_MODULE(lpcmmc, simplebus, lpc_mmc_driver, lpc_mmc_devclass, 0, 0);
776 DRIVER_MODULE(mmc, lpcmmc, mmc_driver, mmc_devclass, NULL, NULL);
777 MODULE_DEPEND(lpcmmc, mmc, 1, 1, 1);