Author: marius Date: Wed Jul 26 22:04:23 2017 New Revision: 321589 URL: https://svnweb.freebsd.org/changeset/base/321589
Log: - 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] Modified: head/sys/dev/sdhci/sdhci.c head/sys/dev/sdhci/sdhci.h head/sys/dev/sdhci/sdhci_acpi.c head/sys/dev/sdhci/sdhci_pci.c Modified: head/sys/dev/sdhci/sdhci.c ============================================================================== --- head/sys/dev/sdhci/sdhci.c Wed Jul 26 21:59:37 2017 (r321588) +++ head/sys/dev/sdhci/sdhci.c Wed Jul 26 22:04:23 2017 (r321589) @@ -742,6 +742,7 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, 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, 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, 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, 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 @@ no_tuning: 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", Modified: head/sys/dev/sdhci/sdhci.h ============================================================================== --- head/sys/dev/sdhci/sdhci.h Wed Jul 26 21:59:37 2017 (r321588) +++ head/sys/dev/sdhci/sdhci.h Wed Jul 26 22:04:23 2017 (r321589) @@ -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 */ Modified: head/sys/dev/sdhci/sdhci_acpi.c ============================================================================== --- head/sys/dev/sdhci/sdhci_acpi.c Wed Jul 26 21:59:37 2017 (r321588) +++ head/sys/dev/sdhci/sdhci_acpi.c Wed Jul 26 22:04:23 2017 (r321589) @@ -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 | Modified: head/sys/dev/sdhci/sdhci_pci.c ============================================================================== --- head/sys/dev/sdhci/sdhci_pci.c Wed Jul 26 21:59:37 2017 (r321588) +++ head/sys/dev/sdhci/sdhci_pci.c Wed Jul 26 22:04:23 2017 (r321589) @@ -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 | _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"