Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Mar 2017 21:02:26 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r314510 - in stable/11/sys: arm/freescale/imx conf dev/sdhci powerpc/mpc85xx
Message-ID:  <201703012102.v21L2Q8F015094@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703012102.v21L2Q8F015094>