diff options
author | gonzo <gonzo@FreeBSD.org> | 2013-02-17 00:23:42 +0000 |
---|---|---|
committer | gonzo <gonzo@FreeBSD.org> | 2013-02-17 00:23:42 +0000 |
commit | 49100b4dc28e35ff854e4ad41151175587323b1f (patch) | |
tree | 3c195b128c49f153627090d146a6f89f41f2b7a0 /sys/arm | |
parent | baf1079adc1673d7cdbb130249a0af6b71b8a5eb (diff) | |
download | FreeBSD-src-49100b4dc28e35ff854e4ad41151175587323b1f.zip FreeBSD-src-49100b4dc28e35ff854e4ad41151175587323b1f.tar.gz |
- Add hw.bcm2835.sdhci.hs tunable to enable/disable highspeed mode in
SDHCI driver
Suggested by: Daisuke Aoyama
- Set initilization sequence frequency to 8MHz. It should fix Data CRC
errors. Standard requires initialization sequence to be executed
at 400KHz but on this hardware low frequncies seems to cause
Data CRC errors.
Value was derived from analyzing hardware signals after
Raspberry Pi is powered up. Before any data is read though DATA line
adapter's clock frequency is changed to 8MHz.
Modern cards should function fine at 8MHz but for older MMC cards it
can be overriden by setting hw.bcm2835.sdhci.min_freq tunable.
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/broadcom/bcm2835/bcm2835_sdhci.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index 14422e2..1b09986 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -78,6 +78,12 @@ __FBSDID("$FreeBSD$"); #define dprintf(fmt, args...) #endif +static int bcm2835_sdhci_min_freq = 8000000; +static int bcm2835_sdhci_hs = 1; + +TUNABLE_INT("hw.bcm2835.sdhci.min_freq", &bcm2835_sdhci_min_freq); +TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs); + struct bcm_sdhci_dmamap_arg { bus_addr_t sc_dma_busaddr; }; @@ -180,7 +186,9 @@ bcm_sdhci_attach(device_t dev) goto fail; } - sc->sc_slot.caps = SDHCI_CAN_VDD_330 | SDHCI_CAN_VDD_180 | SDHCI_CAN_DO_HISPD; + sc->sc_slot.caps = SDHCI_CAN_VDD_330 | SDHCI_CAN_VDD_180; + if (bcm2835_sdhci_hs) + sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD; sc->sc_slot.caps |= (default_freq << SDHCI_CLOCK_BASE_SHIFT); sc->sc_slot.quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL @@ -334,6 +342,19 @@ 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) +{ + + /* + * Arasan HC seems to have problem with + * Data CRC on lower frequencies. Cap minimum + * frequncy at 8MHz (or whatever set via tunable) + * to work around this issue + */ + return bcm2835_sdhci_min_freq; +} + static device_method_t bcm_sdhci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, bcm_sdhci_probe), @@ -353,6 +374,7 @@ static device_method_t bcm_sdhci_methods[] = { DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), /* SDHCI registers accessors */ + DEVMETHOD(sdhci_min_freq, bcm_sdhci_min_freq), DEVMETHOD(sdhci_read_1, bcm_sdhci_read_1), DEVMETHOD(sdhci_read_2, bcm_sdhci_read_2), DEVMETHOD(sdhci_read_4, bcm_sdhci_read_4), |