summaryrefslogtreecommitdiffstats
path: root/sys/arm/broadcom
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2013-02-17 00:23:42 +0000
committergonzo <gonzo@FreeBSD.org>2013-02-17 00:23:42 +0000
commit49100b4dc28e35ff854e4ad41151175587323b1f (patch)
tree3c195b128c49f153627090d146a6f89f41f2b7a0 /sys/arm/broadcom
parentbaf1079adc1673d7cdbb130249a0af6b71b8a5eb (diff)
downloadFreeBSD-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/broadcom')
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_sdhci.c24
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),
OpenPOWER on IntegriCloud