diff options
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_sdhci.c | 59 |
1 files changed, 10 insertions, 49 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index 93bfcab..11cf3bc 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -29,32 +29,17 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> -#include <sys/bio.h> #include <sys/bus.h> -#include <sys/conf.h> -#include <sys/endian.h> #include <sys/kernel.h> -#include <sys/kthread.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/module.h> #include <sys/mutex.h> -#include <sys/queue.h> -#include <sys/resource.h> #include <sys/rman.h> #include <sys/sysctl.h> #include <sys/taskqueue.h> -#include <sys/time.h> -#include <sys/timetc.h> -#include <sys/watchdog.h> - -#include <sys/kdb.h> #include <machine/bus.h> -#include <machine/cpu.h> -#include <machine/cpufunc.h> -#include <machine/resource.h> -#include <machine/intr.h> #include <dev/fdt/fdt_common.h> #include <dev/ofw/ofw_bus.h> @@ -82,16 +67,9 @@ __FBSDID("$FreeBSD$"); #define dprintf(fmt, args...) #endif -/* - * Arasan HC seems to have problem with Data CRC on lower frequencies. - * Use this tunable to cap initialization sequence frequency at higher - * value. Default is standard 400kHz - */ -static int bcm2835_sdhci_min_freq = 400000; static int bcm2835_sdhci_hs = 1; static int bcm2835_sdhci_pio_mode = 0; -TUNABLE_INT("hw.bcm2835.sdhci.min_freq", &bcm2835_sdhci_min_freq); TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs); TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode); @@ -208,16 +186,12 @@ bcm_sdhci_attach(device_t dev) RF_ACTIVE); if (!sc->sc_irq_res) { device_printf(dev, "cannot allocate interrupt\n"); - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); err = ENXIO; goto fail; } if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE, - NULL, bcm_sdhci_intr, sc, &sc->sc_intrhand)) - { - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); + NULL, bcm_sdhci_intr, sc, &sc->sc_intrhand)) { device_printf(dev, "cannot setup interrupt handler\n"); err = ENXIO; goto fail; @@ -283,6 +257,7 @@ fail: bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); if (sc->sc_mem_res) bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); + mtx_destroy(&sc->sc_mtx); return (err); } @@ -319,21 +294,15 @@ RD4(struct bcm_sdhci_softc *sc, bus_size_t off) static inline void WR4(struct bcm_sdhci_softc *sc, bus_size_t off, uint32_t val) { - bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val); - if ((off != SDHCI_BUFFER && off != SDHCI_INT_STATUS && off != SDHCI_CLOCK_CONTROL)) - { - int timeout = 100000; - while (val != bus_space_read_4(sc->sc_bst, sc->sc_bsh, off) - && --timeout > 0) - continue; - - if (timeout <= 0) - printf("sdhci_brcm: writing 0x%X to reg 0x%X " - "always gives 0x%X\n", - val, (uint32_t)off, - bus_space_read_4(sc->sc_bst, sc->sc_bsh, off)); - } + bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val); + /* + * The Arasan HC has a bug where it may lose the content of + * consecutive writes to registers that are within two SD-card + * clock cycles of each other (a clock domain crossing problem). + */ + if (sc->sc_slot.clock > 0) + DELAY(((2 * 1000000) / sc->sc_slot.clock) + 1); } static uint8_t @@ -425,13 +394,6 @@ bcm_sdhci_write_multi_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, bus_space_write_multi_4(sc->sc_bst, sc->sc_bsh, off, data, count); } -static uint32_t -bcm_sdhci_min_freq(device_t dev, struct sdhci_slot *slot) -{ - - return bcm2835_sdhci_min_freq; -} - static void bcm_sdhci_start_dma_seg(struct bcm_sdhci_softc *sc) { @@ -684,7 +646,6 @@ static device_method_t bcm_sdhci_methods[] = { DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host), DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), - DEVMETHOD(sdhci_min_freq, bcm_sdhci_min_freq), /* Platform transfer methods */ DEVMETHOD(sdhci_platform_will_handle, bcm_sdhci_will_handle_transfer), DEVMETHOD(sdhci_platform_start_transfer, bcm_sdhci_start_transfer), |