]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/powerpc/mpc85xx/fsl_sdhc.c
Use 64-bit addresses for configuring inbound and outbound address windows.
[FreeBSD/FreeBSD.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_fsl",
121         fsl_sdhc_methods,
122         sizeof(struct fsl_sdhc_softc)
123 };
124
125 static devclass_t fsl_sdhc_devclass;
126
127 DRIVER_MODULE(sdhci_fsl, 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 %p\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("HOSTCAPBLT = 0x%08x\n", read4(sc, SDHC_HOSTCAPBLT));
986         printf("IRQSTAT = 0x%08x\n", read4(sc, SDHC_IRQSTAT));
987         printf("IRQSTATEN = 0x%08x\n", read4(sc, SDHC_IRQSTATEN));
988         printf("IRQSIGEN = 0x%08x\n", read4(sc, SDHC_IRQSIGEN));
989         printf("WML = 0x%08x\n", read4(sc, SDHC_WML));
990         printf("DSADDR = 0x%08x\n", read4(sc, SDHC_DSADDR));
991         printf("XFERTYP = 0x%08x\n", read4(sc, SDHC_XFERTYP));
992         printf("DCR = 0x%08x\n", read4(sc, SDHC_DCR));
993 }
994 #endif
995
996 /*****************************************************************************
997  * Public methods
998  *****************************************************************************/
999 /*
1000  * Device interface methods.
1001  */
1002 static int
1003 fsl_sdhc_probe(device_t self)
1004 {
1005         static const char *desc =
1006             "Freescale Enhanced Secure Digital Host Controller";
1007
1008         if (!ofw_bus_is_compatible(self, "fsl,p2020-esdhc") &&
1009             !ofw_bus_is_compatible(self, "fsl,esdhc"))
1010                 return (ENXIO);
1011
1012         device_set_desc(self, desc);
1013
1014         return (BUS_PROBE_VENDOR);
1015 }
1016
1017 static int
1018 fsl_sdhc_attach(device_t self)
1019 {
1020         struct fsl_sdhc_softc *sc;
1021
1022         sc = device_get_softc(self);
1023
1024         sc->self = self;
1025
1026         mtx_init(&sc->mtx, device_get_nameunit(self), NULL, MTX_DEF);
1027
1028         /* Setup memory resource */
1029         sc->mem_rid = 0;
1030         sc->mem_resource = bus_alloc_resource_any(self, SYS_RES_MEMORY,
1031             &sc->mem_rid, RF_ACTIVE);
1032         if (sc->mem_resource == NULL) {
1033                 device_printf(self, "Could not allocate memory.\n");
1034                 goto fail;
1035         }
1036         sc->bst = rman_get_bustag(sc->mem_resource);
1037         sc->bsh = rman_get_bushandle(sc->mem_resource);
1038
1039         /* Setup interrupt resource. */
1040         sc->irq_rid = 0;
1041         sc->irq_resource = bus_alloc_resource_any(self, SYS_RES_IRQ,
1042             &sc->irq_rid, RF_ACTIVE);
1043         if (sc->irq_resource == NULL) {
1044                 device_printf(self, "Could not allocate interrupt.\n");
1045                 goto fail;
1046         }
1047         if (bus_setup_intr(self, sc->irq_resource, INTR_TYPE_MISC |
1048             INTR_MPSAFE, NULL, interrupt_handler, sc, &sc->ihl) != 0) {
1049                 device_printf(self, "Could not setup interrupt.\n");
1050                 goto fail;
1051         }
1052
1053         /* Setup DMA. */
1054 #ifndef FSL_SDHC_NO_DMA
1055         if (init_dma(sc) != 0) {
1056                 device_printf(self, "Could not setup DMA\n");
1057         }
1058 #endif
1059         sc->bus_busy = 0;
1060         sc->platform_clock = get_platform_clock(sc);
1061         if (sc->platform_clock == 0) {
1062                 device_printf(self, "Could not get platform clock.\n");
1063                 goto fail;
1064         }
1065         sc->command_done = 1;
1066         sc->data_done = 1;
1067
1068         /* Init card detection task. */
1069         TASK_INIT(&sc->card_detect_task, 0, card_detect_task, sc);
1070         callout_init(&sc->card_detect_callout, 1);
1071
1072         reset_controller_all(sc);
1073         init_controller(sc);
1074         set_clock(sc, 400000);
1075         send_80_clock_ticks(sc);
1076
1077 #ifdef DEBUG
1078         dump_registers(sc);
1079 #endif
1080
1081         return (0);
1082
1083 fail:
1084         fsl_sdhc_detach(self);
1085         return (ENXIO);
1086 }
1087
1088 static int
1089 fsl_sdhc_detach(device_t self)
1090 {
1091         struct fsl_sdhc_softc *sc = device_get_softc(self);
1092         int err;
1093
1094         if (sc->child)
1095                 device_delete_child(self, sc->child);
1096
1097         taskqueue_drain(taskqueue_swi_giant, &sc->card_detect_task);
1098
1099 #ifndef FSL_SDHC_NO_DMA
1100         bus_dmamap_unload(sc->dma_tag, sc->dma_map);
1101         bus_dmamem_free(sc->dma_tag, sc->dma_mem, sc->dma_map);
1102         bus_dma_tag_destroy(sc->dma_tag);
1103 #endif
1104
1105         if (sc->ihl != NULL) {
1106                 err = bus_teardown_intr(self, sc->irq_resource, sc->ihl);
1107                 if (err)
1108                         return (err);
1109         }
1110         if (sc->irq_resource != NULL) {
1111                 err = bus_release_resource(self, SYS_RES_IRQ, sc->irq_rid,
1112                     sc->irq_resource);
1113                 if (err)
1114                         return (err);
1115
1116         }
1117         if (sc->mem_resource != NULL) {
1118                 err = bus_release_resource(self, SYS_RES_MEMORY, sc->mem_rid,
1119                     sc->mem_resource);
1120                 if (err)
1121                         return (err);
1122         }
1123
1124         mtx_destroy(&sc->mtx);
1125
1126         return (0);
1127 }
1128
1129
1130 /*
1131  * Bus interface methods.
1132  */
1133 static int
1134 fsl_sdhc_read_ivar(device_t self, device_t child, int index,
1135     uintptr_t *result)
1136 {
1137         struct mmc_host *host = device_get_ivars(child);
1138
1139         switch (index) {
1140         case MMCBR_IVAR_BUS_MODE:
1141                 *(int *)result = host->ios.bus_mode;
1142                 break;
1143         case MMCBR_IVAR_BUS_WIDTH:
1144                 *(int *)result = host->ios.bus_width;
1145                 break;
1146         case MMCBR_IVAR_CHIP_SELECT:
1147                 *(int *)result = host->ios.chip_select;
1148                 break;
1149         case MMCBR_IVAR_CLOCK:
1150                 *(int *)result = host->ios.clock;
1151                 break;
1152         case MMCBR_IVAR_F_MIN:
1153                 *(int *)result = host->f_min;
1154                 break;
1155         case MMCBR_IVAR_F_MAX:
1156                 *(int *)result = host->f_max;
1157                 break;
1158         case MMCBR_IVAR_HOST_OCR:
1159                 *(int *)result = host->host_ocr;
1160                 break;
1161         case MMCBR_IVAR_MODE:
1162                 *(int *)result = host->mode;
1163                 break;
1164         case MMCBR_IVAR_OCR:
1165                 *(int *)result = host->ocr;
1166                 break;
1167         case MMCBR_IVAR_POWER_MODE:
1168                 *(int *)result = host->ios.power_mode;
1169                 break;
1170         case MMCBR_IVAR_VDD:
1171                 *(int *)result = host->ios.vdd;
1172                 break;
1173         default:
1174                 return (EINVAL);
1175         }
1176
1177         return (0);
1178 }
1179
1180 static int
1181 fsl_sdhc_write_ivar(device_t self, device_t child, int index,
1182     uintptr_t value)
1183 {
1184         struct mmc_host *host = device_get_ivars(child);
1185
1186         switch (index) {
1187         case MMCBR_IVAR_BUS_MODE:
1188                 host->ios.bus_mode = value;
1189                 break;
1190         case MMCBR_IVAR_BUS_WIDTH:
1191                 host->ios.bus_width = value;
1192                 break;
1193         case MMCBR_IVAR_CHIP_SELECT:
1194                 host->ios.chip_select = value;
1195                 break;
1196         case MMCBR_IVAR_CLOCK:
1197                 host->ios.clock = value;
1198                 break;
1199         case MMCBR_IVAR_MODE:
1200                 host->mode = value;
1201                 break;
1202         case MMCBR_IVAR_OCR:
1203                 host->ocr = value;
1204                 break;
1205         case MMCBR_IVAR_POWER_MODE:
1206                 host->ios.power_mode = value;
1207                 break;
1208         case MMCBR_IVAR_VDD:
1209                 host->ios.vdd = value;
1210                 break;
1211         case MMCBR_IVAR_HOST_OCR:
1212         case MMCBR_IVAR_F_MIN:
1213         case MMCBR_IVAR_F_MAX:
1214         default:
1215                 /* Instance variable not writable. */
1216                 return (EINVAL);
1217         }
1218
1219         return (0);
1220 }
1221
1222
1223 /*
1224  * MMC bridge methods.
1225  */
1226 static int
1227 fsl_sdhc_update_ios(device_t self, device_t reqdev)
1228 {
1229         struct fsl_sdhc_softc *sc = device_get_softc(self);
1230         struct mmc_host *host = device_get_ivars(reqdev);
1231         struct mmc_ios *ios = &host->ios;
1232
1233         mtx_lock(&sc->mtx);
1234
1235         /* Full reset on bus power down to clear from any state. */
1236         if (ios->power_mode == power_off) {
1237                 reset_controller_all(sc);
1238                 init_controller(sc);
1239         }
1240
1241         set_clock(sc, ios->clock);
1242         set_bus_width(sc, ios->bus_width);
1243
1244         mtx_unlock(&sc->mtx);
1245
1246         return (0);
1247 }
1248
1249 static int
1250 fsl_sdhc_request(device_t self, device_t reqdev, struct mmc_request *req)
1251 {
1252         struct fsl_sdhc_softc *sc = device_get_softc(self);
1253         int err;
1254
1255         mtx_lock(&sc->mtx);
1256
1257         sc->request = req;
1258         err = start_command(sc, req->cmd);
1259
1260         mtx_unlock(&sc->mtx);
1261
1262         return (err);
1263 }
1264
1265 static int
1266 fsl_sdhc_get_ro(device_t self, device_t reqdev)
1267 {
1268         struct fsl_sdhc_softc *sc = device_get_softc(self);
1269
1270         /* Wouldn't it be faster using branching (if {}) ?? */
1271         return (((read4(sc, SDHC_PRSSTAT) & PRSSTAT_WPSPL) >> 19) ^ 0x1);
1272 }
1273
1274 static int
1275 fsl_sdhc_acquire_host(device_t self, device_t reqdev)
1276 {
1277         struct fsl_sdhc_softc *sc = device_get_softc(self);
1278         int retval = 0;
1279
1280         mtx_lock(&sc->mtx);
1281
1282         while (sc->bus_busy)
1283                 retval = mtx_sleep(sc, &sc->mtx, PZERO, "sdhcah", 0);
1284         ++(sc->bus_busy);
1285
1286         mtx_unlock(&sc->mtx);
1287
1288         return (retval);
1289 }
1290
1291 static int
1292 fsl_sdhc_release_host(device_t self, device_t reqdev)
1293 {
1294         struct fsl_sdhc_softc *sc = device_get_softc(self);
1295
1296         mtx_lock(&sc->mtx);
1297         --(sc->bus_busy);
1298         mtx_unlock(&sc->mtx);
1299         wakeup(sc);
1300
1301         return (0);
1302 }