Author: ian
Date: Wed Mar  1 21:02:26 2017
New Revision: 314510
URL: https://svnweb.freebsd.org/changeset/base/314510

Log:
  MFC r308186, r308188, r308231, r308232:
  
    Move imx_sdhci driver over to a dev/sdhci in preparation for QorIQ support.
    Freescale uses eSDHC in both i.MX (ARM) and QorIQ (PowerPC), with slight
    differences.  This is part one in unifying the drivers.
  
    Merge i.MX and PowerPC SDHCI drivers
    Summary:
    i.MX5 and PowerPC use a very similar eSDHC controller, which is also
    similar to the uSDHC controller used by i.MX6.  The imx_sdhci driver works
    almost completely with PowerPC, with some minor tweaks.
  
    Fix the build.  protctl is only used on powerpc.
    While here, remove the need to check the SVR SPR, as others may be 
compatible
    with the p1022-esdhc type.
  
    Since it's no longer accessing a powerpc-specific register, drop the #ifdef.

Added:
  stable/11/sys/dev/sdhci/fsl_sdhci.c
     - copied, changed from r308186, head/sys/dev/sdhci/fsl_sdhci.c
Deleted:
  stable/11/sys/arm/freescale/imx/imx_sdhci.c
  stable/11/sys/powerpc/mpc85xx/fsl_sdhc.c
  stable/11/sys/powerpc/mpc85xx/fsl_sdhc.h
Modified:
  stable/11/sys/arm/freescale/imx/files.imx5
  stable/11/sys/arm/freescale/imx/files.imx6
  stable/11/sys/conf/files.powerpc
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/freescale/imx/files.imx5
==============================================================================
--- stable/11/sys/arm/freescale/imx/files.imx5  Wed Mar  1 20:23:21 2017        
(r314509)
+++ stable/11/sys/arm/freescale/imx/files.imx5  Wed Mar  1 21:02:26 2017        
(r314510)
@@ -32,7 +32,7 @@ arm/freescale/imx/imx51_ccm.c         standard
 dev/ata/chipsets/ata-fsl.c             optional imxata
 
 # SDHCI/MMC
-arm/freescale/imx/imx_sdhci.c          optional sdhci
+dev/sdhci/fsl_sdhci.c                  optional sdhci
 
 # USB OH3 controller (1 OTG, 3 EHCI)
 arm/freescale/imx/imx_nop_usbphy.c     optional ehci

Modified: stable/11/sys/arm/freescale/imx/files.imx6
==============================================================================
--- stable/11/sys/arm/freescale/imx/files.imx6  Wed Mar  1 20:23:21 2017        
(r314509)
+++ stable/11/sys/arm/freescale/imx/files.imx6  Wed Mar  1 21:02:26 2017        
(r314510)
@@ -32,7 +32,7 @@ arm/freescale/imx/imx6_ipu.c          optional        v
 #
 # Optional devices.
 #
-arm/freescale/imx/imx_sdhci.c          optional sdhci
+dev/sdhci/fsl_sdhci.c                  optional sdhci
 
 arm/freescale/imx/imx_wdog.c           optional imxwdt
 

Modified: stable/11/sys/conf/files.powerpc
==============================================================================
--- stable/11/sys/conf/files.powerpc    Wed Mar  1 20:23:21 2017        
(r314509)
+++ stable/11/sys/conf/files.powerpc    Wed Mar  1 21:02:26 2017        
(r314510)
@@ -63,6 +63,7 @@ dev/ofw/ofw_subr.c            optional        aim powerpc
 dev/powermac_nvram/powermac_nvram.c optional   powermac_nvram powermac
 dev/quicc/quicc_bfe_fdt.c      optional        quicc mpc85xx
 dev/scc/scc_bfe_macio.c                optional        scc powermac
+dev/sdhci/fsl_sdhci.c          optional        mpc85xx sdhci
 dev/sec/sec.c                  optional        sec mpc85xx
 dev/sound/macio/aoa.c          optional        snd_davbus | snd_ai2s powermac
 dev/sound/macio/davbus.c       optional        snd_davbus powermac
