From: Marek Vasut <marek.vasut@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [IXP42x PATCH series v4 04/17] Fix IXP code to work after relocation was added
Date: Sat, 21 May 2011 01:58:56 +0200 [thread overview]
Message-ID: <201105210158.56692.marek.vasut@gmail.com> (raw)
In-Reply-To: <1302126558-1318-5-git-send-email-michael@schwingen.org>
On Wednesday, April 06, 2011 11:49:05 PM Michael Schwingen wrote:
> - 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 <michael@schwingen.org>
> ---
> Changes for V2:
> - fix patch description
> Changes for V3:
> - use I/O accessors
> - move timestamp variable from BSS to global data
> - coding style fixes
> Changes for V4:
> - add changelog
>
> arch/arm/cpu/ixp/cpu.c | 5 --
> arch/arm/cpu/ixp/start.S | 59 ++--------------
> arch/arm/cpu/ixp/timer.c | 124
> +++++++++++++++----------------- arch/arm/include/asm/arch-ixp/ixp425.h |
> 5 +-
> arch/arm/include/asm/global_data.h | 3 +
> 5 files changed, 68 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 <asm/arch/ixp425.h>
> #include <asm/system.h>
>
> -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 561c1f4..faa9a8f 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
> @@ -167,12 +169,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]
> @@ -216,19 +212,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
> @@ -241,19 +224,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
> @@ -269,7 +245,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 */
> @@ -580,28 +556,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..7a44a08 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 at schwingen.org
> + *
> * (C) Copyright 2006
> * Stefan Roese, DENX Software Engineering, sr at denx.de.
> *
> @@ -31,105 +34,94 @@
>
> #include <common.h>
> #include <asm/arch/ixp425.h>
> +#include <asm/io.h>
> +#include <div64.h>
>
> -#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 */ +DECLARE_GLOBAL_DATA_PTR;
>
> /*
> - * 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)
> +unsigned long long get_ticks(void)
> {
> - /* install interrupt handler for timer */
> - irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)×tamp);
> -
> - /* setup the Timer counter value */
> - *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
> + ulong now = *IXP425_OSTS_B;
Aren't you missing an IO accessor here ?
> +
> + if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
> + /* rollover of timestamp timer register */
> + gd->timestamp += (0xFFFFFFFF - gd->lastinc) + now + 1;
> + writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
> + } else {
> + /* move stamp forward with absolut diff ticks */
> + gd->timestamp += (now - gd->lastinc);
> + }
> + gd->lastinc = now;
> + return gd->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;
> + /* capture current timestamp counter */
> + gd->lastinc = readl(IXP425_OSTS_B);
> + /* start "advancing" time stamp from 0 */
> + gd->timestamp = 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)
> +{
> + gd->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)
> {
> + writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
> 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..5132607 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)
This will eventually enjoy being converted to struct ixp_timer_regset { ... }
goo. If you already did it in some further patch, sorry, I didn't get there yet
;-)
> diff --git a/arch/arm/include/asm/global_data.h
> b/arch/arm/include/asm/global_data.h index 2a84d27..c1a59f2 100644
> --- a/arch/arm/include/asm/global_data.h
> +++ b/arch/arm/include/asm/global_data.h
> @@ -64,6 +64,9 @@ typedef struct global_data {
> unsigned long long timer_reset_value;
> unsigned long lastinc;
> #endif
> +#ifdef CONFIG_IXP425
> + unsigned long timestamp;
> +#endif
> unsigned long relocaddr; /* Start address of U-Boot in RAM */
> phys_size_t ram_size; /* RAM size */
> unsigned long mon_len; /* monitor len */
next prev parent reply other threads:[~2011-05-20 23:58 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-06 21:49 [U-Boot] [IXP42x PATCH series v4 00/17] Overview Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 01/17] add XScale sub architecture (IXP/PXA) to maintainer list Michael Schwingen
2011-05-20 23:53 ` Marek Vasut
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 02/17] add support for IXP42x Rev. B1 and newer Michael Schwingen
2011-05-20 23:53 ` Marek Vasut
2011-05-21 18:31 ` Wolfgang Denk
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 03/17] trigger hardware watchdog in IXP42x serial driver Michael Schwingen
2011-05-20 23:54 ` Marek Vasut
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 04/17] Fix IXP code to work after relocation was added Michael Schwingen
2011-05-20 23:58 ` Marek Vasut [this message]
2011-05-22 19:15 ` Michael Schwingen
2011-05-23 0:38 ` Marek Vasut
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 05/17] fix "depend" target in npe directory Michael Schwingen
2011-05-20 23:59 ` Marek Vasut
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 06/17] support CONFIG_SYS_LDSCRIPT on ARM Michael Schwingen
2011-05-22 15:33 ` Marek Vasut
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 07/17] use -ffunction-sections / --gc-sections on IXP42x Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 08/17] update/fix AcTux1 board Michael Schwingen
2011-05-21 0:03 ` Marek Vasut
2011-05-22 15:36 ` Marek Vasut
2011-05-22 21:53 ` Michael Schwingen
2011-05-22 19:51 ` Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 09/17] update/fix AcTux2 board Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 10/17] update/fix AcTux3 board Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 11/17] update/fix AcTux4 board Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 12/17] IXP NPE: add support for fixed-speed MII ports Michael Schwingen
2011-05-21 0:05 ` Marek Vasut
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 13/17] add dvlhost (dLAN 200 AV Wireless G) board Michael Schwingen
2011-05-21 0:06 ` Marek Vasut
2011-05-22 20:53 ` Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 14/17] update/fix IXDP425 / IXDPG425 boards Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 15/17] update/fix PDNB3 board Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 16/17] IXP42x PCI rewrite Michael Schwingen
2011-04-06 21:49 ` [U-Boot] [IXP42x PATCH series v4 17/17] run arm_pci_init after relocation Michael Schwingen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201105210158.56692.marek.vasut@gmail.com \
--to=marek.vasut@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.