diff options
Diffstat (limited to 'arch/arm/boot')
-rw-r--r-- | arch/arm/boot/compressed/Makefile | 13 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head-shmobile.S | 30 | ||||
-rw-r--r-- | arch/arm/boot/compressed/mmcif-sh7372.c | 87 |
3 files changed, 129 insertions, 1 deletions
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 0a8f748e506a..198007d0a7ed 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -4,9 +4,20 @@ # create a compressed vmlinuz image from the original vmlinux # +OBJS = + +# Ensure that mmcif loader code appears early in the image +# to minimise that number of bocks that have to be read in +# order to load it. +ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y) +ifeq ($(CONFIG_ARCH_SH7372),y) +OBJS += mmcif-sh7372.o +endif +endif + AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) HEAD = head.o -OBJS = misc.o decompress.o +OBJS += misc.o decompress.o FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c # diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S index 30973b76e6ae..c943d2e7da9d 100644 --- a/arch/arm/boot/compressed/head-shmobile.S +++ b/arch/arm/boot/compressed/head-shmobile.S @@ -25,6 +25,36 @@ /* load board-specific initialization code */ #include <mach/zboot.h> +#ifdef CONFIG_ZBOOT_ROM_MMCIF + /* Load image from MMC */ + adr sp, __tmp_stack + 128 + ldr r0, __image_start + ldr r1, __image_end + subs r1, r1, r0 + ldr r0, __load_base + bl mmcif_loader + + /* Jump to loaded code */ + ldr r0, __loaded + ldr r1, __image_start + sub r0, r0, r1 + ldr r1, __load_base + add pc, r0, r1 + +__image_start: + .long _start +__image_end: + .long _got_end +__load_base: + .long CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM +__loaded: + .long __continue + .align +__tmp_stack: + .space 128 +__continue: +#endif /* CONFIG_ZBOOT_ROM_MMCIF */ + b 1f __atags:@ tag #1 .long 12 @ tag->hdr.size = tag_size(tag_core); 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); +} |