Deleted Added
full compact
imx_sdhci.c (266152) imx_sdhci.c (266198)
1/*-
2 * Copyright (c) 2013 Ian Lepore <ian@freebsd.org>
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

--- 11 unchanged lines hidden (view full) ---

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#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2013 Ian Lepore <ian@freebsd.org>
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

--- 11 unchanged lines hidden (view full) ---

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#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx_sdhci.c 266152 2014-05-15 16:11:06Z ian $");
28__FBSDID("$FreeBSD: stable/10/sys/arm/freescale/imx/imx_sdhci.c 266198 2014-05-15 22:03:24Z ian $");
29
30/*
31 * SDHCI driver glue for Freescale i.MX SoC family.
32 *
33 * This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs).
34 */
35
36#include <sys/param.h>

--- 29 unchanged lines hidden (view full) ---

66 void * intr_cookie;
67 struct sdhci_slot slot;
68 uint32_t baseclk_hz;
69 uint32_t sdclockreg_freq_bits;
70 uint32_t cmd_and_mode;
71 uint32_t r1bfix_intmask;
72 uint8_t r1bfix_type;
73 uint8_t hwtype;
29
30/*
31 * SDHCI driver glue for Freescale i.MX SoC family.
32 *
33 * This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs).
34 */
35
36#include <sys/param.h>

--- 29 unchanged lines hidden (view full) ---

66 void * intr_cookie;
67 struct sdhci_slot slot;
68 uint32_t baseclk_hz;
69 uint32_t sdclockreg_freq_bits;
70 uint32_t cmd_and_mode;
71 uint32_t r1bfix_intmask;
72 uint8_t r1bfix_type;
73 uint8_t hwtype;
74 boolean_t force_card_present;
74};
75
76#define R1BFIX_NONE 0 /* No fix needed at next interrupt. */
77#define R1BFIX_NODATA 1 /* Synthesize DATA_END for R1B w/o data. */
78#define R1BFIX_AC12 2 /* Wait for busy after auto command 12. */
79
80#define HWTYPE_NONE 0 /* Hardware not recognized/supported. */
81#define HWTYPE_ESDHC 1 /* imx5x and earlier. */
82#define HWTYPE_USDHC 2 /* imx6. */
83
84#define SDHC_WTMK_LVL 0x44 /* Watermark Level register. */
85#define USDHC_MIX_CONTROL 0x48 /* Mix(ed) Control register. */
86#define SDHC_VEND_SPEC 0xC0 /* Vendor-specific register. */
87#define SDHC_VEND_FRC_SDCLK_ON (1 << 8)
88#define SDHC_VEND_IPGEN (1 << 11)
89#define SDHC_VEND_HCKEN (1 << 12)
90#define SDHC_VEND_PEREN (1 << 13)
91
75};
76
77#define R1BFIX_NONE 0 /* No fix needed at next interrupt. */
78#define R1BFIX_NODATA 1 /* Synthesize DATA_END for R1B w/o data. */
79#define R1BFIX_AC12 2 /* Wait for busy after auto command 12. */
80
81#define HWTYPE_NONE 0 /* Hardware not recognized/supported. */
82#define HWTYPE_ESDHC 1 /* imx5x and earlier. */
83#define HWTYPE_USDHC 2 /* imx6. */
84
85#define SDHC_WTMK_LVL 0x44 /* Watermark Level register. */
86#define USDHC_MIX_CONTROL 0x48 /* Mix(ed) Control register. */
87#define SDHC_VEND_SPEC 0xC0 /* Vendor-specific register. */
88#define SDHC_VEND_FRC_SDCLK_ON (1 << 8)
89#define SDHC_VEND_IPGEN (1 << 11)
90#define SDHC_VEND_HCKEN (1 << 12)
91#define SDHC_VEND_PEREN (1 << 13)
92
93#define SDHC_PRES_STATE 0x24
94#define SDHC_PRES_CIHB (1 << 0)
95#define SDHC_PRES_CDIHB (1 << 1)
96#define SDHC_PRES_DLA (1 << 2)
97#define SDHC_PRES_SDSTB (1 << 3)
98#define SDHC_PRES_IPGOFF (1 << 4)
99#define SDHC_PRES_HCKOFF (1 << 5)
100#define SDHC_PRES_PEROFF (1 << 6)
101#define SDHC_PRES_SDOFF (1 << 7)
102#define SDHC_PRES_WTA (1 << 8)
103#define SDHC_PRES_RTA (1 << 9)
104#define SDHC_PRES_BWEN (1 << 10)
105#define SDHC_PRES_BREN (1 << 11)
106#define SDHC_PRES_RTR (1 << 12)
107#define SDHC_PRES_CINST (1 << 16)
108#define SDHC_PRES_CDPL (1 << 18)
109#define SDHC_PRES_WPSPL (1 << 19)
110#define SDHC_PRES_CLSL (1 << 23)
111#define SDHC_PRES_DLSL_SHIFT 24
112#define SDHC_PRES_DLSL_MASK (0xffU << SDHC_PRES_DLSL_SHIFT)
113
92#define SDHC_PROT_CTRL 0x28
93#define SDHC_PROT_LED (1 << 0)
94#define SDHC_PROT_WIDTH_1BIT (0 << 1)
95#define SDHC_PROT_WIDTH_4BIT (1 << 1)
96#define SDHC_PROT_WIDTH_8BIT (2 << 1)
97#define SDHC_PROT_WIDTH_MASK (3 << 1)
98#define SDHC_PROT_D3CD (1 << 3)
99#define SDHC_PROT_EMODE_BIG (0 << 4)

