]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/powerpc/mpc85xx/fsl_sdhc.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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
129
130 /*****************************************************************************
131  * Private methods
132  *****************************************************************************/
133 static inline int
134 read4(struct fsl_sdhc_softc *sc, unsigned int offset)
135 {
136
137         return bus_space_read_4(sc->bst, sc->bsh, offset);
138 }
139
140 static inline void
141 write4(struct fsl_sdhc_softc *sc, unsigned int offset, int value)
142 {
143
144         bus_space_write_4(sc->bst, sc->bsh, offset, value);
145 }
146
147 static inline void
148 set_bit(struct fsl_sdhc_softc *sc, uint32_t offset, uint32_t mask)
149 {
150         uint32_t x = read4(sc, offset);
151
152         write4(sc, offset, x | mask);
153 }
154
155 static inline void
156 clear_bit(struct fsl_sdhc_softc *sc, uint32_t offset, uint32_t mask)
157 {
158         uint32_t x = read4(sc, offset);
159
160         write4(sc, offset, x & ~mask);
161 }
162
163 static int
164 wait_for_bit_clear(struct fsl_sdhc_softc *sc, enum sdhc_reg_off reg,
165     uint32_t bit)
166 {
167         uint32_t timeout = 10;
168         uint32_t stat;
169
170         stat = read4(sc, reg);
171         while (stat & bit) {
172                 if (timeout == 0) {
173                         return (-1);
174                 }
175                 --timeout;
176                 DELAY(1000);
177                 stat = read4(sc, reg);
178         }
179
180         return (0);
181 }
182
183 static int
184 wait_for_free_line(struct fsl_sdhc_softc *sc, enum sdhc_line line)
185 {
186         uint32_t timeout = 100;
187         uint32_t stat;
188
189         stat = read4(sc, SDHC_PRSSTAT);
190         while (stat & line) {
191                 if (timeout == 0) {
192                         return (-1);
193                 }
194                 --timeout;
195                 DELAY(1000);
196                 stat = read4(sc, SDHC_PRSSTAT);
197         }
198
199         return (0);
200 }
201
202 static uint32_t
203 get_platform_clock(struct fsl_sdhc_softc *sc)
204 {
205         device_t self, parent;
206         phandle_t node;
207         uint32_t clock;
208
209         self = sc->self;
210         node = ofw_bus_get_node(self);
211
212         /* Get sdhci node properties */
213         if((OF_getprop(node, "clock-frequency", (void *)&clock,
214             sizeof(clock)) <= 0) || (clock == 0)) {
215
216                 /*
217                  * Trying to get clock from parent device (soc) if correct
218                  * clock cannot be acquired from sdhci node.
219                  */
220                 parent = device_get_parent(self);
221                 node = ofw_bus_get_node(parent);
222
223                 /* Get soc properties */
224                 if ((OF_getprop(node, "bus-frequency", (void *)&clock,
225                     sizeof(clock)) <= 0) || (clock == 0)) {
226                         device_printf(self,"Cannot acquire correct sdhci "
227                             "frequency from DTS.\n");
228
229                         return (0);
230                 }
231         }
232
233         DPRINTF("Acquired clock: %d from DTS\n", clock);
234
235         return (clock);
236 }
237
238 /**
239  * Set clock driving card.
240  * @param sc
241  * @param clock Desired clock frequency in Hz
242  */
243 static void
244 set_clock(struct fsl_sdhc_softc *sc, uint32_t clock)
245 {
246         uint32_t base_clock;
247         uint32_t divisor, prescaler = 1;
248         uint32_t round = 0;
249
250         if (clock == sc->slot.clock)
251                 return;
252
253         if (clock == 0) {
254                 clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL | SYSCTL_PEREN |
255                     SYSCTL_HCKEN | SYSCTL_IPGEN);
256                 return;
257         }
258
259         base_clock = sc->platform_clock;
260         round = base_clock & 0x2;
261         base_clock >>= 2;
262         base_clock += round;
263         round = 0;
264
265         /* SD specification 1.1 doesn't allow frequences above 50 MHz */
266         if (clock > FSL_SDHC_MAX_CLOCK)
267                 clock = FSL_SDHC_MAX_CLOCK;
268
269         /*
270          * divisor = ceil(base_clock / clock)
271          * TODO: Reconsider symmetric rounding here instead of ceiling.
272          */
273         divisor = (base_clock + clock - 1) / clock;
274
275         while (divisor > 16) {
276                 round = divisor & 0x1;
277                 divisor >>= 1;
278
279                 prescaler <<= 1;
280         }
281         divisor += round - 1;
282
283         /* Turn off the clock. */
284         clear_bit(sc, SDHC_SYSCTL, MASK_CLOCK_CONTROL);
285
286         /* Write clock settings. */
287         set_bit(sc, SDHC_SYSCTL, (prescaler << SHIFT_SDCLKFS) |
288             (divisor << SHIFT_DVS));
289
290         /*
291          * Turn on clocks.
292          * TODO: This actually disables clock automatic gating off feature of
293          * the controller which eventually should be enabled but as for now
294          * it prevents controller from generating card insertion/removal
295          * interrupts correctly.
296          */
297         set_bit(sc, SDHC_SYSCTL, SYSCTL_PEREN | SYSCTL_HCKEN | SYSCTL_IPGEN);
298
299         sc->slot.clock = clock;
300
301         DPRINTF("given clock = %d, computed clock = %d\n", clock,
302             (base_clock / prescaler) / (divisor + 1));
303 }
304
305 static inline void
306 send_80_clock_ticks(struct fsl_sdhc_softc *sc)
307 {
308         int err;
309
310         err = wait_for_free_line(sc, SDHC_CMD_LINE | SDHC_DAT_LINE);
311         if (err != 0) {
312                 device_printf(sc->self, "Can't acquire data/cmd lines\n");
313                 return;
314         }
315
316         set_bit(sc, SDHC_SYSCTL, SYSCTL_INITA);
317         err = wait_for_bit_clear(sc, SDHC_SYSCTL, SYSCTL_INITA);
318         if (err != 0) {
319                 device_printf(sc->self, "Can't send 80 clocks to the card.\n");
320         }
321 }
322
323 static void
324 set_bus_width(struct fsl_sdhc_softc *sc, enum mmc_bus_width width)
325 {
326
327         DPRINTF("setting bus width to %d\n", width);
328         switch (width) {
329         case bus_width_1:
330                 set_bit(sc, SDHC_PROCTL, DTW_1);
331                 break;
332         case bus_width_4:
333                 set_bit(sc, SDHC_PROCTL, DTW_4);
334                 break;
335         case bus_width_8:
336                 set_bit(sc, SDHC_PROCTL, DTW_8);
337                 break;
338         default:
339                 device_printf(sc->self, "Unsupported bus width\n");
340         }
341 }
342
343 static void
344 reset_controller_all(struct fsl_sdhc_softc *sc)
345 {
346         uint32_t count = 5;
347
348         set_bit(sc, SDHC_SYSCTL, SYSCTL_RSTA);
349         while (read4(sc, SDHC_SYSCTL) & SYSCTL_RSTA) {
350                 DELAY(FSL_SDHC_RESET_DELAY);
351                 --count;
352                 if (count == 0) {
353                         device_printf(sc->self,
354                             "Can't reset the controller\n");
355                         return;
356                 }
357         }
358 }
359
360 static void
361 reset_controller_dat_cmd(struct fsl_sdhc_softc *sc)
362 {
363         int err;
364
365         set_bit(sc, SDHC_SYSCTL, SYSCTL_RSTD | SYSCTL_RSTC);
366         err = wait_for_bit_clear(sc, SDHC_SYSCTL, SYSCTL_RSTD | SYSCTL_RSTC);
367         if (err != 0) {
368                 device_printf(sc->self, "Can't reset data & command part!\n");
369                 return;
370         }
371 }
372
373 static void
374 init_controller(struct fsl_sdhc_softc *sc)
375 {
376
377         /* Enable interrupts. */
378 #ifdef FSL_SDHC_NO_DMA
379         write4(sc, SDHC_IRQSTATEN, MASK_IRQ_ALL & ~IRQ_DINT & ~IRQ_DMAE);
380         write4(sc, SDHC_IRQSIGEN, MASK_IRQ_ALL & ~IRQ_DINT & ~IRQ_DMAE);
381 #else
382         write4(sc, SDHC_IRQSTATEN, MASK_IRQ_ALL & ~IRQ_BRR & ~IRQ_BWR);
383         write4(sc, SDHC_IRQSIGEN, MASK_IRQ_ALL & ~IRQ_BRR & ~IRQ_BWR);
384
385         /* Write DMA address */
386         write4(sc, SDHC_DSADDR, sc->dma_phys);
387
388         /* Enable snooping and fix for AHB2MAG bypass. */
389         write4(sc, SDHC_DCR, DCR_SNOOP | DCR_AHB2MAG_BYPASS);
390 #endif
391         /* Set data timeout. */
392         set_bit(sc, SDHC_SYSCTL, 0xe << SHIFT_DTOCV);
393
394         /* Set water-mark levels (FIFO buffer size). */
395         write4(sc, SDHC_WML, (FSL_SDHC_FIFO_BUF_WORDS << 16) |
396             FSL_SDHC_FIFO_BUF_WORDS);
397 }
398
399 static void
400 init_mmc_host_struct(struct fsl_sdhc_softc *sc)
401 {
402         struct mmc_host *host = &sc->mmc_host;
403
404         /* Clear host structure. */
405         bzero(host, sizeof(struct mmc_host));
406
407         /* Calculate minimum and maximum operating frequencies. */
408         host->f_min = sc->platform_clock / FSL_SDHC_MAX_DIV;
409         host->f_max = FSL_SDHC_MAX_CLOCK;
410
411         /* Set operation conditions (voltage). */
412         host->host_ocr = MMC_OCR_320_330 | MMC_OCR_330_340;
413
414         /* Set additional host controller capabilities. */
415         host->caps = MMC_CAP_4_BIT_DATA;
416
417         /* Set mode. */
418         host->mode = mode_sd;
419 }
420
421 static void
422 card_detect_task(void *arg, int pending)
423 {
424         struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg;
425         int err;
426         int insert;
427
428         insert = read4(sc, SDHC_PRSSTAT) & PRSSTAT_CINS;
429
430         mtx_lock(&sc->mtx);
431
432         if (insert) {
433                 if (sc->child != NULL) {
434                         mtx_unlock(&sc->mtx);
435                         return;
436                 }
437
438                 sc->child = device_add_child(sc->self, "mmc", -1);
439                 if (sc->child == NULL) {
440                         device_printf(sc->self, "Couldn't add MMC bus!\n");
441                         mtx_unlock(&sc->mtx);
442                         return;
443                 }
444
445                 /* Initialize MMC bus host structure. */
446                 init_mmc_host_struct(sc);
447                 device_set_ivars(sc->child, &sc->mmc_host);
448
449         } else {
450                 if (sc->child == NULL) {
451                         mtx_unlock(&sc->mtx);
452                         return;
453                 }
454         }
455
456         mtx_unlock(&sc->mtx);
457
458         if (insert) {
459                 if ((err = device_probe_and_attach(sc->child)) != 0) {
460                         device_printf(sc->self, "MMC bus failed on probe "
461                             "and attach! error %d\n", err);
462                         device_delete_child(sc->self, sc->child);
463                         sc->child = NULL;
464                 }
465         } else {
466                 if (device_delete_child(sc->self, sc->child) != 0)
467                         device_printf(sc->self, "Could not delete MMC bus!\n");
468                 sc->child = NULL;
469         }
470 }
471
472 static void
473 card_detect_delay(void *arg)
474 {
475         struct fsl_sdhc_softc *sc = arg;
476
477         taskqueue_enqueue(taskqueue_swi_giant, &sc->card_detect_task);
478 }
479
480 static void
481 finalize_request(struct fsl_sdhc_softc *sc)
482 {
483
484         DPRINTF("finishing request %x\n", sc->request);
485
486         sc->request->done(sc->request);
487         sc->request = NULL;
488 }
489
490 /**
491  * Read response from card.
492  * @todo Implement Auto-CMD responses being held in R3 for multi-block xfers.
493  * @param sc
494  */
495 static void
496 get_response(struct fsl_sdhc_softc *sc)
497 {
498         struct mmc_command *cmd = sc->request->cmd;
499         int i;
500         uint32_t val;
501         uint8_t ext = 0;
502
503         if (cmd->flags & MMC_RSP_136) {
504                 /* CRC is stripped, need to shift one byte left. */
505                 for (i = 0; i < 4; i++) {
506                         val = read4(sc, SDHC_CMDRSP0 + i * 4);
507                         cmd->resp[3 - i] = (val << 8) + ext;
508                         ext = val >> 24;
509                 }
510         } else {
511                 cmd->resp[0] = read4(sc, SDHC_CMDRSP0);
512         }
513 }
514
515 #ifdef FSL_SDHC_NO_DMA
516 /**
517  * Read all content of a fifo buffer.
518  * @warning Assumes data buffer is 32-bit aligned.
519  * @param sc
520  */
521 static void
522 read_block_pio(struct fsl_sdhc_softc *sc)
523 {
524         struct mmc_data *data = sc->request->cmd->data;
525         size_t left = min(FSL_SDHC_FIFO_BUF_SIZE, data->len);
526         uint8_t *buf = data->data;
527         uint32_t word;
528
529         buf += sc->data_offset;
530         bus_space_read_multi_4(sc->bst, sc->bsh, SDHC_DATPORT, (uint32_t *)buf,
531             left >> 2);
532
533         sc->data_offset += left;
534
535         /* Handle 32-bit unaligned size case. */
536         left &= 0x3;
537         if (left > 0) {
538                 buf = (uint8_t *)data->data + (sc->data_offset & ~0x3);
539                 word = read4(sc, SDHC_DATPORT);
540                 while (left > 0) {
541                         *(buf++) = word;
542                         word >>= 8;
543                         --left;
544                 }
545         }
546 }
547
548 /**
549  * Write a fifo buffer.
550  * @warning Assumes data buffer size is 32-bit aligned.
551  * @param sc
552  */
553 static void
554 write_block_pio(struct fsl_sdhc_softc *sc)
555 {
556         struct mmc_data *data = sc->request->cmd->data;
557         size_t left = min(FSL_SDHC_FIFO_BUF_SIZE, data->len);
558         uint8_t *buf = data->data;
559         uint32_t word = 0;
560
561         DPRINTF("sc->data_offset %d\n", sc->data_offset);
562
563         buf += sc->data_offset;
564         bus_space_write_multi_4(sc->bst, sc->bsh, SDHC_DATPORT, (uint32_t *)buf,
565             left >> 2);
566
567         sc->data_offset += left;
568
569         /* Handle 32-bit unaligned size case. */
570         left &= 0x3;
571         if (left > 0) {
572                 buf = (uint8_t *)data->data + (sc->data_offset & ~0x3);
573                 while (left > 0) {
574                         word += *(buf++);
575                         word <<= 8;
576                         --left;
577                 }
578                 write4(sc, SDHC_DATPORT, word);
579         }
580 }
581
582 static void
583 pio_read_transfer(struct fsl_sdhc_softc *sc)
584 {
585
586         while (read4(sc, SDHC_PRSSTAT) & PRSSTAT_BREN) {
587                 read_block_pio(sc);
588
589                 /*
590                  * TODO: should we check here whether data_offset >= data->len?
591                  */
592         }
593 }
594
595 static void
596 pio_write_transfer(struct fsl_sdhc_softc *sc)
597 {
598
599         while (read4(sc, SDHC_PRSSTAT) & PRSSTAT_BWEN) {
600                 write_block_pio(sc);
601
602                 /*
603                  * TODO: should we check here whether data_offset >= data->len?
604                  */
605         }
606 }
607 #endif /* FSL_SDHC_USE_DMA */
608
609 static inline void
610 handle_command_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat)
611 {
612         struct mmc_command *cmd = sc->request->cmd;
613
614         /* Handle errors. */
615         if (irq_stat & IRQ_CTOE) {
616                 cmd->error = MMC_ERR_TIMEOUT;
617         } else if (irq_stat & IRQ_CCE) {
618                 cmd->error = MMC_ERR_BADCRC;
619         } else if (irq_stat & (IRQ_CEBE | IRQ_CIE)) {
620                 cmd->error = MMC_ERR_FIFO;
621         }
622
623         if (cmd->error) {
624                 device_printf(sc->self, "Error interrupt occured\n");
625                 reset_controller_dat_cmd(sc);
626                 return;
627         }
628
629         if (sc->command_done)
630                 return;
631
632         if (irq_stat & IRQ_CC) {
633                 sc->command_done = 1;
634
635                 if (cmd->flags & MMC_RSP_PRESENT)
636                         get_response(sc);
637         }
638 }
639
640 static inline void
641 handle_data_intr(struct fsl_sdhc_softc *sc, uint32_t irq_stat)
642 {
643         struct mmc_command *cmd = sc->request->cmd;
644
645         /* Handle errors. */
646         if (irq_stat & IRQ_DTOE) {
647                 cmd->error = MMC_ERR_TIMEOUT;
648         } else if (irq_stat & (IRQ_DCE | IRQ_DEBE)) {
649                 cmd->error = MMC_ERR_BADCRC;
650         } else if (irq_stat & IRQ_ERROR_DATA_MASK) {
651                 cmd->error = MMC_ERR_FAILED;
652         }
653
654         if (cmd->error) {
655                 device_printf(sc->self, "Error interrupt occured\n");
656                 sc->data_done = 1;
657                 reset_controller_dat_cmd(sc);
658                 return;
659         }
660
661         if (sc->data_done)
662                 return;
663
664 #ifdef FSL_SDHC_NO_DMA
665         if (irq_stat & IRQ_BRR) {
666                 pio_read_transfer(sc);
667         }
668
669         if (irq_stat & IRQ_BWR) {
670                 pio_write_transfer(sc);
671         }
672 #else
673         if (irq_stat & IRQ_DINT) {
674                 struct mmc_data *data = sc->request->cmd->data;
675
676                 /* Synchronize DMA. */
677                 if (data->flags & MMC_DATA_READ) {
678                         bus_dmamap_sync(sc->dma_tag, sc->dma_map,
679                             BUS_DMASYNC_POSTREAD);
680                         memcpy(data->data, sc->dma_mem, data->len);
681                 } else {
682                         bus_dmamap_sync(sc->dma_tag, sc->dma_map,
683                             BUS_DMASYNC_POSTWRITE);
684                 }
685
686                 /*
687                  * TODO: For multiple block transfers, address of dma memory
688                  * in DSADDR register should be set to the beginning of the
689                  * segment here. Also offset to data pointer should be handled.
690                  */
691         }
692 #endif
693
694         if (irq_stat & IRQ_TC)
695                 sc->data_done = 1;
696 }
697
698 static void
699 interrupt_handler(void *arg)
700 {
701         struct fsl_sdhc_softc *sc = (struct fsl_sdhc_softc *)arg;
702         uint32_t irq_stat;
703
704         mtx_lock(&sc->mtx);
705
706         irq_stat = read4(sc, SDHC_IRQSTAT);
707
708         /* Card interrupt. */
709         if (irq_stat & IRQ_CINT) {
710                 DPRINTF("Card interrupt recievied\n");
711
712         }
713
714         /* Card insertion interrupt. */
715         if (irq_stat & IRQ_CINS) {
716                 clear_bit(sc, SDHC_IRQSIGEN, IRQ_CINS);
717                 clear_bit(sc, SDHC_IRQSTATEN, IRQ_CINS);
718                 set_bit(sc, SDHC_IRQSIGEN, IRQ_CRM);
719                 set_bit(sc, SDHC_IRQSTATEN, IRQ_CRM);
720
721                 callout_reset(&sc->card_detect_callout, hz / 2,
722                     card_detect_delay, sc);
723         }
724
725         /* Card removal interrupt. */
726         if (irq_stat & IRQ_CRM) {
727                 clear_bit(sc, SDHC_IRQSIGEN, IRQ_CRM);
728                 clear_bit(sc, SDHC_IRQSTATEN, IRQ_CRM);
729                 set_bit(sc, SDHC_IRQSIGEN, IRQ_CINS);
730                 set_bit(sc, SDHC_IRQSTATEN, IRQ_CINS);
731
732                 callout_stop(&sc->card_detect_callout);
733                 taskqueue_enqueue(taskqueue_swi_giant, &sc->card_detect_task);
734         }
735
736         /* Handle request interrupts. */
737         if (sc->request) {
738                 handle_command_intr(sc, irq_stat);
739                 handle_data_intr(sc, irq_stat);
740
741                 /*
742                  * Finalize request when transfer is done successfully
743                  * or was interrupted due to error.
744                  */  
745                 if ((sc->data_done && sc->command_done) ||
746                     (sc->request->cmd->error))
747                         finalize_request(sc);
748         }
749
750         /* Clear status register. */
751         write4(sc, SDHC_IRQSTAT, irq_stat);
752
753         mtx_unlock(&sc->mtx);
754 }
755
756 #ifndef FSL_SDHC_NO_DMA
757 static void
758 dma_get_phys_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
759 {
760
761         if (error != 0)
762                 return;
763
764         /* Get first segment's physical address. */
765         *(bus_addr_t *)arg = segs->ds_addr;
766 }
767
768 static int
769 init_dma(struct fsl_sdhc_softc *sc)
770 {
771         device_t self = sc->self;
772         int err;
773
774         err = bus_dma_tag_create(bus_get_dma_tag(self),
775             FSL_SDHC_DMA_BLOCK_SIZE, 0, BUS_SPACE_MAXADDR_32BIT,
776             BUS_SPACE_MAXADDR, NULL, NULL, FSL_SDHC_DMA_BLOCK_SIZE, 1,
777             FSL_SDHC_DMA_BLOCK_SIZE, BUS_DMA_ALLOCNOW, NULL, NULL,
778             &sc->dma_tag);
779
780         if (err) {
781                 device_printf(self, "Could not create DMA tag!\n");
782                 return (-1);
783         }
784
785         err = bus_dmamem_alloc(sc->dma_tag, (void **)&(sc->dma_mem),
786             BUS_DMA_NOWAIT | BUS_DMA_NOCACHE, &sc->dma_map);
787         if (err) {
788                 device_printf(self, "Could not allocate DMA memory!\n");
789                 goto fail1;
790         }
791
792         err = bus_dmamap_load(sc->dma_tag, sc->dma_map, (void *)sc->dma_mem,
793             FSL_SDHC_DMA_BLOCK_SIZE, dma_get_phys_addr, &sc->dma_phys, 0);
794         if (err) {
795                 device_printf(self, "Could not load DMA map!\n");
796                 goto fail2;
797         }
798
799         return (0);
800
801 fail2:
802         bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map);
803 fail1:
804         bus_dma_tag_destroy(sc->dma_tag);
805
806         return (-1);
807 }
808 #endif /* FSL_SDHC_NO_DMA */
809
810 static uint32_t
811 set_xfertyp_register(const struct mmc_command *cmd)
812 {
813         uint32_t xfertyp = 0;
814
815         /* Set command index. */
816         xfertyp |= cmd->opcode << CMDINX_SHIFT;
817
818         /* Set command type. */
819         if (cmd->opcode == MMC_STOP_TRANSMISSION)
820                 xfertyp |= CMDTYP_ABORT;
821
822         /* Set data preset select. */
823         if (cmd->data) {
824                 xfertyp |= XFERTYP_DPSEL;
825
826                 /* Set transfer direction. */
827                 if (cmd->data->flags & MMC_DATA_READ)
828                         xfertyp |= XFERTYP_DTDSEL;
829         }
830
831         /* Set command index check. */
832         if (cmd->flags & MMC_RSP_OPCODE)
833                 xfertyp |= XFERTYP_CICEN;
834
835         /* Set command CRC check. */
836         if (cmd->flags & MMC_RSP_CRC)
837                 xfertyp |= XFERTYP_CCCEN;
838
839         /* Set response type */
840         if (!(cmd->flags & MMC_RSP_PRESENT))
841                 xfertyp |= RSPTYP_NONE;
842         else if (cmd->flags & MMC_RSP_136)
843                 xfertyp |= RSPTYP_136;
844         else if (cmd->flags & MMC_RSP_BUSY)
845                 xfertyp |= RSPTYP_48_BUSY;
846         else
847                 xfertyp |= RSPTYP_48;
848
849 #ifndef FSL_SDHC_NO_DMA
850         /* Enable DMA */
851         xfertyp |= XFERTYP_DMAEN;
852 #endif
853
854         return (xfertyp);
855 }
856
857 static uint32_t
858 set_blkattr_register(const struct mmc_data *data)
859 {
860
861         if (data->len <= FSL_SDHC_MAX_BLOCK_SIZE) {
862                 /* One block transfer. */
863                 return (BLKATTR_BLOCK_COUNT(1) | ((data->len) &
864                     BLKATTR_BLKSZE));
865         }
866
867         /* TODO: Write code here for multi-block transfers. */
868         return (0);
869 }
870
871 /**
872  * Initiate data transfer. Interrupt handler will finalize it.
873  * @todo Implement multi-block transfers.
874  * @param sc
875  * @param cmd
876  */
877 static int
878 start_data(struct fsl_sdhc_softc *sc, struct mmc_data *data)
879 {
880         uint32_t reg;
881
882         if ((uint32_t)data->data & 0x3) {
883                 device_printf(sc->self, "32-bit unaligned data pointer in "
884                     "request\n");
885                 return (-1);
886         }
887
888         sc->data_done = 0;
889
890 #ifdef FSL_SDHC_NO_DMA
891         sc->data_ptr = data->data;
892         sc->data_offset = 0;
893 #else
894         /* Write DMA address register. */
895         write4(sc, SDHC_DSADDR, sc->dma_phys);
896
897         /* Synchronize DMA. */
898         if (data->flags & MMC_DATA_READ) {
899                 bus_dmamap_sync(sc->dma_tag, sc->dma_map,
900                     BUS_DMASYNC_PREREAD);
901         } else {
902                 memcpy(sc->dma_mem, data->data, data->len);
903                 bus_dmamap_sync(sc->dma_tag, sc->dma_map,
904                     BUS_DMASYNC_PREWRITE);
905         }
906 #endif
907         /* Set block size and count. */
908         reg = set_blkattr_register(data);
909         if (reg == 0) {
910                 device_printf(sc->self, "Requested unsupported multi-block "
911                     "transfer.\n");
912                 return (-1);
913         }
914         write4(sc, SDHC_BLKATTR, reg);
915
916         return (0);
917 }
918
919 static int
920 start_command(struct fsl_sdhc_softc *sc, struct mmc_command *cmd)
921 {
922         struct mmc_request *req = sc->request;
923         uint32_t mask;
924         uint32_t xfertyp;
925         int err;
926
927         DPRINTF("opcode %d, flags 0x%08x\n", cmd->opcode, cmd->flags);
928         DPRINTF("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT));
929
930         sc->command_done = 0;
931
932         cmd->error = MMC_ERR_NONE;
933
934         /* TODO: should we check here for card presence and clock settings? */
935
936         /* Always wait for free CMD line. */
937         mask = SDHC_CMD_LINE;
938         /* Wait for free DAT if we have data or busy signal. */
939         if (cmd->data || (cmd->flags & MMC_RSP_BUSY))
940                 mask |= SDHC_DAT_LINE;
941         /* We shouldn't wait for DAT for stop commands. */
942         if (cmd == req->stop)
943                 mask &= ~SDHC_DAT_LINE;
944         err = wait_for_free_line(sc, mask);
945         if (err != 0) {
946                 device_printf(sc->self, "Controller never released inhibit "
947                     "bit(s).\n");
948                 reset_controller_dat_cmd(sc);
949                 cmd->error = MMC_ERR_FAILED;
950                 sc->request = NULL;
951                 req->done(req);
952                 return (-1);
953         }
954
955         xfertyp = set_xfertyp_register(cmd);
956
957         if (cmd->data != NULL) {
958                 err = start_data(sc, cmd->data);
959                 if (err != 0) {
960                         device_printf(sc->self,
961                             "Data transfer request failed\n");
962                         reset_controller_dat_cmd(sc);
963                         cmd->error = MMC_ERR_FAILED;
964                         sc->request = NULL;
965                         req->done(req);
966                         return (-1);
967                 }
968         }
969
970         write4(sc, SDHC_CMDARG, cmd->arg);
971         write4(sc, SDHC_XFERTYP, xfertyp);
972
973         DPRINTF("XFERTYP = 0x%08x\n", xfertyp);
974         DPRINTF("CMDARG = 0x%08x\n", cmd->arg);
975
976         return (0);
977 }
978
979 #ifdef DEBUG
980 static void
981 dump_registers(struct fsl_sdhc_softc *sc)
982 {
983         printf("PRSSTAT = 0x%08x\n", read4(sc, SDHC_PRSSTAT));
984         printf("PROCTL = 0x%08x\n", read4(sc, SDHC_PROCTL));
985         printf("PMUXCR = 0x%08x\n", ccsr_read4(OCP85XX_PMUXCR));
986         printf("HOSTCAPBLT = 0x%08x\n", read4(sc, SDHC_HOSTCAPBLT));
987         printf("IRQSTAT = 0x%08x\n", read4(sc, SDHC_IRQSTAT));
988         printf("IRQSTATEN = 0x%08x\n", read4(sc, SDHC_IRQSTATEN));
989         printf("IRQSIGEN = 0x%08x\n", read4(sc, SDHC_IRQSIGEN));
990         printf("WML = 0x%08x\n", read4(sc, SDHC_WML));
991         printf("DSADDR = 0x%08x\n", read4(sc, SDHC_DSADDR));
992         printf("XFERTYP = 0x%08x\n", read4(sc, SDHC_XFERTYP));
993         printf("ECMCR = 0x%08x\n", ccsr_read4(OCP85XX_ECMCR));
994         printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR));
995 }
996 #endif
997
998 /*****************************************************************************
999  * Public methods
1000  *****************************************************************************/
1001 /*
1002  * Device interface methods.
1003  */
1004 static int
1005 fsl_sdhc_probe(device_t self)
1006 {
1007         static const char *desc =
1008             "Freescale Enhanced Secure Digital Host Controller";
1009
1010         if (!ofw_bus_is_compatible(self, "fsl,p2020-esdhc") &&
1011             !ofw_bus_is_compatible(self, "fsl,esdhc"))
1012                 return (ENXIO);
1013
1014         device_set_desc(self, desc);
1015
1016         return (BUS_PROBE_VENDOR);
1017 }
1018
1019 static int
1020 fsl_sdhc_attach(device_t self)
1021 {
1022         struct fsl_sdhc_softc *sc;
1023
1024         sc = device_get_softc(self);
1025
1026         sc->self = self;
1027
1028         mtx_init(&sc->mtx, device_get_nameunit(self), NULL, MTX_DEF);
1029
1030         /* Setup memory resource */
1031         sc->mem_rid = 0;
1032         sc->mem_resource = bus_alloc_resource_any(self, SYS_RES_MEMORY,
1033             &sc->mem_rid, RF_ACTIVE);
1034         if (sc->mem_resource == NULL) {
1035                 device_printf(self, "Could not allocate memory.\n");
1036                 goto fail;
1037         }
1038         sc->bst = rman_get_bustag(sc->mem_resource);
1039         sc->bsh = rman_get_bushandle(sc->mem_resource);
1040
1041         /* Setup interrupt resource. */
1042         sc->irq_rid = 0;
1043         sc->irq_resource = bus_alloc_resource_any(self, SYS_RES_IRQ,
1044             &sc->irq_rid, RF_ACTIVE);
1045         if (sc->irq_resource == NULL) {
1046                 device_printf(self, "Could not allocate interrupt.\n");
1047                 goto fail;
1048         }
1049         if (bus_setup_intr(self, sc->irq_resource, INTR_TYPE_MISC |
1050             INTR_MPSAFE, NULL, interrupt_handler, sc, &sc->ihl) != 0) {
1051                 device_printf(self, "Could not setup interrupt.\n");
1052                 goto fail;
1053         }
1054
1055         /* Setup DMA. */
1056 #ifndef FSL_SDHC_NO_DMA
1057         if (init_dma(sc) != 0) {
1058                 device_printf(self, "Could not setup DMA\n");
1059         }
1060 #endif
1061         sc->bus_busy = 0;
1062         sc->platform_clock = get_platform_clock(sc);
1063         if (sc->platform_clock == 0) {
1064                 device_printf(self, "Could not get platform clock.\n");
1065                 goto fail;
1066         }
1067         sc->command_done = 1;
1068         sc->data_done = 1;
1069
1070         /* Init card detection task. */
1071         TASK_INIT(&sc->card_detect_task, 0, card_detect_task, sc);
1072         callout_init(&sc->card_detect_callout, 1);
1073
1074         reset_controller_all(sc);
1075         init_controller(sc);
1076         set_clock(sc, 400000);
1077         send_80_clock_ticks(sc);
1078
1079 #ifdef DEBUG
1080         dump_registers(sc);
1081 #endif
1082
1083         return (0);
1084
1085 fail:
1086         fsl_sdhc_detach(self);
1087         return (ENXIO);
1088 }
1089
1090 static int
1091 fsl_sdhc_detach(device_t self)
1092 {
1093         struct fsl_sdhc_softc *sc = device_get_softc(self);
1094         int err;
1095
1096         if (sc->child)
1097                 device_delete_child(self, sc->child);
1098
1099         taskqueue_drain(taskqueue_swi_giant, &sc->card_detect_task);
1100
1101 #ifndef FSL_SDHC_NO_DMA
1102         bus_dmamap_unload(sc->dma_tag, sc->dma_map);
1103         bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map);
1104         bus_dma_tag_destroy(sc->dma_tag);
1105 #endif
1106
1107         if (sc->ihl != NULL) {
1108                 err = bus_teardown_intr(self, sc->irq_resource, sc->ihl);
1109                 if (err)
1110                         return (err);
1111         }
1112         if (sc->irq_resource != NULL) {
1113                 err = bus_release_resource(self, SYS_RES_IRQ, sc->irq_rid,
1114                     sc->irq_resource);
1115                 if (err)
1116                         return (err);
1117
1118         }
1119         if (sc->mem_resource != NULL) {
1120                 err = bus_release_resource(self, SYS_RES_MEMORY, sc->mem_rid,
1121                     sc->mem_resource);
1122                 if (err)
1123                         return (err);
1124         }
1125
1126         mtx_destroy(&sc->mtx);
1127
1128         return (0);
1129 }
1130
1131
1132 /*
1133  * Bus interface methods.
1134  */
1135 static int
1136 fsl_sdhc_read_ivar(device_t self, device_t child, int index,
1137     uintptr_t *result)
1138 {
1139         struct mmc_host *host = device_get_ivars(child);
1140
1141         switch (index) {
1142         case MMCBR_IVAR_BUS_MODE:
1143                 *(int *)result = host->ios.bus_mode;
1144                 break;
1145         case MMCBR_IVAR_BUS_WIDTH:
1146                 *(int *)result = host->ios.bus_width;
1147                 break;
1148         case MMCBR_IVAR_CHIP_SELECT:
1149                 *(int *)result = host->ios.chip_select;
1150                 break;
1151         case MMCBR_IVAR_CLOCK:
1152                 *(int *)result = host->ios.clock;
1153                 break;
1154         case MMCBR_IVAR_F_MIN:
1155                 *(int *)result = host->f_min;
1156                 break;
1157         case MMCBR_IVAR_F_MAX:
1158                 *(int *)result = host->f_max;
1159                 break;
1160         case MMCBR_IVAR_HOST_OCR:
1161                 *(int *)result = host->host_ocr;
1162                 break;
1163         case MMCBR_IVAR_MODE:
1164                 *(int *)result = host->mode;
1165                 break;
1166         case MMCBR_IVAR_OCR:
1167                 *(int *)result = host->ocr;
1168                 break;
1169         case MMCBR_IVAR_POWER_MODE:
1170                 *(int *)result = host->ios.power_mode;
1171                 break;
1172         case MMCBR_IVAR_VDD:
1173                 *(int *)result = host->ios.vdd;
1174                 break;
1175         default:
1176                 return (EINVAL);
1177         }
1178
1179         return (0);
1180 }
1181
1182 static int
1183 fsl_sdhc_write_ivar(device_t self, device_t child, int index,
1184     uintptr_t value)
1185 {
1186         struct mmc_host *host = device_get_ivars(child);
1187
1188         switch (index) {
1189         case MMCBR_IVAR_BUS_MODE:
1190                 host->ios.bus_mode = value;
1191                 break;
1192         case MMCBR_IVAR_BUS_WIDTH:
1193                 host->ios.bus_width = value;
1194                 break;
1195         case MMCBR_IVAR_CHIP_SELECT:
1196                 host->ios.chip_select = value;
1197                 break;
1198         case MMCBR_IVAR_CLOCK:
1199                 host->ios.clock = value;
1200                 break;
1201         case MMCBR_IVAR_MODE:
1202                 host->mode = value;
1203                 break;
1204         case MMCBR_IVAR_OCR:
1205                 host->ocr = value;
1206                 break;
1207         case MMCBR_IVAR_POWER_MODE:
1208                 host->ios.power_mode = value;
1209                 break;
1210         case MMCBR_IVAR_VDD:
1211                 host->ios.vdd = value;
1212                 break;
1213         case MMCBR_IVAR_HOST_OCR:
1214         case MMCBR_IVAR_F_MIN:
1215         case MMCBR_IVAR_F_MAX:
1216         default:
1217                 /* Instance variable not writable. */
1218                 return (EINVAL);
1219         }
1220
1221         return (0);
1222 }
1223
1224
1225 /*
1226  * MMC bridge methods.
1227  */
1228 static int
1229 fsl_sdhc_update_ios(device_t self, device_t reqdev)
1230 {
1231         struct fsl_sdhc_softc *sc = device_get_softc(self);
1232         struct mmc_host *host = device_get_ivars(reqdev);
1233         struct mmc_ios *ios = &host->ios;
1234
1235         mtx_lock(&sc->mtx);
1236
1237         /* Full reset on bus power down to clear from any state. */
1238         if (ios->power_mode == power_off) {
1239                 reset_controller_all(sc);
1240                 init_controller(sc);
1241         }
1242
1243         set_clock(sc, ios->clock);
1244         set_bus_width(sc, ios->bus_width);
1245
1246         mtx_unlock(&sc->mtx);
1247
1248         return (0);
1249 }
1250
1251 static int
1252 fsl_sdhc_request(device_t self, device_t reqdev, struct mmc_request *req)
1253 {
1254         struct fsl_sdhc_softc *sc = device_get_softc(self);
1255         int err;
1256
1257         mtx_lock(&sc->mtx);
1258
1259         sc->request = req;
1260         err = start_command(sc, req->cmd);
1261
1262         mtx_unlock(&sc->mtx);
1263
1264         return (err);
1265 }
1266
1267 static int
1268 fsl_sdhc_get_ro(device_t self, device_t reqdev)
1269 {
1270         struct fsl_sdhc_softc *sc = device_get_softc(self);
1271
1272         /* Wouldn't it be faster using branching (if {}) ?? */
1273         return (((read4(sc, SDHC_PRSSTAT) & PRSSTAT_WPSPL) >> 19) ^ 0x1);
1274 }
1275
1276 static int
1277 fsl_sdhc_acquire_host(device_t self, device_t reqdev)
1278 {
1279         struct fsl_sdhc_softc *sc = device_get_softc(self);
1280         int retval = 0;
1281
1282         mtx_lock(&sc->mtx);
1283
1284         while (sc->bus_busy)
1285                 retval = mtx_sleep(sc, &sc->mtx, PZERO, "sdhcah", 0);
1286         ++(sc->bus_busy);
1287
1288         mtx_unlock(&sc->mtx);
1289
1290         return (retval);
1291 }
1292
1293 static int
1294 fsl_sdhc_release_host(device_t self, device_t reqdev)
1295 {
1296         struct fsl_sdhc_softc *sc = device_get_softc(self);
1297
1298         mtx_lock(&sc->mtx);
1299         --(sc->bus_busy);
1300         mtx_unlock(&sc->mtx);
1301         wakeup(sc);
1302
1303         return (0);
1304 }