From patchwork Mon Jan 3 13:45:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Schwingen X-Patchwork-Id: 77262 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 9195DB6EE8 for ; Tue, 4 Jan 2011 00:50:47 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 12AA2281AB; Mon, 3 Jan 2011 14:49:13 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ELl9Jwdkk02T; Mon, 3 Jan 2011 14:49:12 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2FF6228181; Mon, 3 Jan 2011 14:48:13 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id F413528165 for ; Mon, 3 Jan 2011 14:48:00 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id RABJWbYcVx4y for ; Mon, 3 Jan 2011 14:48:00 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail.dascon.de (pve-mail.dascon.de [93.159.248.171]) by theia.denx.de (Postfix) with ESMTP id 96B2E28145 for ; Mon, 3 Jan 2011 14:47:51 +0100 (CET) Received: by mail.dascon.de (Postfix, from userid 10) id 5462D21AA; Mon, 3 Jan 2011 14:47:49 +0100 (CET) Received: from discworld.ms.intern (discworld.dascon.de [192.168.11.1]) by a-tuin.dascon.de (Postfix) with ESMTP id 54E9580837 for ; Mon, 3 Jan 2011 14:45:44 +0100 (CET) From: Michael Schwingen To: u-boot@lists.denx.de Date: Mon, 3 Jan 2011 14:45:29 +0100 Message-Id: <1294062338-21084-5-git-send-email-michael@schwingen.org> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1294062338-21084-1-git-send-email-michael@schwingen.org> References: <1294062338-21084-1-git-send-email-michael@schwingen.org> Subject: [U-Boot] [PATCH 04/13] Fix IXP code to work after relocation was added X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de - jump to real flash location after reset before turning off flash mirror - fix timer system to use HZ == 1000, remove broken interrupt-based code Signed-off-by: Michael Schwingen --- arch/arm/cpu/ixp/cpu.c | 5 -- arch/arm/cpu/ixp/start.S | 59 ++-------------- arch/arm/cpu/ixp/timer.c | 125 +++++++++++++++----------------- arch/arm/include/asm/arch-ixp/ixp425.h | 5 +- 4 files changed, 66 insertions(+), 128 deletions(-) diff --git a/arch/arm/cpu/ixp/cpu.c b/arch/arm/cpu/ixp/cpu.c index ce275e5..942845d 100644 --- a/arch/arm/cpu/ixp/cpu.c +++ b/arch/arm/cpu/ixp/cpu.c @@ -36,8 +36,6 @@ #include #include -ulong loops_per_jiffy; - static void cache_flush(void); #if defined(CONFIG_DISPLAY_CPUINFO) @@ -51,17 +49,14 @@ int print_cpuinfo (void) puts("CPU: Intel IXP425 at "); switch ((id & 0x000003f0) >> 4) { case 0x1c: - loops_per_jiffy = 887467; speed = 533; break; case 0x1d: - loops_per_jiffy = 666016; speed = 400; break; case 0x1f: - loops_per_jiffy = 442901; speed = 266; break; } diff --git a/arch/arm/cpu/ixp/start.S b/arch/arm/cpu/ixp/start.S index 9f8c15b..2c49aa4 100644 --- a/arch/arm/cpu/ixp/start.S +++ b/arch/arm/cpu/ixp/start.S @@ -65,7 +65,8 @@ .endm .globl _start -_start: b reset +_start: + ldr pc, _reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort @@ -74,6 +75,7 @@ _start: b reset ldr pc, _irq ldr pc, _fiq +_reset: .word reset _undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort @@ -163,12 +165,6 @@ reset: str r1, [r2] /* make sure flash is visible at 0 */ -#if 0 - ldr r2, =IXP425_EXP_CFG0 - ldr r1, [r2] - orr r1, r1, #0x80000000 - str r1, [r2] -#endif mov r1, #CONFIG_SYS_SDR_CONFIG ldr r2, =IXP425_SDR_CONFIG str r1, [r2] @@ -212,19 +208,6 @@ reset: str r1, [r4] DELAY_FOR 0x4000, r0 - /* copy */ - mov r0, #0 - mov r4, r0 - add r2, r0, #CONFIG_SYS_MONITOR_LEN - mov r1, #0x10000000 - mov r5, r1 - - 30: - ldr r3, [r0], #4 - str r3, [r1], #4 - cmp r0, r2 - bne 30b - /* invalidate I & D caches & BTB */ mcr p15, 0, r0, c7, c7, 0 CPWAIT r0 @@ -237,19 +220,12 @@ reset: mcr p15, 0, r0, c7, c10, 4 CPWAIT r0 - /* move flash to 0x50000000 */ + /* remove flash mirror at 0x00000000 */ ldr r2, =IXP425_EXP_CFG0 ldr r1, [r2] bic r1, r1, #0x80000000 str r1, [r2] - nop - nop - nop - nop - nop - nop - /* invalidate I & Data TLB */ mcr p15, 0, r0, c8, c7, 0 CPWAIT r0 @@ -265,7 +241,7 @@ reset: orr r0,r0,#0x13 msr cpsr,r0 -/* Set stackpointer in internal RAM to call board_init_f */ +/* Set initial stackpointer in SDRAM to call board_init_f */ call_board_init_f: ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ @@ -578,28 +554,3 @@ reset_endless: b reset_endless -#ifdef CONFIG_USE_IRQ - -.LC0: .word loops_per_jiffy - -/* - * 0 <= r0 <= 2000 - */ -.globl __udelay -__udelay: - mov r2, #0x6800 - orr r2, r2, #0x00db - mul r0, r2, r0 - ldr r2, .LC0 - ldr r2, [r2] @ max = 0x0fffffff - mov r0, r0, lsr #11 @ max = 0x00003fff - mov r2, r2, lsr #11 @ max = 0x0003ffff - mul r0, r2, r0 @ max = 2^32-1 - movs r0, r0, lsr #6 - -delay_loop: - subs r0, r0, #1 - bne delay_loop - mov pc, lr - -#endif /* CONFIG_USE_IRQ */ diff --git a/arch/arm/cpu/ixp/timer.c b/arch/arm/cpu/ixp/timer.c index edf341f..54a7a55 100644 --- a/arch/arm/cpu/ixp/timer.c +++ b/arch/arm/cpu/ixp/timer.c @@ -1,4 +1,7 @@ /* + * (C) Copyright 2010 + * Michael Schwingen, michael@schwingen.org + * * (C) Copyright 2006 * Stefan Roese, DENX Software Engineering, sr@denx.de. * @@ -31,105 +34,95 @@ #include #include - -#ifdef CONFIG_TIMER_IRQ - -#define FREQ 66666666 -#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ) -#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */ +#include /* - * When interrupts are enabled, use timer 2 for time/delay generation... + * The IXP42x time-stamp timer runs at 2*OSC_IN (66.666MHz when using a + * 33.333MHz crystal). */ - -static volatile ulong timestamp; - -static void timer_isr(void *data) +static inline unsigned long long tick_to_time(unsigned long long tick) { - unsigned int *pTime = (unsigned int *)data; - - (*pTime)++; - - /* - * Reset IRQ source - */ - *IXP425_OSST = IXP425_OSST_TIMER_2_PEND; + tick *= CONFIG_SYS_HZ; + do_div(tick, CONFIG_IXP425_TIMER_CLK); + return tick; } -ulong get_timer (ulong base) +static inline unsigned long long time_to_tick(unsigned long long time) { - return timestamp - base; + time *= CONFIG_IXP425_TIMER_CLK; + do_div(time, CONFIG_SYS_HZ); + return time; } -void reset_timer (void) +static inline unsigned long long us_to_tick(unsigned long long us) { - timestamp = 0; + us = us * CONFIG_IXP425_TIMER_CLK + 999999; + do_div(us, 1000000); + return us; } -int timer_init (void) +static ulong timestamp; +static ulong lastinc; + +unsigned long long get_ticks (void) { - /* install interrupt handler for timer */ - irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)×tamp); + ulong now = *IXP425_OSTS_B; - /* setup the Timer counter value */ - *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE; + if (*IXP425_OSST & IXP425_OSST_TIMER_TS_PEND) { + /* rollover of timestamp timer register */ + timestamp += (0xFFFFFFFF - lastinc) + now + 1; + *IXP425_OSST = IXP425_OSST_TIMER_TS_PEND; + } + else { + /* move stamp forward with absolut diff ticks */ + timestamp += (now - lastinc); + } + lastinc = now; + return timestamp; +} - /* enable timer irq */ - *IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ); - return 0; -} -#else -ulong get_timer (ulong base) +void reset_timer_masked (void) { - return get_timer_masked () - base; + /* reset time */ + lastinc = *IXP425_OSTS_B; /* capture current timestamp counter */ + timestamp = 0; /* start "advancing" time stamp from 0 */ } -void ixp425_udelay(unsigned long usec) +void reset_timer(void) { - /* - * This function has a max usec, but since it is called from udelay - * we should not have to worry... be happy - */ - unsigned long usecs = CONFIG_SYS_HZ/1000000L & ~IXP425_OST_RELOAD_MASK; - - *IXP425_OSST = IXP425_OSST_TIMER_1_PEND; - usecs |= IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE; - *IXP425_OSRT1 = usecs; - while (!(*IXP425_OSST & IXP425_OSST_TIMER_1_PEND)); + reset_timer_masked(); } -void __udelay (unsigned long usec) +ulong get_timer_masked (void) { - while (usec--) ixp425_udelay(1); + return tick_to_time(get_ticks()); } -static ulong reload_constant = 0xfffffff0; - -void reset_timer_masked (void) +ulong get_timer (ulong base) { - ulong reload = reload_constant | IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE; + return get_timer_masked() - base; +} - *IXP425_OSST = IXP425_OSST_TIMER_1_PEND; - *IXP425_OSRT1 = reload; +void set_timer (ulong t) +{ + timestamp = time_to_tick(t); } -ulong get_timer_masked (void) +/* delay x useconds AND preserve advance timestamp value */ +void __udelay (unsigned long usec) { - /* - * Note that it is possible for this to wrap! - * In this case we return max. - */ - ulong current = *IXP425_OST1; - if (*IXP425_OSST & IXP425_OSST_TIMER_1_PEND) - { - return reload_constant; - } - return (reload_constant - current); + unsigned long long tmp; + + tmp = get_ticks() + us_to_tick(usec); + + while (get_ticks() < tmp) + ; } + int timer_init(void) { + *IXP425_OSST = IXP425_OSST_TIMER_TS_PEND; return 0; } -#endif diff --git a/arch/arm/include/asm/arch-ixp/ixp425.h b/arch/arm/include/asm/arch-ixp/ixp425.h index 2114437..ddbf713 100644 --- a/arch/arm/include/asm/arch-ixp/ixp425.h +++ b/arch/arm/include/asm/arch-ixp/ixp425.h @@ -391,9 +391,8 @@ #define IXP425_TIMER_REG(x) (IXP425_TIMER_BASE_PHYS+(x)) #endif -#if 0 /* test-only: also defined in npe/include/... */ -#define IXP425_OSTS IXP425_TIMER_REG(IXP425_OSTS_OFFSET) -#endif +/* _B to avoid collision: also defined in npe/include/... */ +#define IXP425_OSTS_B IXP425_TIMER_REG(IXP425_OSTS_OFFSET) #define IXP425_OST1 IXP425_TIMER_REG(IXP425_OST1_OFFSET) #define IXP425_OSRT1 IXP425_TIMER_REG(IXP425_OSRT1_OFFSET) #define IXP425_OST2 IXP425_TIMER_REG(IXP425_OST2_OFFSET)