--- 149 unchanged lines hidden (view full) ---

249 * XXX Is it important that we distinguish between "internal" and "card"
250 * clocks? Probably not; transcribe the card clock status to both bits.
251 */
252 if (off == SDHCI_CLOCK_CONTROL) {
253 val32 = 0;
254 wrk32 = RD4(sc, SDHC_VEND_SPEC);
255 if (wrk32 & SDHC_VEND_FRC_SDCLK_ON)
256 val32 |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN;
114#define SDHC_PROT_CTRL 0x28
115#define SDHC_PROT_LED (1 << 0)
116#define SDHC_PROT_WIDTH_1BIT (0 << 1)
117#define SDHC_PROT_WIDTH_4BIT (1 << 1)
118#define SDHC_PROT_WIDTH_8BIT (2 << 1)
119#define SDHC_PROT_WIDTH_MASK (3 << 1)
120#define SDHC_PROT_D3CD (1 << 3)
121#define SDHC_PROT_EMODE_BIG (0 << 4)

--- 149 unchanged lines hidden (view full) ---

271 * XXX Is it important that we distinguish between "internal" and "card"
272 * clocks? Probably not; transcribe the card clock status to both bits.
273 */
274 if (off == SDHCI_CLOCK_CONTROL) {
275 val32 = 0;
276 wrk32 = RD4(sc, SDHC_VEND_SPEC);
277 if (wrk32 & SDHC_VEND_FRC_SDCLK_ON)
278 val32 |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN;
257 wrk32 = RD4(sc, SDHCI_PRESENT_STATE);
258 if (wrk32 & 0x08)
279 wrk32 = RD4(sc, SDHC_PRES_STATE);
280 if (wrk32 & SDHC_PRES_SDSTB)
259 val32 |= SDHCI_CLOCK_INT_STABLE;
260 val32 |= sc->sdclockreg_freq_bits;
261 return (val32);
262 }
263
264 return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
265}
266
267static uint32_t
268imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
269{
270 struct imx_sdhci_softc *sc = device_get_softc(dev);
281 val32 |= SDHCI_CLOCK_INT_STABLE;
282 val32 |= sc->sdclockreg_freq_bits;
283 return (val32);
284 }
285
286 return ((RD4(sc, off & ~3) >> (off & 3) * 8) & 0xffff);
287}
288
289static uint32_t
290imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
291{
292 struct imx_sdhci_softc *sc = device_get_softc(dev);
271 uint32_t val32;
293 uint32_t val32, wrk32;
272
294
295 val32 = RD4(sc, off);
296
273 /*
274 * The hardware leaves the base clock frequency out of the capabilities
275 * register; fill it in. The timeout clock is the same as the active
276 * output sdclock; we indicate that with a quirk setting so don't
277 * populate the timeout frequency bits.
278 *
279 * XXX Turn off (for now) features the hardware can do but this driver
280 * doesn't yet handle (1.8v, suspend/resume, etc).
281 */
282 if (off == SDHCI_CAPABILITIES) {
297 /*
298 * The hardware leaves the base clock frequency out of the capabilities
299 * register; fill it in. The timeout clock is the same as the active
300 * output sdclock; we indicate that with a quirk setting so don't
301 * populate the timeout frequency bits.
302 *
303 * XXX Turn off (for now) features the hardware can do but this driver
304 * doesn't yet handle (1.8v, suspend/resume, etc).
305 */
306 if (off == SDHCI_CAPABILITIES) {
283 val32 = RD4(sc, off);
284 val32 &= ~SDHCI_CAN_VDD_180;
285 val32 &= ~SDHCI_CAN_DO_SUSPEND;
286 val32 |= SDHCI_CAN_DO_8BITBUS;
287 val32 |= (sc->baseclk_hz / 1000000) << SDHCI_CLOCK_BASE_SHIFT;
288 return (val32);
289 }
290
307 val32 &= ~SDHCI_CAN_VDD_180;
308 val32 &= ~SDHCI_CAN_DO_SUSPEND;
309 val32 |= SDHCI_CAN_DO_8BITBUS;
310 val32 |= (sc->baseclk_hz / 1000000) << SDHCI_CLOCK_BASE_SHIFT;
311 return (val32);
312 }
313
291 val32 = RD4(sc, off);
314 /*
315 * The hardware moves bits around in the present state register to make
316 * room for all 8 data line state bits. To translate, mask out all the
317 * bits which are not in the same position in both registers (this also
318 * masks out some freescale-specific bits in locations defined as
319 * reserved by sdhci), then shift the data line and retune request bits
320 * down to their standard locations.
321 */
322 if (off == SDHCI_PRESENT_STATE) {
323 wrk32 = val32;
324 val32 &= 0x000F0F07;
325 val32 |= (wrk32 >> 4) & SDHCI_STATE_DAT_MASK;
326 val32 |= (wrk32 >> 9) & SDHCI_RETUNE_REQUEST;
327 if (sc->force_card_present)
328 val32 |= SDHCI_CARD_PRESENT;
329 return (val32);
330 }
292
293 /*
294 * imx_sdhci_intr() can synthesize a DATA_END interrupt following a
295 * command with an R1B response, mix it into the hardware status.
296 */
297 if (off == SDHCI_INT_STATUS) {
331
332 /*
333 * imx_sdhci_intr() can synthesize a DATA_END interrupt following a
334 * command with an R1B response, mix it into the hardware status.
335 */
336 if (off == SDHCI_INT_STATUS) {
298 val32 |= sc->r1bfix_intmask;
337 return (val32 | sc->r1bfix_intmask);
299 }
300
301 return val32;
302}
303
304static void
305imx_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
306 uint32_t *data, bus_size_t count)

