aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorOleksandr Tymoshenko <gonzo@FreeBSD.org>2013-02-17 00:23:42 +0000
committerOleksandr Tymoshenko <gonzo@FreeBSD.org>2013-02-17 00:23:42 +0000
commitd3d7f709ce4264bfe28287329e524b5af30e2a88 (patch)
tree3c195b128c49f153627090d146a6f89f41f2b7a0 /sys
parent7337a22fb00decfa1168eb8ffebfc1b5eec091d3 (diff)
downloadsrc-d3d7f709ce4264bfe28287329e524b5af30e2a88.tar.gz
src-d3d7f709ce4264bfe28287329e524b5af30e2a88.zip
- 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.
Notes
Notes: svn path=/head/; revision=246888
Diffstat (limited to 'sys')
-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 14422e25f803..1b099866f400 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),