source: rtems-libbsd/freebsd/sys/arm/ti/ti_sdhci.c @ 7e52ab9

55-freebsd-126-freebsd-12
Last change on this file since 7e52ab9 was 7e52ab9, checked in by Sichen Zhao <1473996754@…>, on 11/08/17 at 13:43:31

Import BBB sd driver files from FreeBSD.

  • Property mode set to 100644
File size: 21.2 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/*-
4 * Copyright (c) 2013 Ian Lepore <ian@freebsd.org>
5 * Copyright (c) 2011 Ben Gray <ben.r.gray@gmail.com>.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD$");
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/bus.h>
36#include <sys/gpio.h>
37#include <sys/kernel.h>
38#include <sys/malloc.h>
39#include <sys/module.h>
40#include <rtems/bsd/sys/resource.h>
41#include <sys/rman.h>
42#include <sys/sysctl.h>
43#include <sys/taskqueue.h>
44
45#include <machine/bus.h>
46#include <machine/resource.h>
47#include <machine/intr.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/mmcreg.h>
54#include <dev/mmc/mmcbrvar.h>
55
56#include <dev/sdhci/sdhci.h>
57#include <dev/sdhci/sdhci_fdt_gpio.h>
58#include <rtems/bsd/local/sdhci_if.h>
59
60#include <arm/ti/ti_cpuid.h>
61#include <arm/ti/ti_prcm.h>
62#include <arm/ti/ti_hwmods.h>
63#include <rtems/bsd/local/gpio_if.h>
64
65struct ti_sdhci_softc {
66        device_t                dev;
67        struct sdhci_fdt_gpio * gpio;
68        struct resource *       mem_res;
69        struct resource *       irq_res;
70        void *                  intr_cookie;
71        struct sdhci_slot       slot;
72        clk_ident_t             mmchs_clk_id;
73        uint32_t                mmchs_reg_off;
74        uint32_t                sdhci_reg_off;
75        uint32_t                baseclk_hz;
76        uint32_t                cmd_and_mode;
77        uint32_t                sdhci_clkdiv;
78        boolean_t               disable_highspeed;
79        boolean_t               force_card_present;
80        boolean_t               disable_readonly;
81};
82
83/*
84 * Table of supported FDT compat strings.
85 *
86 * Note that "ti,mmchs" is our own invention, and should be phased out in favor
87 * of the documented names.
88 *
89 * Note that vendor Beaglebone dtsi files use "ti,omap3-hsmmc" for the am335x.
90 */
91static struct ofw_compat_data compat_data[] = {
92        {"ti,omap3-hsmmc",      1},
93        {"ti,omap4-hsmmc",      1},
94        {"ti,mmchs",            1},
95        {NULL,                  0},
96};
97
98/*
99 * The MMCHS hardware has a few control and status registers at the beginning of
100 * the device's memory map, followed by the standard sdhci register block.
101 * Different SoCs have the register blocks at different offsets from the
102 * beginning of the device.  Define some constants to map out the registers we
103 * access, and the various per-SoC offsets.  The SDHCI_REG_OFFSET is how far
104 * beyond the MMCHS block the SDHCI block is found; it's the same on all SoCs.
105 */
106#define OMAP3_MMCHS_REG_OFFSET          0x000
107#define OMAP4_MMCHS_REG_OFFSET          0x100
108#define AM335X_MMCHS_REG_OFFSET         0x100
109#define SDHCI_REG_OFFSET                0x100
110
111#define MMCHS_SYSCONFIG                 0x010
112#define   MMCHS_SYSCONFIG_RESET           (1 << 1)
113#define MMCHS_SYSSTATUS                 0x014
114#define   MMCHS_SYSSTATUS_RESETDONE       (1 << 0)
115#define MMCHS_CON                       0x02C
116#define   MMCHS_CON_DW8                   (1 << 5)
117#define   MMCHS_CON_DVAL_8_4MS            (3 << 9)
118#define   MMCHS_CON_OD                    (1 << 0)
119#define MMCHS_SYSCTL                    0x12C
120#define   MMCHS_SYSCTL_CLKD_MASK           0x3FF
121#define   MMCHS_SYSCTL_CLKD_SHIFT          6
122#define MMCHS_SD_CAPA                   0x140
123#define   MMCHS_SD_CAPA_VS18              (1 << 26)
124#define   MMCHS_SD_CAPA_VS30              (1 << 25)
125#define   MMCHS_SD_CAPA_VS33              (1 << 24)
126
127static inline uint32_t
128ti_mmchs_read_4(struct ti_sdhci_softc *sc, bus_size_t off)
129{
130
131        return (bus_read_4(sc->mem_res, off + sc->mmchs_reg_off));
132}
133
134static inline void
135ti_mmchs_write_4(struct ti_sdhci_softc *sc, bus_size_t off, uint32_t val)
136{
137
138        bus_write_4(sc->mem_res, off + sc->mmchs_reg_off, val);
139}
140
141static inline uint32_t
142RD4(struct ti_sdhci_softc *sc, bus_size_t off)
143{
144
145        return (bus_read_4(sc->mem_res, off + sc->sdhci_reg_off));
146}
147
148static inline void
149WR4(struct ti_sdhci_softc *sc, bus_size_t off, uint32_t val)
150{
151
152        bus_write_4(sc->mem_res, off + sc->sdhci_reg_off, val);
153}
154
155static uint8_t
156ti_sdhci_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off)
157{
158        struct ti_sdhci_softc *sc = device_get_softc(dev);
159
160        return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xff);
161}
162
163static uint16_t
164ti_sdhci_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off)
165{
166        struct ti_sdhci_softc *sc = device_get_softc(dev);
167        uint32_t clkdiv, val32;
168
169        /*
170         * The MMCHS hardware has a non-standard interpretation of the sdclock
171         * divisor bits.  It uses the same bit positions as SDHCI 3.0 (15..6)
172         * but doesn't split them into low:high fields.  Instead they're a
173         * single number in the range 0..1023 and the number is exactly the
174         * clock divisor (with 0 and 1 both meaning divide by 1).  The SDHCI
175         * driver code expects a v2.0 or v3.0 divisor.  The shifting and masking
176         * here extracts the MMCHS representation from the hardware word, cleans
177         * those bits out, applies the 2N adjustment, and plugs the result into
178         * the bit positions for the 2.0 or 3.0 divisor in the returned register
179         * value. The ti_sdhci_write_2() routine performs the opposite
180         * transformation when the SDHCI driver writes to the register.
181         */
182        if (off == SDHCI_CLOCK_CONTROL) {
183                val32 = RD4(sc, SDHCI_CLOCK_CONTROL);
184                clkdiv = ((val32 >> MMCHS_SYSCTL_CLKD_SHIFT) &
185                    MMCHS_SYSCTL_CLKD_MASK) / 2;
186                val32 &= ~(MMCHS_SYSCTL_CLKD_MASK << MMCHS_SYSCTL_CLKD_SHIFT);
187                val32 |= (clkdiv & SDHCI_DIVIDER_MASK) << SDHCI_DIVIDER_SHIFT;
188                if (slot->version >= SDHCI_SPEC_300)
189                        val32 |= ((clkdiv >> SDHCI_DIVIDER_MASK_LEN) &
190                            SDHCI_DIVIDER_HI_MASK) << SDHCI_DIVIDER_HI_SHIFT;
191                return (val32 & 0xffff);
192        }
193
194        /*
195         * Standard 32-bit handling of command and transfer mode.
196         */
197        if (off == SDHCI_TRANSFER_MODE) {
198                return (sc->cmd_and_mode >> 16);
199        } else if (off == SDHCI_COMMAND_FLAGS) {
200                return (sc->cmd_and_mode & 0x0000ffff);
201        }
202
203        return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
204}
205
206static uint32_t
207ti_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
208{
209        struct ti_sdhci_softc *sc = device_get_softc(dev);
210        uint32_t val32;
211
212        val32 = RD4(sc, off);
213
214        /*
215         * If we need to disallow highspeed mode due to the OMAP4 erratum, strip
216         * that flag from the returned capabilities.
217         */
218        if (off == SDHCI_CAPABILITIES && sc->disable_highspeed)
219                val32 &= ~SDHCI_CAN_DO_HISPD;
220
221        /*
222         * Force the card-present state if necessary.
223         */
224        if (off == SDHCI_PRESENT_STATE && sc->force_card_present)
225                val32 |= SDHCI_CARD_PRESENT;
226
227        return (val32);
228}
229
230static void
231ti_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
232    uint32_t *data, bus_size_t count)
233{
234        struct ti_sdhci_softc *sc = device_get_softc(dev);
235
236        bus_read_multi_4(sc->mem_res, off + sc->sdhci_reg_off, data, count);
237}
238
239static void
240ti_sdhci_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off,
241    uint8_t val)
242{
243        struct ti_sdhci_softc *sc = device_get_softc(dev);
244        uint32_t val32;
245
246        val32 = RD4(sc, off & ~3);
247        val32 &= ~(0xff << (off & 3) * 8);
248        val32 |= (val << (off & 3) * 8);
249
250        WR4(sc, off & ~3, val32);
251}
252
253static void
254ti_sdhci_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off,
255    uint16_t val)
256{
257        struct ti_sdhci_softc *sc = device_get_softc(dev);
258        uint32_t clkdiv, val32;
259
260        /*
261         * Translate between the hardware and SDHCI 2.0 or 3.0 representations
262         * of the clock divisor.  See the comments in ti_sdhci_read_2() for
263         * details.
264         */
265        if (off == SDHCI_CLOCK_CONTROL) {
266                clkdiv = (val >> SDHCI_DIVIDER_SHIFT) & SDHCI_DIVIDER_MASK;
267                if (slot->version >= SDHCI_SPEC_300)
268                        clkdiv |= ((val >> SDHCI_DIVIDER_HI_SHIFT) &
269                            SDHCI_DIVIDER_HI_MASK) << SDHCI_DIVIDER_MASK_LEN;
270                clkdiv *= 2;
271                if (clkdiv > MMCHS_SYSCTL_CLKD_MASK)
272                        clkdiv = MMCHS_SYSCTL_CLKD_MASK;
273                val32 = RD4(sc, SDHCI_CLOCK_CONTROL);
274                val32 &= 0xffff0000;
275                val32 |= val & ~(MMCHS_SYSCTL_CLKD_MASK <<
276                    MMCHS_SYSCTL_CLKD_SHIFT);
277                val32 |= clkdiv << MMCHS_SYSCTL_CLKD_SHIFT;
278                WR4(sc, SDHCI_CLOCK_CONTROL, val32);
279                return;
280        }
281
282        /*
283         * Standard 32-bit handling of command and transfer mode.
284         */
285        if (off == SDHCI_TRANSFER_MODE) {
286                sc->cmd_and_mode = (sc->cmd_and_mode & 0xffff0000) |
287                    ((uint32_t)val & 0x0000ffff);
288                return;
289        } else if (off == SDHCI_COMMAND_FLAGS) {
290                sc->cmd_and_mode = (sc->cmd_and_mode & 0x0000ffff) |
291                    ((uint32_t)val << 16);
292                WR4(sc, SDHCI_TRANSFER_MODE, sc->cmd_and_mode);
293                return;
294        }
295
296        val32 = RD4(sc, off & ~3);
297        val32 &= ~(0xffff << (off & 3) * 8);
298        val32 |= ((val & 0xffff) << (off & 3) * 8);
299        WR4(sc, off & ~3, val32);       
300}
301
302static void
303ti_sdhci_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
304    uint32_t val)
305{
306        struct ti_sdhci_softc *sc = device_get_softc(dev);
307
308        WR4(sc, off, val);
309}
310
311static void
312ti_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
313    uint32_t *data, bus_size_t count)
314{
315        struct ti_sdhci_softc *sc = device_get_softc(dev);
316
317        bus_write_multi_4(sc->mem_res, off + sc->sdhci_reg_off, data, count);
318}
319
320static void
321ti_sdhci_intr(void *arg)
322{
323        struct ti_sdhci_softc *sc = arg;
324
325        sdhci_generic_intr(&sc->slot);
326}
327
328static int
329ti_sdhci_update_ios(device_t brdev, device_t reqdev)
330{
331        struct ti_sdhci_softc *sc = device_get_softc(brdev);
332        struct sdhci_slot *slot;
333        struct mmc_ios *ios;
334        uint32_t val32, newval32;
335
336        slot = device_get_ivars(reqdev);
337        ios = &slot->host.ios;
338
339        /*
340         * There is an 8-bit-bus bit in the MMCHS control register which, when
341         * set, overrides the 1 vs 4 bit setting in the standard SDHCI
342         * registers.  Set that bit first according to whether an 8-bit bus is
343         * requested, then let the standard driver handle everything else.
344         */
345        val32 = ti_mmchs_read_4(sc, MMCHS_CON);
346        newval32  = val32;
347
348        if (ios->bus_width == bus_width_8)
349                newval32 |= MMCHS_CON_DW8;
350        else
351                newval32 &= ~MMCHS_CON_DW8;
352
353        if (ios->bus_mode == opendrain)
354                newval32 |= MMCHS_CON_OD;
355        else /* if (ios->bus_mode == pushpull) */
356                newval32 &= ~MMCHS_CON_OD;
357
358        if (newval32 != val32)
359                ti_mmchs_write_4(sc, MMCHS_CON, newval32);
360
361        return (sdhci_generic_update_ios(brdev, reqdev));
362}
363
364static int
365ti_sdhci_get_ro(device_t brdev, device_t reqdev)
366{
367        struct ti_sdhci_softc *sc = device_get_softc(brdev);
368
369        if (sc->disable_readonly)
370                return (0);
371
372        return (sdhci_fdt_gpio_get_readonly(sc->gpio));
373}
374
375static bool
376ti_sdhci_get_card_present(device_t dev, struct sdhci_slot *slot)
377{
378        struct ti_sdhci_softc *sc = device_get_softc(dev);
379
380        return (sdhci_fdt_gpio_get_present(sc->gpio));
381}
382
383static int
384ti_sdhci_detach(device_t dev)
385{
386
387        /* sdhci_fdt_gpio_teardown(sc->gpio); */
388
389        return (EBUSY);
390}
391
392static void
393ti_sdhci_hw_init(device_t dev)
394{
395        struct ti_sdhci_softc *sc = device_get_softc(dev);
396        uint32_t regval;
397        unsigned long timeout;
398
399        /* Enable the controller and interface/functional clocks */
400        if (ti_prcm_clk_enable(sc->mmchs_clk_id) != 0) {
401                device_printf(dev, "Error: failed to enable MMC clock\n");
402                return;
403        }
404
405        /* Get the frequency of the source clock */
406        if (ti_prcm_clk_get_source_freq(sc->mmchs_clk_id,
407            &sc->baseclk_hz) != 0) {
408                device_printf(dev, "Error: failed to get source clock freq\n");
409                return;
410        }
411
412        /* Issue a softreset to the controller */
413        ti_mmchs_write_4(sc, MMCHS_SYSCONFIG, MMCHS_SYSCONFIG_RESET);
414        timeout = 1000;
415        while (!(ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) &
416            MMCHS_SYSSTATUS_RESETDONE)) {
417                if (--timeout == 0) {
418                        device_printf(dev,
419                            "Error: Controller reset operation timed out\n");
420                        break;
421                }
422                DELAY(100);
423        }
424
425        /*
426         * Reset the command and data state machines and also other aspects of
427         * the controller such as bus clock and power.
428         *
429         * If we read the software reset register too fast after writing it we
430         * can get back a zero that means the reset hasn't started yet rather
431         * than that the reset is complete. Per TI recommendations, work around
432         * it by reading until we see the reset bit asserted, then read until
433         * it's clear. We also set the SDHCI_QUIRK_WAITFOR_RESET_ASSERTED quirk
434         * so that the main sdhci driver uses this same logic in its resets.
435         */
436        ti_sdhci_write_1(dev, NULL, SDHCI_SOFTWARE_RESET, SDHCI_RESET_ALL);
437        timeout = 10000;
438        while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) &
439            SDHCI_RESET_ALL) != SDHCI_RESET_ALL) {
440                if (--timeout == 0) {
441                        break;
442                }
443                DELAY(1);
444        }
445        timeout = 10000;
446        while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) &
447            SDHCI_RESET_ALL)) {
448                if (--timeout == 0) {
449                        device_printf(dev,
450                            "Error: Software reset operation timed out\n");
451                        break;
452                }
453                DELAY(100);
454        }
455
456        /*
457         * The attach() routine has examined fdt data and set flags in
458         * slot.host.caps to reflect what voltages we can handle.  Set those
459         * values in the CAPA register.  The manual says that these values can
460         * only be set once, "before initialization" whatever that means, and
461         * that they survive a reset.  So maybe doing this will be a no-op if
462         * u-boot has already initialized the hardware.
463         */
464        regval = ti_mmchs_read_4(sc, MMCHS_SD_CAPA);
465        if (sc->slot.host.caps & MMC_OCR_LOW_VOLTAGE)
466                regval |= MMCHS_SD_CAPA_VS18;
467        if (sc->slot.host.caps & (MMC_OCR_290_300 | MMC_OCR_300_310))
468                regval |= MMCHS_SD_CAPA_VS30;
469        ti_mmchs_write_4(sc, MMCHS_SD_CAPA, regval);
470
471        /* Set initial host configuration (1-bit, std speed, pwr off). */
472        ti_sdhci_write_1(dev, NULL, SDHCI_HOST_CONTROL, 0);
473        ti_sdhci_write_1(dev, NULL, SDHCI_POWER_CONTROL, 0);
474
475        /* Set the initial controller configuration. */
476        ti_mmchs_write_4(sc, MMCHS_CON, MMCHS_CON_DVAL_8_4MS);
477}
478
479static int
480ti_sdhci_attach(device_t dev)
481{
482        struct ti_sdhci_softc *sc = device_get_softc(dev);
483        int rid, err;
484        pcell_t prop;
485        phandle_t node;
486
487        sc->dev = dev;
488
489        /*
490         * Get the MMCHS device id from FDT.  If it's not there use the newbus
491         * unit number (which will work as long as the devices are in order and
492         * none are skipped in the fdt).  Note that this is a property we made
493         * up and added in freebsd, it doesn't exist in the published bindings.
494         */
495        node = ofw_bus_get_node(dev);
496        sc->mmchs_clk_id = ti_hwmods_get_clock(dev);
497        if (sc->mmchs_clk_id == INVALID_CLK_IDENT) {
498                device_printf(dev, "failed to get clock based on hwmods property\n");
499        }
500
501        /*
502         * The hardware can inherently do dual-voltage (1p8v, 3p0v) on the first
503         * device, and only 1p8v on other devices unless an external transceiver
504         * is used.  The only way we could know about a transceiver is fdt data.
505         * Note that we have to do this before calling ti_sdhci_hw_init() so
506         * that it can set the right values in the CAPA register, which can only
507         * be done once and never reset.
508         */
509        sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE;
510        if (sc->mmchs_clk_id == MMC1_CLK || OF_hasprop(node, "ti,dual-volt")) {
511                sc->slot.host.caps |= MMC_OCR_290_300 | MMC_OCR_300_310;
512        }
513
514        /*
515         * Set the offset from the device's memory start to the MMCHS registers.
516         * Also for OMAP4 disable high speed mode due to erratum ID i626.
517         */
518        switch (ti_chip()) {
519#ifdef SOC_OMAP4
520        case CHIP_OMAP_4:
521                sc->mmchs_reg_off = OMAP4_MMCHS_REG_OFFSET;
522                sc->disable_highspeed = true;
523                break;
524#endif
525#ifdef SOC_TI_AM335X
526        case CHIP_AM335X:
527                sc->mmchs_reg_off = AM335X_MMCHS_REG_OFFSET;
528                break;
529#endif
530        default:
531                panic("Unknown OMAP device\n");
532        }
533
534        /*
535         * The standard SDHCI registers are at a fixed offset (the same on all
536         * SoCs) beyond the MMCHS registers.
537         */
538        sc->sdhci_reg_off = sc->mmchs_reg_off + SDHCI_REG_OFFSET;
539
540        /* Resource setup. */
541        rid = 0;
542        sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
543            RF_ACTIVE);
544        if (!sc->mem_res) {
545                device_printf(dev, "cannot allocate memory window\n");
546                err = ENXIO;
547                goto fail;
548        }
549
550        rid = 0;
551        sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
552            RF_ACTIVE);
553        if (!sc->irq_res) {
554                device_printf(dev, "cannot allocate interrupt\n");
555                err = ENXIO;
556                goto fail;
557        }
558
559        if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
560            NULL, ti_sdhci_intr, sc, &sc->intr_cookie)) {
561                device_printf(dev, "cannot setup interrupt handler\n");
562                err = ENXIO;
563                goto fail;
564        }
565
566        /*
567         * Set up handling of card-detect and write-protect gpio lines.
568         *
569         * If there is no write protect info in the fdt data, fall back to the
570         * historical practice of assuming that the card is writable.  This
571         * works around bad fdt data from the upstream source.  The alternative
572         * would be to trust the sdhci controller's PRESENT_STATE register WP
573         * bit, but it may say write protect is in effect when it's not if the
574         * pinmux setup doesn't route the WP signal into the sdchi block.
575         */
576        sc->gpio = sdhci_fdt_gpio_setup(sc->dev, &sc->slot);
577
578        if (!OF_hasprop(node, "wp-gpios") && !OF_hasprop(node, "wp-disable"))
579                sc->disable_readonly = true;
580
581        /* Initialise the MMCHS hardware. */
582        ti_sdhci_hw_init(dev);
583
584        /*
585         * The capabilities register can only express base clock frequencies in
586         * the range of 0-63MHz for a v2.0 controller.  Since our clock runs
587         * faster than that, the hardware sets the frequency to zero in the
588         * register.  When the register contains zero, the sdhci driver expects
589         * slot.max_clk to already have the right value in it.
590         */
591        sc->slot.max_clk = sc->baseclk_hz;
592
593        /*
594         * The MMCHS timeout counter is based on the output sdclock.  Tell the
595         * sdhci driver to recalculate the timeout clock whenever the output
596         * sdclock frequency changes.
597         */
598        sc->slot.quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK;
599
600        /*
601         * The MMCHS hardware shifts the 136-bit response data (in violation of
602         * the spec), so tell the sdhci driver not to do the same in software.
603         */
604        sc->slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE;
605
606        /*
607         * Reset bits are broken, have to wait to see the bits asserted
608         * before waiting to see them de-asserted.
609         */
610        sc->slot.quirks |= SDHCI_QUIRK_WAITFOR_RESET_ASSERTED;
611       
612        /*
613         * The controller waits for busy responses.
614         */
615        sc->slot.quirks |= SDHCI_QUIRK_WAIT_WHILE_BUSY;
616
617        /*
618         * DMA is not really broken, I just haven't implemented it yet.
619         */
620        sc->slot.quirks |= SDHCI_QUIRK_BROKEN_DMA;
621
622        /*
623         *  Set up the hardware and go.  Note that this sets many of the
624         *  slot.host.* fields, so we have to do this before overriding any of
625         *  those values based on fdt data, below.
626         */
627        sdhci_init_slot(dev, &sc->slot, 0);
628
629        /*
630         * The SDHCI controller doesn't realize it, but we can support 8-bit
631         * even though we're not a v3.0 controller.  If there's an fdt bus-width
632         * property, honor it.
633         */
634        if (OF_getencprop(node, "bus-width", &prop, sizeof(prop)) > 0) {
635                sc->slot.host.caps &= ~(MMC_CAP_4_BIT_DATA |
636                    MMC_CAP_8_BIT_DATA);
637                switch (prop) {
638                case 8:
639                        sc->slot.host.caps |= MMC_CAP_8_BIT_DATA;
640                        /* FALLTHROUGH */
641                case 4:
642                        sc->slot.host.caps |= MMC_CAP_4_BIT_DATA;
643                        break;
644                case 1:
645                        break;
646                default:
647                        device_printf(dev, "Bad bus-width value %u\n", prop);
648                        break;
649                }
650        }
651
652        /*
653         * If the slot is flagged with the non-removable property, set our flag
654         * to always force the SDHCI_CARD_PRESENT bit on.
655         */
656        node = ofw_bus_get_node(dev);
657        if (OF_hasprop(node, "non-removable"))
658                sc->force_card_present = true;
659
660        bus_generic_probe(dev);
661        bus_generic_attach(dev);
662
663        sdhci_start_slot(&sc->slot);
664
665        return (0);
666
667fail:
668        if (sc->intr_cookie)
669                bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie);
670        if (sc->irq_res)
671                bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
672        if (sc->mem_res)
673                bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
674
675        return (err);
676}
677
678static int
679ti_sdhci_probe(device_t dev)
680{
681
682        if (!ofw_bus_status_okay(dev))
683                return (ENXIO);
684
685        if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) {
686                device_set_desc(dev, "TI MMCHS (SDHCI 2.0)");
687                return (BUS_PROBE_DEFAULT);
688        }
689
690        return (ENXIO);
691}
692
693static device_method_t ti_sdhci_methods[] = {
694        /* Device interface */
695        DEVMETHOD(device_probe,         ti_sdhci_probe),
696        DEVMETHOD(device_attach,        ti_sdhci_attach),
697        DEVMETHOD(device_detach,        ti_sdhci_detach),
698
699        /* Bus interface */
700        DEVMETHOD(bus_read_ivar,        sdhci_generic_read_ivar),
701        DEVMETHOD(bus_write_ivar,       sdhci_generic_write_ivar),
702
703        /* MMC bridge interface */
704        DEVMETHOD(mmcbr_update_ios,     ti_sdhci_update_ios),
705        DEVMETHOD(mmcbr_request,        sdhci_generic_request),
706        DEVMETHOD(mmcbr_get_ro,         ti_sdhci_get_ro),
707        DEVMETHOD(mmcbr_acquire_host,   sdhci_generic_acquire_host),
708        DEVMETHOD(mmcbr_release_host,   sdhci_generic_release_host),
709
710        /* SDHCI registers accessors */
711        DEVMETHOD(sdhci_read_1,         ti_sdhci_read_1),
712        DEVMETHOD(sdhci_read_2,         ti_sdhci_read_2),
713        DEVMETHOD(sdhci_read_4,         ti_sdhci_read_4),
714        DEVMETHOD(sdhci_read_multi_4,   ti_sdhci_read_multi_4),
715        DEVMETHOD(sdhci_write_1,        ti_sdhci_write_1),
716        DEVMETHOD(sdhci_write_2,        ti_sdhci_write_2),
717        DEVMETHOD(sdhci_write_4,        ti_sdhci_write_4),
718        DEVMETHOD(sdhci_write_multi_4,  ti_sdhci_write_multi_4),
719        DEVMETHOD(sdhci_get_card_present, ti_sdhci_get_card_present),
720
721        DEVMETHOD_END
722};
723
724static devclass_t ti_sdhci_devclass;
725
726static driver_t ti_sdhci_driver = {
727        "sdhci_ti",
728        ti_sdhci_methods,
729        sizeof(struct ti_sdhci_softc),
730};
731
732DRIVER_MODULE(sdhci_ti, simplebus, ti_sdhci_driver, ti_sdhci_devclass, NULL,
733    NULL);
734MODULE_DEPEND(sdhci_ti, sdhci, 1, 1, 1);
735MMC_DECLARE_BRIDGE(sdhci_ti);
Note: See TracBrowser for help on using the repository browser.