--- 210 unchanged lines hidden (view full) ---

517 if ((sc->r1bfix_type == R1BFIX_NODATA &&
518 (intmask & SDHCI_INT_RESPONSE)) ||
519 (sc->r1bfix_type == R1BFIX_AC12 &&
520 (intmask & SDHCI_INT_DATA_END))) {
521 uint32_t count;
522 count = 0;
523 /* XXX use a callout or something instead of busy-waiting. */
524 while (count < 250000 &&
338 }
339
340 return val32;
341}
342
343static void
344imx_sdhci_read_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off,
345 uint32_t *data, bus_size_t count)

--- 210 unchanged lines hidden (view full) ---

556 if ((sc->r1bfix_type == R1BFIX_NODATA &&
557 (intmask & SDHCI_INT_RESPONSE)) ||
558 (sc->r1bfix_type == R1BFIX_AC12 &&
559 (intmask & SDHCI_INT_DATA_END))) {
560 uint32_t count;
561 count = 0;
562 /* XXX use a callout or something instead of busy-waiting. */
563 while (count < 250000 &&
525 (RD4(sc, SDHCI_PRESENT_STATE) & SDHCI_DAT_ACTIVE)) {
564 (RD4(sc, SDHC_PRES_STATE) & SDHC_PRES_DLA)) {
526 ++count;
527 DELAY(1);
528 }
529 if (count >= 250000)
530 sc->r1bfix_intmask = SDHCI_INT_DATA_TIMEOUT;
531 else if (sc->r1bfix_type == R1BFIX_NODATA)
532 sc->r1bfix_intmask = SDHCI_INT_DATA_END;
533 sc->r1bfix_type = R1BFIX_NONE;

--- 16 unchanged lines hidden (view full) ---

550 return (EBUSY);
551}
552
553static int
554imx_sdhci_attach(device_t dev)
555{
556 struct imx_sdhci_softc *sc = device_get_softc(dev);
557 int rid, err;
565 ++count;
566 DELAY(1);
567 }
568 if (count >= 250000)
569 sc->r1bfix_intmask = SDHCI_INT_DATA_TIMEOUT;
570 else if (sc->r1bfix_type == R1BFIX_NODATA)
571 sc->r1bfix_intmask = SDHCI_INT_DATA_END;
572 sc->r1bfix_type = R1BFIX_NONE;

