Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Jan 2017 23:26:10 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r312400 - in stable/10/sys/dev: mmc sdhci
Message-ID:  <201701182326.v0INQAO6095562@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Wed Jan 18 23:26:10 2017
New Revision: 312400
URL: https://svnweb.freebsd.org/changeset/base/312400

Log:
  MFC: r273180, r283754, r297329, r299414, r300707, r310309, r310340 (partial),
       r310341, r311664, r311793-311794
  
  o Use correct response bits for MMC_RSP_R4-R7 types
  
  o Make sdhci(4) work after suspend/resume for chipsets that require
    the frequency quirk. This makes it work on eg ThinkPad T420.
  
  o Add a convenience macro that masks all the bits related to clock divisors
    in all versions of the sdhci spec (the HI bits are just unused reserved
    bits in earlier versions).
  
  o sdhci/mmc: Minor whitespace cleanups
  
  o Add Braswell PCI IDs for Intel Cherryview
  
  o mmc: Accept even lower voltage for Cherryview
  
    And HP x2 210, per DragonFlyBSD 240bd9cd58f8259c12c14a8006837e698.
  
  o In mmcsd_task(), bio_resid was not being set to 0 on a successful read
    or write, resulting in random short-read and short-write returns for
    requests. Fixing this fixes nominal block I/O via mmcsd(4).
  
    Obtained from: DragonFlyBSD (fd4b97583be1a1e57234713c25f6e81bc0411cb0)
  
  o Add support for Intel Apollo Lake and Bay Trail eMMC PCI controllers.
  
  o Flesh out the support for Intel Braswell eMMC controllers further.
  
  o In sdhci_init_slot(), use the right capability field for determining
    the announced bus width based on MMC_CAP_*_BIT_DATA.

Modified:
  stable/10/sys/dev/mmc/mmc.c
  stable/10/sys/dev/mmc/mmcreg.h
  stable/10/sys/dev/mmc/mmcsd.c
  stable/10/sys/dev/sdhci/sdhci.c
  stable/10/sys/dev/sdhci/sdhci.h
  stable/10/sys/dev/sdhci/sdhci_pci.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/mmc/mmc.c
==============================================================================
--- stable/10/sys/dev/mmc/mmc.c	Wed Jan 18 23:25:46 2017	(r312399)
+++ stable/10/sys/dev/mmc/mmc.c	Wed Jan 18 23:26:10 2017	(r312400)
@@ -401,7 +401,7 @@ mmc_wait_for_req(struct mmc_softc *sc, s
 		msleep(req, &sc->sc_mtx, 0, "mmcreq", 0);
 	MMC_UNLOCK(sc);
 	if (mmc_debug > 2 || (mmc_debug > 0 && req->cmd->error != MMC_ERR_NONE))
-		device_printf(sc->dev, "CMD%d RESULT: %d\n", 
+		device_printf(sc->dev, "CMD%d RESULT: %d\n",
 		    req->cmd->opcode, req->cmd->error);
 	return (0);
 }
@@ -511,7 +511,7 @@ mmc_idle_cards(struct mmc_softc *sc)
 {
 	device_t dev;
 	struct mmc_command cmd;
-	
+
 	dev = sc->dev;
 	mmcbr_set_chip_select(dev, cs_high);
 	mmcbr_update_ios(dev);
@@ -795,7 +795,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
 		data.len = 8;
 		data.flags = MMC_DATA_WRITE;
 		mmc_wait_for_cmd(sc, &cmd, 0);
-		
+
 		memset(&cmd, 0, sizeof(cmd));
 		memset(&data, 0, sizeof(data));
 		cmd.opcode = MMC_BUSTEST_R;
@@ -808,7 +808,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
 		data.flags = MMC_DATA_READ;
 		err = mmc_wait_for_cmd(sc, &cmd, 0);
 		sc->squelched--;
-		
+
 		mmcbr_set_bus_width(sc->dev, bus_width_1);
 		mmcbr_update_ios(sc->dev);
 
@@ -832,7 +832,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
 		data.len = 4;
 		data.flags = MMC_DATA_WRITE;
 		mmc_wait_for_cmd(sc, &cmd, 0);
-		
+
 		memset(&cmd, 0, sizeof(cmd));
 		memset(&data, 0, sizeof(data));
 		cmd.opcode = MMC_BUSTEST_R;
@@ -1017,7 +1017,7 @@ mmc_decode_csd_sd(uint32_t *raw_csd, str
 		csd->r2w_factor = 1 << mmc_get_bits(raw_csd, 128, 26, 3);
 		csd->write_bl_len = 1 << mmc_get_bits(raw_csd, 128, 22, 4);
 		csd->write_bl_partial = mmc_get_bits(raw_csd, 128, 21, 1);
-	} else 
+	} else
 		panic("unknown SD CSD version");
 }
 
