]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/amlogic/aml8726/aml8726_mmc.c
Upgrade Unbound to 1.8.0. More to follow.
[FreeBSD/FreeBSD.git] / sys / arm / amlogic / aml8726 / aml8726_mmc.c
1 /*-
2  * Copyright 2013-2015 John Wehle <john@feith.com>
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  * Amlogic aml8726 MMC host controller driver.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/lock.h>
40 #include <sys/mutex.h>
41 #include <sys/resource.h>
42 #include <sys/rman.h>
43
44 #include <sys/gpio.h>
45
46 #include <machine/bus.h>
47 #include <machine/cpu.h>
48
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51
52 #include <dev/mmc/bridge.h>
53 #include <dev/mmc/mmcbrvar.h>
54
55 #include <arm/amlogic/aml8726/aml8726_mmc.h>
56
57 #include "gpio_if.h"
58 #include "mmcbr_if.h"
59
60 struct aml8726_mmc_gpio {
61         device_t        dev;
62         uint32_t        pin;
63         uint32_t        pol;
64 };
65
66 struct aml8726_mmc_softc {
67         device_t                dev;
68         struct resource         *res[2];
69         struct mtx              mtx;
70         struct callout          ch;
71         uint32_t                port;
72         unsigned int            ref_freq;
73         struct aml8726_mmc_gpio pwr_en;
74         int                     voltages[2];
75         struct aml8726_mmc_gpio vselect;
76         bus_dma_tag_t           dmatag;
77         bus_dmamap_t            dmamap;
78         void                    *ih_cookie;
79         struct mmc_host         host;
80         int                     bus_busy;
81         struct mmc_command      *cmd;
82         uint32_t                stop_timeout;
83 };
84
85 static struct resource_spec aml8726_mmc_spec[] = {
86         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
87         { SYS_RES_IRQ,          0,      RF_ACTIVE },
88         { -1, 0 }
89 };
90
91 #define AML_MMC_LOCK(sc)                mtx_lock(&(sc)->mtx)
92 #define AML_MMC_UNLOCK(sc)              mtx_unlock(&(sc)->mtx)
93 #define AML_MMC_LOCK_ASSERT(sc)         mtx_assert(&(sc)->mtx, MA_OWNED)
94 #define AML_MMC_LOCK_INIT(sc)           \
95     mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev),        \
96     "mmc", MTX_DEF)
97 #define AML_MMC_LOCK_DESTROY(sc)        mtx_destroy(&(sc)->mtx);
98
99 #define CSR_WRITE_4(sc, reg, val)       bus_write_4((sc)->res[0], reg, (val))
100 #define CSR_READ_4(sc, reg)             bus_read_4((sc)->res[0], reg)
101 #define CSR_BARRIER(sc, reg)            bus_barrier((sc)->res[0], reg, 4, \
102     (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE))
103
104 #define PWR_ON_FLAG(pol)                ((pol) == 0 ? GPIO_PIN_LOW :    \
105     GPIO_PIN_HIGH)
106 #define PWR_OFF_FLAG(pol)               ((pol) == 0 ? GPIO_PIN_HIGH :   \
107     GPIO_PIN_LOW)
108
109 #define MSECS_TO_TICKS(ms)              (((ms)*hz)/1000 + 1)
110
111 static void aml8726_mmc_timeout(void *arg);
112
113 static unsigned int
114 aml8726_mmc_clk(phandle_t node)
115 {
116         pcell_t prop;
117         ssize_t len;
118         phandle_t clk_node;
119
120         len = OF_getencprop(node, "clocks", &prop, sizeof(prop));
121         if ((len / sizeof(prop)) != 1 || prop == 0 ||
122             (clk_node = OF_node_from_xref(prop)) == 0)
123                 return (0);
124
125         len = OF_getencprop(clk_node, "clock-frequency", &prop, sizeof(prop));
126         if ((len / sizeof(prop)) != 1 || prop == 0)
127                 return (0);
128
129         return ((unsigned int)prop);
130 }
131
132 static uint32_t
133 aml8726_mmc_freq(struct aml8726_mmc_softc *sc, uint32_t divisor)
134 {
135
136         return (sc->ref_freq / ((divisor + 1) * 2));
137 }
138
139 static uint32_t
140 aml8726_mmc_div(struct aml8726_mmc_softc *sc, uint32_t desired_freq)
141 {
142         uint32_t divisor;
143
144         divisor = sc->ref_freq / (desired_freq * 2);
145
146         if (divisor == 0)
147                 divisor = 1;
148
149         divisor -= 1;
150
151         if (aml8726_mmc_freq(sc, divisor) > desired_freq)
152                 divisor += 1;
153
154         if (divisor > (AML_MMC_CONFIG_CMD_CLK_DIV_MASK >>
155             AML_MMC_CONFIG_CMD_CLK_DIV_SHIFT)) {
156                 divisor = AML_MMC_CONFIG_CMD_CLK_DIV_MASK >>
157                     AML_MMC_CONFIG_CMD_CLK_DIV_SHIFT;
158         }
159
160         return (divisor);
161 }
162
163 static void
164 aml8726_mmc_mapmem(void *arg, bus_dma_segment_t *segs, int nseg, int error)
165 {
166         bus_addr_t *busaddrp;
167
168         /*
169          * There should only be one bus space address since
170          * bus_dma_tag_create was called with nsegments = 1.
171          */
172
173         busaddrp = (bus_addr_t *)arg;
174         *busaddrp = segs->ds_addr;
175 }
176
177 static int
178 aml8726_mmc_power_off(struct aml8726_mmc_softc *sc)
179 {
180
181         if (sc->pwr_en.dev == NULL)
182                 return (0);
183
184         return (GPIO_PIN_SET(sc->pwr_en.dev, sc->pwr_en.pin,
185             PWR_OFF_FLAG(sc->pwr_en.pol)));
186 }
187
188 static int
189 aml8726_mmc_power_on(struct aml8726_mmc_softc *sc)
190 {
191
192         if (sc->pwr_en.dev == NULL)
193                 return (0);
194
195         return (GPIO_PIN_SET(sc->pwr_en.dev, sc->pwr_en.pin,
196             PWR_ON_FLAG(sc->pwr_en.pol)));
197 }
198
199 static void
200 aml8726_mmc_soft_reset(struct aml8726_mmc_softc *sc, boolean_t enable_irq)
201 {
202         uint32_t icr;
203
204         icr = AML_MMC_IRQ_CONFIG_SOFT_RESET;
205
206         if (enable_irq == true)
207                 icr |= AML_MMC_IRQ_CONFIG_CMD_DONE_EN;
208
209         CSR_WRITE_4(sc, AML_MMC_IRQ_CONFIG_REG, icr);
210         CSR_BARRIER(sc, AML_MMC_IRQ_CONFIG_REG);
211 }
212
213 static int
214 aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
215 {
216         struct mmc_ios *ios = &sc->host.ios;
217         bus_addr_t baddr;
218         uint32_t block_size;
219         uint32_t bus_width;
220         uint32_t cmdr;
221         uint32_t extr;
222         uint32_t mcfgr;
223         uint32_t nbits_per_pkg;
224         uint32_t timeout;
225         int error;
226         struct mmc_data *data;
227
228         if (cmd->opcode > 0x3f)
229                 return (MMC_ERR_INVALID);
230
231         /*
232          * Ensure the hardware state machine is in a known state.
233          */
234         aml8726_mmc_soft_reset(sc, true);
235
236         /*
237          * Start and transmission bits are per section 4.7.2 of the:
238          *
239          *   SD Specifications Part 1
240          *   Physical Layer Simplified Specification
241          *   Version 4.10
242          */
243         cmdr = AML_MMC_CMD_START_BIT | AML_MMC_CMD_TRANS_BIT_HOST | cmd->opcode;
244         baddr = 0;
245         extr = 0;
246         mcfgr = sc->port;
247         timeout = AML_MMC_CMD_TIMEOUT;
248
249         /*
250          * If this is a linked command, then use the previous timeout.
251          */
252         if (cmd == cmd->mrq->stop && sc->stop_timeout)
253                 timeout = sc->stop_timeout;
254         sc->stop_timeout = 0;
255
256         if ((cmd->flags & MMC_RSP_136) != 0) {
257                 cmdr |= AML_MMC_CMD_RESP_CRC7_FROM_8;
258                 cmdr |= (133 << AML_MMC_CMD_RESP_BITS_SHIFT);
259         } else if ((cmd->flags & MMC_RSP_PRESENT) != 0)
260                 cmdr |= (45 << AML_MMC_CMD_RESP_BITS_SHIFT);
261
262         if ((cmd->flags & MMC_RSP_CRC) == 0)
263                 cmdr |= AML_MMC_CMD_RESP_NO_CRC7;
264
265         if ((cmd->flags & MMC_RSP_BUSY) != 0)
266                 cmdr |= AML_MMC_CMD_CHECK_DAT0_BUSY;
267
268         data = cmd->data;
269
270         if (data && data->len &&
271             (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) {
272                 block_size = data->len;
273
274                 if ((data->flags & MMC_DATA_MULTI) != 0) {
275                         block_size = MMC_SECTOR_SIZE;
276                         if ((data->len % block_size) != 0)
277                                 return (MMC_ERR_INVALID);
278                 }
279
280                 cmdr |= (((data->len / block_size) - 1) <<
281                     AML_MMC_CMD_REP_PKG_CNT_SHIFT);
282
283                 mcfgr |= (data->flags & MMC_DATA_STREAM) ?
284                     AML_MMC_MULT_CONFIG_STREAM_EN : 0;
285
286                 /*
287                  * The number of bits per package equals the number
288                  * of data bits + the number of CRC bits.  There are
289                  * 16 bits of CRC calculate per bus line.
290                  *
291                  * A completed package appears to be detected by when
292                  * a counter decremented by the width underflows, thus
293                  * a value of zero always transfers 1 (or 4 bits depending
294                  * on the mode) which is why bus_width is subtracted.
295                  */
296                 bus_width = (ios->bus_width == bus_width_4) ? 4 : 1;
297                 nbits_per_pkg = block_size * 8 + 16 * bus_width - bus_width;
298                 if (nbits_per_pkg > 0x3fff)
299                         return (MMC_ERR_INVALID);
300
301                 extr |= (nbits_per_pkg << AML_MMC_EXTENSION_PKT_SIZE_SHIFT);
302
303                 error = bus_dmamap_load(sc->dmatag, sc->dmamap,
304                     data->data, data->len, aml8726_mmc_mapmem, &baddr,
305                     BUS_DMA_NOWAIT);
306                 if (error)
307                         return (MMC_ERR_NO_MEMORY);
308
309                 if ((data->flags & MMC_DATA_READ) != 0) {
310                         cmdr |= AML_MMC_CMD_RESP_HAS_DATA;
311                         bus_dmamap_sync(sc->dmatag, sc->dmamap,
312                             BUS_DMASYNC_PREREAD);
313                         timeout = AML_MMC_READ_TIMEOUT *
314                             (data->len / block_size);
315                 } else {
316                         cmdr |= AML_MMC_CMD_CMD_HAS_DATA;
317                         bus_dmamap_sync(sc->dmatag, sc->dmamap,
318                             BUS_DMASYNC_PREWRITE);
319                         timeout = AML_MMC_WRITE_TIMEOUT *
320                             (data->len / block_size);
321                 }
322
323                 /*
324                  * Stop terminates a multiblock read / write and thus
325                  * can take as long to execute as an actual read / write.
326                  */
327                 if (cmd->mrq->stop != NULL)
328                         sc->stop_timeout = timeout;
329         }
330
331         sc->cmd = cmd;
332
333         cmd->error = MMC_ERR_NONE;
334
335         if (timeout > AML_MMC_MAX_TIMEOUT)
336                 timeout = AML_MMC_MAX_TIMEOUT;
337
338         callout_reset(&sc->ch, MSECS_TO_TICKS(timeout),
339             aml8726_mmc_timeout, sc);
340
341         CSR_WRITE_4(sc, AML_MMC_CMD_ARGUMENT_REG, cmd->arg);
342         CSR_WRITE_4(sc, AML_MMC_MULT_CONFIG_REG, mcfgr);
343         CSR_WRITE_4(sc, AML_MMC_EXTENSION_REG, extr);
344         CSR_WRITE_4(sc, AML_MMC_DMA_ADDR_REG, (uint32_t)baddr);
345
346         CSR_WRITE_4(sc, AML_MMC_CMD_SEND_REG, cmdr);
347         CSR_BARRIER(sc, AML_MMC_CMD_SEND_REG);
348
349         return (MMC_ERR_NONE);
350 }
351
352 static void
353 aml8726_mmc_finish_command(struct aml8726_mmc_softc *sc, int mmc_error)
354 {
355         int mmc_stop_error;
356         struct mmc_command *cmd;
357         struct mmc_command *stop_cmd;
358         struct mmc_data *data;
359
360         AML_MMC_LOCK_ASSERT(sc);
361
362         /* Clear all interrupts since the request is no longer in flight. */
363         CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
364         CSR_BARRIER(sc, AML_MMC_IRQ_STATUS_REG);
365
366         /* In some cases (e.g. finish called via timeout) this is a NOP. */
367         callout_stop(&sc->ch);
368
369         cmd = sc->cmd;
370         sc->cmd = NULL;
371
372         cmd->error = mmc_error;
373
374         data = cmd->data;
375
376         if (data && data->len &&
377             (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) != 0) {
378                 if ((data->flags & MMC_DATA_READ) != 0)
379                         bus_dmamap_sync(sc->dmatag, sc->dmamap,
380                             BUS_DMASYNC_POSTREAD);
381                 else
382                         bus_dmamap_sync(sc->dmatag, sc->dmamap,
383                             BUS_DMASYNC_POSTWRITE);
384                 bus_dmamap_unload(sc->dmatag, sc->dmamap);
385         }
386
387         /*
388          * If there's a linked stop command, then start the stop command.
389          * In order to establish a known state attempt the stop command
390          * even if the original request encountered an error.
391          */
392
393         stop_cmd = (cmd->mrq->stop != cmd) ? cmd->mrq->stop : NULL;
394
395         if (stop_cmd != NULL) {
396                 mmc_stop_error = aml8726_mmc_start_command(sc, stop_cmd);
397                 if (mmc_stop_error == MMC_ERR_NONE) {
398                         AML_MMC_UNLOCK(sc);
399                         return;
400                 }
401                 stop_cmd->error = mmc_stop_error;
402         }
403
404         AML_MMC_UNLOCK(sc);
405
406         /* Execute the callback after dropping the lock. */
407         if (cmd->mrq)
408                 cmd->mrq->done(cmd->mrq);
409 }
410
411 static void
412 aml8726_mmc_timeout(void *arg)
413 {
414         struct aml8726_mmc_softc *sc = (struct aml8726_mmc_softc *)arg;
415
416         /*
417          * The command failed to complete in time so forcefully
418          * terminate it.
419          */
420         aml8726_mmc_soft_reset(sc, false);
421
422         /*
423          * Ensure the command has terminated before continuing on
424          * to things such as bus_dmamap_sync / bus_dmamap_unload.
425          */
426         while ((CSR_READ_4(sc, AML_MMC_IRQ_STATUS_REG) &
427             AML_MMC_IRQ_STATUS_CMD_BUSY) != 0)
428                 cpu_spinwait();
429
430         aml8726_mmc_finish_command(sc, MMC_ERR_TIMEOUT);
431 }
432
433 static void
434 aml8726_mmc_intr(void *arg)
435 {
436         struct aml8726_mmc_softc *sc = (struct aml8726_mmc_softc *)arg;
437         uint32_t cmdr;
438         uint32_t isr;
439         uint32_t mcfgr;
440         uint32_t previous_byte;
441         uint32_t resp;
442         int mmc_error;
443         unsigned int i;
444
445         AML_MMC_LOCK(sc);
446
447         isr = CSR_READ_4(sc, AML_MMC_IRQ_STATUS_REG);
448         cmdr = CSR_READ_4(sc, AML_MMC_CMD_SEND_REG);
449
450         if (sc->cmd == NULL)
451                 goto spurious;
452
453         mmc_error = MMC_ERR_NONE;
454
455         if ((isr & AML_MMC_IRQ_STATUS_CMD_DONE_IRQ) != 0) {
456                 /* Check for CRC errors if the command has completed. */
457                 if ((cmdr & AML_MMC_CMD_RESP_NO_CRC7) == 0 &&
458                     (isr & AML_MMC_IRQ_STATUS_RESP_CRC7_OK) == 0)
459                         mmc_error = MMC_ERR_BADCRC;
460                 if ((cmdr & AML_MMC_CMD_RESP_HAS_DATA) != 0 &&
461                     (isr & AML_MMC_IRQ_STATUS_RD_CRC16_OK) == 0)
462                         mmc_error = MMC_ERR_BADCRC;
463                 if ((cmdr & AML_MMC_CMD_CMD_HAS_DATA) != 0 &&
464                     (isr & AML_MMC_IRQ_STATUS_WR_CRC16_OK) == 0)
465                         mmc_error = MMC_ERR_BADCRC;
466         } else {
467 spurious:
468
469                 /*
470                  * Clear spurious interrupts while leaving intacted any
471                  * interrupts that may have occurred after we read the
472                  * interrupt status register.
473                  */
474
475                 CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG,
476                     (AML_MMC_IRQ_STATUS_CLEAR_IRQ & isr));
477                 CSR_BARRIER(sc, AML_MMC_IRQ_STATUS_REG);
478                 AML_MMC_UNLOCK(sc);
479                 return;
480         }
481
482         if ((cmdr & AML_MMC_CMD_RESP_BITS_MASK) != 0) {
483                 mcfgr = sc->port;
484                 mcfgr |= AML_MMC_MULT_CONFIG_RESP_READOUT_EN;
485                 CSR_WRITE_4(sc, AML_MMC_MULT_CONFIG_REG, mcfgr);
486
487                 if ((cmdr & AML_MMC_CMD_RESP_CRC7_FROM_8) != 0) {
488
489                         /*
490                          * Controller supplies 135:8 instead of
491                          * 127:0 so discard the leading 8 bits
492                          * and provide a trailing 8 zero bits
493                          * where the CRC belongs.
494                          */
495
496                         previous_byte = 0;
497
498                         for (i = 0; i < 4; i++) {
499                                 resp = CSR_READ_4(sc, AML_MMC_CMD_ARGUMENT_REG);
500                                 sc->cmd->resp[3 - i] = (resp << 8) |
501                                     previous_byte;
502                                 previous_byte = (resp >> 24) & 0xff;
503                         }
504                 } else
505                         sc->cmd->resp[0] = CSR_READ_4(sc,
506                             AML_MMC_CMD_ARGUMENT_REG);
507         }
508
509         if ((isr & AML_MMC_IRQ_STATUS_CMD_BUSY) != 0 &&
510             /*
511              * A multiblock operation may keep the hardware
512              * busy until stop transmission is executed.
513              */
514             (isr & AML_MMC_IRQ_STATUS_CMD_DONE_IRQ) == 0) {
515                 if (mmc_error == MMC_ERR_NONE)
516                         mmc_error = MMC_ERR_FAILED;
517
518                 /*
519                  * Issue a soft reset to terminate the command.
520                  *
521                  * Ensure the command has terminated before continuing on
522                  * to things such as bus_dmamap_sync / bus_dmamap_unload.
523                  */
524
525                 aml8726_mmc_soft_reset(sc, false);
526
527                 while ((CSR_READ_4(sc, AML_MMC_IRQ_STATUS_REG) &
528                     AML_MMC_IRQ_STATUS_CMD_BUSY) != 0)
529                         cpu_spinwait();
530         }
531
532         aml8726_mmc_finish_command(sc, mmc_error);
533 }
534
535 static int
536 aml8726_mmc_probe(device_t dev)
537 {
538
539         if (!ofw_bus_status_okay(dev))
540                 return (ENXIO);
541
542         if (!ofw_bus_is_compatible(dev, "amlogic,aml8726-mmc"))
543                 return (ENXIO);
544
545         device_set_desc(dev, "Amlogic aml8726 MMC");
546
547         return (BUS_PROBE_DEFAULT);
548 }
549
550 static int
551 aml8726_mmc_attach(device_t dev)
552 {
553         struct aml8726_mmc_softc *sc = device_get_softc(dev);
554         char *function_name;
555         char *voltages;
556         char *voltage;
557         int error;
558         int nvoltages;
559         pcell_t prop[3];
560         phandle_t node;
561         ssize_t len;
562         device_t child;
563
564         sc->dev = dev;
565
566         node = ofw_bus_get_node(dev);
567
568         sc->ref_freq = aml8726_mmc_clk(node);
569
570         if (sc->ref_freq == 0) {
571                 device_printf(dev, "missing clocks attribute in FDT\n");
572                 return (ENXIO);
573         }
574
575         /*
576          * The pins must be specified as part of the device in order
577          * to know which port to used.
578          */
579
580         len = OF_getencprop(node, "pinctrl-0", prop, sizeof(prop));
581
582         if ((len / sizeof(prop[0])) != 1 || prop[0] == 0) {
583                 device_printf(dev, "missing pinctrl-0 attribute in FDT\n");
584                 return (ENXIO);
585         }
586
587         len = OF_getprop_alloc(OF_node_from_xref(prop[0]), "amlogic,function",
588             (void **)&function_name);
589
590         if (len < 0) {
591                 device_printf(dev,
592                     "missing amlogic,function attribute in FDT\n");
593                 return (ENXIO);
594         }
595
596         if (strncmp("sdio-a", function_name, len) == 0)
597                 sc->port = AML_MMC_MULT_CONFIG_PORT_A;
598         else if (strncmp("sdio-b", function_name, len) == 0)
599                 sc->port = AML_MMC_MULT_CONFIG_PORT_B;
600         else if (strncmp("sdio-c", function_name, len) == 0)
601                 sc->port = AML_MMC_MULT_CONFIG_PORT_C;
602         else {
603                 device_printf(dev, "unknown function attribute %.*s in FDT\n",
604                     len, function_name);
605                 OF_prop_free(function_name);
606                 return (ENXIO);
607         }
608
609         OF_prop_free(function_name);
610
611         sc->pwr_en.dev = NULL;
612
613         len = OF_getencprop(node, "mmc-pwr-en", prop, sizeof(prop));
614         if (len > 0) {
615                 if ((len / sizeof(prop[0])) == 3) {
616                         sc->pwr_en.dev = OF_device_from_xref(prop[0]);
617                         sc->pwr_en.pin = prop[1];
618                         sc->pwr_en.pol = prop[2];
619                 }
620
621                 if (sc->pwr_en.dev == NULL) {
622                         device_printf(dev,
623                             "unable to process mmc-pwr-en attribute in FDT\n");
624                         return (ENXIO);
625                 }
626
627                 /* Turn off power and then configure the output driver. */
628                 if (aml8726_mmc_power_off(sc) != 0 ||
629                     GPIO_PIN_SETFLAGS(sc->pwr_en.dev, sc->pwr_en.pin,
630                     GPIO_PIN_OUTPUT) != 0) {
631                         device_printf(dev,
632                             "could not use gpio to control power\n");
633                         return (ENXIO);
634                 }
635         }
636
637         len = OF_getprop_alloc(node, "mmc-voltages",
638             (void **)&voltages);
639
640         if (len < 0) {
641                 device_printf(dev, "missing mmc-voltages attribute in FDT\n");
642                 return (ENXIO);
643         }
644
645         sc->voltages[0] = 0;
646         sc->voltages[1] = 0;
647
648         voltage = voltages;
649         nvoltages = 0;
650
651         while (len && nvoltages < 2) {
652                 if (strncmp("1.8", voltage, len) == 0)
653                         sc->voltages[nvoltages] = MMC_OCR_LOW_VOLTAGE;
654                 else if (strncmp("3.3", voltage, len) == 0)
655                         sc->voltages[nvoltages] = MMC_OCR_320_330 |
656                             MMC_OCR_330_340;
657                 else {
658                         device_printf(dev,
659                             "unknown voltage attribute %.*s in FDT\n",
660                             len, voltage);
661                         OF_prop_free(voltages);
662                         return (ENXIO);
663                 }
664
665                 nvoltages++;
666
667                 /* queue up next string */
668                 while (*voltage && len) {
669                         voltage++;
670                         len--;
671                 }
672                 if (len) {
673                         voltage++;
674                         len--;
675                 }
676         }
677
678         OF_prop_free(voltages);
679
680         sc->vselect.dev = NULL;
681
682         len = OF_getencprop(node, "mmc-vselect", prop, sizeof(prop));
683         if (len > 0) {
684                 if ((len / sizeof(prop[0])) == 2) {
685                         sc->vselect.dev = OF_device_from_xref(prop[0]);
686                         sc->vselect.pin = prop[1];
687                         sc->vselect.pol = 1;
688                 }
689
690                 if (sc->vselect.dev == NULL) {
691                         device_printf(dev,
692                           "unable to process mmc-vselect attribute in FDT\n");
693                         return (ENXIO);
694                 }
695
696                 /*
697                  * With the power off select voltage 0 and then
698                  * configure the output driver.
699                  */
700                 if (GPIO_PIN_SET(sc->vselect.dev, sc->vselect.pin, 0) != 0 ||
701                     GPIO_PIN_SETFLAGS(sc->vselect.dev, sc->vselect.pin,
702                     GPIO_PIN_OUTPUT) != 0) {
703                         device_printf(dev,
704                             "could not use gpio to set voltage\n");
705                         return (ENXIO);
706                 }
707         }
708
709         if (nvoltages == 0) {
710                 device_printf(dev, "no voltages in FDT\n");
711                 return (ENXIO);
712         } else if (nvoltages == 1 && sc->vselect.dev != NULL) {
713                 device_printf(dev, "only one voltage in FDT\n");
714                 return (ENXIO);
715         } else if (nvoltages == 2 && sc->vselect.dev == NULL) {
716                 device_printf(dev, "too many voltages in FDT\n");
717                 return (ENXIO);
718         }
719
720         if (bus_alloc_resources(dev, aml8726_mmc_spec, sc->res)) {
721                 device_printf(dev, "could not allocate resources for device\n");
722                 return (ENXIO);
723         }
724
725         AML_MMC_LOCK_INIT(sc);
726
727         error = bus_dma_tag_create(bus_get_dma_tag(dev), AML_MMC_ALIGN_DMA, 0,
728             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
729             AML_MMC_MAX_DMA, 1, AML_MMC_MAX_DMA, 0, NULL, NULL, &sc->dmatag);
730         if (error)
731                 goto fail;
732
733         error = bus_dmamap_create(sc->dmatag, 0, &sc->dmamap);
734
735         if (error)
736                 goto fail;
737
738         error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
739             NULL, aml8726_mmc_intr, sc, &sc->ih_cookie);
740         if (error) {
741                 device_printf(dev, "could not setup interrupt handler\n");
742                 goto fail;
743         }
744
745         callout_init_mtx(&sc->ch, &sc->mtx, CALLOUT_RETURNUNLOCKED);
746
747         sc->host.f_min = aml8726_mmc_freq(sc, aml8726_mmc_div(sc, 200000));
748         sc->host.f_max = aml8726_mmc_freq(sc, aml8726_mmc_div(sc, 50000000));
749         sc->host.host_ocr = sc->voltages[0] | sc->voltages[1];
750         sc->host.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_HSPEED;
751
752         child = device_add_child(dev, "mmc", -1);
753
754         if (!child) {
755                 device_printf(dev, "could not add mmc\n");
756                 error = ENXIO;
757                 goto fail;
758         }
759
760         error = device_probe_and_attach(child);
761
762         if (error) {
763                 device_printf(dev, "could not attach mmc\n");
764                 goto fail;
765         }
766
767         return (0);
768
769 fail:
770         if (sc->ih_cookie)
771                 bus_teardown_intr(dev, sc->res[1], sc->ih_cookie);
772
773         if (sc->dmamap)
774                 bus_dmamap_destroy(sc->dmatag, sc->dmamap);
775
776         if (sc->dmatag)
777                 bus_dma_tag_destroy(sc->dmatag);
778
779         AML_MMC_LOCK_DESTROY(sc);
780
781         aml8726_mmc_power_off(sc);
782
783         bus_release_resources(dev, aml8726_mmc_spec, sc->res);
784
785         return (error);
786 }
787
788 static int
789 aml8726_mmc_detach(device_t dev)
790 {
791         struct aml8726_mmc_softc *sc = device_get_softc(dev);
792
793         AML_MMC_LOCK(sc);
794
795         if (sc->cmd != NULL) {
796                 AML_MMC_UNLOCK(sc);
797                 return (EBUSY);
798         }
799
800         /*
801          * Turn off the power, reset the hardware state machine,
802          * disable the interrupts, and clear the interrupts.
803          */
804         (void)aml8726_mmc_power_off(sc);
805         aml8726_mmc_soft_reset(sc, false);
806         CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
807
808         /* This should be a NOP since no command was in flight. */
809         callout_stop(&sc->ch);
810
811         AML_MMC_UNLOCK(sc);
812
813         bus_generic_detach(dev);
814
815         bus_teardown_intr(dev, sc->res[1], sc->ih_cookie);
816
817         bus_dmamap_destroy(sc->dmatag, sc->dmamap);
818
819         bus_dma_tag_destroy(sc->dmatag);
820
821         AML_MMC_LOCK_DESTROY(sc);
822
823         bus_release_resources(dev, aml8726_mmc_spec, sc->res);
824
825         return (0);
826 }
827
828 static int
829 aml8726_mmc_shutdown(device_t dev)
830 {
831         struct aml8726_mmc_softc *sc = device_get_softc(dev);
832
833         /*
834          * Turn off the power, reset the hardware state machine,
835          * disable the interrupts, and clear the interrupts.
836          */
837         (void)aml8726_mmc_power_off(sc);
838         aml8726_mmc_soft_reset(sc, false);
839         CSR_WRITE_4(sc, AML_MMC_IRQ_STATUS_REG, AML_MMC_IRQ_STATUS_CLEAR_IRQ);
840
841         return (0);
842 }
843
844 static int
845 aml8726_mmc_update_ios(device_t bus, device_t child)
846 {
847         struct aml8726_mmc_softc *sc = device_get_softc(bus);
848         struct mmc_ios *ios = &sc->host.ios;
849         int error;
850         int i;
851         uint32_t cfgr;
852
853         cfgr = (2 << AML_MMC_CONFIG_WR_CRC_STAT_SHIFT) |
854             (2 << AML_MMC_CONFIG_WR_DELAY_SHIFT) |
855             AML_MMC_CONFIG_DMA_ENDIAN_SBW |
856             (39 << AML_MMC_CONFIG_CMD_ARG_BITS_SHIFT);
857
858         switch (ios->bus_width) {
859         case bus_width_4:
860                 cfgr |= AML_MMC_CONFIG_BUS_WIDTH_4;
861                 break;
862         case bus_width_1:
863                 cfgr |= AML_MMC_CONFIG_BUS_WIDTH_1;
864                 break;
865         default:
866                 return (EINVAL);
867         }
868
869         cfgr |= aml8726_mmc_div(sc, ios->clock) <<
870             AML_MMC_CONFIG_CMD_CLK_DIV_SHIFT;
871
872         CSR_WRITE_4(sc, AML_MMC_CONFIG_REG, cfgr);
873
874         error = 0;
875
876         switch (ios->power_mode) {
877         case power_up:
878                 /*
879                  * Configure and power on the regulator so that the
880                  * voltage stabilizes prior to powering on the card.
881                  */
882                 if (sc->vselect.dev != NULL) {
883                         for (i = 0; i < 2; i++)
884                                 if ((sc->voltages[i] & (1 << ios->vdd)) != 0)
885                                         break;
886                         if (i >= 2)
887                                 return (EINVAL);
888                         error = GPIO_PIN_SET(sc->vselect.dev,
889                             sc->vselect.pin, i);
890                 }
891                 break;
892         case power_on:
893                 error = aml8726_mmc_power_on(sc);
894                 break;
895         case power_off:
896                 error = aml8726_mmc_power_off(sc);
897                 break;
898         default:
899                 return (EINVAL);
900         }
901
902         return (error);
903 }
904
905 static int
906 aml8726_mmc_request(device_t bus, device_t child, struct mmc_request *req)
907 {
908         struct aml8726_mmc_softc *sc = device_get_softc(bus);
909         int mmc_error;
910
911         AML_MMC_LOCK(sc);
912
913         if (sc->cmd != NULL) {
914                 AML_MMC_UNLOCK(sc);
915                 return (EBUSY);
916         }
917
918         mmc_error = aml8726_mmc_start_command(sc, req->cmd);
919
920         AML_MMC_UNLOCK(sc);
921
922         /* Execute the callback after dropping the lock. */
923         if (mmc_error != MMC_ERR_NONE) {
924                 req->cmd->error = mmc_error;
925                 req->done(req);
926         }
927
928         return (0);
929 }
930
931 static int
932 aml8726_mmc_read_ivar(device_t bus, device_t child,
933     int which, uintptr_t *result)
934 {
935         struct aml8726_mmc_softc *sc = device_get_softc(bus);
936
937         switch (which) {
938         case MMCBR_IVAR_BUS_MODE:
939                 *(int *)result = sc->host.ios.bus_mode;
940                 break;
941         case MMCBR_IVAR_BUS_WIDTH:
942                 *(int *)result = sc->host.ios.bus_width;
943                 break;
944         case MMCBR_IVAR_CHIP_SELECT:
945                 *(int *)result = sc->host.ios.chip_select;
946                 break;
947         case MMCBR_IVAR_CLOCK:
948                 *(int *)result = sc->host.ios.clock;
949                 break;
950         case MMCBR_IVAR_F_MIN:
951                 *(int *)result = sc->host.f_min;
952                 break;
953         case MMCBR_IVAR_F_MAX:
954                 *(int *)result = sc->host.f_max;
955                 break;
956         case MMCBR_IVAR_HOST_OCR:
957                 *(int *)result = sc->host.host_ocr;
958                 break;
959         case MMCBR_IVAR_MODE:
960                 *(int *)result = sc->host.mode;
961                 break;
962         case MMCBR_IVAR_OCR:
963                 *(int *)result = sc->host.ocr;
964                 break;
965         case MMCBR_IVAR_POWER_MODE:
966                 *(int *)result = sc->host.ios.power_mode;
967                 break;
968         case MMCBR_IVAR_VDD:
969                 *(int *)result = sc->host.ios.vdd;
970                 break;
971         case MMCBR_IVAR_CAPS:
972                 *(int *)result = sc->host.caps;
973                 break;
974         case MMCBR_IVAR_MAX_DATA:
975                 *(int *)result = AML_MMC_MAX_DMA / MMC_SECTOR_SIZE;
976                 break;
977         default:
978                 return (EINVAL);
979         }
980
981         return (0);
982 }
983
984 static int
985 aml8726_mmc_write_ivar(device_t bus, device_t child,
986     int which, uintptr_t value)
987 {
988         struct aml8726_mmc_softc *sc = device_get_softc(bus);
989
990         switch (which) {
991         case MMCBR_IVAR_BUS_MODE:
992                 sc->host.ios.bus_mode = value;
993                 break;
994         case MMCBR_IVAR_BUS_WIDTH:
995                 sc->host.ios.bus_width = value;
996                 break;
997         case MMCBR_IVAR_CHIP_SELECT:
998                 sc->host.ios.chip_select = value;
999                 break;
1000         case MMCBR_IVAR_CLOCK:
1001                 sc->host.ios.clock = value;
1002                 break;
1003         case MMCBR_IVAR_MODE:
1004                 sc->host.mode = value;
1005                 break;
1006         case MMCBR_IVAR_OCR:
1007                 sc->host.ocr = value;
1008                 break;
1009         case MMCBR_IVAR_POWER_MODE:
1010                 sc->host.ios.power_mode = value;
1011                 break;
1012         case MMCBR_IVAR_VDD:
1013                 sc->host.ios.vdd = value;
1014                 break;
1015         /* These are read-only */
1016         case MMCBR_IVAR_CAPS:
1017         case MMCBR_IVAR_HOST_OCR:
1018         case MMCBR_IVAR_F_MIN:
1019         case MMCBR_IVAR_F_MAX:
1020         case MMCBR_IVAR_MAX_DATA:
1021         default:
1022                 return (EINVAL);
1023         }
1024
1025         return (0);
1026 }
1027
1028 static int
1029 aml8726_mmc_get_ro(device_t bus, device_t child)
1030 {
1031
1032         return (0);
1033 }
1034
1035 static int
1036 aml8726_mmc_acquire_host(device_t bus, device_t child)
1037 {
1038         struct aml8726_mmc_softc *sc = device_get_softc(bus);
1039
1040         AML_MMC_LOCK(sc);
1041
1042         while (sc->bus_busy)
1043                 mtx_sleep(sc, &sc->mtx, PZERO, "mmc", hz / 5);
1044         sc->bus_busy++;
1045
1046         AML_MMC_UNLOCK(sc);
1047
1048         return (0);
1049 }
1050
1051 static int
1052 aml8726_mmc_release_host(device_t bus, device_t child)
1053 {
1054         struct aml8726_mmc_softc *sc = device_get_softc(bus);
1055
1056         AML_MMC_LOCK(sc);
1057
1058         sc->bus_busy--;
1059         wakeup(sc);
1060
1061         AML_MMC_UNLOCK(sc);
1062
1063         return (0);
1064 }
1065
1066 static device_method_t aml8726_mmc_methods[] = {
1067         /* Device interface */
1068         DEVMETHOD(device_probe,         aml8726_mmc_probe),
1069         DEVMETHOD(device_attach,        aml8726_mmc_attach),
1070         DEVMETHOD(device_detach,        aml8726_mmc_detach),
1071         DEVMETHOD(device_shutdown,      aml8726_mmc_shutdown),
1072
1073         /* Bus interface */
1074         DEVMETHOD(bus_read_ivar,        aml8726_mmc_read_ivar),
1075         DEVMETHOD(bus_write_ivar,       aml8726_mmc_write_ivar),
1076
1077         /* MMC bridge interface */
1078         DEVMETHOD(mmcbr_update_ios,     aml8726_mmc_update_ios),
1079         DEVMETHOD(mmcbr_request,        aml8726_mmc_request),
1080         DEVMETHOD(mmcbr_get_ro,         aml8726_mmc_get_ro),
1081         DEVMETHOD(mmcbr_acquire_host,   aml8726_mmc_acquire_host),
1082         DEVMETHOD(mmcbr_release_host,   aml8726_mmc_release_host),
1083
1084         DEVMETHOD_END
1085 };
1086
1087 static driver_t aml8726_mmc_driver = {
1088         "aml8726_mmc",
1089         aml8726_mmc_methods,
1090         sizeof(struct aml8726_mmc_softc),
1091 };
1092
1093 static devclass_t aml8726_mmc_devclass;
1094
1095 DRIVER_MODULE(aml8726_mmc, simplebus, aml8726_mmc_driver,
1096     aml8726_mmc_devclass, NULL, NULL);
1097 MODULE_DEPEND(aml8726_mmc, aml8726_gpio, 1, 1, 1);
1098 MMC_DECLARE_BRIDGE(aml8726_mmc);