Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add driper for R-Pi eMMC controller

  • Loading branch information...
commit c78b8ea9ae717432770843b825ea8a1a77f223fc 1 parent b58d9ae
@gonzoua authored
View
16 arch/arm/cpu/arm1176/bcm2835/init.c
@@ -21,6 +21,7 @@
#include <config.h>
#include <common.h>
+#include <asm/arch/regs.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -31,19 +32,28 @@ DECLARE_GLOBAL_DATA_PTR;
int arch_cpu_init(void)
{
-#ifdef CONFIG_USB_DWC_OTG
+#if defined(CONFIG_USB_DWC_OTG) || defined(CONFIG_BCM2835_SDHCI)
/*
- * Request power for USB
+ * Request power for USB
*/
volatile uint32_t *mbox0_read = (volatile uint32_t *)BCM2835_ARM_MBOX0_BASE;
volatile uint32_t *mbox0_write = (volatile uint32_t *)BCM2835_ARM_MBOX1_BASE;
volatile uint32_t *mbox0_status = (volatile uint32_t *)(BCM2835_ARM_MBOX0_BASE + 0x18);
volatile uint32_t *mbox0_config = (volatile uint32_t *)(BCM2835_ARM_MBOX0_BASE + 0x1C);
+ uint32_t val = 0;
+
+#if defined(CONFIG_USB_DWC_OTG)
+ val |= 8 << 4;
+#endif
+
+#if defined(CONFIG_BCM2835_SDHCI)
+ val |= 1 << 4;
+#endif
while (*mbox0_status & 0x80000000) {
}
- *mbox0_write = MBOX_MSG(0, (8 << 4));
+ *mbox0_write = MBOX_MSG(0, val);
#endif
return 0;
View
1  arch/arm/cpu/arm1176/bcm2835/timer.c
@@ -16,6 +16,7 @@
#include <common.h>
#include <asm/io.h>
+#include <asm/arch/regs.h>
#include <asm/arch/timer.h>
int timer_init(void)
View
7 arch/arm/include/asm/arch-bcm2835/regs.h
@@ -0,0 +1,7 @@
+#ifndef _BCM2835_REGS_H
+#define _BCM2835_REGS_H
+
+#define BCM2835_TIMER_PHYSADDR 0x20003000
+#define BCM2835_EMMC_PHYSADDR 0x20300000
+
+#endif
View
2  arch/arm/include/asm/arch-bcm2835/timer.h
@@ -17,8 +17,6 @@
#ifndef _BCM2835_TIMER_H
#define _BCM2835_TIMER_H
-#define BCM2835_TIMER_PHYSADDR 0x20003000
-
struct bcm2835_timer_regs {
u32 cs;
u32 clo;
View
1  drivers/mmc/Makefile
@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libmmc.o
+COBJS-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o
COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
COBJS-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o
COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
View
158 drivers/mmc/bcm2835_sdhci.c
@@ -0,0 +1,158 @@
+/*
+ * Support for SDHCI device on 2835
+ * Based on sdhci-bcm2708.c (c) 2010 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * SDHCI platform device - Arasan SD controller in BCM2708
+ *
+ * Inspired by sdhci-pci.c, by Pierre Ossman
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <sdhci.h>
+#include <asm/arch/regs.h>
+
+#undef BCM2835_TRACE_REGISTERS
+#define WRITE_DELAY 40
+
+static char *BCMSDH_NAME = "bcm2835_sdh";
+static struct sdhci_ops bcm2835_ops;
+
+inline static void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ writel(val, host->ioaddr + reg);
+ udelay(20000);
+}
+
+inline static u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg)
+{
+
+ return readl(host->ioaddr + reg);
+}
+
+static void bcm2835_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+#ifdef BCM2835_TRACE_REGISTERS
+ printf("SDHCI[%02x] writel %08x\n", reg, val);
+#endif
+ writel(val, host->ioaddr + reg);
+}
+
+static void bcm2835_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ static u32 shadow = 0;
+
+#ifdef BCM2835_TRACE_REGISTERS
+ printf("SDHCI[%02x] writew %04x\n", reg, val);
+#endif
+
+ u32 p = reg == SDHCI_COMMAND ? shadow :
+ bcm2835_sdhci_raw_readl(host, reg & ~3);
+ u32 s = reg << 3 & 0x18;
+ u32 l = val << s;
+ u32 m = 0xffff << s;
+
+ if (reg == SDHCI_TRANSFER_MODE)
+ shadow = (p & ~m) | l;
+ else {
+ bcm2835_sdhci_raw_writel(host, (p & ~m) | l, reg & ~3);
+ }
+}
+
+static void bcm2835_sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+#ifdef BCM2835_TRACE_REGISTERS
+ printf("SDHCI[%02x] writeb %02x\n", reg, val);
+#endif
+
+ u32 p = bcm2835_sdhci_raw_readl(host, reg & ~3);
+ u32 s = reg << 3 & 0x18;
+ u32 l = val << s;
+ u32 m = 0xff << s;
+
+ bcm2835_sdhci_raw_writel(host, (p & ~m) | l, reg & ~3);
+}
+
+static u32 bcm2835_sdhci_readl(struct sdhci_host *host, int reg)
+{
+ u32 val = readl(host->ioaddr + reg);
+#ifdef BCM2835_TRACE_REGISTERS
+ printf("SDHCI[%02x] readl %08x\n", reg, val);
+#endif
+ return val;
+}
+
+static u16 bcm2835_sdhci_readw(struct sdhci_host *host, int reg)
+{
+ u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3));
+ val = val >> (reg << 3 & 0x18) & 0xffff;
+
+#ifdef BCM2835_TRACE_REGISTERS
+ printf("SDHCI[%02x] readw %04x\n", reg, val);
+#endif
+
+ return (u16)val;
+}
+
+static u8 bcm2835_sdhci_readb(struct sdhci_host *host, int reg)
+{
+ u32 val = bcm2835_sdhci_raw_readl(host, (reg & ~3));
+ val = val >> (reg << 3 & 0x18) & 0xff;
+
+#ifdef BCM2835_TRACE_REGISTERS
+ printf("SDHCI[%02x] readb %02x\n", reg, val);
+#endif
+
+ return (u8)val;
+}
+
+int bcm2835_sdh_init(u32 regbase)
+{
+ struct sdhci_host *host = NULL;
+
+ host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
+ if (!host) {
+ printf("sdh_host malloc fail!\n");
+ return 1;
+ }
+
+ host->name = BCMSDH_NAME;
+ host->ioaddr = (void *)regbase;
+ host->quirks = SDHCI_QUIRK_BROKEN_VOLTAGE;
+ host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;;
+
+ memset(&bcm2835_ops, 0, sizeof(struct sdhci_ops));
+ bcm2835_ops.write_l = bcm2835_sdhci_writel;
+ bcm2835_ops.write_w = bcm2835_sdhci_writew;
+ bcm2835_ops.write_b = bcm2835_sdhci_writeb;
+ bcm2835_ops.read_l = bcm2835_sdhci_readl;
+ bcm2835_ops.read_w = bcm2835_sdhci_readw;
+ bcm2835_ops.read_b = bcm2835_sdhci_readb;
+ host->ops = &bcm2835_ops;
+
+ host->version = sdhci_readw(host, SDHCI_HOST_VERSION) & 0xff;
+ add_sdhci(host, 80000000, 0);
+
+ return 0;
+}
+
+int board_mmc_init()
+{
+
+ bcm2835_sdh_init(BCM2835_EMMC_PHYSADDR);
+}
View
10 include/configs/rpi_b.h
@@ -60,6 +60,13 @@
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
sizeof(CONFIG_SYS_PROMPT) + 16)
+/* SD/MMC configuration */
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MMC
+#define CONFIG_SDHCI
+#define CONFIG_MMC_SDHCI_IO_ACCESSORS
+#define CONFIG_BCM2835_SDHCI
+
/* Environment */
#define CONFIG_ENV_SIZE SZ_16K
#define CONFIG_ENV_IS_NOWHERE
@@ -91,4 +98,7 @@
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+
#endif
Please sign in to comment.
Something went wrong with that request. Please try again.