@@ -135,7 +136,6 @@ powerpc/mikrotik/platform_rb.c      optional        
 powerpc/mpc85xx/atpic.c                optional        mpc85xx isa
 powerpc/mpc85xx/ds1553_bus_fdt.c       optional        ds1553 fdt
 powerpc/mpc85xx/ds1553_core.c  optional        ds1553
-powerpc/mpc85xx/fsl_sdhc.c     optional        mpc85xx sdhc | qoriq_dpaa sdhc
 powerpc/mpc85xx/i2c.c          optional        iicbus fdt
 powerpc/mpc85xx/isa.c          optional        mpc85xx isa
 powerpc/mpc85xx/lbc.c          optional        mpc85xx | qoriq_dpaa

Copied and modified: stable/11/sys/dev/sdhci/fsl_sdhci.c (from r308186, 
head/sys/dev/sdhci/fsl_sdhci.c)
==============================================================================
--- head/sys/dev/sdhci/fsl_sdhci.c      Wed Nov  2 00:51:09 2016        
(r308186, copy source)
+++ stable/11/sys/dev/sdhci/fsl_sdhci.c Wed Mar  1 21:02:26 2017        
(r314510)
@@ -28,7 +28,7 @@
 __FBSDID("$FreeBSD$");
 
 /*
- * SDHCI driver glue for Freescale i.MX SoC family.
+ * SDHCI driver glue for Freescale i.MX SoC and QorIQ families.
  *
  * This supports both eSDHC (earlier SoCs) and uSDHC (more recent SoCs).
  */
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/bus.h>
 #include <sys/callout.h>
+#include <sys/endian.h>
 #include <sys/kernel.h>
 #include <sys/libkern.h>
 #include <sys/lock.h>
@@ -52,9 +53,11 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/bus.h>
 #include <machine/resource.h>
+#ifdef __arm__
 #include <machine/intr.h>
 
 #include <arm/freescale/imx/imx_ccmvar.h>
