Lines Matching +full:no +full:- +full:mmc +full:- +full:hs400

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2020 - 2021 Alstom Group.
5 * Copyright (c) 2020 - 2021 Semihalf.
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 #include <dev/mmc/bridge.h>
45 #include <dev/mmc/mmcbrvar.h>
46 #include <dev/mmc/mmc_fdt_helpers.h>
56 #define RD4 (sc->read)
57 #define WR4 (sc->write)
166 * In HS400 mode only 4, 8, 12 clock dividers can be used.
178 * HS400 tuning is done in HS200 mode, but it has to be done using
219 .syscon_compat = "fsl,ls1012a-scfg",
234 .syscon_compat = "fsl,ls1046a-scfg",
250 {"fsl,ls1012a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1012a_soc_data},
251 {"fsl,ls1028a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1028a_soc_data},
252 {"fsl,ls1046a-esdhc", (uintptr_t)&sdhci_fsl_fdt_ls1046a_soc_data},
261 return (be32toh(bus_read_4(sc->mem_res, off)));
268 bus_write_4(sc->mem_res, off, htobe32(val));
275 return (bus_read_4(sc->mem_res, off));
282 bus_write_4(sc->mem_res, off, val);
291 val = sc->sdclk_bits | SDHCI_CLOCK_INT_EN;
306 (pre) = (sc)->vendor_ver < SDHCI_FSL_VENDOR_V23 ? 2 : 1;\
321 sc->sdclk_bits = val & SDHCI_DIVIDERS_MASK;
333 SDHCI_FSL_FDT_CLK_DIV(sc, sc->baseclk_hz, slot->clock, prescale, div);
338 * According to limited clock division erratum, clock dividers in hs400
341 if ((sc->soc_data->errata & SDHCI_FSL_HS400_LIMITED_CLK_DIV) &&
342 (sc->slot.host.ios.timing == bus_timing_mmc_hs400 ||
343 (sc->flags & SDHCI_FSL_HS400_FLAG))) {
354 device_printf(sc->dev, "Unsupported clock divider.\n");
358 sc->div_ratio = prescale * div;
360 device_printf(sc->dev,
361 "Desired SD/MMC freq: %d, actual: %d; base %d prescale %d divisor %d\n",
362 slot->clock, sc->baseclk_hz / (prescale * div),
363 sc->baseclk_hz, prescale, div);
366 div -= 1;
416 return (sc->cmd_and_mode & UINT16_MAX);
418 return (sc->cmd_and_mode >> 16);
441 return (bus_read_4(sc->mem_res, off));
464 bus_read_multi_4(sc->mem_res, off, data, count);
485 /* Bus width is 1-bit when this flag is not set. */
524 sc->cmd_and_mode = val;
527 sc->cmd_and_mode =
528 (sc->cmd_and_mode & UINT16_MAX) | (val << 16);
529 WR4(sc, SDHCI_TRANSFER_MODE, sc->cmd_and_mode);
530 sc->cmd_and_mode = 0;
534 * Switching to HS400 requires a special procedure,
558 bus_write_4(sc->mem_res, off, val);
584 bus_write_multi_4(sc->mem_res, off, data, count);
593 sdhci_generic_intr(&sc->slot);
611 ios = &slot->host.ios;
613 switch (ios->power_mode) {
618 device_printf(sc->dev, "Powering down sd/mmc\n");
620 if (sc->fdt_helper.vmmc_supply)
621 regulator_disable(sc->fdt_helper.vmmc_supply);
622 if (sc->fdt_helper.vqmmc_supply)
623 regulator_disable(sc->fdt_helper.vqmmc_supply);
627 device_printf(sc->dev, "Powering up sd/mmc\n");
629 if (sc->fdt_helper.vmmc_supply)
630 regulator_enable(sc->fdt_helper.vmmc_supply);
631 if (sc->fdt_helper.vqmmc_supply)
632 regulator_enable(sc->fdt_helper.vqmmc_supply);
647 if (sc->soc_data->syscon_compat == NULL) {
653 sc->soc_data->syscon_compat);
707 switch (slot->host.ios.vccq) {
709 if (sc->soc_data->errata & SDHCI_FSL_UNSUPP_1_8V)
725 if (sc->soc_data->errata & SDHCI_FSL_MISSING_VCCQ_REG) {
727 slot->host.ios.vccq);
732 vqmmc_supply = sc->fdt_helper.vqmmc_supply;
746 device_printf(sc->dev, "Cannot set vqmmc to %d<->%d\n", uvolt, uvolt);
758 return (sdhci_fdt_gpio_get_readonly(sc->gpio));
767 return (sdhci_fdt_gpio_get_present(sc->gpio));
790 device_printf(dev, "Voltage range %d - %d is out of bounds\n",
818 /* Call mmc_fdt_parse in order to get mmc related properties. */
819 mmc_fdt_parse(dev, node, &sc->fdt_helper, &sc->slot.host);
821 sc->slot.quirks |= SDHCI_QUIRK_MISSING_CAPS;
822 sc->slot.caps = sdhci_fsl_fdt_read_4(dev, &sc->slot,
824 sc->slot.caps2 = sdhci_fsl_fdt_read_4(dev, &sc->slot,
827 /* Parse the "voltage-ranges" dts property. */
828 num_ranges = OF_getencprop_alloc(node, "voltage-ranges",
838 (vdd_mask != (sc->slot.caps & SDHCI_FSL_CAN_VDD_MASK))) {
839 sc->slot.caps &= ~(SDHCI_FSL_CAN_VDD_MASK);
840 sc->slot.caps |= vdd_mask;
853 if (!retries--)
877 sdhci_fsl_fdt_compat_data)->ocd_data;
878 sc->dev = dev;
879 sc->flags = 0;
880 host = &sc->slot.host;
889 sc->soc_data = &sdhci_fsl_fdt_lx2160a_soc_data;
891 sc->soc_data = (struct sdhci_fsl_fdt_soc_data *)ocd_data;
893 sc->slot.quirks = sc->soc_data->quirks;
895 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
897 if (sc->mem_res == NULL) {
904 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
906 if (sc->irq_res == NULL) {
913 ret = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
914 NULL, sdhci_fsl_fdt_irq, sc, &sc->irq_cookie);
933 sc->baseclk_hz = clk_hz / sc->soc_data->baseclk_div;
936 if (OF_hasprop(node, "little-endian")) {
937 sc->read = read_le;
938 sc->write = write_le;
941 sc->read = read_be;
942 sc->write = write_be;
946 sc->vendor_ver = (RD4(sc, SDHCI_FSL_HOST_VERSION) &
950 sc->maxclk_hz = host->f_max ? host->f_max : sc->baseclk_hz;
954 * If the eSDHC block is connected over a big-endian bus, the data
973 sc->slot.max_clk = sc->maxclk_hz;
974 sc->gpio = sdhci_fdt_gpio_setup(dev, &sc->slot);
981 * re-check the status and potentially wait for more data. The main
982 * sdhci driver provides no hook for doing status checking on less than
985 * watermark size will work correctly too, no need to change the
992 ret = sdhci_init_slot(dev, &sc->slot, 0);
995 sc->slot_init_done = true;
996 sdhci_start_slot(&sc->slot);
1002 sdhci_fdt_gpio_teardown(sc->gpio);
1004 bus_teardown_intr(dev, sc->irq_res, sc->irq_cookie);
1006 bus_free_resource(dev, SYS_RES_IRQ, sc->irq_res);
1008 bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res);
1018 if (sc->slot_init_done)
1019 sdhci_cleanup_slot(&sc->slot);
1020 if (sc->gpio != NULL)
1021 sdhci_fdt_gpio_teardown(sc->gpio);
1022 if (sc->irq_cookie != NULL)
1023 bus_teardown_intr(dev, sc->irq_res, sc->irq_cookie);
1024 if (sc->irq_res != NULL)
1025 bus_free_resource(dev, SYS_RES_IRQ, sc->irq_res);
1026 if (sc->mem_res != NULL)
1027 bus_free_resource(dev, SYS_RES_MEMORY, sc->mem_res);
1039 sdhci_fsl_fdt_compat_data)->ocd_data)
1052 if (which == MMCBR_IVAR_MAX_DATA && (slot->opt & SDHCI_HAVE_DMA)) {
1058 *result = howmany(slot->sdma_bbufsz, 512);
1075 slot->host.ios.clock = 0;
1081 SDHCI_FSL_FDT_CLK_DIV(sc, sc->baseclk_hz, value, prescale, div);
1082 slot->host.ios.clock = sc->baseclk_hz / (prescale * div);
1104 if (slot->version >= SDHCI_SPEC_300) {
1114 if (sc->soc_data->errata & SDHCI_FSL_UNRELIABLE_PULSE_DET) {
1120 sc->flags = 0;
1143 device_t child, bool hs400, uint32_t wnd_start, uint32_t wnd_end)
1148 if (sc->soc_data->errata & SDHCI_FSL_TUNING_ERRATUM_TYPE1 ||
1149 abs(wnd_start - wnd_end) <= (4 * sc->div_ratio + 2)) {
1150 wnd_start = 5 * sc->div_ratio;
1151 wnd_end = 3 * sc->div_ratio;
1153 wnd_start = 8 * sc->div_ratio;
1154 wnd_end = 4 * sc->div_ratio;
1180 error = sdhci_generic_tune(bus, child, hs400);
1190 sdhci_fsl_fdt_tune(device_t bus, device_t child, bool hs400)
1201 if (sc->slot.host.ios.timing == bus_timing_uhs_sdr50 &&
1202 !(slot->opt & SDHCI_SDR50_NEEDS_TUNING))
1211 clk_divider = sc->baseclk_hz / slot->clock;
1215 if (hs400)
1216 sc->flags |= SDHCI_FSL_HS400_FLAG;
1219 fsl_sdhc_fdt_set_clock(sc, slot, sc->sdclk_bits);
1243 * "eSDHC takes care of the re-tuning during data transfer
1244 * (auto re-tuning).".
1253 fsl_sdhc_fdt_set_clock(sc, slot, SDHCI_CLOCK_CARD_EN | sc->sdclk_bits);
1263 error = sdhci_generic_tune(bus, child, hs400);
1276 sc->soc_data->errata & SDHCI_FSL_TUNING_ERRATUM_TYPE2 &&
1277 abs(wnd_start - wnd_end) > (4 * sc->div_ratio + 2)) {
1283 (sc->soc_data->errata &
1286 error = sdhci_fsl_sw_tuning(sc, bus, child, hs400, wnd_start,
1296 if (hs400) {
1314 if (!(slot->opt & SDHCI_TUNING_ENABLED))
1317 /* HS400 must be tuned in HS200 mode. */
1318 if (slot->host.ios.timing == bus_timing_mmc_hs400)
1322 * Only re-tuning with full reset is supported.
1324 * periodic re-tuning is done automatically. See comment in
1326 * Because of that re-tuning should only be triggered as a result
1333 sc->flags & SDHCI_FSL_HS400_FLAG));
1341 /* Check if HS400 is enabled right now. */
1354 fsl_sdhc_fdt_set_clock(sc, &sc->slot, sc->sdclk_bits);
1365 fsl_sdhc_fdt_set_clock(sc, &sc->slot, SDHCI_CLOCK_CARD_EN |
1366 sc->sdclk_bits);
1394 fsl_sdhc_fdt_set_clock(sc, slot, sc->sdclk_bits);
1410 sc->sdclk_bits);
1440 fsl_sdhc_fdt_set_clock(sc, slot, sc->sdclk_bits);
1459 sc->sdclk_bits);
1476 ios = &slot->host.ios;
1480 * When we switch to HS400 this function is called twice.
1483 * The controller can be switched to HS400 only after the latter
1486 if (slot->host.ios.timing == bus_timing_mmc_hs400 &&
1487 ios->clock > SD_SDR50_MAX)
1489 else if (slot->host.ios.timing < bus_timing_mmc_hs400) {
1493 * Switching to HS400 requires a custom procedure executed in
1499 if (ios->clock > SD_SDR50_MAX)
1501 else if (ios->clock > SD_SDR25_MAX)
1503 else if (ios->clock > SD_SDR12_MAX) {
1504 if (ios->timing == bus_timing_uhs_ddr50 ||
1505 ios->timing == bus_timing_mmc_ddr52)
1509 } else if (ios->clock > SD_MMC_CARD_ID_FREQUENCY)
1527 /* MMC bridge interface. */