Lines Matching +full:sdhci +full:- +full:caps

1 /*-
29 * SDHCI driver glue for NVIDIA Tegra family
58 #include <dev/sdhci/sdhci.h>
59 #include <dev/sdhci/sdhci_fdt_gpio.h>
95 {"nvidia,tegra124-sdhci", 1},
96 {"nvidia,tegra210-sdhci", 1},
106 u_int caps; /* If we override SDHCI_CAPABILITIES */ member
122 return (bus_read_4(sc->mem_res, off)); in RD4()
131 return (bus_read_1(sc->mem_res, off)); in tegra_sdhci_read_1()
140 return (bus_read_2(sc->mem_res, off)); in tegra_sdhci_read_2()
150 val32 = bus_read_4(sc->mem_res, off); in tegra_sdhci_read_4()
151 /* Force the card-present state if necessary. */ in tegra_sdhci_read_4()
152 if (off == SDHCI_PRESENT_STATE && sc->force_card_present) in tegra_sdhci_read_4()
164 bus_read_multi_4(sc->mem_res, off, data, count); in tegra_sdhci_read_multi_4()
174 bus_write_1(sc->mem_res, off, val); in tegra_sdhci_write_1()
184 bus_write_2(sc->mem_res, off, val); in tegra_sdhci_write_2()
194 bus_write_4(sc->mem_res, off, val); in tegra_sdhci_write_4()
204 bus_write_multi_4(sc->mem_res, off, data, count); in tegra_sdhci_write_multi_4()
212 sdhci_generic_intr(&sc->slot); in tegra_sdhci_intr()
221 return (sdhci_fdt_gpio_get_readonly(sc->gpio)); in tegra_sdhci_get_ro()
229 return (sdhci_fdt_gpio_get_present(sc->gpio)); in tegra_sdhci_get_card_present()
245 if (cd->ocd_data == 0) in tegra_sdhci_probe()
249 device_set_desc(dev, "Tegra SDHCI controller"); in tegra_sdhci_probe()
251 /* Allow dts to patch quirks, slots, and max-frequency. */ in tegra_sdhci_probe()
253 sc->quirks = cid; in tegra_sdhci_probe()
254 if ((OF_getencprop(node, "max-frequency", &cid, sizeof(cid))) > 0) in tegra_sdhci_probe()
255 sc->max_clk = cid; in tegra_sdhci_probe()
269 sc->dev = dev; in tegra_sdhci_attach()
273 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in tegra_sdhci_attach()
275 if (!sc->mem_res) { in tegra_sdhci_attach()
282 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in tegra_sdhci_attach()
284 if (!sc->irq_res) { in tegra_sdhci_attach()
290 rv = hwreset_get_by_ofw_name(sc->dev, 0, "sdhci", &sc->reset); in tegra_sdhci_attach()
292 device_printf(sc->dev, "Cannot get 'sdhci' reset\n"); in tegra_sdhci_attach()
295 rv = hwreset_assert(sc->reset); in tegra_sdhci_attach()
297 device_printf(dev, "Cannot reset 'sdhci' reset\n"); in tegra_sdhci_attach()
301 gpio_pin_get_by_ofw_property(sc->dev, node, "power-gpios", in tegra_sdhci_attach()
302 &sc->gpio_power); in tegra_sdhci_attach()
304 if (OF_hasprop(node, "assigned-clocks")) { in tegra_sdhci_attach()
305 rv = clk_set_assigned(sc->dev, node); in tegra_sdhci_attach()
312 rv = clk_get_by_ofw_index(dev, 0, 0, &sc->clk); in tegra_sdhci_attach()
317 rv = clk_enable(sc->clk); in tegra_sdhci_attach()
322 rv = clk_set_freq(sc->clk, 48000000, CLK_SET_ROUND_DOWN); in tegra_sdhci_attach()
326 rv = clk_get_freq(sc->clk, &freq); in tegra_sdhci_attach()
332 rv = hwreset_deassert(sc->reset); in tegra_sdhci_attach()
334 device_printf(dev, "Cannot unreset 'sdhci' reset\n"); in tegra_sdhci_attach()
341 sc->max_clk = (int)freq; in tegra_sdhci_attach()
342 sc->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | in tegra_sdhci_attach()
347 sc->caps = RD4(sc, SDHCI_CAPABILITIES); in tegra_sdhci_attach()
348 if (OF_getencprop(node, "bus-width", &prop, sizeof(prop)) > 0) { in tegra_sdhci_attach()
349 sc->caps &= ~(MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA); in tegra_sdhci_attach()
352 sc->caps |= MMC_CAP_8_BIT_DATA; in tegra_sdhci_attach()
355 sc->caps |= MMC_CAP_4_BIT_DATA; in tegra_sdhci_attach()
360 device_printf(dev, "Bad bus-width value %u\n", prop); in tegra_sdhci_attach()
364 if (OF_hasprop(node, "non-removable")) in tegra_sdhci_attach()
365 sc->force_card_present = 1; in tegra_sdhci_attach()
367 * Clear clock field, so SDHCI driver uses supplied frequency. in tegra_sdhci_attach()
368 * in sc->slot.max_clk in tegra_sdhci_attach()
370 sc->caps &= ~SDHCI_CLOCK_V3_BASE_MASK; in tegra_sdhci_attach()
372 sc->slot.quirks = sc->quirks; in tegra_sdhci_attach()
373 sc->slot.max_clk = sc->max_clk; in tegra_sdhci_attach()
374 sc->slot.caps = sc->caps; in tegra_sdhci_attach()
376 if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO | INTR_MPSAFE, in tegra_sdhci_attach()
377 NULL, tegra_sdhci_intr, sc, &sc->intr_cookie)) { in tegra_sdhci_attach()
382 rv = sdhci_init_slot(dev, &sc->slot, 0); in tegra_sdhci_attach()
387 sc->gpio = sdhci_fdt_gpio_setup(sc->dev, &sc->slot); in tegra_sdhci_attach()
392 sdhci_start_slot(&sc->slot); in tegra_sdhci_attach()
397 if (sc->gpio != NULL) in tegra_sdhci_attach()
398 sdhci_fdt_gpio_teardown(sc->gpio); in tegra_sdhci_attach()
399 if (sc->intr_cookie != NULL) in tegra_sdhci_attach()
400 bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); in tegra_sdhci_attach()
401 if (sc->gpio_power != NULL) in tegra_sdhci_attach()
402 gpio_pin_release(sc->gpio_power); in tegra_sdhci_attach()
403 if (sc->clk != NULL) in tegra_sdhci_attach()
404 clk_release(sc->clk); in tegra_sdhci_attach()
405 if (sc->reset != NULL) in tegra_sdhci_attach()
406 hwreset_release(sc->reset); in tegra_sdhci_attach()
407 if (sc->irq_res != NULL) in tegra_sdhci_attach()
408 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); in tegra_sdhci_attach()
409 if (sc->mem_res != NULL) in tegra_sdhci_attach()
410 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); in tegra_sdhci_attach()
419 struct sdhci_slot *slot = &sc->slot; in tegra_sdhci_detach()
422 sdhci_fdt_gpio_teardown(sc->gpio); in tegra_sdhci_detach()
423 clk_release(sc->clk); in tegra_sdhci_detach()
424 bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); in tegra_sdhci_detach()
425 bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq_res), in tegra_sdhci_detach()
426 sc->irq_res); in tegra_sdhci_detach()
430 rman_get_rid(sc->mem_res), in tegra_sdhci_detach()
431 sc->mem_res); in tegra_sdhci_detach()
452 /* SDHCI registers accessors */
466 static DEFINE_CLASS_0(sdhci, tegra_sdhci_driver, tegra_sdhci_methods,
471 MMC_DECLARE_BRIDGE(sdhci);