Patchwork [U-Boot,V5,REPOST,7/7] ARM: rpi_b: enable SD controller, add related env/cmds

login
register
mail settings
Submitter Stephen Warren
Date Jan. 16, 2013, 2:26 a.m.
Message ID <1358303219-17503-7-git-send-email-swarren@wwwdotorg.org>
Download mbox | patch
Permalink /patch/212380/
State Superseded
Delegated to: Albert ARIBAUD
Headers show

Comments

Stephen Warren - Jan. 16, 2013, 2:26 a.m.
Enable the SD controller driver for the Raspberry Pi. Enable a number
of useful MMC, partition, and filesystem-related commands. Set up the
environment to provide standard locations for loading a kernel, DTB,
etc. Provide a boot command that loads and executes boot.scr.uimg from
the SD card; this is written considering future extensibilty to USB
storage.

Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
---
v5: No change.
v4:
* Merged with video patch series due to dependencies in rpi_b.h.
* Rebased onto latest u-boot-arm/master; no real changes.
v3: No such version was posted.
v2: No change.
---
 arch/arm/include/asm/arch-bcm2835/mbox.h |   26 ++++++++++++
 board/raspberrypi/rpi_b/rpi_b.c          |   26 ++++++++++++
 include/configs/rpi_b.h                  |   68 ++++++++++++++++++++++++++++--
 3 files changed, 117 insertions(+), 3 deletions(-)
Albert ARIBAUD - March 20, 2013, 3:31 p.m.
Hi Stephen,

On Tue, 15 Jan 2013 19:26:59 -0700, Stephen Warren
<swarren@wwwdotorg.org> wrote:

