diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rwxr-xr-x | board/st/u8500/emmc.c | 8 | ||||
-rwxr-xr-x | cpu/arm_cortexa9/stw8500/timer.c | 42 | ||||
-rw-r--r-- | include/asm-arm/boottime.h | 20 | ||||
-rw-r--r-- | include/asm-arm/setup.h | 14 | ||||
-rw-r--r--[-rwxr-xr-x] | include/configs/u8500.h | 14 | ||||
-rw-r--r-- | lib_arm/bootm.c | 44 |
7 files changed, 134 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore index ae67d7a81..4c663b5c9 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,8 @@ /LOG /errlog /reloc_off + +# ignore build output directories build* # stgit generated dirs diff --git a/board/st/u8500/emmc.c b/board/st/u8500/emmc.c index 780ddaebc..214b2b14b 100755 --- a/board/st/u8500/emmc.c +++ b/board/st/u8500/emmc.c @@ -26,6 +26,7 @@ #include "mmc.h" #include "emmc.h" #include "gpio.h" +#include <asm/boottime.h> #define PIB_EMMC_ADDR 0x00 /* ======================================================================== @@ -233,7 +234,9 @@ int emmc_read(u32 block_offset, u32 read_buffer, u32 filesize) remaining = filesize; printf(" eMMC read start filesize=0x%x \n", filesize); - + + boottime_tag_load_kernel(); + blocks = (n%512==0)?(n/512):(n/512)+1; while(blocks>=8) @@ -259,7 +262,8 @@ int emmc_read(u32 block_offset, u32 read_buffer, u32 filesize) return 1; } } - printf(" eMMC read done \n"); + + printf(" eMMC read done \n"); return 0; } diff --git a/cpu/arm_cortexa9/stw8500/timer.c b/cpu/arm_cortexa9/stw8500/timer.c index 16067c900..7b4092a9b 100755 --- a/cpu/arm_cortexa9/stw8500/timer.c +++ b/cpu/arm_cortexa9/stw8500/timer.c @@ -23,33 +23,57 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/mtu.h> +#include <asm/boottime.h> /* * The timer is a decrementer, we'll left it free running at 2.4MHz. * We have 2.4 ticks per microsecond and an overflow in almost 30min + * + * EABEJON: On HREF (atleast) there is no way the timer runs at 2.4MHz + * It is more likely that it around ~100 MHz with 1 as perscaler. + * Changing the perscaler setting to 16 gives a timer decrease rate of + * ~6.25MHz. + * + * Use the 3rd counter on MTU0 and let it run free since we're interested + * in how long time it takes to boot uboot+linux. Linux ux500 uses MTU0, + * timer0 and MTU1, timer0. + * */ + +#if 0 #define TIMER_CLOCK (24 * 100 * 1000) #define COUNT_TO_USEC(x) ((x) * 5 / 12) /* overflows at 6min */ #define USEC_TO_COUNT(x) ((x) * 12 / 5) /* overflows at 6min */ +#endif + +#define TIMER_CLOCK (625 * 10 * 1000) +#define COUNT_TO_USEC(x) ((x) * 4 / 25) +#define USEC_TO_COUNT(x) ((x) * 25 / 4) + #define TICKS_PER_HZ (TIMER_CLOCK / CONFIG_SYS_HZ) #define TICKS_TO_HZ(x) ((x) / TICKS_PER_HZ) +/* Timer on MTU0 (from 0 to 3) */ +#define MTU_TIMER 2 + + /* macro to read the 32 bit timer: since it decrements, we invert read value */ -#define READ_TIMER() (~readl(CONFIG_SYS_TIMERBASE + MTU_VAL(0))) +#define READ_TIMER() (~readl(CONFIG_SYS_TIMERBASE + MTU_VAL(MTU_TIMER))) -/* Configure a free-running, auto-wrap counter with no prescaler */ +/* Configure a free-running, auto-wrap counter with division by 16 as prescaler */ int timer_init(void) { - writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS, - CONFIG_SYS_TIMERBASE + MTU_CR(0)); + writel(MTU_CRn_ENA | MTU_CRn_PRESCALE_16 | MTU_CRn_32BITS, + CONFIG_SYS_TIMERBASE + MTU_CR(MTU_TIMER)); reset_timer(); + boottime_tag_uboot_init(); return 0; } /* Restart counting from 0 */ void reset_timer(void) { - writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(0)); /* Immediate effect */ + writel(0, CONFIG_SYS_TIMERBASE + MTU_LR(MTU_TIMER)); /* Immediate effect */ } /* Return how many HZ passed since "base" */ @@ -58,6 +82,14 @@ ulong get_timer(ulong base) return TICKS_TO_HZ(READ_TIMER()) - base; } + +/* Return how many HZ passed since "base" */ +ulong get_raw_timer(void) +{ + return READ_TIMER(); +} + + /* Delay x useconds */ void udelay(unsigned long usec) { diff --git a/include/asm-arm/boottime.h b/include/asm-arm/boottime.h new file mode 100644 index 000000000..3f8971380 --- /dev/null +++ b/include/asm-arm/boottime.h @@ -0,0 +1,20 @@ + +#ifndef BOOTTIME_H +#define BOOTTIME_H + +ulong get_raw_timer(void); +extern ulong boottime_ticks_uboot_init; +extern ulong boottime_ticks_load_kernel; +extern ulong boottime_ticks_uboot_done; + +#ifdef CONFIG_BOOTTIME +#define boottime_tag_uboot_init() boottime_ticks_uboot_init = get_raw_timer(); +#define boottime_tag_load_kernel() boottime_ticks_load_kernel = get_raw_timer(); +#define boottime_tag_uboot_done() boottime_ticks_uboot_done = get_raw_timer(); +#else +#define boottime_tag_uboot_init() +#define boottime_tag_load_kernel() +#define boottime_tag_uboot_done() +#endif + +#endif diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h index 89df4dc70..cadc12435 100644 --- a/include/asm-arm/setup.h +++ b/include/asm-arm/setup.h @@ -205,6 +205,15 @@ struct tag_memclk { u32 fmemclk; }; +/* for automatic boot timing testcases */ +#define ATAG_BOOTTIME_UBOOT_INIT 0x41000403 +#define ATAG_BOOTTIME_LOAD_KERNEL 0x41000404 +#define ATAG_BOOTTIME_UBOOT_DONE 0x41000405 + +struct tag_boottime { + u32 tick; +}; + struct tag { struct tag_header hdr; union { @@ -227,6 +236,11 @@ struct tag { * DC21285 specific */ struct tag_memclk memclk; + /* + * Boot time + */ + struct tag_boottime boottime; + } u; }; diff --git a/include/configs/u8500.h b/include/configs/u8500.h index 91fd37f00..b9469b2af 100755..100644 --- a/include/configs/u8500.h +++ b/include/configs/u8500.h @@ -32,6 +32,8 @@ #define CONFIG_U8500_ED 1 #define CONFIG_L2_OFF 1 +#define CONFIG_BOOTTIME /* enable boot time stamps */ + #define CONFIG_SYS_MEMTEST_START 0x00000000 #define CONFIG_SYS_MEMTEST_END 0x1FFFFFFF #define CONFIG_SYS_HZ 1000 /* must be 1000 */ @@ -79,9 +81,15 @@ #define CONFIG_BAUDRATE 115200 #define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } +/* + * Devices and file systems + */ #define CONFIG_MMC 1 #define CONFIG_DOS_PARTITION 1 +/* + * Commands + */ #define CONFIG_CMD_MEMORY #define CONFIG_CMD_BOOTD #define CONFIG_CMD_BDI @@ -100,10 +108,12 @@ #ifdef CONFIG_USB_TTY #define CONFIG_BOOTDELAY -1 /* disable autoboot */ -#else -#define CONFIG_BOOTDELAY 5 #endif /* CONFIG_USB_TTY */ +#ifndef CONFIG_BOOTDELAY +#define CONFIG_BOOTDELAY 5 +#endif + #define CONFIG_BOOTARGS "cachepolicy=writealloc root=/dev/mmcblk0p2 noinitrd rootfstype=ext3 rootdelay=1 init=/linuxrc console=ttyAMA2,115200n8 board_id=1 mem=96M@0 mem=128M@128M" #define CONFIG_BOOTCOMMAND "emmc_read 0x100000 0x14000000 0x200000; bootm 0x100000" diff --git a/lib_arm/bootm.c b/lib_arm/bootm.c index 128b7e313..ebaf2b3f2 100644 --- a/lib_arm/bootm.c +++ b/lib_arm/bootm.c @@ -26,6 +26,7 @@ #include <image.h> #include <u-boot/zlib.h> #include <asm/byteorder.h> +#include <asm/boottime.h> DECLARE_GLOBAL_DATA_PTR; @@ -56,6 +57,13 @@ static void setup_videolfb_tag (gd_t *gd); static struct tag *params; #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */ +#ifdef CONFIG_BOOTTIME +ulong boottime_ticks_uboot_init = 0; +ulong boottime_ticks_load_kernel = 0; +ulong boottime_ticks_uboot_done = 0; +static void setup_boottime_tags(void); +#endif + int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; @@ -83,14 +91,20 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) debug ("## Transferring control to Linux (at address %08lx) ...\n", (ulong) theKernel); + boottime_tag_uboot_done() + #if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ defined (CONFIG_SERIAL_TAG) || \ defined (CONFIG_REVISION_TAG) || \ defined (CONFIG_LCD) || \ - defined (CONFIG_VFD) + defined (CONFIG_VFD) || \ + defined (CONFIG_BOOTTIME) setup_start_tag (bd); +#ifdef CONFIG_BOOTTIME + setup_boottime_tags(); +#endif #ifdef CONFIG_SERIAL_TAG setup_serial_tag (¶ms); #endif @@ -113,6 +127,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) setup_end_tag (bd); #endif + /* we assume that the kernel is in place */ printf ("\nStarting kernel ...\n\n"); @@ -153,6 +168,33 @@ static void setup_start_tag (bd_t *bd) params = tag_next (params); } +#ifdef CONFIG_BOOTTIME +static void setup_boottime_tags(void) +{ + if(!boottime_ticks_uboot_init) + printf("Warning: uboot init time not tracked\n"); + if(!boottime_ticks_load_kernel) + printf("Warning: load kernel time not tracked\n"); + if(!boottime_ticks_uboot_done) + printf("Warning: uboot done time not tracked\n"); + + params->hdr.tag = ATAG_BOOTTIME_UBOOT_INIT; + params->hdr.size = tag_size (tag_boottime); + params->u.boottime.tick = boottime_ticks_uboot_init; + params = tag_next (params); + + params->hdr.tag = ATAG_BOOTTIME_LOAD_KERNEL; + params->hdr.size = tag_size (tag_boottime); + params->u.boottime.tick = boottime_ticks_load_kernel; + params = tag_next (params); + + params->hdr.tag = ATAG_BOOTTIME_UBOOT_DONE; + params->hdr.size = tag_size (tag_boottime); + params->u.boottime.tick = boottime_ticks_uboot_done; + params = tag_next (params); + +} +#endif #ifdef CONFIG_SETUP_MEMORY_TAGS static void setup_memory_tags (bd_t *bd) |