]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/powerpc/mpc85xx/fsl_sdhc.c
MFC: r292180 (partial), r297127 (partial), r311911, r311923, r312939,
[FreeBSD/stable/10.git] / sys / powerpc / mpc85xx / fsl_sdhc.c
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$");
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 */
78 static int      fsl_sdhc_probe(device_t);
79 static int      fsl_sdhc_attach(device_t);
80 static int      fsl_sdhc_detach(device_t);
81
82 static int      fsl_sdhc_read_ivar(device_t, device_t, int, uintptr_t *);
83 static int      fsl_sdhc_write_ivar(device_t, device_t, int, uintptr_t);
84
85 static int      fsl_sdhc_update_ios(device_t, device_t);
86 static int      fsl_sdhc_request(device_t, device_t, struct mmc_request *);
87 static int      fsl_sdhc_get_ro(device_t, device_t);
88 static int      fsl_sdhc_acquire_host(device_t, device_t);
89 static int      fsl_sdhc_release_host(device_t, device_t);
90
91 static 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 */
119 static driver_t fsl_sdhc_driver = {
120         "sdhci",
121         fsl_sdhc_methods,
122         sizeof(struct fsl_sdhc_softc)
123 };
124
125 static devclass_t fsl_sdhc_devclass;
126
127 DRIVER_MODULE(sdhci, simplebus, fsl_sdhc_driver, fsl_sdhc_devclass, 0, 0);
128 DRIVER_MODULE(mmc, sdhci_fsl, mmc_driver, mmc_devclass, NULL, NULL);
129 MODULE_DEPEND(sdhci_fsl, mmc, 1, 1, 1);
130
131 /*****************************************************************************
132  * Private methods
133  *****************************************************************************/
134 static inline int
135 read4(struct fsl_sdhc_softc *sc, unsigned int offset)
136 {
137
138         return bus_space_read_4(sc->bst, sc->bsh, offset);
139 }
140
141 static inline void
142 write4(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
148 static inline void
149 set_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
156 static inline void
157 clear_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
164 static int
165 wait_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
184 static int
185 wait_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
203 static uint32_t
204 get_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  */
244 static void
245 set_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
306 static inline void
307 send_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
324 static void
325 set_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
344 static void
345 reset_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
361 static void
362 reset_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
374 static void
375 init_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
400 static void
401 init_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
422 static void
423 card_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
473 static void
474 card_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
481 static void
482 finalize_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  */
496 static void
497 get_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  */
522 static void
523 read_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  */
554 static void
555 write_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
583 static void
584 pio_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
596 static void
597 pio_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
610 static inline void
611 handle_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
641 static inline void
642 handle_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
699 static void
700 interrupt_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
758 static void
759 dma_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
769 static int
770 init_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
802 fail2:
803         bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map);
804 fail1:
805         bus_dma_tag_destroy(sc->dma_tag);
806
807         return (-1);
808 }
809 #endif /* FSL_SDHC_NO_DMA */
810
811 static uint32_t
812 set_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
858 static uint32_t
859 set_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  */
878 static int
879 start_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
920 static int
921 start_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
981 static void
982 dump_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  */
1005 static int
1006 fsl_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
1020 static int
1021 fsl_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
1086 fail:
1087         fsl_sdhc_detach(self);
1088         return (ENXIO);
1089 }
1090
1091 static int
1092 fsl_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  */
1136 static int
1137 fsl_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
1183 static int
1184 fsl_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  */
1229 static int
1230 fsl_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
1252 static int
1253 fsl_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
1268 static int
1269 fsl_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
1277 static int
1278 fsl_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
1294 static int
1295 fsl_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 }