+#endif
 
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
@@ -146,7 +149,6 @@ struct fsl_sdhci_softc {
 #define         SDHC_PROT_CDSS         (1 << 7)
 
 #define        SDHC_SYS_CTRL           0x2c
-#define        SDHC_INT_STATUS         0x30
 
 /*
  * The clock enable bits exist in different registers for ESDHC vs USDHC, but
@@ -169,6 +171,7 @@ static struct ofw_compat_data compat_dat
        {"fsl,imx6sl-usdhc",    HWTYPE_USDHC},
        {"fsl,imx53-esdhc",     HWTYPE_ESDHC},
        {"fsl,imx51-esdhc",     HWTYPE_ESDHC},
+       {"fsl,esdhc",           HWTYPE_ESDHC},
        {NULL,                  HWTYPE_NONE},
 };
 
@@ -397,6 +400,11 @@ fsl_sdhci_write_1(device_t dev, struct s
        if (off == SDHCI_POWER_CONTROL) {
                return;
        }
+#ifdef __powerpc__
+       /* XXX Reset doesn't seem to work as expected.  Do nothing for now. */
+       if (off == SDHCI_SOFTWARE_RESET)
+               return;
+#endif
 
        val32 = RD4(sc, off & ~3);
        val32 &= ~(0xff << (off & 3) * 8);
@@ -531,17 +539,20 @@ fsl_sdhc_get_clock(struct fsl_sdhci_soft
            val |= SDHCI_CLOCK_INT_STABLE;
 
        /*
-        * On ESDHC hardware the card bus clock enable is in the usual sdhci
-        * register but it's a different bit, so transcribe it (note the
+        * On i.MX ESDHC hardware the card bus clock enable is in the usual
+        * sdhci register but it's a different bit, so transcribe it (note the
         * difference between standard SDHCI_ and Freescale SDHC_ prefixes
-        * here). On USDHC hardware there is a force-on bit, but no force-off
-        * for the card bus clock (the hardware runs the clock when transfers
-        * are active no matter what), so we always say the clock is on.
+        * here). On USDHC and QorIQ ESDHC hardware there is a force-on bit, but
+        * no force-off for the card bus clock (the hardware runs the clock when
+        * transfers are active no matter what), so we always say the clock is
+        * on.
         * XXX Maybe we should say it's in whatever state the sdhci driver last
         * set it to.
         */
        if (sc->hwtype == HWTYPE_ESDHC) {
+#ifdef __arm__
                if (RD4(sc, SDHC_SYS_CTRL) & SDHC_CLK_SDCLKEN)
+#endif
                        val |= SDHCI_CLOCK_CARD_EN;
        } else {
                val |= SDHCI_CLOCK_CARD_EN;
@@ -565,15 +576,18 @@ fsl_sdhc_set_clock(struct fsl_sdhci_soft
        sc->sdclockreg_freq_bits = val & SDHCI_DIVIDERS_MASK;
        if (sc->hwtype == HWTYPE_ESDHC) {
                /*
-                * The ESDHC hardware requires the driver to manually start and
-                * stop the sd bus clock.  If the enable bit is not set, turn
-                * off the clock in hardware and we're done, otherwise decode
-                * the requested frequency.  ESDHC hardware is sdhci 2.0; the
-                * sdhci driver will use the original 8-bit divisor field and
-                * the "base / 2^N" divisor scheme.
+                * The i.MX5 ESDHC hardware requires the driver to manually
+                * start and stop the sd bus clock.  If the enable bit is not
+                * set, turn off the clock in hardware and we're done, otherwise
+                * decode the requested frequency.  ESDHC hardware is sdhci 2.0;
+                * the sdhci driver will use the original 8-bit divisor field
+                * and the "base / 2^N" divisor scheme.
                 */
                if ((val & SDHCI_CLOCK_CARD_EN) == 0) {
+#ifdef __arm__
+                       /* On QorIQ, this is a reserved bit. */
                        WR4(sc, SDHCI_CLOCK_CONTROL, val32 & ~SDHC_CLK_SDCLKEN);
+#endif
                        return;
 
                }
@@ -625,6 +639,7 @@ fsl_sdhc_set_clock(struct fsl_sdhci_soft
        val32 &= ~(SDHC_CLK_DIVISOR_MASK | SDHC_CLK_PRESCALE_MASK);
        val32 |= divisor << SDHC_CLK_DIVISOR_SHIFT;
        val32 |= prescale << SDHC_CLK_PRESCALE_SHIFT;
+       val32 |= SDHC_CLK_IPGEN;
        WR4(sc, SDHCI_CLOCK_CONTROL, val32);
 }
 
@@ -710,10 +725,10 @@ fsl_sdhci_intr(void *arg)
         */
        switch (sc->r1bfix_type) {
        case R1BFIX_NODATA:
-               intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_RESPONSE;
+               intmask = RD4(sc, SDHCI_INT_STATUS) & SDHCI_INT_RESPONSE;
                break;
        case R1BFIX_AC12:
-               intmask = RD4(sc, SDHC_INT_STATUS) & SDHCI_INT_DATA_END;
+               intmask = RD4(sc, SDHCI_INT_STATUS) & SDHCI_INT_DATA_END;
                break;
        default:
                intmask = 0;
@@ -722,8 +737,8 @@ fsl_sdhci_intr(void *arg)
        if (intmask) {
                sc->r1bfix_timeout_at = getsbinuptime() + 250 * SBT_1MS;
                if (!fsl_sdhci_r1bfix_is_wait_done(sc)) {
-                       WR4(sc, SDHC_INT_STATUS, intmask);
-                       bus_barrier(sc->mem_res, SDHC_INT_STATUS, 4, 
+                       WR4(sc, SDHCI_INT_STATUS, intmask);
+                       bus_barrier(sc->mem_res, SDHCI_INT_STATUS, 4, 
                            BUS_SPACE_BARRIER_WRITE);
                }
        }
@@ -735,9 +750,53 @@ fsl_sdhci_intr(void *arg)
 static int
 fsl_sdhci_get_ro(device_t bus, device_t child)
 {
+       struct fsl_sdhci_softc *sc = device_get_softc(bus);
+
+       if (RD4(sc, SDHCI_PRESENT_STATE) & SDHC_PRES_WPSPL)
+               return (false);
+       return (true);
+}
+
+#ifdef __powerpc__
+static uint32_t
+fsl_sdhci_get_platform_clock(device_t dev)
+{
+       device_t parent;
+       phandle_t node;
+       uint32_t clock;
+
+       node = ofw_bus_get_node(dev);
 
-       return (false);
+       /* Get sdhci node properties */
+       if((OF_getprop(node, "clock-frequency", (void *)&clock,
+           sizeof(clock)) <= 0) || (clock == 0)) {
+
+               /*
+                * Trying to get clock from parent device (soc) if correct
+                * clock cannot be acquired from sdhci node.
+                */
+               parent = device_get_parent(dev);
+               node = ofw_bus_get_node(parent);
+
+               /* Get soc properties */
+               if ((OF_getprop(node, "bus-frequency", (void *)&clock,
+                   sizeof(clock)) <= 0) || (clock == 0)) {
+                       device_printf(dev,"Cannot acquire correct sdhci "
+                           "frequency from DTS.\n");
+
+                       return (0);
+               }
+               /* eSDHC clock is 1/2 platform clock. */
+               clock /= 2;
+       }
+
+       if (bootverbose)
+               device_printf(dev, "Acquired clock: %d from DTS\n", clock);
+
+       return (clock);
 }
+#endif
+
 
 static int
 fsl_sdhci_detach(device_t dev)
@@ -752,6 +811,9 @@ fsl_sdhci_attach(device_t dev)
        struct fsl_sdhci_softc *sc = device_get_softc(dev);
        int rid, err;
        phandle_t node;
+#ifdef __powerpc__
+       uint32_t protctl;
+#endif
 
        sc->dev = dev;
 
@@ -807,9 +869,21 @@ fsl_sdhci_attach(device_t dev)
         *
         * XXX need named constants for this stuff.
         */
-       WR4(sc, SDHC_WTMK_LVL, 0x08800880);
+       /* P1022 has the '*_BRST_LEN' fields as reserved, always reading 0x10 */
+       if (ofw_bus_is_compatible(dev, "fsl,p1022-esdhc"))
+               WR4(sc, SDHC_WTMK_LVL, 0x10801080);
+       else
+               WR4(sc, SDHC_WTMK_LVL, 0x08800880);
 
+       /*
+        * We read in native byte order in the main driver, but the register
+        * defaults to little endian.
+        */
+#ifdef __powerpc__
+       sc->baseclk_hz = fsl_sdhci_get_platform_clock(dev);
+#else
        sc->baseclk_hz = imx_ccm_sdhci_hz();
+#endif
        sc->slot.max_clk = sc->baseclk_hz;
 
        /*
@@ -830,6 +904,16 @@ fsl_sdhci_attach(device_t dev)
                /* XXX put real gpio hookup here. */
                sc->force_card_present = true;
        }
+#ifdef __powerpc__
+       /* Default to big-endian on powerpc */
+       protctl = RD4(sc, SDHC_PROT_CTRL);
+       protctl &= ~SDHC_PROT_EMODE_MASK;
+       if (OF_hasprop(node, "little-endian"))
+               protctl |= SDHC_PROT_EMODE_LITTLE;
+       else
+               protctl |= SDHC_PROT_EMODE_BIG;
+       WR4(sc, SDHC_PROT_CTRL, protctl);
+#endif
 
        callout_init(&sc->r1bfix_callout, 1);
        sdhci_init_slot(dev, &sc->slot, 0);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to