@@ -1349,9 +1349,9 @@ mmc_discover_cards(struct mmc_softc *sc)
 			if (ivar->csd.csd_structure > 0)
 				ivar->high_cap = 1;
 			ivar->tran_speed = ivar->csd.tran_speed;
-			ivar->erase_sector = ivar->csd.erase_sector * 
+			ivar->erase_sector = ivar->csd.erase_sector *
 			    ivar->csd.write_bl_len / MMC_SECTOR_SIZE;
-			
+
 			err = mmc_send_status(sc, ivar->rca, &status);
 			if (err != MMC_ERR_NONE) {
 				device_printf(sc->dev,
@@ -1446,7 +1446,7 @@ mmc_discover_cards(struct mmc_softc *sc)
 		mmc_decode_csd_mmc(ivar->raw_csd, &ivar->csd);
 		ivar->sec_count = ivar->csd.capacity / MMC_SECTOR_SIZE;
 		ivar->tran_speed = ivar->csd.tran_speed;
-		ivar->erase_sector = ivar->csd.erase_sector * 
+		ivar->erase_sector = ivar->csd.erase_sector *
 		    ivar->csd.write_bl_len / MMC_SECTOR_SIZE;
 
 		err = mmc_send_status(sc, ivar->rca, &status);
@@ -1655,7 +1655,7 @@ mmc_calculate_clock(struct mmc_softc *sc
 	int nkid, i, f_max;
 	device_t *kids;
 	struct mmc_ivars *ivar;
-	
+
 	f_max = mmcbr_get_f_max(sc->dev);
 	max_dtr = max_hs_dtr = f_max;
 	if ((mmcbr_get_caps(sc->dev) & MMC_CAP_HSPEED))
@@ -1770,7 +1770,7 @@ static void
 mmc_delayed_attach(void *xsc)
 {
 	struct mmc_softc *sc = xsc;
-	
+
 	mmc_scan(sc);
 	config_intrhook_disestablish(&sc->config_intrhook);
 }

Modified: stable/10/sys/dev/mmc/mmcreg.h
==============================================================================
--- stable/10/sys/dev/mmc/mmcreg.h	Wed Jan 18 23:25:46 2017	(r312399)
+++ stable/10/sys/dev/mmc/mmcreg.h	Wed Jan 18 23:26:10 2017	(r312400)
@@ -85,8 +85,11 @@ struct mmc_command {
 #define	MMC_RSP_R1B	(MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY)
 #define	MMC_RSP_R2	(MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC)
 #define	MMC_RSP_R3	(MMC_RSP_PRESENT)
-#define	MMC_RSP_R6	(MMC_RSP_PRESENT | MMC_RSP_CRC)
-#define	MMC_RSP_R7	(MMC_RSP_PRESENT | MMC_RSP_CRC)
+#define	MMC_RSP_R4	(MMC_RSP_PRESENT)
+#define	MMC_RSP_R5	(MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
+#define	MMC_RSP_R5B	(MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY)
+#define	MMC_RSP_R6	(MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
+#define	MMC_RSP_R7	(MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
 #define	MMC_RSP(x)	((x) & MMC_RSP_MASK)
 	uint32_t	retries;
 	uint32_t	error;
@@ -352,8 +355,8 @@ struct mmc_request {
  */
 #define	MMC_OCR_VOLTAGE	0x3fffffffU	/* Vdd Voltage mask */
 #define	MMC_OCR_LOW_VOLTAGE (1u << 7)	/* Low Voltage Range -- tbd */
+#define	MMC_OCR_MIN_VOLTAGE_SHIFT	7
 #define	MMC_OCR_200_210	(1U << 8)	/* Vdd voltage 2.00 ~ 2.10 */
-#define	MMC_OCR_MIN_VOLTAGE_SHIFT	8
 #define	MMC_OCR_210_220	(1U << 9)	/* Vdd voltage 2.10 ~ 2.20 */
 #define	MMC_OCR_220_230	(1U << 10)	/* Vdd voltage 2.20 ~ 2.30 */
 #define	MMC_OCR_230_240	(1U << 11)	/* Vdd voltage 2.30 ~ 2.40 */

Modified: stable/10/sys/dev/mmc/mmcsd.c
==============================================================================
--- stable/10/sys/dev/mmc/mmcsd.c	Wed Jan 18 23:25:46 2017	(r312399)
+++ stable/10/sys/dev/mmc/mmcsd.c	Wed Jan 18 23:26:10 2017	(r312400)
@@ -160,14 +160,13 @@ mmcsd_attach(device_t dev)
 	d->d_dump = mmcsd_dump;
 	d->d_name = "mmcsd";
 	d->d_drv1 = sc;
-	d->d_maxsize = 4*1024*1024;	/* Maximum defined SD card AU size. */
 	d->d_sectorsize = mmc_get_sector_size(dev);
+	d->d_maxsize = mmc_get_max_data(dev) * d->d_sectorsize;
 	d->d_mediasize = (off_t)mmc_get_media_size(dev) * d->d_sectorsize;
-	d->d_stripeoffset = 0;
 	d->d_stripesize = mmc_get_erase_sector(dev) * d->d_sectorsize;
 	d->d_unit = device_get_unit(dev);
 	d->d_flags = DISKFLAG_CANDELETE;
-	d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize * 1; /* conservative */
+	d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize;
 	strlcpy(d->d_ident, mmc_get_card_sn_string(dev), sizeof(d->d_ident));
 	strlcpy(d->d_descr, mmc_get_card_id_string(dev), sizeof(d->d_descr));
 
@@ -545,6 +544,8 @@ mmcsd_task(void *arg)
 			bp->bio_error = EIO;
 			bp->bio_resid = (end - block) * sz;
 			bp->bio_flags |= BIO_ERROR;
+		} else {
+			bp->bio_resid = 0;
 		}
 		biodone(bp);
 	}

Modified: stable/10/sys/dev/sdhci/sdhci.c
==============================================================================
--- stable/10/sys/dev/sdhci/sdhci.c	Wed Jan 18 23:25:46 2017	(r312399)
+++ stable/10/sys/dev/sdhci/sdhci.c	Wed Jan 18 23:26:10 2017	(r312400)
@@ -377,6 +377,13 @@ sdhci_set_power(struct sdhci_slot *slot,
 	/* Turn on the power. */
 	pwr |= SDHCI_POWER_ON;
 	WR1(slot, SDHCI_POWER_CONTROL, pwr);
+
+	if (slot->quirks & SDHCI_QUIRK_INTEL_POWER_UP_RESET) {
+		WR1(slot, SDHCI_POWER_CONTROL, pwr | 0x10);
+		DELAY(10);
+		WR1(slot, SDHCI_POWER_CONTROL, pwr);
+		DELAY(300);
+	}
 }
 
 static void
@@ -630,9 +637,11 @@ sdhci_init_slot(device_t dev, struct sdh
 		device_printf(dev, "Hardware doesn't specify base clock "
 		    "frequency, using %dMHz as default.\n", SDHCI_DEFAULT_MAX_FREQ);
 	}
-	/* Calculate timeout clock frequency. */
+	/* Calculate/set timeout clock frequency. */
 	if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) {
 		slot->timeout_clk = slot->max_clk / 1000;
+	} else if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_1MHZ) {
+		slot->timeout_clk = 1000;
 	} else {
 		slot->timeout_clk =
 			(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
@@ -676,6 +685,8 @@ sdhci_init_slot(device_t dev, struct sdh
 		slot->opt &= ~SDHCI_HAVE_DMA;
 	if (slot->quirks & SDHCI_QUIRK_FORCE_DMA)
 		slot->opt |= SDHCI_HAVE_DMA;
+	if (slot->quirks & SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE)
+		slot->opt |= SDHCI_NON_REMOVABLE;
 
 	/* 
 	 * Use platform-provided transfer backend
@@ -688,8 +699,9 @@ sdhci_init_slot(device_t dev, struct sdh
 		slot_printf(slot, "%uMHz%s %s%s%s%s %s\n",
 		    slot->max_clk / 1000000,
 		    (caps & SDHCI_CAN_DO_HISPD) ? " HS" : "",
-		    (caps & MMC_CAP_8_BIT_DATA) ? "8bits" :
-			((caps & MMC_CAP_4_BIT_DATA) ? "4bits" : "1bit"),
+		    (slot->host.caps & MMC_CAP_8_BIT_DATA) ? "8bits" :
+			((slot->host.caps & MMC_CAP_4_BIT_DATA) ? "4bits" :
+			"1bit"),
 		    (caps & SDHCI_CAN_VDD_330) ? " 3.3V" : "",
 		    (caps & SDHCI_CAN_VDD_300) ? " 3.0V" : "",
 		    (caps & SDHCI_CAN_VDD_180) ? " 1.8V" : "",

Modified: stable/10/sys/dev/sdhci/sdhci.h
==============================================================================
--- stable/10/sys/dev/sdhci/sdhci.h	Wed Jan 18 23:25:46 2017	(r312399)
+++ stable/10/sys/dev/sdhci/sdhci.h	Wed Jan 18 23:26:10 2017	(r312400)
@@ -66,7 +66,13 @@
 /* Alternate clock source is required when supplying a 400 KHz clock. */
 #define	SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC		(1<<16)
 /* Card insert/remove interrupts don't work, polling required. */
-#define SDHCI_QUIRK_POLL_CARD_PRESENT				(1<<17)
+#define	SDHCI_QUIRK_POLL_CARD_PRESENT			(1<<17)
+/* All controller slots are non-removable. */
+#define	SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE		(1<<18)
+/* Issue custom Intel controller reset sequence after power-up. */
+#define	SDHCI_QUIRK_INTEL_POWER_UP_RESET		(1<<19)
+/* Data timeout is invalid, use 1 MHz clock instead. */
+#define	SDHCI_QUIRK_DATA_TIMEOUT_1MHZ			(1<<20)
 
 /*
  * Controller registers
@@ -155,6 +161,9 @@
 #define  SDHCI_CLOCK_CARD_EN	0x0004
 #define  SDHCI_CLOCK_INT_STABLE	0x0002
 #define  SDHCI_CLOCK_INT_EN	0x0001
+#define  SDHCI_DIVIDERS_MASK	\
+    ((SDHCI_DIVIDER_MASK << SDHCI_DIVIDER_SHIFT) | \
+    (SDHCI_DIVIDER_HI_MASK << SDHCI_DIVIDER_HI_SHIFT))
 
 #define SDHCI_TIMEOUT_CONTROL	0x2E
 

Modified: stable/10/sys/dev/sdhci/sdhci_pci.c
==============================================================================
--- stable/10/sys/dev/sdhci/sdhci_pci.c	Wed Jan 18 23:25:46 2017	(r312399)
+++ stable/10/sys/dev/sdhci/sdhci_pci.c	Wed Jan 18 23:26:10 2017	(r312400)
@@ -63,15 +63,15 @@ __FBSDID("$FreeBSD$");
 #define PCI_SDHCI_IFVENDOR		0x02
 
 #define PCI_SLOT_INFO			0x40	/* 8 bits */
-#define  PCI_SLOT_INFO_SLOTS(x)		(((x >> 4) & 7) + 1)
-#define  PCI_SLOT_INFO_FIRST_BAR(x)	((x) & 7)
+#define PCI_SLOT_INFO_SLOTS(x)		(((x >> 4) & 7) + 1)
+#define PCI_SLOT_INFO_FIRST_BAR(x)	((x) & 7)
 
 /*
  * RICOH specific PCI registers
  */
 #define	SDHC_PCI_MODE_KEY		0xf9
 #define	SDHC_PCI_MODE			0x150
-#define	 SDHC_PCI_MODE_SD20		0x10
+#define	SDHC_PCI_MODE_SD20		0x10
 #define	SDHC_PCI_BASE_FREQ_KEY		0xfc
 #define	SDHC_PCI_BASE_FREQ		0xe1
 
@@ -107,6 +107,19 @@ static const struct sdhci_device {
 	    SDHCI_QUIRK_RESET_AFTER_REQUEST },
 	{ 0x16bc14e4,	0xffff,	"Broadcom BCM577xx SDXC/MMC Card Reader",
 	    SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC },
+	{ 0x0f148086,	0xffff,	"Intel Bay Trail eMMC 4.5 Controller",
+	    SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
+	    SDHCI_QUIRK_INTEL_POWER_UP_RESET },
+	{ 0x0f508086,	0xffff,	"Intel Bay Trail eMMC 4.5 Controller",
+	    SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
+	    SDHCI_QUIRK_INTEL_POWER_UP_RESET },
+	{ 0x22948086,	0xffff,	"Intel Braswell eMMC 4.5.1 Controller",
+	    SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
+	    SDHCI_QUIRK_DATA_TIMEOUT_1MHZ |
+	    SDHCI_QUIRK_INTEL_POWER_UP_RESET },
+	{ 0x5acc8086,	0xffff,	"Intel Apollo Lake eMMC 5.0 Controller",
+	    SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
+	    SDHCI_QUIRK_INTEL_POWER_UP_RESET },
 	{ 0,		0xffff,	NULL,
 	    0 }
 };
@@ -119,8 +132,8 @@ struct sdhci_pci_softc {
 	int		num_slots;	/* Number of slots on this controller */
 	struct sdhci_slot slots[6];
 	struct resource	*mem_res[6];	/* Memory resource */
-	uint8_t		cfg_freq;	/* Saved mode */
-	uint8_t		cfg_mode;	/* Saved frequency */
+	uint8_t		cfg_freq;	/* Saved frequency */
+	uint8_t		cfg_mode;	/* Saved mode */
 };
 
 static int sdhci_enable_msi = 1;
@@ -413,11 +426,16 @@ static int
 sdhci_pci_resume(device_t dev)
 {
 	struct sdhci_pci_softc *sc = device_get_softc(dev);
-	int i;
+	int i, err;
 
 	for (i = 0; i < sc->num_slots; i++)
 		sdhci_generic_resume(&sc->slots[i]);
-	return (bus_generic_resume(dev));
+	err = bus_generic_resume(dev);
+	if (err)
+		return (err);
+	if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY)
+		sdhci_lower_frequency(dev);
+	return (0);
 }
 
 static void
@@ -446,11 +464,11 @@ static device_method_t sdhci_methods[] =
 	DEVMETHOD(bus_write_ivar,	sdhci_generic_write_ivar),
 
 	/* mmcbr_if */
-	DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios),
-	DEVMETHOD(mmcbr_request, sdhci_generic_request),
-	DEVMETHOD(mmcbr_get_ro, sdhci_generic_get_ro),
-	DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
-	DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
+	DEVMETHOD(mmcbr_update_ios,     sdhci_generic_update_ios),
+	DEVMETHOD(mmcbr_request,        sdhci_generic_request),
+	DEVMETHOD(mmcbr_get_ro,         sdhci_generic_get_ro),
+	DEVMETHOD(mmcbr_acquire_host,   sdhci_generic_acquire_host),
+	DEVMETHOD(mmcbr_release_host,   sdhci_generic_release_host),
 
 	/* SDHCI registers accessors */
 	DEVMETHOD(sdhci_read_1,		sdhci_pci_read_1),



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