- Check the slot type capability, set SDHCI_SLOT_{EMBEDDED,NON_REMOVABLE}

for embedded slots. Fail in the sdhci(4) initialization for slot type
  shared, which is completely unsupported by this driver at the moment. [1]
  For Intel eMMC controllers, taking the embedded slot type into account
  obsoltes setting SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE so remove these quirk
  entries.
- Hide the 1.8 V VDD capability when the slot is detected as non-embedded,
  as the SDHCI specification explicitly states that 1.8 V VDD is applicable
  to embedded slots only. [2]
- Define some easy bits of the SDHCI specification v4.20. [3]
- Don't leak bus_dma(9) resources in failure paths of sdhci_init_slot().

Obtained from:	DragonFlyBSD 65704a46 [1], 7ba10b88 [2], 0df14648 [3]
This commit is contained in:
Marius Strobl 2017-07-26 22:04:23 +00:00
parent 7a777659ff
commit 7fcf47802a
4 changed files with 36 additions and 10 deletions

View File

@ -742,6 +742,7 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
BUS_DMA_NOWAIT, &slot->dmamap);
if (err != 0) {
device_printf(dev, "Can't alloc DMA memory\n");
bus_dma_tag_destroy(slot->dmatag);
SDHCI_LOCK_DESTROY(slot);
return (err);
}
@ -751,6 +752,8 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
sdhci_getaddr, &slot->paddr, 0);
if (err != 0 || slot->paddr == 0) {
device_printf(dev, "Can't load DMA memory\n");
bus_dmamem_free(slot->dmatag, slot->dmamem, slot->dmamap);
bus_dma_tag_destroy(slot->dmatag);
SDHCI_LOCK_DESTROY(slot);
if (err)
return (err);
@ -770,6 +773,22 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
else
caps2 = 0;
}
if (slot->version >= SDHCI_SPEC_300) {
if ((caps & SDHCI_SLOTTYPE_MASK) != SDHCI_SLOTTYPE_REMOVABLE &&
(caps & SDHCI_SLOTTYPE_MASK) != SDHCI_SLOTTYPE_EMBEDDED) {
device_printf(dev,
"Driver doesn't support shared bus slots\n");
bus_dmamap_unload(slot->dmatag, slot->dmamap);
bus_dmamem_free(slot->dmatag, slot->dmamem,
slot->dmamap);
bus_dma_tag_destroy(slot->dmatag);
SDHCI_LOCK_DESTROY(slot);
return (ENXIO);
} else if ((caps & SDHCI_SLOTTYPE_MASK) ==
SDHCI_SLOTTYPE_EMBEDDED) {
slot->opt |= SDHCI_SLOT_EMBEDDED | SDHCI_NON_REMOVABLE;
}
}
/* Calculate base clock frequency. */
if (slot->version >= SDHCI_SPEC_300)
freq = (caps & SDHCI_CLOCK_V3_BASE_MASK) >>
@ -819,7 +838,8 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
slot->host.host_ocr |= MMC_OCR_320_330 | MMC_OCR_330_340;
if (caps & SDHCI_CAN_VDD_300)
slot->host.host_ocr |= MMC_OCR_290_300 | MMC_OCR_300_310;
if (caps & SDHCI_CAN_VDD_180)
/* 1.8V VDD is not supposed to be used for removable cards. */
if ((caps & SDHCI_CAN_VDD_180) && (slot->opt & SDHCI_SLOT_EMBEDDED))
slot->host.host_ocr |= MMC_OCR_LOW_VOLTAGE;
if (slot->host.host_ocr == 0) {
device_printf(dev, "Hardware doesn't report any "
@ -966,20 +986,24 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
if (bootverbose || sdhci_debug) {
slot_printf(slot,
"%uMHz%s %s VDD:%s%s%s VCCQ: 3.3V%s%s DRV: B%s%s%s %s\n",
"%uMHz%s %s VDD:%s%s%s VCCQ: 3.3V%s%s DRV: B%s%s%s %s %s\n",
slot->max_clk / 1000000,
(caps & SDHCI_CAN_DO_HISPD) ? " HS" : "",
(host_caps & MMC_CAP_8_BIT_DATA) ? "8bits" :
((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" : "",
((caps & SDHCI_CAN_VDD_180) &&
(slot->opt & SDHCI_SLOT_EMBEDDED)) ? " 1.8V" : "",
(host_caps & MMC_CAP_SIGNALING_180) ? " 1.8V" : "",
(host_caps & MMC_CAP_SIGNALING_120) ? " 1.2V" : "",
(host_caps & MMC_CAP_DRIVER_TYPE_A) ? "A" : "",
(host_caps & MMC_CAP_DRIVER_TYPE_C) ? "C" : "",
(host_caps & MMC_CAP_DRIVER_TYPE_D) ? "D" : "",
(slot->opt & SDHCI_HAVE_DMA) ? "DMA" : "PIO");
(slot->opt & SDHCI_HAVE_DMA) ? "DMA" : "PIO",
(slot->opt & SDHCI_SLOT_EMBEDDED) ? "embedded" :
(slot->opt & SDHCI_NON_REMOVABLE) ? "non-removable" :
"removable");
if (host_caps & (MMC_CAP_MMC_DDR52 | MMC_CAP_MMC_HS200 |
MMC_CAP_MMC_HS400 | MMC_CAP_MMC_ENH_STROBE))
slot_printf(slot, "eMMC:%s%s%s%s\n",

View File

@ -237,6 +237,11 @@
#define SDHCI_HOST_CONTROL2 0x3E
#define SDHCI_CTRL2_PRESET_VALUE 0x8000
#define SDHCI_CTRL2_ASYNC_INTR 0x4000
#define SDHCI_CTRL2_64BIT_ENABLE 0x2000
#define SDHCI_CTRL2_HOST_V4_ENABLE 0x1000
#define SDHCI_CTRL2_CMD23_ENABLE 0x0800
#define SDHCI_CTRL2_ADMA2_LENGTH_MODE 0x0400
#define SDHCI_CTRL2_UHS2_IFACE_ENABLE 0x0100
#define SDHCI_CTRL2_SAMPLING_CLOCK 0x0080
#define SDHCI_CTRL2_EXEC_TUNING 0x0040
#define SDHCI_CTRL2_DRIVER_TYPE_MASK 0x0030
@ -321,6 +326,8 @@
#define SDHCI_SPEC_200 1
#define SDHCI_SPEC_300 2
#define SDHCI_SPEC_400 3
#define SDHCI_SPEC_410 4
#define SDHCI_SPEC_420 5
SYSCTL_DECL(_hw_sdhci);
@ -342,6 +349,7 @@ struct sdhci_slot {
#define SDHCI_TUNING_SUPPORTED 0x08
#define SDHCI_TUNING_ENABLED 0x10
#define SDHCI_SDR50_NEEDS_TUNING 0x20
#define SDHCI_SLOT_EMBEDDED 0x40
u_char version;
int timeout; /* Transfer timeout */
uint32_t max_clk; /* Max possible freq */

View File

@ -58,7 +58,6 @@ static const struct sdhci_acpi_device {
u_int quirks;
} sdhci_acpi_devices[] = {
{ "80860F14", 1, "Intel Bay Trail/Braswell eMMC 4.5/4.5.1 Controller",
SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_MMC_DDR52 |
@ -76,7 +75,6 @@ static const struct sdhci_acpi_device {
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ "80865ACC", 0, "Intel Apollo Lake eMMC 5.0 Controller",
SDHCI_QUIRK_BROKEN_DMA | /* APL18 erratum */
SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_MMC_DDR52 |

View File

@ -106,7 +106,6 @@ static const struct sdhci_device {
{ 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 |
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_MMC_DDR52 |
@ -116,14 +115,12 @@ static const struct sdhci_device {
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ 0x0f508086, 0xffff, "Intel Bay Trail eMMC 4.5 Controller",
SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
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_ALL_SLOTS_NON_REMOVABLE |
SDHCI_QUIRK_DATA_TIMEOUT_1MHZ |
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
SDHCI_QUIRK_WAIT_WHILE_BUSY |
@ -139,7 +136,6 @@ static const struct sdhci_device {
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
{ 0x5acc8086, 0xffff, "Intel Apollo Lake eMMC 5.0 Controller",
SDHCI_QUIRK_BROKEN_DMA | /* APL18 erratum */
SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE |
SDHCI_QUIRK_INTEL_POWER_UP_RESET |
SDHCI_QUIRK_WAIT_WHILE_BUSY |
SDHCI_QUIRK_MMC_DDR52 |