summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rwxr-xr-xboard/st/u8500/emmc.c8
-rwxr-xr-xcpu/arm_cortexa9/stw8500/timer.c42
-rw-r--r--include/asm-arm/boottime.h20
-rw-r--r--include/asm-arm/setup.h14
-rw-r--r--[-rwxr-xr-x]include/configs/u8500.h14
-rw-r--r--lib_arm/bootm.c44
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 (&params);
#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)