<br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Nov 26, 2012 at 10:38 PM, Stephen Warren <span dir="ltr"><<a href="mailto:swarren@wwwdotorg.org" target="_blank">swarren@wwwdotorg.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This adds a simple driver for the BCM2835's SD controller.<br>
<br>
Workarounds are implemented for:<br>
* Register writes can't be too close to each-other in time, or they will<br>
  be lost.<br>
* Register accesses must all be 32-bit, so implement custom accessors.<br>
<br>
This code was extracted from:<br>
git://<a href="http://github.com/gonzoua/u-boot-pi.git" target="_blank">github.com/gonzoua/u-boot-pi.git</a> master<br>
which was created by Oleksandr Tymoshenko.<br>
<br>
Portions of the code there were obviously based on the Linux kernel at:<br>
git://<a href="http://github.com/raspberrypi/linux.git" target="_blank">github.com/raspberrypi/linux.git</a> rpi-3.6.y<br>
commit f5b930b "Main bcm2708 linux port" signed-off-by Dom Cobley.<br>
<br>
swarren changed the following for upstream:<br>
* Removed hack udelay()s in bcm2835_sdhci_raw_writel(); setting<br>
  SDHCI_QUIRK_WAIT_SEND_CMD appears to solve the issues.<br>
* Remove register logging from read*/write* functions.<br>
* Sort out confusion with min/max_freq values passed to add_sdhci().<br>
* Use more descriptive variable names and calculations in IO accessors.<br>
* Simplified and commented twoticks_delay calculation.<br>
* checkpatch fixes.<br>
<br>
Cc: Andy Fleming <<a href="mailto:afleming@gmail.com">afleming@gmail.com</a>><br>
Signed-off-by: Oleksandr Tymoshenko <<a href="mailto:gonzo@bluezbox.com">gonzo@bluezbox.com</a>><br>
Signed-off-by: Stephen Warren <<a href="mailto:swarren@wwwdotorg.org">swarren@wwwdotorg.org</a>><br>
---<br>
v4:<br>
* Merged with video patch series due to dependencies in rpi_b.h.<br>
* Rebased onto latest u-boot-arm/master; no real changes.<br>
v3: No such version was posted.<br>
v2:<br>
* Use more descriptive variable names and calculations in IO accessors.<br>
* Add Oleksandr's S-o-b.<br>
* Rewrite commit description to note that the Linux code this was derived<br>
  from was S-o-b Dom Cobley.<br>
---<br>
 arch/arm/include/asm/arch-bcm2835/sdhci.h |   24 ++++<br>
 drivers/mmc/Makefile                      |    1 +<br>
 drivers/mmc/bcm2835_sdhci.c               |  177 +++++++++++++++++++++++++++++<br>
 3 files changed, 202 insertions(+)<br>
 create mode 100644 arch/arm/include/asm/arch-bcm2835/sdhci.h<br>
 create mode 100644 drivers/mmc/bcm2835_sdhci.c<br>
<br>
diff --git a/arch/arm/include/asm/arch-bcm2835/sdhci.h b/arch/arm/include/asm/arch-bcm2835/sdhci.h<br>
new file mode 100644<br>
index 0000000..a4f867b<br>
--- /dev/null<br>
+++ b/arch/arm/include/asm/arch-bcm2835/sdhci.h<br>
@@ -0,0 +1,24 @@<br>
+/*<br>
+ * (C) Copyright 2012 Stephen Warren<br>
+ *<br>
+ * See file CREDITS for list of people who contributed to this<br>
+ * project.<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or<br>
+ * modify it under the terms of the GNU General Public License<br>
+ * version 2 as published by the Free Software Foundation.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful, but<br>
+ * WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
+ * GNU General Public License for more details.<br>
+ */<br>
+<br>
+#ifndef _BCM2835_SDHCI_H_<br>
+#define _BCM2835_SDHCI_H_<br>
+<br>
+#define BCM2835_SDHCI_BASE 0x20300000<br>
+<br>
+int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq);<br>
+<br>
+#endif<br>
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile<br>
index a1dd730..6be36f2 100644<br>
--- a/drivers/mmc/Makefile<br>
+++ b/drivers/mmc/Makefile<br>
@@ -43,6 +43,7 @@ COBJS-$(CONFIG_MXS_MMC) += mxsmmc.o<br>
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o<br>
 COBJS-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o<br>
 COBJS-$(CONFIG_SDHCI) += sdhci.o<br>
+COBJS-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o<br>
 COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o<br>
 COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o<br>
 COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o<br>
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c<br>
new file mode 100644<br>
index 0000000..8f2137e<br>
--- /dev/null<br>
+++ b/drivers/mmc/bcm2835_sdhci.c<br>
@@ -0,0 +1,177 @@<br>
+/*<br>
+ * This code was extracted from:<br>
+ * git://<a href="http://github.com/gonzoua/u-boot-pi.git" target="_blank">github.com/gonzoua/u-boot-pi.git</a> master<br>
+ * and hence presumably (C) 2012 Oleksandr Tymoshenko<br>
+ *<br>
+ * Tweaks for U-Boot upstreaming<br>
+ * (C) 2012 Stephen Warren<br>
+ *<br>
+ * Portions (e.g. read/write macros, concepts for back-to-back register write<br>
+ * timing workarounds) obviously extracted from the Linux kernel at:<br>
+ * <a href="https://github.com/raspberrypi/linux.git" target="_blank">https://github.com/raspberrypi/linux.git</a> rpi-3.6.y<br>
+ *<br>
+ * The Linux kernel code has the following (c) and license, which is hence<br>
+ * propagated to Oleksandr's tree and here:<br>
+ *<br>
+ * Support for SDHCI device on 2835<br>
+ * Based on sdhci-bcm2708.c (c) 2010 Broadcom<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or modify<br>
+ * it under the terms of the GNU General Public License version 2 as<br>
+ * published by the Free Software Foundation.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
+ * GNU General Public License for more details.<br>
+ *<br>
+ * You should have received a copy of the GNU General Public License<br>
+ * along with this program; if not, write to the Free Software<br>
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br>
+ */<br>
+<br>
+/* Supports:<br>
+ * SDHCI platform device - Arasan SD controller in BCM2708<br>
+ *<br>
+ * Inspired by sdhci-pci.c, by Pierre Ossman<br>
+ */<br>
+<br>
+#include <common.h><br>
+#include <malloc.h><br>
+#include <sdhci.h><br>
+<br>
+/* 400KHz is max freq for card ID etc. Use that as min */<br>
+#define MIN_FREQ 400000<br>
+<br>
+static uint twoticks_delay;<br>
+<br>
+static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,<br>
+                                               int reg)<br>
+{<br>
+       static ulong last_write;<br></blockquote><div><br></div><div><br></div><div>I don't suppose there's any way you could do this without a global variable? If someone ever plops two of these things down on a system, we're gonna have weird race condition possibilities. Perhaps an array, accessed via host->index?</div>
<div><br></div><div> Andy</div></div></div>