freebsd-dev/sys/dev/sdhci/sdhci_pci.c

534 lines
16 KiB
C
Raw Normal View History

/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2008 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_mmccam.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <dev/mmc/bridge.h>
#include <dev/sdhci/sdhci.h>
#include "mmcbr_if.h"
#include "sdhci_if.h"
/*
* PCI registers
*/
#define PCI_SDHCI_IFPIO 0x00
#define PCI_SDHCI_IFDMA 0x01
#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)
/*
* RICOH specific PCI registers
*/
#define SDHC_PCI_MODE_KEY 0xf9
#define SDHC_PCI_MODE 0x150
#define SDHC_PCI_MODE_SD20 0x10
#define SDHC_PCI_BASE_FREQ_KEY 0xfc
#define SDHC_PCI_BASE_FREQ 0xe1
static const struct sdhci_device {
uint32_t model;
uint16_t subvendor;
const char *desc;
u_int quirks;
} sdhci_devices[] = {
{ 0x08221180, 0xffff, "RICOH R5C822 SD",
SDHCI_QUIRK_FORCE_DMA },
{ 0xe8221180, 0xffff, "RICOH R5CE822 SD",
SDHCI_QUIRK_FORCE_DMA |
SDHCI_QUIRK_LOWER_FREQUENCY },
{ 0xe8231180, 0xffff, "RICOH R5CE823 SD",
SDHCI_QUIRK_LOWER_FREQUENCY },
{ 0x8034104c, 0xffff, "TI XX21/XX11 SD",
SDHCI_QUIRK_FORCE_DMA },
{ 0x05501524, 0xffff, "ENE CB712 SD",
SDHCI_QUIRK_BROKEN_TIMINGS },
{ 0x05511524, 0xffff, "ENE CB712 SD 2",
SDHCI_QUIRK_BROKEN_TIMINGS },
{ 0x07501524, 0xffff, "ENE CB714 SD",
SDHCI_QUIRK_RESET_ON_IOS |
SDHCI_QUIRK_BROKEN_TIMINGS },
{ 0x07511524, 0xffff, "ENE CB714 SD 2",
SDHCI_QUIRK_RESET_ON_IOS |
SDHCI_QUIRK_BROKEN_TIMINGS },
{ 0x410111ab, 0xffff, "Marvell CaFe SD",
SDHCI_QUIRK_INCR_TIMEOUT_CONTROL },
{ 0x2381197B, 0xffff, "JMicron JMB38X SD",
SDHCI_QUIRK_32BIT_DMA_SIZE |
SDHCI_QUIRK_RESET_AFTER_REQUEST },
Add support for the BCM57765 card reader. This patch adds support for the BCM57765[2] card reader function included in Broadcom's BCM57766 ethernet/sd3.0 controller. This controller is commonly found in laptops and Apple hardware (MBP, iMac, etc). The BCM57765 chipset is almost fully compatible with the SD3.0 spec, but does not support deriving a frequency below 781KHz from its default base clock via the standard SD3.0-configured 10-bit clock divisor. If such a divisor is set, card identification (which requires a 400KHz clock frequency) will time out[1]. As a work-around, I've made use of an undocumented device-specific clock control register to switch the controller to a 63MHz clock source when targeting clock speeds below 781KHz; the clock source is likewise switched back to the 200MHz clock when targeting speeds greater than 781KHz. Additionally, this patch fixes a small sdhci_pci bug; the sdhci_pci_softc->quirks flag was not copied to the sdhci_slot, resulting in `quirk` behavior not being applied by sdhci.c. [1] A number of Linux/FreeBSD users have noted that bringing up the chipsets' associated ethernet interface will allow SD cards to enumerate (slowly). This is a controller implementation side-effect triggered by the ethernet driver's reading of the hardware statistics registers. [2] This may also fix card detection when using the BCM57785 chipset, but I don't have access to the BCM57785 chipset and can't verify. I actually snagged some BCM57785 hardware recently (2012 Retina MacBook Pro) and can confirm that this also fixes card enumeration with the BCM57785 chipset; with the patch, I can boot off of the internal sdcard reader. PR: kern/203385 Submitted by: Landon Fuller <landon@landonf.org>
2015-10-15 04:22:56 +00:00
{ 0x16bc14e4, 0xffff, "Broadcom BCM577xx SDXC/MMC Card Reader",
SDHCI_QUIRK_BCM577XX_400KHZ_CLKSRC },
{ 0x0f148086, 0xffff, "Intel Bay Trail eMMC 4.5 Controller",
/* DDR52 is supported but affected by the VLI54 erratum */
- Add support for eMMC "partitions". Besides the user data area, i. e. the default partition, eMMC v4.41 and later devices can additionally provide up to: 1 enhanced user data area partition 2 boot partitions 1 RPMB (Replay Protected Memory Block) partition 4 general purpose partitions (optionally with a enhanced or extended attribute) Of these "partitions", only the enhanced user data area one actually slices the user data area partition and, thus, gets handled with the help of geom_flashmap(4). The other types of partitions have address space independent from the default partition and need to be switched to via CMD6 (SWITCH), i. e. constitute a set of additional "disks". The second kind of these "partitions" doesn't fit that well into the design of mmc(4) and mmcsd(4). I've decided to let mmcsd(4) hook all of these "partitions" up as disk(9)'s (except for the RPMB partition as it didn't seem to make much sense to be able to put a file-system there and may require authentication; therefore, RPMB partitions are solely accessible via the newly added IOCTL interface currently; see also below). This approach for one resulted in cleaner code. Second, it retains the notion of mmcsd(4) children corresponding to a single physical device each. With the addition of some layering violations, it also would have been possible for mmc(4) to add separate mmcsd(4) instances with one disk each for all of these "partitions", however. Still, both mmc(4) and mmcsd(4) share some common code now e. g. for issuing CMD6, which has been factored out into mmc_subr.c. Besides simply subdividing eMMC devices, some Intel NUCs having UEFI code in the boot partitions etc., another use case for the partition support is the activation of pseudo-SLC mode, which manufacturers of eMMC chips typically associate with the enhanced user data area and/ or the enhanced attribute of general purpose partitions. CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation. - Now that properly issuing CMD6 is crucial (so data isn't written to the wrong partition for example), make a step into the direction of correctly handling the timeout for these commands in the MMC layer. Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as recommended by relevant specifications. However, quite some work is left to be done in this regard; all other R1B-type commands done by the MMC layer also should be followed by a SEND_STATUS (CMD13), the erase timeout calculations/handling as documented in specifications are entirely ignored so far, the MMC layer doesn't provide timeouts applicable up to the bridge drivers and at least sdhci(4) currently is hardcoding 1 s as timeout for all command types unconditionally. Let alone already available return codes often not being checked in the MMC layer ... - Add an IOCTL interface to mmcsd(4); this is sufficiently compatible with Linux so that the GNU mmc-utils can be ported to and used with FreeBSD (note that due to the remaining deficiencies outlined above SANITIZE operations issued by/with `mmc` currently most likely will fail). These latter will be added to ports as sysutils/mmc-utils in a bit. Among others, the `mmc` tool of the GNU mmc-utils allows for partitioning eMMC devices (tested working). - For devices following the eMMC specification v4.41 or later, year 0 is 2013 rather than 1997; so correct this for assembling the device ID string properly. - Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at least for some of the above a matching pair is required. - In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC controllers as such in order to match the PCI one. Additionally, in the entry for the 80860F14 SDXC controller remove the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET. OKed by: imp Submitted by: ian (mmc_switch_status() implementation)
2017-03-16 22:23:04 +00:00
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 |
SDHCI_QUIRK_PRESET_VALUE_BROKEN},
- Add support for eMMC "partitions". Besides the user data area, i. e. the default partition, eMMC v4.41 and later devices can additionally provide up to: 1 enhanced user data area partition 2 boot partitions 1 RPMB (Replay Protected Memory Block) partition 4 general purpose partitions (optionally with a enhanced or extended attribute) Of these "partitions", only the enhanced user data area one actually slices the user data area partition and, thus, gets handled with the help of geom_flashmap(4). The other types of partitions have address space independent from the default partition and need to be switched to via CMD6 (SWITCH), i. e. constitute a set of additional "disks". The second kind of these "partitions" doesn't fit that well into the design of mmc(4) and mmcsd(4). I've decided to let mmcsd(4) hook all of these "partitions" up as disk(9)'s (except for the RPMB partition as it didn't seem to make much sense to be able to put a file-system there and may require authentication; therefore, RPMB partitions are solely accessible via the newly added IOCTL interface currently; see also below). This approach for one resulted in cleaner code. Second, it retains the notion of mmcsd(4) children corresponding to a single physical device each. With the addition of some layering violations, it also would have been possible for mmc(4) to add separate mmcsd(4) instances with one disk each for all of these "partitions", however. Still, both mmc(4) and mmcsd(4) share some common code now e. g. for issuing CMD6, which has been factored out into mmc_subr.c. Besides simply subdividing eMMC devices, some Intel NUCs having UEFI code in the boot partitions etc., another use case for the partition support is the activation of pseudo-SLC mode, which manufacturers of eMMC chips typically associate with the enhanced user data area and/ or the enhanced attribute of general purpose partitions. CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation. - Now that properly issuing CMD6 is crucial (so data isn't written to the wrong partition for example), make a step into the direction of correctly handling the timeout for these commands in the MMC layer. Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as recommended by relevant specifications. However, quite some work is left to be done in this regard; all other R1B-type commands done by the MMC layer also should be followed by a SEND_STATUS (CMD13), the erase timeout calculations/handling as documented in specifications are entirely ignored so far, the MMC layer doesn't provide timeouts applicable up to the bridge drivers and at least sdhci(4) currently is hardcoding 1 s as timeout for all command types unconditionally. Let alone already available return codes often not being checked in the MMC layer ... - Add an IOCTL interface to mmcsd(4); this is sufficiently compatible with Linux so that the GNU mmc-utils can be ported to and used with FreeBSD (note that due to the remaining deficiencies outlined above SANITIZE operations issued by/with `mmc` currently most likely will fail). These latter will be added to ports as sysutils/mmc-utils in a bit. Among others, the `mmc` tool of the GNU mmc-utils allows for partitioning eMMC devices (tested working). - For devices following the eMMC specification v4.41 or later, year 0 is 2013 rather than 1997; so correct this for assembling the device ID string properly. - Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at least for some of the above a matching pair is required. - In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC controllers as such in order to match the PCI one. Additionally, in the entry for the 80860F14 SDXC controller remove the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET. OKed by: imp Submitted by: ian (mmc_switch_status() implementation)
2017-03-16 22:23:04 +00:00
{ 0x0f158086, 0xffff, "Intel Bay Trail SDXC Controller",
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ 0x0f508086, 0xffff, "Intel Bay Trail eMMC 4.5 Controller",
/* DDR52 is supported but affected by the VLI54 erratum */
- Add support for eMMC "partitions". Besides the user data area, i. e. the default partition, eMMC v4.41 and later devices can additionally provide up to: 1 enhanced user data area partition 2 boot partitions 1 RPMB (Replay Protected Memory Block) partition 4 general purpose partitions (optionally with a enhanced or extended attribute) Of these "partitions", only the enhanced user data area one actually slices the user data area partition and, thus, gets handled with the help of geom_flashmap(4). The other types of partitions have address space independent from the default partition and need to be switched to via CMD6 (SWITCH), i. e. constitute a set of additional "disks". The second kind of these "partitions" doesn't fit that well into the design of mmc(4) and mmcsd(4). I've decided to let mmcsd(4) hook all of these "partitions" up as disk(9)'s (except for the RPMB partition as it didn't seem to make much sense to be able to put a file-system there and may require authentication; therefore, RPMB partitions are solely accessible via the newly added IOCTL interface currently; see also below). This approach for one resulted in cleaner code. Second, it retains the notion of mmcsd(4) children corresponding to a single physical device each. With the addition of some layering violations, it also would have been possible for mmc(4) to add separate mmcsd(4) instances with one disk each for all of these "partitions", however. Still, both mmc(4) and mmcsd(4) share some common code now e. g. for issuing CMD6, which has been factored out into mmc_subr.c. Besides simply subdividing eMMC devices, some Intel NUCs having UEFI code in the boot partitions etc., another use case for the partition support is the activation of pseudo-SLC mode, which manufacturers of eMMC chips typically associate with the enhanced user data area and/ or the enhanced attribute of general purpose partitions. CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation. - Now that properly issuing CMD6 is crucial (so data isn't written to the wrong partition for example), make a step into the direction of correctly handling the timeout for these commands in the MMC layer. Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as recommended by relevant specifications. However, quite some work is left to be done in this regard; all other R1B-type commands done by the MMC layer also should be followed by a SEND_STATUS (CMD13), the erase timeout calculations/handling as documented in specifications are entirely ignored so far, the MMC layer doesn't provide timeouts applicable up to the bridge drivers and at least sdhci(4) currently is hardcoding 1 s as timeout for all command types unconditionally. Let alone already available return codes often not being checked in the MMC layer ... - Add an IOCTL interface to mmcsd(4); this is sufficiently compatible with Linux so that the GNU mmc-utils can be ported to and used with FreeBSD (note that due to the remaining deficiencies outlined above SANITIZE operations issued by/with `mmc` currently most likely will fail). These latter will be added to ports as sysutils/mmc-utils in a bit. Among others, the `mmc` tool of the GNU mmc-utils allows for partitioning eMMC devices (tested working). - For devices following the eMMC specification v4.41 or later, year 0 is 2013 rather than 1997; so correct this for assembling the device ID string properly. - Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at least for some of the above a matching pair is required. - In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC controllers as such in order to match the PCI one. Additionally, in the entry for the 80860F14 SDXC controller remove the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET. OKed by: imp Submitted by: ian (mmc_switch_status() implementation)
2017-03-16 22:23:04 +00:00
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ 0x19db8086, 0xffff, "Intel Denverton eMMC 5.0 Controller",
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_MMC_DDR52 |
SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ 0x22948086, 0xffff, "Intel Braswell eMMC 4.5.1 Controller",
SDHCI_QUIRK_DATA_TIMEOUT_1MHZ |
- Add support for eMMC "partitions". Besides the user data area, i. e. the default partition, eMMC v4.41 and later devices can additionally provide up to: 1 enhanced user data area partition 2 boot partitions 1 RPMB (Replay Protected Memory Block) partition 4 general purpose partitions (optionally with a enhanced or extended attribute) Of these "partitions", only the enhanced user data area one actually slices the user data area partition and, thus, gets handled with the help of geom_flashmap(4). The other types of partitions have address space independent from the default partition and need to be switched to via CMD6 (SWITCH), i. e. constitute a set of additional "disks". The second kind of these "partitions" doesn't fit that well into the design of mmc(4) and mmcsd(4). I've decided to let mmcsd(4) hook all of these "partitions" up as disk(9)'s (except for the RPMB partition as it didn't seem to make much sense to be able to put a file-system there and may require authentication; therefore, RPMB partitions are solely accessible via the newly added IOCTL interface currently; see also below). This approach for one resulted in cleaner code. Second, it retains the notion of mmcsd(4) children corresponding to a single physical device each. With the addition of some layering violations, it also would have been possible for mmc(4) to add separate mmcsd(4) instances with one disk each for all of these "partitions", however. Still, both mmc(4) and mmcsd(4) share some common code now e. g. for issuing CMD6, which has been factored out into mmc_subr.c. Besides simply subdividing eMMC devices, some Intel NUCs having UEFI code in the boot partitions etc., another use case for the partition support is the activation of pseudo-SLC mode, which manufacturers of eMMC chips typically associate with the enhanced user data area and/ or the enhanced attribute of general purpose partitions. CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation. - Now that properly issuing CMD6 is crucial (so data isn't written to the wrong partition for example), make a step into the direction of correctly handling the timeout for these commands in the MMC layer. Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as recommended by relevant specifications. However, quite some work is left to be done in this regard; all other R1B-type commands done by the MMC layer also should be followed by a SEND_STATUS (CMD13), the erase timeout calculations/handling as documented in specifications are entirely ignored so far, the MMC layer doesn't provide timeouts applicable up to the bridge drivers and at least sdhci(4) currently is hardcoding 1 s as timeout for all command types unconditionally. Let alone already available return codes often not being checked in the MMC layer ... - Add an IOCTL interface to mmcsd(4); this is sufficiently compatible with Linux so that the GNU mmc-utils can be ported to and used with FreeBSD (note that due to the remaining deficiencies outlined above SANITIZE operations issued by/with `mmc` currently most likely will fail). These latter will be added to ports as sysutils/mmc-utils in a bit. Among others, the `mmc` tool of the GNU mmc-utils allows for partitioning eMMC devices (tested working). - For devices following the eMMC specification v4.41 or later, year 0 is 2013 rather than 1997; so correct this for assembling the device ID string properly. - Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at least for some of the above a matching pair is required. - In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC controllers as such in order to match the PCI one. Additionally, in the entry for the 80860F14 SDXC controller remove the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET. OKed by: imp Submitted by: ian (mmc_switch_status() implementation)
2017-03-16 22:23:04 +00:00
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_MMC_DDR52 |
SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
- Add support for eMMC "partitions". Besides the user data area, i. e. the default partition, eMMC v4.41 and later devices can additionally provide up to: 1 enhanced user data area partition 2 boot partitions 1 RPMB (Replay Protected Memory Block) partition 4 general purpose partitions (optionally with a enhanced or extended attribute) Of these "partitions", only the enhanced user data area one actually slices the user data area partition and, thus, gets handled with the help of geom_flashmap(4). The other types of partitions have address space independent from the default partition and need to be switched to via CMD6 (SWITCH), i. e. constitute a set of additional "disks". The second kind of these "partitions" doesn't fit that well into the design of mmc(4) and mmcsd(4). I've decided to let mmcsd(4) hook all of these "partitions" up as disk(9)'s (except for the RPMB partition as it didn't seem to make much sense to be able to put a file-system there and may require authentication; therefore, RPMB partitions are solely accessible via the newly added IOCTL interface currently; see also below). This approach for one resulted in cleaner code. Second, it retains the notion of mmcsd(4) children corresponding to a single physical device each. With the addition of some layering violations, it also would have been possible for mmc(4) to add separate mmcsd(4) instances with one disk each for all of these "partitions", however. Still, both mmc(4) and mmcsd(4) share some common code now e. g. for issuing CMD6, which has been factored out into mmc_subr.c. Besides simply subdividing eMMC devices, some Intel NUCs having UEFI code in the boot partitions etc., another use case for the partition support is the activation of pseudo-SLC mode, which manufacturers of eMMC chips typically associate with the enhanced user data area and/ or the enhanced attribute of general purpose partitions. CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation. - Now that properly issuing CMD6 is crucial (so data isn't written to the wrong partition for example), make a step into the direction of correctly handling the timeout for these commands in the MMC layer. Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as recommended by relevant specifications. However, quite some work is left to be done in this regard; all other R1B-type commands done by the MMC layer also should be followed by a SEND_STATUS (CMD13), the erase timeout calculations/handling as documented in specifications are entirely ignored so far, the MMC layer doesn't provide timeouts applicable up to the bridge drivers and at least sdhci(4) currently is hardcoding 1 s as timeout for all command types unconditionally. Let alone already available return codes often not being checked in the MMC layer ... - Add an IOCTL interface to mmcsd(4); this is sufficiently compatible with Linux so that the GNU mmc-utils can be ported to and used with FreeBSD (note that due to the remaining deficiencies outlined above SANITIZE operations issued by/with `mmc` currently most likely will fail). These latter will be added to ports as sysutils/mmc-utils in a bit. Among others, the `mmc` tool of the GNU mmc-utils allows for partitioning eMMC devices (tested working). - For devices following the eMMC specification v4.41 or later, year 0 is 2013 rather than 1997; so correct this for assembling the device ID string properly. - Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at least for some of the above a matching pair is required. - In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC controllers as such in order to match the PCI one. Additionally, in the entry for the 80860F14 SDXC controller remove the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET. OKed by: imp Submitted by: ian (mmc_switch_status() implementation)
2017-03-16 22:23:04 +00:00
{ 0x22968086, 0xffff, "Intel Braswell SDXC Controller",
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
- Add support for eMMC "partitions". Besides the user data area, i. e. the default partition, eMMC v4.41 and later devices can additionally provide up to: 1 enhanced user data area partition 2 boot partitions 1 RPMB (Replay Protected Memory Block) partition 4 general purpose partitions (optionally with a enhanced or extended attribute) Of these "partitions", only the enhanced user data area one actually slices the user data area partition and, thus, gets handled with the help of geom_flashmap(4). The other types of partitions have address space independent from the default partition and need to be switched to via CMD6 (SWITCH), i. e. constitute a set of additional "disks". The second kind of these "partitions" doesn't fit that well into the design of mmc(4) and mmcsd(4). I've decided to let mmcsd(4) hook all of these "partitions" up as disk(9)'s (except for the RPMB partition as it didn't seem to make much sense to be able to put a file-system there and may require authentication; therefore, RPMB partitions are solely accessible via the newly added IOCTL interface currently; see also below). This approach for one resulted in cleaner code. Second, it retains the notion of mmcsd(4) children corresponding to a single physical device each. With the addition of some layering violations, it also would have been possible for mmc(4) to add separate mmcsd(4) instances with one disk each for all of these "partitions", however. Still, both mmc(4) and mmcsd(4) share some common code now e. g. for issuing CMD6, which has been factored out into mmc_subr.c. Besides simply subdividing eMMC devices, some Intel NUCs having UEFI code in the boot partitions etc., another use case for the partition support is the activation of pseudo-SLC mode, which manufacturers of eMMC chips typically associate with the enhanced user data area and/ or the enhanced attribute of general purpose partitions. CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation. - Now that properly issuing CMD6 is crucial (so data isn't written to the wrong partition for example), make a step into the direction of correctly handling the timeout for these commands in the MMC layer. Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as recommended by relevant specifications. However, quite some work is left to be done in this regard; all other R1B-type commands done by the MMC layer also should be followed by a SEND_STATUS (CMD13), the erase timeout calculations/handling as documented in specifications are entirely ignored so far, the MMC layer doesn't provide timeouts applicable up to the bridge drivers and at least sdhci(4) currently is hardcoding 1 s as timeout for all command types unconditionally. Let alone already available return codes often not being checked in the MMC layer ... - Add an IOCTL interface to mmcsd(4); this is sufficiently compatible with Linux so that the GNU mmc-utils can be ported to and used with FreeBSD (note that due to the remaining deficiencies outlined above SANITIZE operations issued by/with `mmc` currently most likely will fail). These latter will be added to ports as sysutils/mmc-utils in a bit. Among others, the `mmc` tool of the GNU mmc-utils allows for partitioning eMMC devices (tested working). - For devices following the eMMC specification v4.41 or later, year 0 is 2013 rather than 1997; so correct this for assembling the device ID string properly. - Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at least for some of the above a matching pair is required. - In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC controllers as such in order to match the PCI one. Additionally, in the entry for the 80860F14 SDXC controller remove the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET. OKed by: imp Submitted by: ian (mmc_switch_status() implementation)
2017-03-16 22:23:04 +00:00
{ 0x5aca8086, 0xffff, "Intel Apollo Lake SDXC Controller",
SDHCI_QUIRK_BROKEN_DMA | /* APL18 erratum */
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ 0x5acc8086, 0xffff, "Intel Apollo Lake eMMC 5.0 Controller",
SDHCI_QUIRK_BROKEN_DMA | /* APL18 erratum */
- Add support for eMMC "partitions". Besides the user data area, i. e. the default partition, eMMC v4.41 and later devices can additionally provide up to: 1 enhanced user data area partition 2 boot partitions 1 RPMB (Replay Protected Memory Block) partition 4 general purpose partitions (optionally with a enhanced or extended attribute) Of these "partitions", only the enhanced user data area one actually slices the user data area partition and, thus, gets handled with the help of geom_flashmap(4). The other types of partitions have address space independent from the default partition and need to be switched to via CMD6 (SWITCH), i. e. constitute a set of additional "disks". The second kind of these "partitions" doesn't fit that well into the design of mmc(4) and mmcsd(4). I've decided to let mmcsd(4) hook all of these "partitions" up as disk(9)'s (except for the RPMB partition as it didn't seem to make much sense to be able to put a file-system there and may require authentication; therefore, RPMB partitions are solely accessible via the newly added IOCTL interface currently; see also below). This approach for one resulted in cleaner code. Second, it retains the notion of mmcsd(4) children corresponding to a single physical device each. With the addition of some layering violations, it also would have been possible for mmc(4) to add separate mmcsd(4) instances with one disk each for all of these "partitions", however. Still, both mmc(4) and mmcsd(4) share some common code now e. g. for issuing CMD6, which has been factored out into mmc_subr.c. Besides simply subdividing eMMC devices, some Intel NUCs having UEFI code in the boot partitions etc., another use case for the partition support is the activation of pseudo-SLC mode, which manufacturers of eMMC chips typically associate with the enhanced user data area and/ or the enhanced attribute of general purpose partitions. CAVEAT EMPTOR: Partitioning eMMC devices is a one-time operation. - Now that properly issuing CMD6 is crucial (so data isn't written to the wrong partition for example), make a step into the direction of correctly handling the timeout for these commands in the MMC layer. Also, do a SEND_STATUS when CMD6 is invoked with an R1B response as recommended by relevant specifications. However, quite some work is left to be done in this regard; all other R1B-type commands done by the MMC layer also should be followed by a SEND_STATUS (CMD13), the erase timeout calculations/handling as documented in specifications are entirely ignored so far, the MMC layer doesn't provide timeouts applicable up to the bridge drivers and at least sdhci(4) currently is hardcoding 1 s as timeout for all command types unconditionally. Let alone already available return codes often not being checked in the MMC layer ... - Add an IOCTL interface to mmcsd(4); this is sufficiently compatible with Linux so that the GNU mmc-utils can be ported to and used with FreeBSD (note that due to the remaining deficiencies outlined above SANITIZE operations issued by/with `mmc` currently most likely will fail). These latter will be added to ports as sysutils/mmc-utils in a bit. Among others, the `mmc` tool of the GNU mmc-utils allows for partitioning eMMC devices (tested working). - For devices following the eMMC specification v4.41 or later, year 0 is 2013 rather than 1997; so correct this for assembling the device ID string properly. - Let mmcsd.ko depend on mmc.ko. Additionally, bump MMC_VERSION as at least for some of the above a matching pair is required. - In the ACPI front-end of sdhci(4) describe the Intel eMMC and SDXC controllers as such in order to match the PCI one. Additionally, in the entry for the 80860F14 SDXC controller remove the eMMC-only SDHCI_QUIRK_INTEL_POWER_UP_RESET. OKed by: imp Submitted by: ian (mmc_switch_status() implementation)
2017-03-16 22:23:04 +00:00
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_MMC_DDR52 |
SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ 0, 0xffff, NULL,
0 }
};
struct sdhci_pci_softc {
u_int quirks; /* Chip specific quirks */
struct resource *irq_res; /* IRQ resource */
void *intrhand; /* Interrupt handle */
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 frequency */
uint8_t cfg_mode; /* Saved mode */
};
static int sdhci_enable_msi = 1;
SYSCTL_INT(_hw_sdhci, OID_AUTO, enable_msi, CTLFLAG_RDTUN, &sdhci_enable_msi,
0, "Enable MSI interrupts");
static uint8_t
sdhci_pci_read_1(device_t dev, struct sdhci_slot *slot __unused, bus_size_t off)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_barrier(sc->mem_res[slot->num], 0, 0xFF,
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
return bus_read_1(sc->mem_res[slot->num], off);
}
static void
sdhci_pci_write_1(device_t dev, struct sdhci_slot *slot __unused,
bus_size_t off, uint8_t val)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_barrier(sc->mem_res[slot->num], 0, 0xFF,
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
bus_write_1(sc->mem_res[slot->num], off, val);
}
static uint16_t
sdhci_pci_read_2(device_t dev, struct sdhci_slot *slot __unused, bus_size_t off)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_barrier(sc->mem_res[slot->num], 0, 0xFF,
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
return bus_read_2(sc->mem_res[slot->num], off);
}
static void
sdhci_pci_write_2(device_t dev, struct sdhci_slot *slot __unused,
bus_size_t off, uint16_t val)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_barrier(sc->mem_res[slot->num], 0, 0xFF,
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
bus_write_2(sc->mem_res[slot->num], off, val);
}
static uint32_t
sdhci_pci_read_4(device_t dev, struct sdhci_slot *slot __unused, bus_size_t off)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_barrier(sc->mem_res[slot->num], 0, 0xFF,
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
return bus_read_4(sc->mem_res[slot->num], off);
}
static void
sdhci_pci_write_4(device_t dev, struct sdhci_slot *slot __unused,
bus_size_t off, uint32_t val)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_barrier(sc->mem_res[slot->num], 0, 0xFF,
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
bus_write_4(sc->mem_res[slot->num], off, val);
}
static void
sdhci_pci_read_multi_4(device_t dev, struct sdhci_slot *slot __unused,
bus_size_t off, uint32_t *data, bus_size_t count)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_read_multi_stream_4(sc->mem_res[slot->num], off, data, count);
}
static void
sdhci_pci_write_multi_4(device_t dev, struct sdhci_slot *slot __unused,
bus_size_t off, uint32_t *data, bus_size_t count)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
bus_write_multi_stream_4(sc->mem_res[slot->num], off, data, count);
}
static void sdhci_pci_intr(void *arg);
static void
sdhci_lower_frequency(device_t dev)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
/*
* Enable SD2.0 mode.
* NB: for RICOH R5CE823, this changes the PCI device ID to 0xe822.
*/
pci_write_config(dev, SDHC_PCI_MODE_KEY, 0xfc, 1);
sc->cfg_mode = pci_read_config(dev, SDHC_PCI_MODE, 1);
pci_write_config(dev, SDHC_PCI_MODE, SDHC_PCI_MODE_SD20, 1);
pci_write_config(dev, SDHC_PCI_MODE_KEY, 0x00, 1);
/*
* Some SD/MMC cards don't work with the default base
* clock frequency of 200 MHz. Lower it to 50 MHz.
*/
pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x01, 1);
sc->cfg_freq = pci_read_config(dev, SDHC_PCI_BASE_FREQ, 1);
pci_write_config(dev, SDHC_PCI_BASE_FREQ, 50, 1);
pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x00, 1);
}
static void
sdhci_restore_frequency(device_t dev)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
/* Restore mode. */
pci_write_config(dev, SDHC_PCI_MODE_KEY, 0xfc, 1);
pci_write_config(dev, SDHC_PCI_MODE, sc->cfg_mode, 1);
pci_write_config(dev, SDHC_PCI_MODE_KEY, 0x00, 1);
/* Restore frequency. */
pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x01, 1);
pci_write_config(dev, SDHC_PCI_BASE_FREQ, sc->cfg_freq, 1);
pci_write_config(dev, SDHC_PCI_BASE_FREQ_KEY, 0x00, 1);
}
static int
sdhci_pci_probe(device_t dev)
{
uint32_t model;
uint16_t subvendor;
uint8_t class, subclass;
int i, result;
model = (uint32_t)pci_get_device(dev) << 16;
model |= (uint32_t)pci_get_vendor(dev) & 0x0000ffff;
subvendor = pci_get_subvendor(dev);
class = pci_get_class(dev);
subclass = pci_get_subclass(dev);
result = ENXIO;
for (i = 0; sdhci_devices[i].model != 0; i++) {
if (sdhci_devices[i].model == model &&
(sdhci_devices[i].subvendor == 0xffff ||
sdhci_devices[i].subvendor == subvendor)) {
device_set_desc(dev, sdhci_devices[i].desc);
result = BUS_PROBE_DEFAULT;
break;
}
}
if (result == ENXIO && class == PCIC_BASEPERIPH &&
subclass == PCIS_BASEPERIPH_SDHC) {
device_set_desc(dev, "Generic SD HCI");
result = BUS_PROBE_GENERIC;
}
return (result);
}
static int
sdhci_pci_attach(device_t dev)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
struct sdhci_slot *slot;
uint32_t model;
uint16_t subvendor;
int bar, err, rid, slots, i;
model = (uint32_t)pci_get_device(dev) << 16;
model |= (uint32_t)pci_get_vendor(dev) & 0x0000ffff;
subvendor = pci_get_subvendor(dev);
/* Apply chip specific quirks. */
for (i = 0; sdhci_devices[i].model != 0; i++) {
if (sdhci_devices[i].model == model &&
(sdhci_devices[i].subvendor == 0xffff ||
sdhci_devices[i].subvendor == subvendor)) {
sc->quirks = sdhci_devices[i].quirks;
break;
}
}
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
sc->quirks &= ~sdhci_quirk_clear;
sc->quirks |= sdhci_quirk_set;
/* Some controllers need to be bumped into the right mode. */
if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY)
sdhci_lower_frequency(dev);
/* Read slots info from PCI registers. */
slots = pci_read_config(dev, PCI_SLOT_INFO, 1);
bar = PCI_SLOT_INFO_FIRST_BAR(slots);
slots = PCI_SLOT_INFO_SLOTS(slots);
if (slots > 6 || bar > 5) {
device_printf(dev, "Incorrect slots information (%d, %d).\n",
slots, bar);
return (EINVAL);
}
/* Allocate IRQ. */
i = 1;
rid = 0;
if (sdhci_enable_msi != 0 && pci_alloc_msi(dev, &i) == 0)
rid = 1;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE | (rid != 0 ? 0 : RF_SHAREABLE));
if (sc->irq_res == NULL) {
device_printf(dev, "Can't allocate IRQ\n");
pci_release_msi(dev);
return (ENOMEM);
}
/* Scan all slots. */
for (i = 0; i < slots; i++) {
slot = &sc->slots[sc->num_slots];
/* Allocate memory. */
rid = PCIR_BAR(bar + i);
sc->mem_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE);
if (sc->mem_res[i] == NULL) {
device_printf(dev,
"Can't allocate memory for slot %d\n", i);
continue;
}
Add support for the BCM57765 card reader. This patch adds support for the BCM57765[2] card reader function included in Broadcom's BCM57766 ethernet/sd3.0 controller. This controller is commonly found in laptops and Apple hardware (MBP, iMac, etc). The BCM57765 chipset is almost fully compatible with the SD3.0 spec, but does not support deriving a frequency below 781KHz from its default base clock via the standard SD3.0-configured 10-bit clock divisor. If such a divisor is set, card identification (which requires a 400KHz clock frequency) will time out[1]. As a work-around, I've made use of an undocumented device-specific clock control register to switch the controller to a 63MHz clock source when targeting clock speeds below 781KHz; the clock source is likewise switched back to the 200MHz clock when targeting speeds greater than 781KHz. Additionally, this patch fixes a small sdhci_pci bug; the sdhci_pci_softc->quirks flag was not copied to the sdhci_slot, resulting in `quirk` behavior not being applied by sdhci.c. [1] A number of Linux/FreeBSD users have noted that bringing up the chipsets' associated ethernet interface will allow SD cards to enumerate (slowly). This is a controller implementation side-effect triggered by the ethernet driver's reading of the hardware statistics registers. [2] This may also fix card detection when using the BCM57785 chipset, but I don't have access to the BCM57785 chipset and can't verify. I actually snagged some BCM57785 hardware recently (2012 Retina MacBook Pro) and can confirm that this also fixes card enumeration with the BCM57785 chipset; with the patch, I can boot off of the internal sdcard reader. PR: kern/203385 Submitted by: Landon Fuller <landon@landonf.org>
2015-10-15 04:22:56 +00:00
slot->quirks = sc->quirks;
if (sdhci_init_slot(dev, slot, i) != 0)
continue;
sc->num_slots++;
}
device_printf(dev, "%d slot(s) allocated\n", sc->num_slots);
/* Activate the interrupt */
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, sdhci_pci_intr, sc, &sc->intrhand);
if (err)
device_printf(dev, "Can't setup IRQ\n");
pci_enable_busmaster(dev);
/* Process cards detection. */
for (i = 0; i < sc->num_slots; i++) {
sdhci_start_slot(&sc->slots[i]);
}
return (0);
}
static int
sdhci_pci_detach(device_t dev)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
int i;
bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->irq_res), sc->irq_res);
pci_release_msi(dev);
for (i = 0; i < sc->num_slots; i++) {
sdhci_cleanup_slot(&sc->slots[i]);
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem_res[i]), sc->mem_res[i]);
}
if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY)
sdhci_restore_frequency(dev);
return (0);
}
static int
sdhci_pci_shutdown(device_t dev)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY)
sdhci_restore_frequency(dev);
return (0);
}
static int
sdhci_pci_suspend(device_t dev)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
int i, err;
err = bus_generic_suspend(dev);
if (err)
return (err);
for (i = 0; i < sc->num_slots; i++)
sdhci_generic_suspend(&sc->slots[i]);
return (0);
}
static int
sdhci_pci_resume(device_t dev)
{
struct sdhci_pci_softc *sc = device_get_softc(dev);
Make sdhci(4) work after suspend/resume for chipsets that require the frequency quirk. This makes it work on eg ThinkPad T420. Without it, after resume one can see this: mmc0: ACMD42 failed, RESULT: 4 mmcsd0: Error indicated: 1 Timeout mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC sdhci_pci0-slot0: Got data interrupt 0x00200000, but there is no active command. sdhci_pci0-slot0: ============== REGISTER DUMP ============== sdhci_pci0-slot0: Sys addr: 0x06317200 | Version: 0x00000502 sdhci_pci0-slot0: Blk size: 0x00000200 | Blk cnt: 0x00000010 sdhci_pci0-slot0: Argument: 0x00000200 | Trn mode: 0x00000037 sdhci_pci0-slot0: Present: 0x01ff0000 | Host ctl: 0x00000007 sdhci_pci0-slot0: Power: 0x0000000f | Blk gap: 0x00000000 sdhci_pci0-slot0: Wake-up: 0x00000000 | Clock: 0x00000007 sdhci_pci0-slot0: Timeout: 0x0000000d | Int stat: 0x00000000 sdhci_pci0-slot0: Int enab: 0x01ff00fb | Sig enab: 0x01ff00fb sdhci_pci0-slot0: AC12 err: 0x00000000 | Slot int: 0x00000000 sdhci_pci0-slot0: Caps: 0x21e8c8b2 | Max curr: 0x00000040 sdhci_pci0-slot0: =========================================== sdhci_pci0-slot0: Got data interrupt 0x00200000, but there is no active command. sdhci_pci0-slot0: ============== REGISTER DUMP ============== sdhci_pci0-slot0: Sys addr: 0x06317200 | Version: 0x00000502 sdhci_pci0-slot0: Blk size: 0x00000200 | Blk cnt: 0x00000001 sdhci_pci0-slot0: Argument: 0x00000040 | Trn mode: 0x00000013 sdhci_pci0-slot0: Present: 0x01ff0000 | Host ctl: 0x00000007 sdhci_pci0-slot0: Power: 0x0000000f | Blk gap: 0x00000000 sdhci_pci0-slot0: Wake-up: 0x00000000 | Clock: 0x00000007 sdhci_pci0-slot0: Timeout: 0x0000000d | Int stat: 0x00000000 autofs_flush: /net flushed sdhci_pci0-slot0: Int enab: 0x01ff00fb | Sig enab: 0x01ff00fb autofs_flush: /media flushed sdhci_pci0-slot0: AC12 err: 0x00000000 | Slot int: 0x00000000 sdhci_pci0-slot0: Caps: 0x21e8c8b2 | Max curr: 0x00000040 sdhci_pci0-slot0: =========================================== Afterwards all operations on /dev/mmcsd0 fail with EIO. Reviewed by: jhb@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D6265
2016-05-11 07:50:35 +00:00
int i, err;
for (i = 0; i < sc->num_slots; i++)
sdhci_generic_resume(&sc->slots[i]);
Make sdhci(4) work after suspend/resume for chipsets that require the frequency quirk. This makes it work on eg ThinkPad T420. Without it, after resume one can see this: mmc0: ACMD42 failed, RESULT: 4 mmcsd0: Error indicated: 1 Timeout mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC mmcsd0: Error indicated: 2 Bad CRC sdhci_pci0-slot0: Got data interrupt 0x00200000, but there is no active command. sdhci_pci0-slot0: ============== REGISTER DUMP ============== sdhci_pci0-slot0: Sys addr: 0x06317200 | Version: 0x00000502 sdhci_pci0-slot0: Blk size: 0x00000200 | Blk cnt: 0x00000010 sdhci_pci0-slot0: Argument: 0x00000200 | Trn mode: 0x00000037 sdhci_pci0-slot0: Present: 0x01ff0000 | Host ctl: 0x00000007 sdhci_pci0-slot0: Power: 0x0000000f | Blk gap: 0x00000000 sdhci_pci0-slot0: Wake-up: 0x00000000 | Clock: 0x00000007 sdhci_pci0-slot0: Timeout: 0x0000000d | Int stat: 0x00000000 sdhci_pci0-slot0: Int enab: 0x01ff00fb | Sig enab: 0x01ff00fb sdhci_pci0-slot0: AC12 err: 0x00000000 | Slot int: 0x00000000 sdhci_pci0-slot0: Caps: 0x21e8c8b2 | Max curr: 0x00000040 sdhci_pci0-slot0: =========================================== sdhci_pci0-slot0: Got data interrupt 0x00200000, but there is no active command. sdhci_pci0-slot0: ============== REGISTER DUMP ============== sdhci_pci0-slot0: Sys addr: 0x06317200 | Version: 0x00000502 sdhci_pci0-slot0: Blk size: 0x00000200 | Blk cnt: 0x00000001 sdhci_pci0-slot0: Argument: 0x00000040 | Trn mode: 0x00000013 sdhci_pci0-slot0: Present: 0x01ff0000 | Host ctl: 0x00000007 sdhci_pci0-slot0: Power: 0x0000000f | Blk gap: 0x00000000 sdhci_pci0-slot0: Wake-up: 0x00000000 | Clock: 0x00000007 sdhci_pci0-slot0: Timeout: 0x0000000d | Int stat: 0x00000000 autofs_flush: /net flushed sdhci_pci0-slot0: Int enab: 0x01ff00fb | Sig enab: 0x01ff00fb autofs_flush: /media flushed sdhci_pci0-slot0: AC12 err: 0x00000000 | Slot int: 0x00000000 sdhci_pci0-slot0: Caps: 0x21e8c8b2 | Max curr: 0x00000040 sdhci_pci0-slot0: =========================================== Afterwards all operations on /dev/mmcsd0 fail with EIO. Reviewed by: jhb@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D6265
2016-05-11 07:50:35 +00:00
err = bus_generic_resume(dev);
if (err)
return (err);
if (sc->quirks & SDHCI_QUIRK_LOWER_FREQUENCY)
sdhci_lower_frequency(dev);
return (0);
}
static void
sdhci_pci_intr(void *arg)
{
struct sdhci_pci_softc *sc = (struct sdhci_pci_softc *)arg;
int i;
for (i = 0; i < sc->num_slots; i++)
sdhci_generic_intr(&sc->slots[i]);
}
static device_method_t sdhci_methods[] = {
/* device_if */
DEVMETHOD(device_probe, sdhci_pci_probe),
DEVMETHOD(device_attach, sdhci_pci_attach),
DEVMETHOD(device_detach, sdhci_pci_detach),
DEVMETHOD(device_shutdown, sdhci_pci_shutdown),
DEVMETHOD(device_suspend, sdhci_pci_suspend),
DEVMETHOD(device_resume, sdhci_pci_resume),
/* Bus interface */
DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar),
DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar),
/* mmcbr_if */
DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios),
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
DEVMETHOD(mmcbr_switch_vccq, sdhci_generic_switch_vccq),
o Add support for eMMC HS200 and HS400 bus speed modes at 200 MHz to sdhci(4), mmc(4) and mmcsd(4). For the most part, this consists of: - Correcting and extending the infrastructure for negotiating and enabling post-DDR52 modes already added as part of r315598. In fact, HS400ES now should work as well but hasn't been activated due to lack of corresponding hardware. - Adding support executing standard SDHCI initial tuning as well as re-tuning as required for eMMC HS200/HS400 and the fast UHS-I SD card modes. Currently, corresponding methods are only hooked up to the ACPI and PCI front-ends of sdhci(4), though. Moreover, sdhci(4) won't offer any modes requiring (re-)tuning to the MMC/SD layer in order to not break operations with other sdhci(4) front- ends. Likewise, sdhci(4) now no longer offers modes requiring the set_uhs_timing method introduced in r315598 to be implemented/ hooked up (previously, this method was used with DDR52 only, which in turn is only available with Intel controllers so far, i. e. no such limitation was necessary before). Similarly for 1.2/1.8 V VCCQ support and the switch_vccq method. - Addition of locking to the IOCTL half of mmcsd(4) to prevent races with detachment and suspension, especially since it's required to immediately switch away from RPMB partitions again after an access to these (so re-tuning can take place anew, given that the current eMMC specification v5.1 doesn't allow tuning commands to be issued with a RPMB partition selected). Therefore, the existing part_mtx lock in the mmcsd(4) softc is additionally renamed to disk_mtx in order to denote that it only refers to the disk(9) half, likewise for corresponding macros. On the system where the addition of DDR52 support increased the read throughput to ~80 MB/s (from ~45 MB/s at high speed), HS200 yields ~154 MB/s and HS400 ~187 MB/s, i. e. performance now has more than quadrupled compared to pre-r315598. Also, with the advent of (re-)tuning support, most infrastructure necessary for SD card UHS-I modes up to SDR104 now is also in place. Note, though, that the standard SDHCI way of (re-)tuning is special in several ways, which also is why sending the actual tuning requests to the device is part of sdhci(4). SDHCI implementations not following the specification, MMC and non-SDHCI SD card controllers likely will use a generic implementation in the MMC/SD layer for executing tuning, which hasn't been written so far, though. However, in fact this isn't a feature-only change; there are boards based on Intel Bay Trail where DDR52 is problematic and the suggested workaround is to use HS200 mode instead. So far exact details are unknown, however, i. e. whether that's due to a defect in these SoCs or on the boards. Moreover, due to the above changes requiring to be aware of possible MMC siblings in the fast path of mmc(4), corresponding information now is cached in mmc_softc. As a side-effect, mmc_calculate_clock(), mmc_delete_cards(), mmc_discover_cards() and mmc_rescan_cards() now all are guaranteed to operate on the same set of devices as there no longer is any use of device_get_children(9), which can fail in low memory situations. Likewise, mmc_calculate_clock() now longer will trigger a panic due to the latter. o Fix a bug in the failure reporting of mmcsd_delete(); in case of an error when the starting block of a previously stored erase request is used (in order to be able to erase a full erase sector worth of data), the starting block of the newly supplied bio_pblkno has to be returned for indicating no progress. Otherwise, upper layers might be told that a negative number of BIOs have been completed, leading to a panic. o Fix 2 bugs on resume: - Things done in fork1(9) like the acquisition of an SX lock or the sleepable memory allocation are incompatible with a MTX_DEF taken. Thus, mmcsd_resume() must not call kproc_create(9), which in turn uses fork1(9), with the disk_mtx (formerly part_mtx) held. - In mmc_suspend(), the bus is powered down, which in the typical case of a device being selected at the time of suspension, causes the device deselection as part of the bus acquisition by mmc(4) in mmc_scan() to fail as the bus isn't powered up again before later in mmc_go_discovery(). Thus, power down with the bus acquired in mmc_suspend(), which will trigger the deselection up-front. o Fix a memory leak in mmcsd_ioctl() in case copyin(9) fails. [1] o Fix missing variable initialization in mmc_switch_status(). [2] o Fix R1_SWITCH_ERROR detection in mmc_switch_status(). [3] o Handle the case of device_add_child(9) failing, for example due to a memory shortage, gracefully in mmc(4) and sdhci(4), including not leaking memory for the instance variables in case of mmc(4) (which might or might not fix [4] as the latter problem has been discovered independently). o Handle the case of an unknown SD CSD version in mmc_decode_csd_sd() gracefully instead of calling panic(9). o Again, check and handle the return values of some additional function calls in mmc(4) instead of assuming that everything went right or mark non-fatal errors by casting the return value to void. o Correct a typo in the Linux IOCTL compatibility; it should have been MMC_IOC_MULTI_CMD rather than MMC_IOC_CMD_MULTI. o Now that we are reaching ever faster speeds (more improvement in this regard is to be expected when adding ADMA support to sdhci(4)), apply a few micro-optimizations like predicting mmc(4) and sdhci(4) debugging to be off or caching erase sector and maximum data sizes as well support of block addressing in mmsd(4) (instead of doing 2 indirections on every read/write request for determining the maximum data size for example). Reported by: Coverity CID: 1372612 [1], 1372624 [2], 1372594 [3], 1007069 [4]
2017-07-23 16:11:47 +00:00
DEVMETHOD(mmcbr_tune, sdhci_generic_tune),
DEVMETHOD(mmcbr_retune, sdhci_generic_retune),
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),
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
/* SDHCI accessors */
DEVMETHOD(sdhci_read_1, sdhci_pci_read_1),
DEVMETHOD(sdhci_read_2, sdhci_pci_read_2),
DEVMETHOD(sdhci_read_4, sdhci_pci_read_4),
DEVMETHOD(sdhci_read_multi_4, sdhci_pci_read_multi_4),
DEVMETHOD(sdhci_write_1, sdhci_pci_write_1),
DEVMETHOD(sdhci_write_2, sdhci_pci_write_2),
DEVMETHOD(sdhci_write_4, sdhci_pci_write_4),
DEVMETHOD(sdhci_write_multi_4, sdhci_pci_write_multi_4),
o Add support for eMMC DDR bus speed mode at 52 MHz to sdhci(4) and mmc(4). For the most part, this consists of support for: - Switching the signal voltage (VCCQ) to 1.8 V or (if supported by the host controller) to 1.2 V, - setting the UHS mode as appropriate in the SDHCI_HOST_CONTROL2 register, - setting the power class in the eMMC device according to the core supply voltage (VCC), - using different bits for enabling a bus width of 4 and 8 bits in the the eMMC device at DDR or higher timings respectively, - arbitrating timings faster than high speed if there actually are additional devices on the same MMC bus. Given that support for DDR52 is not denoted by SDHCI capability registers, availability of that timing is indicated by a new quirk SDHCI_QUIRK_MMC_DDR52 and only enabled for Intel SDHCI controllers so far. Generally, what it takes for a sdhci(4) front-end to enable support for DDR52 is to hook up the bridge method mmcbr_switch_vccq (which especially for 1.2 V signaling support is chip/board specific) and the sdhci_set_uhs_timing sdhci(4) method. As a side-effect, this change also fixes communication with some eMMC devices at SDR high speed mode with 52 MHz due to the signaling voltage and UHS bits in the SDHCI controller no longer being left in an inappropriate state. Compared to 52 MHz at SDR high speed which typically yields ~45 MB/s with the eMMC chips tested, throughput goes up to ~80 MB/s at DDR52. Additionally, this change already adds infrastructure and quite some code for modes up to HS400ES and SDR104 respectively (I did not want to add to much stuff at a time, though). Essentially, what is still missing in order to be able to activate support for these latter is is support for and handling of (re-)tuning. o In sdhci(4), add two tunables hw.sdhci.quirk_clear as well as hw.sdhci.quirk_set, which (when hooked up in the front-end) allow to set/clear sdhci(4) quirks for debugging and testing purposes. However, especially for SDHCI controllers on the PCI bus which have no specific support code so far and, thus, are picked up as generic SDHCI controllers, hw.sdhci.quirk_set allows for setting the necessary quirks (if required). o In mmc(4), check and handle the return values of some more function calls instead of assuming that everything went right. In case failures actually are not problematic, indicate that by casting the return value to void. Reviewed by: jmcneill
2017-03-19 23:27:17 +00:00
DEVMETHOD(sdhci_set_uhs_timing, sdhci_generic_set_uhs_timing),
DEVMETHOD_END
};
static driver_t sdhci_pci_driver = {
"sdhci_pci",
sdhci_methods,
sizeof(struct sdhci_pci_softc),
};
static devclass_t sdhci_pci_devclass;
DRIVER_MODULE(sdhci_pci, pci, sdhci_pci_driver, sdhci_pci_devclass, NULL,
NULL);
2018-12-30 23:08:06 +00:00
SDHCI_DEPEND(sdhci_pci);
#ifndef MMCCAM
MMC_DECLARE_BRIDGE(sdhci_pci);
#endif