Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Oct 2019 01:30:37 +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-12@freebsd.org
Subject:   svn commit: r353675 - in stable/12/sys: arm/ti dev/sdhci
Message-ID:  <201910170130.x9H1Ubjq058118@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Thu Oct 17 01:30:37 2019
New Revision: 353675
URL: https://svnweb.freebsd.org/changeset/base/353675

Log:
  MFC r353651-r353652
  
  r353651:
  Relax the sdhci(4) check that filters out the 1.8v voltage option unless
  the slot is flagged as 'embedded'.
  
  The features related to embedded and shared slots were added in v3.0 of
  the sdhci spec.  Hardware prior to v3 sometimes supported 1.8v on non-
  removable devices in embedded systems, but had no way to indicate that
  via the standard sdhci registers (instead they use out of band metadata
  such as FDT data).
  
  This change adds the controller specification version to the check for
  whether to filter out the 1.8v selection.  On older hardware, the 1.8v
  option is allowed to remain.  On 3.0 or later it still requires the
  embedded-slot flag to remain.
  
  This is part of the fix for PR 241301 (eMMC not detected on Beaglebone).
  Changes to the sdhci_ti driver are also needed for a full fix.
  
  PR:		241301
  
  r353652:
  Revert r351218 (by manu).  While the changes in r351218 appear to be (and
  should be) correct, they lead to the eMMC on a Beaglebone failing to work
  in some situations.
  
  The TI sdhci hardware is kind of strange.  The first device inherently
  supports 1.8v and 3.3v and the abililty to switch between them, and the
  other two devices must be set to 1.8v in the sdhci power control register to
  operate correctly, but doing so actually makes them run at 3.3v (unless an
  external level-shifter is present in the signal path).  Even the 1.8v on the
  first device may actually be 3.3v (or any other value), depending on what
  voltage is fed to the VDDS1-VDDS7 power supply pins on the am335x chip.
  
  Another strange quirk is that the convention for am335x sdhci drivers in
  linux and uboot and the am335x boot ROM seems to be to set the voltage in
  the sdhci capabilities register to 3.0v even though the actual voltage is
  3.3v.  Why this is done is a complete mystery to me, but it seems to be
  required for correct operation.
  
  If we had complete modern support for the am335x chip we could get the
  actual voltages from the FDT data and the regulator framework.  But our
  am335x code currently doesn't have any regulator framework support.
  Reverting to the prior code will get the popular Beaglebone boards working
  again.
  
  This is part of the fix for PR 241301, but also requires r353651 for a
  complete fix.
  
  PR:		241301
  Discussed with: manu
  
  Approved by:	re(gjb) for MFC without 3-day wait

Modified:
  stable/12/sys/arm/ti/ti_sdhci.c
  stable/12/sys/dev/sdhci/sdhci.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/arm/ti/ti_sdhci.c
==============================================================================
--- stable/12/sys/arm/ti/ti_sdhci.c	Thu Oct 17 00:34:53 2019	(r353674)
+++ stable/12/sys/arm/ti/ti_sdhci.c	Thu Oct 17 01:30:37 2019	(r353675)
@@ -482,14 +482,15 @@ ti_sdhci_hw_init(device_t dev)
 	 * The attach() routine has examined fdt data and set flags in
 	 * slot.host.caps to reflect what voltages we can handle.  Set those
 	 * values in the CAPA register.  The manual says that these values can
-	 * only be set once, and that they survive a reset so unless u-boot didn't
-	 * set this register this code is a no-op.
+	 * only be set once, "before initialization" whatever that means, and
+	 * that they survive a reset.  So maybe doing this will be a no-op if
+	 * u-boot has already initialized the hardware.
 	 */
 	regval = ti_mmchs_read_4(sc, MMCHS_SD_CAPA);
 	if (sc->slot.host.caps & MMC_OCR_LOW_VOLTAGE)
 		regval |= MMCHS_SD_CAPA_VS18;
-	if (sc->slot.host.caps & (MMC_OCR_320_330 | MMC_OCR_330_340))
-		regval |= MMCHS_SD_CAPA_VS33;
+	if (sc->slot.host.caps & (MMC_OCR_290_300 | MMC_OCR_300_310))
+		regval |= MMCHS_SD_CAPA_VS30;
 	ti_mmchs_write_4(sc, MMCHS_SD_CAPA, regval);
 
 	/* Set initial host configuration (1-bit, std speed, pwr off). */
@@ -523,20 +524,17 @@ ti_sdhci_attach(device_t dev)
 	}
 
 	/*
-	 * The hardware can inherently do dual-voltage (1p8v, 3p3v) on the first
+	 * The hardware can inherently do dual-voltage (1p8v, 3p0v) on the first
 	 * device, and only 1p8v on other devices unless an external transceiver
 	 * is used.  The only way we could know about a transceiver is fdt data.
 	 * Note that we have to do this before calling ti_sdhci_hw_init() so
 	 * that it can set the right values in the CAPA register, which can only
 	 * be done once and never reset.
 	 */
-	if (OF_hasprop(node, "ti,dual-volt")) {
-		sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE | MMC_OCR_320_330 | MMC_OCR_330_340;
-	} else if (OF_hasprop(node, "no-1-8-v")) {
-		sc->slot.host.caps |= MMC_OCR_320_330 | MMC_OCR_330_340;
-	} else
-		sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE;
-
+	sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE;
+	if (sc->mmchs_clk_id == MMC1_CLK || OF_hasprop(node, "ti,dual-volt")) {
+		sc->slot.host.caps |= MMC_OCR_290_300 | MMC_OCR_300_310;
+	}
 
 	/*
 	 * Set the offset from the device's memory start to the MMCHS registers.

Modified: stable/12/sys/dev/sdhci/sdhci.c
==============================================================================
--- stable/12/sys/dev/sdhci/sdhci.c	Thu Oct 17 00:34:53 2019	(r353674)
+++ stable/12/sys/dev/sdhci/sdhci.c	Thu Oct 17 01:30:37 2019	(r353675)
@@ -902,8 +902,13 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot,
 	    slot->host.host_ocr |= MMC_OCR_320_330 | MMC_OCR_330_340;
 	if (caps & SDHCI_CAN_VDD_300)
 	    slot->host.host_ocr |= MMC_OCR_290_300 | MMC_OCR_300_310;
-	/* 1.8V VDD is not supposed to be used for removable cards. */
-	if ((caps & SDHCI_CAN_VDD_180) && (slot->opt & SDHCI_SLOT_EMBEDDED))
+	/*
+	 * 1.8V VDD is not supposed to be used for removable cards.  Hardware
+	 * prior to v3.0 had no way to indicate embedded slots, but did
+	 * sometimes support 1.8v for non-removable devices.
+	 */
+	if ((caps & SDHCI_CAN_VDD_180) && (slot->version < SDHCI_SPEC_300 ||
+	    (slot->opt & SDHCI_SLOT_EMBEDDED)))
 	    slot->host.host_ocr |= MMC_OCR_LOW_VOLTAGE;
 	if (slot->host.host_ocr == 0) {
 		slot_printf(slot, "Hardware doesn't report any "



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