> Enable the SD controller driver for the Raspberry Pi. Enable a number
> of useful MMC, partition, and filesystem-related commands. Set up the
> environment to provide standard locations for loading a kernel, DTB,
> etc. Provide a boot command that loads and executes boot.scr.uimg from
> the SD card; this is written considering future extensibilty to USB
> storage.
> 
> Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
> ---
> v5: No change.
> v4:
> * Merged with video patch series due to dependencies in rpi_b.h.
> * Rebased onto latest u-boot-arm/master; no real changes.
> v3: No such version was posted.
> v2: No change.
> ---
>  arch/arm/include/asm/arch-bcm2835/mbox.h |   26 ++++++++++++
>  board/raspberrypi/rpi_b/rpi_b.c          |   26 ++++++++++++
>  include/configs/rpi_b.h                  |   68 ++++++++++++++++++++++++++++--
>  3 files changed, 117 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h
> index 4752091..b07c4a0 100644
> --- a/arch/arm/include/asm/arch-bcm2835/mbox.h
> +++ b/arch/arm/include/asm/arch-bcm2835/mbox.h
> @@ -144,6 +144,32 @@ struct bcm2835_mbox_tag_get_arm_mem {
>  	} body;
>  };
>  
> +#define BCM2835_MBOX_TAG_GET_CLOCK_RATE	0x00030002
> +
> +#define BCM2835_MBOX_CLOCK_ID_EMMC	1
> +#define BCM2835_MBOX_CLOCK_ID_UART	2
> +#define BCM2835_MBOX_CLOCK_ID_ARM	3
> +#define BCM2835_MBOX_CLOCK_ID_CORE	4
> +#define BCM2835_MBOX_CLOCK_ID_V3D	5
> +#define BCM2835_MBOX_CLOCK_ID_H264	6
> +#define BCM2835_MBOX_CLOCK_ID_ISP	7
> +#define BCM2835_MBOX_CLOCK_ID_SDRAM	8
> +#define BCM2835_MBOX_CLOCK_ID_PIXEL	9
> +#define BCM2835_MBOX_CLOCK_ID_PWM	10
> +
> +struct bcm2835_mbox_tag_get_clock_rate {
> +	struct bcm2835_mbox_tag_hdr tag_hdr;
> +	union {
> +		struct {
> +			u32 clock_id;
> +		} req;
> +		struct {
> +			u32 clock_id;
> +			u32 rate_hz;
> +		} resp;
> +	} body;
> +};
> +
>  #define BCM2835_MBOX_TAG_ALLOCATE_BUFFER	0x00040001
>  
>  struct bcm2835_mbox_tag_allocate_buffer {
> diff --git a/board/raspberrypi/rpi_b/rpi_b.c b/board/raspberrypi/rpi_b/rpi_b.c
> index 3c654a1..6b3e095 100644
> --- a/board/raspberrypi/rpi_b/rpi_b.c
> +++ b/board/raspberrypi/rpi_b/rpi_b.c
> @@ -16,6 +16,7 @@
>  
>  #include <common.h>
>  #include <asm/arch/mbox.h>
> +#include <asm/arch/sdhci.h>
>  #include <asm/global_data.h>
>  
>  DECLARE_GLOBAL_DATA_PTR;
> @@ -26,6 +27,12 @@ struct msg_get_arm_mem {
>  	u32 end_tag;
>  };
>  
> +struct msg_get_clock_rate {
> +	struct bcm2835_mbox_hdr hdr;
> +	struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
> +	u32 end_tag;
> +};
> +
>  int dram_init(void)
>  {
>  	ALLOC_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1, 16);
> @@ -51,3 +58,22 @@ int board_init(void)
>  
>  	return 0;
>  }
> +
> +int board_mmc_init(void)
> +{
> +	ALLOC_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1, 16);
> +	int ret;
> +
> +	BCM2835_MBOX_INIT_HDR(msg_clk);
> +	BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE);
> +	msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
> +
> +	ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr);
> +	if (ret) {
> +		printf("bcm2835: Could not query eMMC clock rate\n");
> +		return -1;
> +	}
> +
> +	return bcm2835_sdhci_init(BCM2835_SDHCI_BASE,
> +				  msg_clk->get_clock_rate.body.resp.rate_hz);
> +}
> diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h
> index e485a06..3d55d36 100644
> --- a/include/configs/rpi_b.h
> +++ b/include/configs/rpi_b.h
> @@ -51,6 +51,7 @@
>  #define CONFIG_SYS_MALLOC_LEN		SZ_4M
>  #define CONFIG_SYS_MEMTEST_START	0x00100000
>  #define CONFIG_SYS_MEMTEST_END		0x00200000
> +#define CONFIG_LOADADDR			0x00200000
>  
>  /* Flash */
>  #define CONFIG_SYS_NO_FLASH
> @@ -70,6 +71,13 @@
>  #define CONFIG_VIDEO_BCM2835
>  #define CONFIG_SYS_WHITE_ON_BLACK
>  
> +/* SD/MMC configuration */
> +#define CONFIG_GENERIC_MMC
> +#define CONFIG_MMC
> +#define CONFIG_SDHCI
> +#define CONFIG_MMC_SDHCI_IO_ACCESSORS
> +#define CONFIG_BCM2835_SDHCI
> +
>  /* Console UART */
>  #define CONFIG_PL011_SERIAL
>  #define CONFIG_PL011_CLOCK		3000000
> @@ -85,12 +93,59 @@
>  /* Environment */
>  #define CONFIG_ENV_SIZE			SZ_16K
>  #define CONFIG_ENV_IS_NOWHERE
> +#define CONFIG_ENV_VARS_UBOOT_CONFIG
>  #define CONFIG_SYS_LOAD_ADDR		0x1000000
>  #define CONFIG_CONSOLE_MUX
>  #define CONFIG_SYS_CONSOLE_IS_IN_ENV
> -#define CONFIG_EXTRA_ENV_SETTINGS	"stdin=serial\0" \
> -					"stderr=serial,lcd\0" \
> -					"stdout=serial,lcd\0"
> +/*
> + * Memory layout for where various images get loaded by boot scripts:
> + *
> + * scriptaddr can be pretty much anywhere that doesn't conflict with something
> + *   else. Put it low in memory to avoid conflicts.
> + *
> + * kernel_addr_r must be within the first 128M of RAM in order for the
> + *   kernel's CONFIG_AUTO_ZRELADDR option to work. Since the kernel will
> + *   decompress itself to 0x8000 after the start of RAM, kernel_addr_r
> + *   should not overlap that area, or the kernel will have to copy itself
> + *   somewhere else before decompression. Similarly, the address of any other
> + *   data passed to the kernel shouldn't overlap the start of RAM. Pushing
> + *   this up to 16M allows for a sizable kernel to be decompressed below the
> + *   compressed load address.
> + *
> + * fdt_addr_r simply shouldn't overlap anything else. Choosing 32M allows for
> + *   the compressed kernel to be up to 16M too.
> + *
> + * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 33M allows
> + *   for the FDT/DTB to be up to 1M, which is hopefully plenty.
> + */
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> +	"stdin=serial\0" \
> +	"stderr=serial,lcd\0" \
> +	"stdout=serial,lcd\0" \
> +	"scriptaddr=0x00000000\0" \
> +	"kernel_addr_r=0x01000000\0" \
> +	"fdt_addr_r=0x02000000\0" \
> +	"ramdisk_addr_r=0x02100000\0" \
> +	"boot_targets=mmc0\0" \
> +	\
> +	"script_boot=" \
> +		"if fatload ${devtype} ${devnum}:1 " \
> +					"${scriptaddr} boot.scr.uimg; then " \
> +			"source ${scriptaddr}; " \
> +		"fi;\0" \
> +	\
> +	"mmc_boot=" \
> +		"setenv devtype mmc; " \
> +		"if mmc dev ${devnum}; then " \
> +			"run script_boot; " \
> +		"fi\0" \
> +	\
> +	"bootcmd_mmc0=setenv devnum 0; run mmc_boot\0" \
> +
> +#define CONFIG_BOOTCOMMAND \
> +	"for target in ${boot_targets}; do run bootcmd_${target}; done"
> +
> +#define CONFIG_BOOTDELAY		2
>  
>  /* Shell */
>  #define CONFIG_SYS_HUSH_PARSER
> @@ -105,6 +160,13 @@
>  #include <config_cmd_default.h>
>  #define CONFIG_CMD_BOOTZ
>  #define CONFIG_CMD_GPIO
> +#define CONFIG_CMD_MMC
> +#define CONFIG_DOS_PARTITION
> +#define CONFIG_PARTITION_UUIDS
> +#define CONFIG_CMD_PART
> +#define CONFIG_CMD_FS_GENERIC
> +#define CONFIG_CMD_FAT
> +#define CONFIG_CMD_EXT
>  /* Some things don't make sense on this HW or yet */
>  #undef CONFIG_CMD_FPGA
>  #undef CONFIG_CMD_NET

