Lines Matching +full:sdhci +full:- +full:caps
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
57 #include <dev/sdhci/sdhci.h>
58 #include <dev/sdhci/sdhci_fdt_gpio.h>
90 * Note that vendor Beaglebone dtsi files use "ti,omap3-hsmmc" for the am335x.
93 {"ti,am335-sdhci", 1},
94 {"ti,omap3-hsmmc", 1},
95 {"ti,omap4-hsmmc", 1},
102 * the device's memory map, followed by the standard sdhci register block.
105 * access, and the various per-SoC offsets. The SDHCI_REG_OFFSET is how far
106 * beyond the MMCHS block the SDHCI block is found; it's the same on all SoCs.
129 /* Forward declarations, CAM-relataed */
138 return (bus_read_4(sc->mem_res, off + sc->mmchs_reg_off)); in ti_mmchs_read_4()
145 bus_write_4(sc->mem_res, off + sc->mmchs_reg_off, val); in ti_mmchs_write_4()
152 return (bus_read_4(sc->mem_res, off + sc->sdhci_reg_off)); in RD4()
159 bus_write_4(sc->mem_res, off + sc->sdhci_reg_off, val); in WR4()
177 * The MMCHS hardware has a non-standard interpretation of the sdclock in ti_sdhci_read_2()
178 * divisor bits. It uses the same bit positions as SDHCI 3.0 (15..6) in ti_sdhci_read_2()
181 * clock divisor (with 0 and 1 both meaning divide by 1). The SDHCI in ti_sdhci_read_2()
187 * transformation when the SDHCI driver writes to the register. in ti_sdhci_read_2()
195 if (slot->version >= SDHCI_SPEC_300) in ti_sdhci_read_2()
202 * Standard 32-bit handling of command and transfer mode. in ti_sdhci_read_2()
205 return (sc->cmd_and_mode >> 16); in ti_sdhci_read_2()
207 return (sc->cmd_and_mode & 0x0000ffff); in ti_sdhci_read_2()
225 if (off == SDHCI_CAPABILITIES && sc->disable_highspeed) in ti_sdhci_read_4()
229 * Force the card-present state if necessary. in ti_sdhci_read_4()
231 if (off == SDHCI_PRESENT_STATE && sc->force_card_present) in ti_sdhci_read_4()
243 bus_read_multi_4(sc->mem_res, off + sc->sdhci_reg_off, data, count); in ti_sdhci_read_multi_4()
259 device_printf(dev, "Custom-enabling 8-bit bus\n"); in ti_sdhci_write_1()
262 device_printf(dev, "Custom-disabling 8-bit bus\n"); in ti_sdhci_write_1()
284 * Translate between the hardware and SDHCI 2.0 or 3.0 representations in ti_sdhci_write_2()
290 if (slot->version >= SDHCI_SPEC_300) in ti_sdhci_write_2()
306 * Standard 32-bit handling of command and transfer mode. in ti_sdhci_write_2()
309 sc->cmd_and_mode = (sc->cmd_and_mode & 0xffff0000) | in ti_sdhci_write_2()
313 sc->cmd_and_mode = (sc->cmd_and_mode & 0x0000ffff) | in ti_sdhci_write_2()
315 WR4(sc, SDHCI_TRANSFER_MODE, sc->cmd_and_mode); in ti_sdhci_write_2()
340 bus_write_multi_4(sc->mem_res, off + sc->sdhci_reg_off, data, count); in ti_sdhci_write_multi_4()
348 sdhci_generic_intr(&sc->slot); in ti_sdhci_intr()
360 ios = &slot->host.ios; in ti_sdhci_update_ios()
363 * There is an 8-bit-bus bit in the MMCHS control register which, when in ti_sdhci_update_ios()
364 * set, overrides the 1 vs 4 bit setting in the standard SDHCI in ti_sdhci_update_ios()
365 * registers. Set that bit first according to whether an 8-bit bus is in ti_sdhci_update_ios()
371 if (ios->bus_width == bus_width_8) in ti_sdhci_update_ios()
376 if (ios->bus_mode == opendrain) in ti_sdhci_update_ios()
378 else /* if (ios->bus_mode == pushpull) */ in ti_sdhci_update_ios()
392 if (sc->disable_readonly) in ti_sdhci_get_ro()
395 return (sdhci_fdt_gpio_get_readonly(sc->gpio)); in ti_sdhci_get_ro()
403 return (sdhci_fdt_gpio_get_present(sc->gpio)); in ti_sdhci_get_card_present()
410 /* sdhci_fdt_gpio_teardown(sc->gpio); */ in ti_sdhci_detach()
436 err = clk_get_freq(mmc_clk, &sc->baseclk_hz); in ti_sdhci_hw_init()
439 /* AM335x TRM 8.1.6.8 table 8-24 96MHz @ OPP100 */ in ti_sdhci_hw_init()
440 sc->baseclk_hz = 96000000; in ti_sdhci_hw_init()
448 if (--timeout == 0) { in ti_sdhci_hw_init()
465 * so that the main sdhci driver uses this same logic in its resets. in ti_sdhci_hw_init()
471 if (--timeout == 0) { in ti_sdhci_hw_init()
479 if (--timeout == 0) { in ti_sdhci_hw_init()
489 * slot.host.caps to reflect what voltages we can handle. Set those in ti_sdhci_hw_init()
496 if (sc->slot.host.caps & MMC_OCR_LOW_VOLTAGE) in ti_sdhci_hw_init()
498 if (sc->slot.host.caps & (MMC_OCR_290_300 | MMC_OCR_300_310)) in ti_sdhci_hw_init()
502 /* Set initial host configuration (1-bit, std speed, pwr off). */ in ti_sdhci_hw_init()
520 sc->dev = dev; in ti_sdhci_attach()
528 * The hardware can inherently do dual-voltage (1p8v, 3p0v) on the first in ti_sdhci_attach()
534 sc->slot.host.caps |= MMC_OCR_LOW_VOLTAGE; in ti_sdhci_attach()
536 if (OF_hasprop(node, "ti,dual-volt")) { in ti_sdhci_attach()
537 sc->slot.host.caps |= MMC_OCR_290_300 | MMC_OCR_300_310; in ti_sdhci_attach()
547 sc->mmchs_reg_off = OMAP4_MMCHS_REG_OFFSET; in ti_sdhci_attach()
548 sc->disable_highspeed = true; in ti_sdhci_attach()
553 sc->mmchs_reg_off = AM335X_MMCHS_REG_OFFSET; in ti_sdhci_attach()
561 * The standard SDHCI registers are at a fixed offset (the same on all in ti_sdhci_attach()
564 sc->sdhci_reg_off = sc->mmchs_reg_off + SDHCI_REG_OFFSET; in ti_sdhci_attach()
568 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in ti_sdhci_attach()
570 if (!sc->mem_res) { in ti_sdhci_attach()
577 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in ti_sdhci_attach()
579 if (!sc->irq_res) { in ti_sdhci_attach()
585 if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE, in ti_sdhci_attach()
586 NULL, ti_sdhci_intr, sc, &sc->intr_cookie)) { in ti_sdhci_attach()
593 * Set up handling of card-detect and write-protect gpio lines. in ti_sdhci_attach()
598 * would be to trust the sdhci controller's PRESENT_STATE register WP in ti_sdhci_attach()
602 sc->gpio = sdhci_fdt_gpio_setup(sc->dev, &sc->slot); in ti_sdhci_attach()
604 if (!OF_hasprop(node, "wp-gpios") && !OF_hasprop(node, "wp-disable")) in ti_sdhci_attach()
605 sc->disable_readonly = true; in ti_sdhci_attach()
616 * the range of 0-63MHz for a v2.0 controller. Since our clock runs in ti_sdhci_attach()
618 * register. When the register contains zero, the sdhci driver expects in ti_sdhci_attach()
621 sc->slot.max_clk = sc->baseclk_hz; in ti_sdhci_attach()
625 * sdhci driver to recalculate the timeout clock whenever the output in ti_sdhci_attach()
628 sc->slot.quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; in ti_sdhci_attach()
631 * The MMCHS hardware shifts the 136-bit response data (in violation of in ti_sdhci_attach()
632 * the spec), so tell the sdhci driver not to do the same in software. in ti_sdhci_attach()
634 sc->slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE; in ti_sdhci_attach()
638 * before waiting to see them de-asserted. in ti_sdhci_attach()
640 sc->slot.quirks |= SDHCI_QUIRK_WAITFOR_RESET_ASSERTED; in ti_sdhci_attach()
645 sc->slot.quirks |= SDHCI_QUIRK_WAIT_WHILE_BUSY; in ti_sdhci_attach()
650 sc->slot.quirks |= SDHCI_QUIRK_BROKEN_DMA; in ti_sdhci_attach()
657 sdhci_init_slot(dev, &sc->slot, 0); in ti_sdhci_attach()
660 * The SDHCI controller doesn't realize it, but we can support 8-bit in ti_sdhci_attach()
661 * even though we're not a v3.0 controller. If there's an fdt bus-width in ti_sdhci_attach()
664 if (OF_getencprop(node, "bus-width", &prop, sizeof(prop)) > 0) { in ti_sdhci_attach()
665 sc->slot.host.caps &= ~(MMC_CAP_4_BIT_DATA | in ti_sdhci_attach()
669 sc->slot.host.caps |= MMC_CAP_8_BIT_DATA; in ti_sdhci_attach()
672 sc->slot.host.caps |= MMC_CAP_4_BIT_DATA; in ti_sdhci_attach()
677 device_printf(dev, "Bad bus-width value %u\n", prop); in ti_sdhci_attach()
683 * If the slot is flagged with the non-removable property, set our flag in ti_sdhci_attach()
687 if (OF_hasprop(node, "non-removable")) in ti_sdhci_attach()
688 sc->force_card_present = true; in ti_sdhci_attach()
693 sdhci_start_slot(&sc->slot); in ti_sdhci_attach()
697 if (sc->intr_cookie) in ti_sdhci_attach()
698 bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); in ti_sdhci_attach()
699 if (sc->irq_res) in ti_sdhci_attach()
700 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); in ti_sdhci_attach()
701 if (sc->mem_res) in ti_sdhci_attach()
702 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); in ti_sdhci_attach()
714 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data != 0) { in ti_sdhci_probe()
715 device_set_desc(dev, "TI MMCHS (SDHCI 2.0)"); in ti_sdhci_probe()
739 /* SDHCI registers accessors */