diff mbox

[1/2,rfc] mmc, sh: Read MMCIF during zboot

Message ID 1290812757-20571-2-git-send-email-horms@verge.net.au (mailing list archive)
State Superseded
Headers show

Commit Message

Simon Horman Nov. 26, 2010, 11:05 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0a8f748..f730c10 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -49,6 +49,10 @@  ifeq ($(CONFIG_ARCH_SHMOBILE),y)
 OBJS		+= head-shmobile.o
 endif
 
+ifeq ($(CONFIG_ARCH_SH7372),y)
+OBJS		+= mmcif-sh7372.o
+endif
+
 #
 # We now have a PIC decompressor implementation.  Decompressors running
 # from RAM should not define ZTEXTADDR.  Decompressors running directly
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
index 30973b7..700d622 100644
--- a/arch/arm/boot/compressed/head-shmobile.S
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -26,6 +26,22 @@ 
 #include <mach/zboot.h>
 
 	b	1f
+	.align
+__tmp_stack:
+	.space	128
+__dummy_buf:
+	.space	512
+__dummy_buf_size:
+	.long	512
+1:
+	adr	sp, __tmp_stack
+	add	sp, sp, #128
+	adr	r0, __dummy_buf
+	ldr	r1, __dummy_buf_size
+	mov	lr, pc
+	b	mmcif_loader
+
+	b	1f
 __atags:@ tag #1
 	.long	12			@ tag->hdr.size = tag_size(tag_core);
 	.long	0x54410001		@ tag->hdr.tag = ATAG_CORE;
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
new file mode 100644
index 0000000..7ffaf27
--- /dev/null
+++ b/arch/arm/boot/compressed/mmcif-sh7372.c
@@ -0,0 +1,100 @@ 
+/*
+ * sh7372 MMCIF loader
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2010 Simon Horman
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/mmc/sh_mmcif.h>
+
+#define MMCIF_BASE      (void __iomem *)0xe6bd0000
+
+#define PORT84CR	0xe6050054
+#define PORT85CR	0xe6050055
+#define PORT86CR	0xe6050056
+#define PORT87CR	0xe6050057
+#define PORT88CR	0xe6050058
+#define PORT89CR	0xe6050059
+#define PORT90CR	0xe605005a
+#define PORT91CR	0xe605005b
+#define PORT92CR	0xe605005c
+#define PORT99CR	0xe6050063
+#define PORT185CR	0xe60520b9
+#define PORT186CR	0xe60520ba
+#define PORT187CR	0xe60520bb
+#define PORT188CR	0xe60520bc
+#define PORTR191_160DR  0xe6056014
+
+#define SMSTPCR3	0xe615013c
+
+enum { MMCIF_PROGRESS_ENTER, MMCIF_PROGRESS_INIT,
+       MMCIF_PROGRESS_LOAD, MMCIF_PROGRESS_DONE };
+
+static void mmcif_update_progress(int n)
+{
+	__raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
+		     (1 << (25 + n)), PORTR191_160DR);
+}
+
+/* SH7372 specific MMCIF loader
+ *
+ * loads the romImage from an MMC card starting from block 512
+ * use the following line to write the romImage to an MMC card
+ * # dd if=arch/sh/boot/romImage of=/dev/sdx bs=512 seek=512
+ */
+asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes)
+{
+	/* Initialise LEDS1-4
+	 * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
+	 * value:     0x10 - enable output
+	 */
+	__raw_writeb(0x10, PORT185CR);
+	__raw_writeb(0x10, PORT186CR);
+	__raw_writeb(0x10, PORT187CR);
+	__raw_writeb(0x10, PORT188CR);
+
+	mmcif_update_progress(MMCIF_PROGRESS_ENTER);
+
+	/* Initialise MMC
+	 * registers: PORT84CR-PORT92CR
+	 *            (MMCD0_0-MMCD0_7,MMCCMD0 Control)
+	 * value: 0x04 - select function 4
+	 */
+	 __raw_writeb(0x04, PORT84CR);
+	 __raw_writeb(0x04, PORT85CR);
+	 __raw_writeb(0x04, PORT86CR);
+	 __raw_writeb(0x04, PORT87CR);
+	 __raw_writeb(0x04, PORT88CR);
+	 __raw_writeb(0x04, PORT89CR);
+	 __raw_writeb(0x04, PORT90CR);
+	 __raw_writeb(0x04, PORT91CR);
+	 __raw_writeb(0x04, PORT92CR);
+
+	/* Initialise MMC
+	 * registers: PORT99CR (MMCCLK0 Control)
+	 * value: 0x10 | 0x04 - enable output | select function 4
+	 */
+	__raw_writeb(0x14, PORT99CR);
+
+	/* Enable clock to MMC hardware block */
+	__raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
+
+	mmcif_update_progress(MMCIF_PROGRESS_INIT);
+
+	/* setup MMCIF hardware */
+	sh_mmcif_boot_init(MMCIF_BASE);
+
+	mmcif_update_progress(MMCIF_PROGRESS_LOAD);
+
+	/* load kernel via MMCIF interface */
+	sh_mmcif_boot_slurp(MMCIF_BASE, buf, no_bytes);
+
+	/* Disable clock to MMC hardware block */
+	__raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+
+	mmcif_update_progress(MMCIF_PROGRESS_DONE);
+}