mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-10-05 02:50:44 +09:00
Fix IXP code to work after relocation was added
- 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>
This commit is contained in:
parent
009e464802
commit
ce04bb41a6
@ -36,8 +36,6 @@
|
|||||||
#include <asm/arch/ixp425.h>
|
#include <asm/arch/ixp425.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
|
||||||
ulong loops_per_jiffy;
|
|
||||||
|
|
||||||
static void cache_flush(void);
|
static void cache_flush(void);
|
||||||
|
|
||||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||||
@ -51,17 +49,14 @@ int print_cpuinfo (void)
|
|||||||
puts("CPU: Intel IXP425 at ");
|
puts("CPU: Intel IXP425 at ");
|
||||||
switch ((id & 0x000003f0) >> 4) {
|
switch ((id & 0x000003f0) >> 4) {
|
||||||
case 0x1c:
|
case 0x1c:
|
||||||
loops_per_jiffy = 887467;
|
|
||||||
speed = 533;
|
speed = 533;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
loops_per_jiffy = 666016;
|
|
||||||
speed = 400;
|
speed = 400;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1f:
|
case 0x1f:
|
||||||
loops_per_jiffy = 442901;
|
|
||||||
speed = 266;
|
speed = 266;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,8 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.globl _start
|
.globl _start
|
||||||
_start: b reset
|
_start:
|
||||||
|
ldr pc, _reset
|
||||||
ldr pc, _undefined_instruction
|
ldr pc, _undefined_instruction
|
||||||
ldr pc, _software_interrupt
|
ldr pc, _software_interrupt
|
||||||
ldr pc, _prefetch_abort
|
ldr pc, _prefetch_abort
|
||||||
@ -74,6 +75,7 @@ _start: b reset
|
|||||||
ldr pc, _irq
|
ldr pc, _irq
|
||||||
ldr pc, _fiq
|
ldr pc, _fiq
|
||||||
|
|
||||||
|
_reset: .word reset
|
||||||
_undefined_instruction: .word undefined_instruction
|
_undefined_instruction: .word undefined_instruction
|
||||||
_software_interrupt: .word software_interrupt
|
_software_interrupt: .word software_interrupt
|
||||||
_prefetch_abort: .word prefetch_abort
|
_prefetch_abort: .word prefetch_abort
|
||||||
@ -167,12 +169,6 @@ reset:
|
|||||||
str r1, [r2]
|
str r1, [r2]
|
||||||
|
|
||||||
/* make sure flash is visible at 0 */
|
/* 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
|
mov r1, #CONFIG_SYS_SDR_CONFIG
|
||||||
ldr r2, =IXP425_SDR_CONFIG
|
ldr r2, =IXP425_SDR_CONFIG
|
||||||
str r1, [r2]
|
str r1, [r2]
|
||||||
@ -216,19 +212,6 @@ reset:
|
|||||||
str r1, [r4]
|
str r1, [r4]
|
||||||
DELAY_FOR 0x4000, r0
|
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 */
|
/* invalidate I & D caches & BTB */
|
||||||
mcr p15, 0, r0, c7, c7, 0
|
mcr p15, 0, r0, c7, c7, 0
|
||||||
CPWAIT r0
|
CPWAIT r0
|
||||||
@ -241,19 +224,12 @@ reset:
|
|||||||
mcr p15, 0, r0, c7, c10, 4
|
mcr p15, 0, r0, c7, c10, 4
|
||||||
CPWAIT r0
|
CPWAIT r0
|
||||||
|
|
||||||
/* move flash to 0x50000000 */
|
/* remove flash mirror at 0x00000000 */
|
||||||
ldr r2, =IXP425_EXP_CFG0
|
ldr r2, =IXP425_EXP_CFG0
|
||||||
ldr r1, [r2]
|
ldr r1, [r2]
|
||||||
bic r1, r1, #0x80000000
|
bic r1, r1, #0x80000000
|
||||||
str r1, [r2]
|
str r1, [r2]
|
||||||
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
nop
|
|
||||||
|
|
||||||
/* invalidate I & Data TLB */
|
/* invalidate I & Data TLB */
|
||||||
mcr p15, 0, r0, c8, c7, 0
|
mcr p15, 0, r0, c8, c7, 0
|
||||||
CPWAIT r0
|
CPWAIT r0
|
||||||
@ -269,7 +245,7 @@ reset:
|
|||||||
orr r0,r0,#0x13
|
orr r0,r0,#0x13
|
||||||
msr cpsr,r0
|
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:
|
call_board_init_f:
|
||||||
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
|
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
|
||||||
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
|
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
|
||||||
@ -580,28 +556,3 @@ reset_endless:
|
|||||||
|
|
||||||
b 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 */
|
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Schwingen, michael@schwingen.org
|
||||||
|
*
|
||||||
* (C) Copyright 2006
|
* (C) Copyright 2006
|
||||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||||
*
|
*
|
||||||
@ -31,105 +34,94 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <asm/arch/ixp425.h>
|
#include <asm/arch/ixp425.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <div64.h>
|
||||||
|
|
||||||
#ifdef CONFIG_TIMER_IRQ
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
#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 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 inline unsigned long long tick_to_time(unsigned long long tick)
|
||||||
static volatile ulong timestamp;
|
|
||||||
|
|
||||||
static void timer_isr(void *data)
|
|
||||||
{
|
{
|
||||||
unsigned int *pTime = (unsigned int *)data;
|
tick *= CONFIG_SYS_HZ;
|
||||||
|
do_div(tick, CONFIG_IXP425_TIMER_CLK);
|
||||||
(*pTime)++;
|
return tick;
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset IRQ source
|
|
||||||
*/
|
|
||||||
*IXP425_OSST = IXP425_OSST_TIMER_2_PEND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
ulong now = readl(IXP425_OSTS_B);
|
||||||
irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)×tamp);
|
|
||||||
|
|
||||||
/* setup the Timer counter value */
|
if (readl(IXP425_OSST) & IXP425_OSST_TIMER_TS_PEND) {
|
||||||
*IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE;
|
/* rollover of timestamp timer register */
|
||||||
|
gd->timestamp += (0xFFFFFFFF - gd->lastinc) + now + 1;
|
||||||
/* enable timer irq */
|
writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
|
||||||
*IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ);
|
} else {
|
||||||
|
/* move stamp forward with absolut diff ticks */
|
||||||
return 0;
|
gd->timestamp += (now - gd->lastinc);
|
||||||
}
|
|
||||||
#else
|
|
||||||
ulong get_timer (ulong base)
|
|
||||||
{
|
|
||||||
return get_timer_masked () - base;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ixp425_udelay(unsigned long usec)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
void __udelay (unsigned long usec)
|
|
||||||
{
|
|
||||||
while (usec--) ixp425_udelay(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ulong reload_constant = 0xfffffff0;
|
|
||||||
|
|
||||||
void reset_timer_masked (void)
|
|
||||||
{
|
|
||||||
ulong reload = reload_constant | IXP425_OST_ONE_SHOT | IXP425_OST_ENABLE;
|
|
||||||
|
|
||||||
*IXP425_OSST = IXP425_OSST_TIMER_1_PEND;
|
|
||||||
*IXP425_OSRT1 = reload;
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong get_timer_masked (void)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 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);
|
gd->lastinc = now;
|
||||||
|
return gd->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void reset_timer_masked(void)
|
||||||
|
{
|
||||||
|
/* capture current timestamp counter */
|
||||||
|
gd->lastinc = readl(IXP425_OSTS_B);
|
||||||
|
/* start "advancing" time stamp from 0 */
|
||||||
|
gd->timestamp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_timer(void)
|
||||||
|
{
|
||||||
|
reset_timer_masked();
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong get_timer_masked(void)
|
||||||
|
{
|
||||||
|
return tick_to_time(get_ticks());
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong get_timer(ulong base)
|
||||||
|
{
|
||||||
|
return get_timer_masked() - base;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_timer(ulong t)
|
||||||
|
{
|
||||||
|
gd->timestamp = time_to_tick(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delay x useconds AND preserve advance timestamp value */
|
||||||
|
void __udelay(unsigned long usec)
|
||||||
|
{
|
||||||
|
unsigned long long tmp;
|
||||||
|
|
||||||
|
tmp = get_ticks() + us_to_tick(usec);
|
||||||
|
|
||||||
|
while (get_ticks() < tmp)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timer_init(void)
|
int timer_init(void)
|
||||||
{
|
{
|
||||||
|
writel(IXP425_OSST_TIMER_TS_PEND, IXP425_OSST);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
@ -391,9 +391,8 @@
|
|||||||
#define IXP425_TIMER_REG(x) (IXP425_TIMER_BASE_PHYS+(x))
|
#define IXP425_TIMER_REG(x) (IXP425_TIMER_BASE_PHYS+(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* test-only: also defined in npe/include/... */
|
/* _B to avoid collision: also defined in npe/include/... */
|
||||||
#define IXP425_OSTS IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
|
#define IXP425_OSTS_B IXP425_TIMER_REG(IXP425_OSTS_OFFSET)
|
||||||
#endif
|
|
||||||
#define IXP425_OST1 IXP425_TIMER_REG(IXP425_OST1_OFFSET)
|
#define IXP425_OST1 IXP425_TIMER_REG(IXP425_OST1_OFFSET)
|
||||||
#define IXP425_OSRT1 IXP425_TIMER_REG(IXP425_OSRT1_OFFSET)
|
#define IXP425_OSRT1 IXP425_TIMER_REG(IXP425_OSRT1_OFFSET)
|
||||||
#define IXP425_OST2 IXP425_TIMER_REG(IXP425_OST2_OFFSET)
|
#define IXP425_OST2 IXP425_TIMER_REG(IXP425_OST2_OFFSET)
|
||||||
|
@ -63,6 +63,9 @@ typedef struct global_data {
|
|||||||
unsigned long tbu;
|
unsigned long tbu;
|
||||||
unsigned long long timer_reset_value;
|
unsigned long long timer_reset_value;
|
||||||
unsigned long lastinc;
|
unsigned long lastinc;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_IXP425
|
||||||
|
unsigned long timestamp;
|
||||||
#endif
|
#endif
|
||||||
unsigned long relocaddr; /* Start address of U-Boot in RAM */
|
unsigned long relocaddr; /* Start address of U-Boot in RAM */
|
||||||
phys_size_t ram_size; /* RAM size */
|
phys_size_t ram_size; /* RAM size */
|
||||||
|
Loading…
Reference in New Issue
Block a user