summaryrefslogtreecommitdiff
path: root/arch/arm/boot/compressed/mmcif-sh7372.c
diff options
context:
space:
mode:
authorSimon Horman <horms@verge.net.au>2011-01-11 04:01:08 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-01-25 15:06:52 +0000
commitf45b1149911cc4c3ab50e56c8844ad4ec04a4575 (patch)
treeb7567322fae765fcc9b24f3ec1604b13c21a5c34 /arch/arm/boot/compressed/mmcif-sh7372.c
parent1bae4ce27c9c90344f23c65ea6966c50ffeae2f5 (diff)
ARM: 6617/1: mmc, Add zboot from MMC support for SuperH Mobile ARM
This allows a ROM-able zImage to be written to MMC and for SuperH Mobile ARM to boot directly from the MMCIF hardware block. This is achieved by the MaskROM loading the first portion of the image into MERAM and then jumping to it. This portion contains loader code which copies the entire image to SDRAM and jumps to it. From there the zImage boot code proceeds as normal, uncompressing the image into its final location and then jumping to it. Cc: Magnus Damm <magnus.damm@gmail.com> Russell, please consider merging this for 2.6.38. This patch depends on: * "mmc, sh: Move MMCIF_PROGRESS_* into sh_mmcif.h" which will be merged though Paul Mundt's rmobile sh-2.6. The absence of this patch will break the build if the (new) CONFIG_ZBOOT_ROM_MMCIF option is set. There are no subtle side-effects. v2: Addressed comments by Magnus Damm * Fix copyright in vrl4.c * Fix use of #define CONFIG_ZBOOT_ROM_MMCIF in mmcif-sh7372.c * Initialise LED GPIO lines in head-ap4evb.txt instead of mmcif-sh7372.c as this is considered board-specific. v3: Addressed comments made in person by Magnus Damm * Move mmcif_loader to be earlier in the image and reduce the number of blocks of boot program loaded by the MaskRom from 40 to 8 accordingly. * Move LED GPIO initialisation into mmcif_progress_init - This leaves the partner jet script unbloated Other * inline mmcif_update_progress so it is a static inline in a header file v4: * Use htole16() and htole32() in v4rl.c to ensure that the output is little endian v5: Addressed comments by Russell King * Simplify assembly code * Jump to code rather than an address <- bug fix * Use (void __iomem *) as appropriate Roll in mackerel support * This was previously a separate patch, only because of the order in which this code was developed Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/boot/compressed/mmcif-sh7372.c')
-rw-r--r--arch/arm/boot/compressed/mmcif-sh7372.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
new file mode 100644
index 000000000000..e6180af241f6
--- /dev/null
+++ b/arch/arm/boot/compressed/mmcif-sh7372.c
@@ -0,0 +1,87 @@
+/*
+ * 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>
+#include <mach/mmcif.h>
+
+#define MMCIF_BASE (void __iomem *)0xe6bd0000
+
+#define PORT84CR (void __iomem *)0xe6050054
+#define PORT85CR (void __iomem *)0xe6050055
+#define PORT86CR (void __iomem *)0xe6050056
+#define PORT87CR (void __iomem *)0xe6050057
+#define PORT88CR (void __iomem *)0xe6050058
+#define PORT89CR (void __iomem *)0xe6050059
+#define PORT90CR (void __iomem *)0xe605005a
+#define PORT91CR (void __iomem *)0xe605005b
+#define PORT92CR (void __iomem *)0xe605005c
+#define PORT99CR (void __iomem *)0xe6050063
+
+#define SMSTPCR3 (void __iomem *)0xe615013c
+
+/* SH7372 specific MMCIF loader
+ *
+ * loads the zImage from an MMC card starting from block 1.
+ *
+ * The image must be start with a vrl4 header and
+ * the zImage must start at offset 512 of the image. That is,
+ * at block 2 (=byte 1024) on the media
+ *
+ * Use the following line to write the vrl4 formated zImage
+ * to an MMC card
+ * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1
+ */
+asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
+{
+ mmcif_init_progress();
+ 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_do_read(MMCIF_BASE, 2, /* Kernel is at block 2 */
+ (len + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, buf);
+
+
+ /* Disable clock to MMC hardware block */
+ __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+
+ mmcif_update_progress(MMCIF_PROGRESS_DONE);
+}