Applied to u-boot-arm/master, thanks!

Amicalement,

Patch

diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h
index 4752091..b07c4a0 100644
--- a/arch/arm/include/asm/arch-bcm2835/mbox.h
+++ b/arch/arm/include/asm/arch-bcm2835/mbox.h
@@ -144,6 +144,32 @@  struct bcm2835_mbox_tag_get_arm_mem {
 	} body;
 };
 
+#define BCM2835_MBOX_TAG_GET_CLOCK_RATE	0x00030002
+
+#define BCM2835_MBOX_CLOCK_ID_EMMC	1
+#define BCM2835_MBOX_CLOCK_ID_UART	2
+#define BCM2835_MBOX_CLOCK_ID_ARM	3
+#define BCM2835_MBOX_CLOCK_ID_CORE	4
+#define BCM2835_MBOX_CLOCK_ID_V3D	5
+#define BCM2835_MBOX_CLOCK_ID_H264	6
+#define BCM2835_MBOX_CLOCK_ID_ISP	7
+#define BCM2835_MBOX_CLOCK_ID_SDRAM	8
+#define BCM2835_MBOX_CLOCK_ID_PIXEL	9
+#define BCM2835_MBOX_CLOCK_ID_PWM	10
+
+struct bcm2835_mbox_tag_get_clock_rate {
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct {
+			u32 clock_id;
+		} req;
+		struct {
+			u32 clock_id;
+			u32 rate_hz;
+		} resp;
+	} body;
+};
+
 #define BCM2835_MBOX_TAG_ALLOCATE_BUFFER	0x00040001
 
 struct bcm2835_mbox_tag_allocate_buffer {
diff --git a/board/raspberrypi/rpi_b/rpi_b.c b/board/raspberrypi/rpi_b/rpi_b.c
index 3c654a1..6b3e095 100644
--- a/board/raspberrypi/rpi_b/rpi_b.c
+++ b/board/raspberrypi/rpi_b/rpi_b.c
@@ -16,6 +16,7 @@ 
 
 #include <common.h>
 #include <asm/arch/mbox.h>
+#include <asm/arch/sdhci.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -26,6 +27,12 @@  struct msg_get_arm_mem {
 	u32 end_tag;
 };
 
+struct msg_get_clock_rate {
+	struct bcm2835_mbox_hdr hdr;
+	struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
+	u32 end_tag;
+};
+
 int dram_init(void)
 {
 	ALLOC_ALIGN_BUFFER(struct msg_get_arm_mem, msg, 1, 16);
@@ -51,3 +58,22 @@  int board_init(void)
 
 	return 0;
 }
