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