Author: ian
Date: Thu Feb 13 02:38:16 2014
New Revision: 261815
URL: http://svnweb.freebsd.org/changeset/base/261815

Log:
  Write translation code for the SDHCI_PRESENT_STATE register.  Freescale
  moved some bits around in their version of the register, adjust things
  so that the sdhci code sees the standard layout.

Modified:
  head/sys/arm/freescale/imx/imx_sdhci.c

Modified: head/sys/arm/freescale/imx/imx_sdhci.c
==============================================================================
--- head/sys/arm/freescale/imx/imx_sdhci.c      Wed Feb 12 22:25:08 2014        
(r261814)
+++ head/sys/arm/freescale/imx/imx_sdhci.c      Thu Feb 13 02:38:16 2014        
(r261815)
@@ -89,6 +89,27 @@ struct imx_sdhci_softc {
 #define         SDHC_VEND_HCKEN        (1 << 12)
 #define         SDHC_VEND_PEREN        (1 << 13)
 
+#define        SDHC_PRES_STATE         0x24
+#define          SDHC_PRES_CIHB          (1 <<  0)
+#define          SDHC_PRES_CDIHB         (1 <<  1)
+#define          SDHC_PRES_DLA           (1 <<  2)
+#define          SDHC_PRES_SDSTB         (1 <<  3)
+#define          SDHC_PRES_IPGOFF        (1 <<  4)
+#define          SDHC_PRES_HCKOFF        (1 <<  5)
+#define          SDHC_PRES_PEROFF        (1 <<  6)
+#define          SDHC_PRES_SDOFF         (1 <<  7)
+#define          SDHC_PRES_WTA           (1 <<  8)
+#define          SDHC_PRES_RTA           (1 <<  9)
+#define          SDHC_PRES_BWEN          (1 << 10)
+#define          SDHC_PRES_BREN          (1 << 11)
+#define          SDHC_PRES_RTR           (1 << 12)
+#define          SDHC_PRES_CINST         (1 << 16)
+#define          SDHC_PRES_CDPL          (1 << 18)
+#define          SDHC_PRES_WPSPL         (1 << 19)
+#define          SDHC_PRES_CLSL          (1 << 23)
+#define          SDHC_PRES_DLSL_SHIFT    24
+#define          SDHC_PRES_DLSL_MASK     (0xffU << SDHC_PRES_DLSL_SHIFT)
+
 #define        SDHC_PROT_CTRL          0x28
 #define         SDHC_PROT_LED          (1 << 0)
 #define         SDHC_PROT_WIDTH_1BIT   (0 << 1)
@@ -254,8 +275,8 @@ imx_sdhci_read_2(device_t dev, struct sd
                wrk32 = RD4(sc, SDHC_VEND_SPEC);
                if (wrk32 & SDHC_VEND_FRC_SDCLK_ON)
                        val32 |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_CARD_EN;
-               wrk32 = RD4(sc, SDHCI_PRESENT_STATE);
-               if (wrk32 & 0x08)
+               wrk32 = RD4(sc, SDHC_PRES_STATE);
+               if (wrk32 & SDHC_PRES_SDSTB)
                        val32 |= SDHCI_CLOCK_INT_STABLE;
                val32 |= sc->sdclockreg_freq_bits;
                return (val32);
@@ -268,7 +289,9 @@ static uint32_t
 imx_sdhci_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off)
 {
        struct imx_sdhci_softc *sc = device_get_softc(dev);
-       uint32_t val32;
+       uint32_t val32, wrk32;
+
+       val32 = RD4(sc, off);
 
        /*
         * The hardware leaves the base clock frequency out of the capabilities
@@ -280,7 +303,6 @@ imx_sdhci_read_4(device_t dev, struct sd
         * doesn't yet handle (1.8v, suspend/resume, etc).
         */
        if (off == SDHCI_CAPABILITIES) {
-               val32 = RD4(sc, off);
                val32 &= ~SDHCI_CAN_VDD_180;
                val32 &= ~SDHCI_CAN_DO_SUSPEND;
                val32 |= SDHCI_CAN_DO_8BITBUS;
@@ -288,14 +310,28 @@ imx_sdhci_read_4(device_t dev, struct sd
                return (val32);
        }
        
-       val32 = RD4(sc, off);
+       /*
+        * The hardware moves bits around in the present state register to make
+        * room for all 8 data line state bits.  To translate, mask out all the
+        * bits which are not in the same position in both registers (this also
+        * masks out some freescale-specific bits in locations defined as
+        * reserved by sdhci), then shift the data line and retune request bits
+        * down to their standard locations.
+        */
+       if (off == SDHCI_PRESENT_STATE) {
+               wrk32 = val32;
+               val32 &= 0x000F0F07;
+               val32 |= (wrk32 >> 4) & SDHCI_STATE_DAT_MASK;
+               val32 |= (wrk32 >> 9) & SDHCI_RETUNE_REQUEST;
+               return (val32);
+       }
 
        /*
         * imx_sdhci_intr() can synthesize a DATA_END interrupt following a
         * command with an R1B response, mix it into the hardware status.
         */
        if (off == SDHCI_INT_STATUS) {
-               val32 |= sc->r1bfix_intmask;
+               return (val32 | sc->r1bfix_intmask);
        }
 
        return val32;
@@ -522,7 +558,7 @@ imx_sdhci_intr(void *arg)
                count = 0;
                /* XXX use a callout or something instead of busy-waiting. */
                while (count < 250000 && 
-                      (RD4(sc, SDHCI_PRESENT_STATE) & SDHCI_DAT_ACTIVE)) {
+                  (RD4(sc, SDHC_PRES_STATE) & SDHC_PRES_DLA)) {
                        ++count;
                        DELAY(1);
                }
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to