diff options
Diffstat (limited to 'board/integratorcp/integratorcp.c')
-rw-r--r-- | board/integratorcp/integratorcp.c | 185 |
1 files changed, 175 insertions, 10 deletions
diff --git a/board/integratorcp/integratorcp.c b/board/integratorcp/integratorcp.c index 6fe8f05babb..216876b469d 100644 --- a/board/integratorcp/integratorcp.c +++ b/board/integratorcp/integratorcp.c @@ -24,7 +24,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -42,19 +42,12 @@ void peripheral_power_enable (void); #if defined(CONFIG_SHOW_BOOT_PROGRESS) void show_boot_progress(int progress) { - printf("Boot reached stage %d\n", progress); + printf("Boot reached stage %d\n", progress); } #endif #define COMP_MODE_ENABLE ((unsigned int)0x0000EAEF) -static inline void delay (unsigned long loops) -{ - __asm__ volatile ("1:\n" - "subs %0, %1, #1\n" - "bne 1b":"=r" (loops):"0" (loops)); -} - /* * Miscellaneous platform dependent initialisations */ @@ -71,6 +64,11 @@ int board_init (void) gd->flags = 0; +#ifdef CONFIG_CM_REMAP +extern void cm_remap(void); + cm_remap(); /* remaps writeable memory to 0x00000000 */ +#endif + icache_enable (); flash__init (); @@ -95,7 +93,7 @@ void flash__init (void) /************************************************************* Routine:ether__init Description: take the Ethernet controller out of reset and wait - for the EEPROM load to complete. + for the EEPROM load to complete. *************************************************************/ void ether__init (void) { @@ -107,5 +105,172 @@ void ether__init (void) ******************************/ int dram_init (void) { + DECLARE_GLOBAL_DATA_PTR; + + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + +#ifdef CONFIG_CM_SPD_DETECT + { +extern void dram_query(void); + unsigned long cm_reg_sdram; + unsigned long sdram_shift; + + dram_query(); /* Assembler accesses to CM registers */ + /* Queries the SPD values */ + + /* Obtain the SDRAM size from the CM SDRAM register */ + + cm_reg_sdram = *(volatile ulong *)(CM_BASE + OS_SDRAM); + /* Register SDRAM size + * + * 0xXXXXXXbbb000bb 16 MB + * 0xXXXXXXbbb001bb 32 MB + * 0xXXXXXXbbb010bb 64 MB + * 0xXXXXXXbbb011bb 128 MB + * 0xXXXXXXbbb100bb 256 MB + * + */ + sdram_shift = ((cm_reg_sdram & 0x0000001C)/4)%4; + gd->bd->bi_dram[0].size = 0x01000000 << sdram_shift; + + } +#endif /* CM_SPD_DETECT */ + return 0; } + +/* The Integrator/CP timer1 is clocked at 1MHz + * can be divided by 16 or 256 + * and can be set up as a 32-bit timer + */ +/* U-Boot expects a 32 bit timer, running at CFG_HZ */ +/* Keep total timer count to avoid losing decrements < div_timer */ +static unsigned long long total_count = 0; +static unsigned long long lastdec; /* Timer reading at last call */ +static unsigned long long div_clock = 1; /* Divisor applied to timer clock */ +static unsigned long long div_timer = 1; /* Divisor to convert timer reading + * change to U-Boot ticks + */ +/* CFG_HZ = CFG_HZ_CLOCK/(div_clock * div_timer) */ +static ulong timestamp; /* U-Boot ticks since startup */ + +#define TIMER_LOAD_VAL ((ulong)0xFFFFFFFF) +#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+4)) + +/* all function return values in U-Boot ticks i.e. (1/CFG_HZ) sec + * - unless otherwise stated + */ + +/* starts up a counter + * - the Integrator/CP timer can be set up to issue an interrupt */ +int interrupt_init (void) +{ + /* Load timer with initial value */ + *(volatile ulong *)(CFG_TIMERBASE + 0) = TIMER_LOAD_VAL; + /* Set timer to be + * enabled 1 + * periodic 1 + * no interrupts 0 + * X 0 + * divider 1 00 == less rounding error + * 32 bit 1 + * wrapping 0 + */ + *(volatile ulong *)(CFG_TIMERBASE + 8) = 0x000000C2; + /* init the timestamp */ + total_count = 0ULL; + reset_timer_masked(); + + div_timer = (unsigned long long)(CFG_HZ_CLOCK / CFG_HZ); + div_timer /= div_clock; + + return (0); +} + +/* + * timer without interrupts + */ +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base_ticks) +{ + return get_timer_masked () - base_ticks; +} + +void set_timer (ulong ticks) +{ + timestamp = ticks; + total_count = (unsigned long long)ticks * div_timer; +} + +/* delay usec useconds */ +void udelay (unsigned long usec) +{ + ulong tmo, tmp; + + /* Convert to U-Boot ticks */ + tmo = usec * CFG_HZ; + tmo /= (1000000L); + + tmp = get_timer_masked(); /* get current timestamp */ + tmo += tmp; /* form target timestamp */ + + while (get_timer_masked () < tmo) {/* loop till event */ + /*NOP*/; + } +} + +void reset_timer_masked (void) +{ + /* capure current decrementer value */ + lastdec = (unsigned long long)READ_TIMER; + /* start "advancing" time stamp from 0 */ + timestamp = 0L; +} + +/* converts the timer reading to U-Boot ticks */ +/* the timestamp is the number of ticks since reset */ +ulong get_timer_masked (void) +{ + /* get current count */ + unsigned long long now = (unsigned long long)READ_TIMER; + + if(now > lastdec) { + /* Must have wrapped */ + total_count += lastdec + TIMER_LOAD_VAL + 1 - now; + } else { + total_count += lastdec - now; + } + lastdec = now; + timestamp = (ulong)(total_count/div_timer); + + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + udelay(usec); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return (unsigned long long)get_timer(0); +} + +/* + * Return the timebase clock frequency + * i.e. how often the timer decrements + */ +ulong get_tbclk (void) +{ + return (ulong)(((unsigned long long)CFG_HZ_CLOCK)/div_clock); +} |