--- 16 unchanged lines hidden (view full) ---

589 return (EBUSY);
590}
591
592static int
593imx_sdhci_attach(device_t dev)
594{
595 struct imx_sdhci_softc *sc = device_get_softc(dev);
596 int rid, err;
597 phandle_t node;
558
559 sc->dev = dev;
560
561 sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
562 if (sc->hwtype == HWTYPE_NONE)
563 panic("Impossible: not compatible in imx_sdhci_attach()");
564
565 rid = 0;

--- 50 unchanged lines hidden (view full) ---

616 if (sc->hwtype == HWTYPE_USDHC) {
617 sc->baseclk_hz = 200000000;
618 } else if (sc->hwtype == HWTYPE_ESDHC) {
619 sc->baseclk_hz = imx51_get_clock(IMX51CLK_PERCLK_ROOT);
620 }
621
622 sdhci_init_slot(dev, &sc->slot, 0);
623
598
599 sc->dev = dev;
600
601 sc->hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
602 if (sc->hwtype == HWTYPE_NONE)
603 panic("Impossible: not compatible in imx_sdhci_attach()");
604
605 rid = 0;

--- 50 unchanged lines hidden (view full) ---

656 if (sc->hwtype == HWTYPE_USDHC) {
657 sc->baseclk_hz = 200000000;
658 } else if (sc->hwtype == HWTYPE_ESDHC) {
659 sc->baseclk_hz = imx51_get_clock(IMX51CLK_PERCLK_ROOT);
660 }
661
662 sdhci_init_slot(dev, &sc->slot, 0);
663
664 /*
665 * If the slot is flagged with the non-removable property, set our flag
666 * to always force the SDHCI_CARD_PRESENT bit on.
667 *
668 * XXX Workaround for gpio-based card detect...
669 *
670 * We don't have gpio support yet. If there's a cd-gpios property just
671 * force the SDHCI_CARD_PRESENT bit on for now. If there isn't really a
672 * card there it will fail to probe at the mmc layer and nothing bad
673 * happens except instantiating a /dev/mmcN device for an empty slot.
674 */
675 node = ofw_bus_get_node(dev);
676 if (OF_hasprop(node, "non-removable"))
677 sc->force_card_present = true;
678 else if (OF_hasprop(node, "cd-gpios")) {
679 /* XXX put real gpio hookup here. */
680 sc->force_card_present = true;
681 }
682
624 bus_generic_probe(dev);
625 bus_generic_attach(dev);
626
627 sdhci_start_slot(&sc->slot);
628
629 return (0);
630
631fail:

--- 72 unchanged lines hidden ---
683 bus_generic_probe(dev);
684 bus_generic_attach(dev);
685
686 sdhci_start_slot(&sc->slot);
687
688 return (0);
689
690fail:

--- 72 unchanged lines hidden ---