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 --- |