+
+int board_mmc_init(void)
+{
+	ALLOC_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1, 16);
+	int ret;
+
+	BCM2835_MBOX_INIT_HDR(msg_clk);
+	BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE);
+	msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
+
+	ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr);
+	if (ret) {
+		printf("bcm2835: Could not query eMMC clock rate\n");
+		return -1;
+	}
+
+	return bcm2835_sdhci_init(BCM2835_SDHCI_BASE,
+				  msg_clk->get_clock_rate.body.resp.rate_hz);
+}
diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h
index e485a06..3d55d36 100644
--- a/include/configs/rpi_b.h
+++ b/include/configs/rpi_b.h
@@ -51,6 +51,7 @@ 
 #define CONFIG_SYS_MALLOC_LEN		SZ_4M
 #define CONFIG_SYS_MEMTEST_START	0x00100000
 #define CONFIG_SYS_MEMTEST_END		0x00200000
+#define CONFIG_LOADADDR			0x00200000
 
 /* Flash */
 #define CONFIG_SYS_NO_FLASH
@@ -70,6 +71,13 @@ 
 #define CONFIG_VIDEO_BCM2835
 #define CONFIG_SYS_WHITE_ON_BLACK
 
+/* SD/MMC configuration */
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MMC
+#define CONFIG_SDHCI
+#define CONFIG_MMC_SDHCI_IO_ACCESSORS
+#define CONFIG_BCM2835_SDHCI
+
 /* Console UART */
 #define CONFIG_PL011_SERIAL
 #define CONFIG_PL011_CLOCK		3000000
@@ -85,12 +93,59 @@ 
 /* Environment */
 #define CONFIG_ENV_SIZE			SZ_16K
 #define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_VARS_UBOOT_CONFIG
 #define CONFIG_SYS_LOAD_ADDR		0x1000000
 #define CONFIG_CONSOLE_MUX
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
-#define CONFIG_EXTRA_ENV_SETTINGS	"stdin=serial\0" \
-					"stderr=serial,lcd\0" \
-					"stdout=serial,lcd\0"
+/*
+ * Memory layout for where various images get loaded by boot scripts:
+ *
+ * scriptaddr can be pretty much anywhere that doesn't conflict with something
+ *   else. Put it low in memory to avoid conflicts.
+ *
+ * kernel_addr_r must be within the first 128M of RAM in order for the
+ *   kernel's CONFIG_AUTO_ZRELADDR option to work. Since the kernel will
+ *   decompress itself to 0x8000 after the start of RAM, kernel_addr_r
+ *   should not overlap that area, or the kernel will have to copy itself
+ *   somewhere else before decompression. Similarly, the address of any other
+ *   data passed to the kernel shouldn't overlap the start of RAM. Pushing
+ *   this up to 16M allows for a sizable kernel to be decompressed below the
+ *   compressed load address.
+ *
+ * fdt_addr_r simply shouldn't overlap anything else. Choosing 32M allows for
+ *   the compressed kernel to be up to 16M too.
+ *
+ * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 33M allows
+ *   for the FDT/DTB to be up to 1M, which is hopefully plenty.
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"stdin=serial\0" \
+	"stderr=serial,lcd\0" \
+	"stdout=serial,lcd\0" \
+	"scriptaddr=0x00000000\0" \
+	"kernel_addr_r=0x01000000\0" \
+	"fdt_addr_r=0x02000000\0" \
+	"ramdisk_addr_r=0x02100000\0" \
+	"boot_targets=mmc0\0" \
+	\
+	"script_boot=" \
+		"if fatload ${devtype} ${devnum}:1 " \
+					"${scriptaddr} boot.scr.uimg; then " \
+			"source ${scriptaddr}; " \
+		"fi;\0" \
+	\
+	"mmc_boot=" \
+		"setenv devtype mmc; " \
+		"if mmc dev ${devnum}; then " \
+			"run script_boot; " \
+		"fi\0" \
+	\
+	"bootcmd_mmc0=setenv devnum 0; run mmc_boot\0" \
+
+#define CONFIG_BOOTCOMMAND \
+	"for target in ${boot_targets}; do run bootcmd_${target}; done"
+
+#define CONFIG_BOOTDELAY		2
 
 /* Shell */
 #define CONFIG_SYS_HUSH_PARSER
@@ -105,6 +160,13 @@ 
 #include <config_cmd_default.h>
 #define CONFIG_CMD_BOOTZ
 #define CONFIG_CMD_GPIO
+#define CONFIG_CMD_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_PARTITION_UUIDS
+#define CONFIG_CMD_PART
+#define CONFIG_CMD_FS_GENERIC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT
 /* Some things don't make sense on this HW or yet */
 #undef CONFIG_CMD_FPGA
 #undef CONFIG_CMD_NET