From 8c725b9364ac92338d659dd31457223ed0e7f538 Mon Sep 17 00:00:00 2001 From: stroese Date: Thu, 16 Dec 2004 18:09:49 +0000 Subject: [PATCH] Coldfire MCF5249 support added --- cpu/mcf52x2/cpu.c | 23 ++++++++ cpu/mcf52x2/cpu_init.c | 112 ++++++++++++++++++++++++++++++++++++++- cpu/mcf52x2/interrupts.c | 16 +++++- cpu/mcf52x2/serial.c | 10 +++- cpu/mcf52x2/speed.c | 4 ++ cpu/mcf52x2/start.S | 33 +++++++++++- 6 files changed, 192 insertions(+), 6 deletions(-) diff --git a/cpu/mcf52x2/cpu.c b/cpu/mcf52x2/cpu.c index b012222794..32a524f7e7 100644 --- a/cpu/mcf52x2/cpu.c +++ b/cpu/mcf52x2/cpu.c @@ -34,6 +34,10 @@ #endif +#ifdef CONFIG_M5249 +#include +#endif + #ifdef CONFIG_M5272 int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { @@ -121,3 +125,22 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { return 0; }; #endif + +#ifdef CONFIG_M5249 /* test-only: todo... */ +int checkcpu (void) +{ + char buf[32]; + + printf ("CPU: MOTOROLA Coldfire MCF5249 at %s MHz\n", strmhz(buf, CFG_CLK)); + return 0; +} + +int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) { + /* enable watchdog, set timeout to 0 and wait */ + mbar_writeByte(MCFSIM_SYPCR, 0xc0); + while (1); + + /* we don't return! */ + return 0; +}; +#endif diff --git a/cpu/mcf52x2/cpu_init.c b/cpu/mcf52x2/cpu_init.c index 8aff8f1ae2..350c431dba 100644 --- a/cpu/mcf52x2/cpu_init.c +++ b/cpu/mcf52x2/cpu_init.c @@ -34,7 +34,11 @@ #include #endif -#ifdef CONFIG_M5272 +#ifdef CONFIG_M5249 +#include +#endif + +#if defined(CONFIG_M5272) /* * Breath some life into the CPU... * @@ -118,7 +122,7 @@ int cpu_init_r (void) { return (0); } -#endif /* #ifdef CONFIG_M5272 */ +#endif /* #if defined(CONFIG_M5272) */ #ifdef CONFIG_M5282 @@ -142,3 +146,107 @@ int cpu_init_r (void) return (0); } #endif + +#if defined(CONFIG_M5249) +/* + * Breath some life into the CPU... + * + * Set up the memory map, + * initialize a bunch of registers, + * initialize the UPM's + */ +void cpu_init_f (void) +{ +#ifndef CFG_PLL_BYPASS + /* + * Setup the PLL to run at the specified speed + * + */ + volatile unsigned long cpll = mbar2_readLong(MCFSIM_PLLCR); + unsigned long pllcr; +#ifdef CFG_FAST_CLK + pllcr = 0x925a3100; /* ~140MHz clock (PLL bypass = 0) */ +#else + pllcr = 0x135a4140; /* ~72MHz clock (PLL bypass = 0) */ +#endif + cpll = cpll & 0xfffffffe; /* Set PLL bypass mode = 0 (PSTCLK = crystal) */ + mbar2_writeLong(MCFSIM_PLLCR, cpll); /* Set the PLL to bypass mode (PSTCLK = crystal) */ + mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* set the clock speed */ + pllcr ^= 0x00000001; /* Set pll bypass to 1 */ + mbar2_writeLong(MCFSIM_PLLCR, pllcr); /* Start locking (pll bypass = 1) */ + udelay(0x20); /* Wait for a lock ... */ +#endif /* #ifndef CFG_PLL_BYPASS */ + + /* + * NOTE: by setting the GPIO_FUNCTION registers, we ensure that the UART pins + * (UART0: gpio 30,27, UART1: gpio 31, 28) will be used as UART pins + * which is their primary function. + * ~Jeremy + */ + mbar2_writeLong(MCFSIM_GPIO_FUNC, CFG_GPIO_FUNC); + mbar2_writeLong(MCFSIM_GPIO1_FUNC, CFG_GPIO1_FUNC); + mbar2_writeLong(MCFSIM_GPIO_EN, CFG_GPIO_EN); + mbar2_writeLong(MCFSIM_GPIO1_EN, CFG_GPIO1_EN); + mbar2_writeLong(MCFSIM_GPIO_OUT, CFG_GPIO_OUT); + mbar2_writeLong(MCFSIM_GPIO1_OUT, CFG_GPIO1_OUT); + + /* + * dBug Compliance: + * You can verify these values by using dBug's 'ird' + * (Internal Register Display) command + * ~Jeremy + * + */ + mbar_writeByte(MCFSIM_MPARK, 0x30); /* 5249 Internal Core takes priority over DMA */ + mbar_writeByte(MCFSIM_SYPCR, 0x00); + mbar_writeByte(MCFSIM_SWIVR, 0x0f); + mbar_writeByte(MCFSIM_SWSR, 0x00); + mbar_writeLong(MCFSIM_IMR, 0xfffffbff); + mbar_writeByte(MCFSIM_SWDICR, 0x00); + mbar_writeByte(MCFSIM_TIMER1ICR, 0x00); + mbar_writeByte(MCFSIM_TIMER2ICR, 0x88); + mbar_writeByte(MCFSIM_I2CICR, 0x00); + mbar_writeByte(MCFSIM_UART1ICR, 0x00); + mbar_writeByte(MCFSIM_UART2ICR, 0x00); + mbar_writeByte(MCFSIM_ICR6, 0x00); + mbar_writeByte(MCFSIM_ICR7, 0x00); + mbar_writeByte(MCFSIM_ICR8, 0x00); + mbar_writeByte(MCFSIM_ICR9, 0x00); + mbar_writeByte(MCFSIM_QSPIICR, 0x00); + + mbar2_writeLong(MCFSIM_GPIO_INT_EN, 0x00000080); + mbar2_writeByte(MCFSIM_INTBASE, 0x40); /* Base interrupts at 64 */ + mbar2_writeByte(MCFSIM_SPURVEC, 0x00); + mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); /* Enable a 1 cycle pre-drive cycle on CS1 */ + + /* Setup interrupt priorities for gpio7 */ + /* mbar2_writeLong(MCFSIM_INTLEV5, 0x70000000); */ + + /* IDE Config registers */ + mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); + mbar2_writeLong(MCFSIM_IDECONFIG2, 0x00000000); + + /* + * Setup chip selects... + */ + + mbar_writeShort(MCFSIM_CSAR1, CFG_CSAR1); + mbar_writeShort(MCFSIM_CSCR1, CFG_CSCR1); + mbar_writeLong(MCFSIM_CSMR1, CFG_CSMR1); + + mbar_writeShort(MCFSIM_CSAR0, CFG_CSAR0); + mbar_writeShort(MCFSIM_CSCR0, CFG_CSCR0); + mbar_writeLong(MCFSIM_CSMR0, CFG_CSMR0); + + /* enable instruction cache now */ + icache_enable(); +} + +/* + * initialize higher level parts of CPU like timers + */ +int cpu_init_r (void) +{ + return (0); +} +#endif /* #if defined(CONFIG_M5249) */ diff --git a/cpu/mcf52x2/interrupts.c b/cpu/mcf52x2/interrupts.c index 1836f27167..868df39194 100644 --- a/cpu/mcf52x2/interrupts.c +++ b/cpu/mcf52x2/interrupts.c @@ -37,6 +37,10 @@ #include #endif +#ifdef CONFIG_M5249 +#include +#endif + #define NR_IRQS 31 @@ -142,10 +146,11 @@ void int_handler (struct pt_regs *fp) irq_vecs[vec - vec_base].handler (irq_vecs[vec - vec_base].arg); } else { - printf ("\nBogus External Interrupt Vector %ld\n", vec); + printf ("\nBogus External Interrupt Vector %d\n", vec); } } + #ifdef CONFIG_M5272 int interrupt_init (void) { @@ -172,3 +177,12 @@ int interrupt_init (void) return 0; } #endif + +#ifdef CONFIG_M5249 +int interrupt_init (void) +{ + enable_interrupts (); + + return 0; +} +#endif diff --git a/cpu/mcf52x2/serial.c b/cpu/mcf52x2/serial.c index fbbd14d623..c7309220f1 100644 --- a/cpu/mcf52x2/serial.c +++ b/cpu/mcf52x2/serial.c @@ -34,11 +34,19 @@ #include #endif +#ifdef CONFIG_M5249 +#include +#endif + +#ifdef CONFIG_M5249 +#define DoubleClock(a) ((double)(CFG_CLK/2) / 32.0 / (double)(a)) +#else #define DoubleClock(a) ((double)(CFG_CLK) / 32.0 / (double)(a)) +#endif void rs_serial_setbaudrate(int port,int baudrate) { -#ifdef CONFIG_M5272 +#if defined(CONFIG_M5272) || defined(CONFIG_M5249) volatile unsigned char *uartp; double clock, fraction; diff --git a/cpu/mcf52x2/speed.c b/cpu/mcf52x2/speed.c index 8d5c92f370..519c992581 100644 --- a/cpu/mcf52x2/speed.c +++ b/cpu/mcf52x2/speed.c @@ -32,6 +32,10 @@ int get_clocks (void) DECLARE_GLOBAL_DATA_PTR; gd->cpu_clk = CFG_CLK; +#ifdef CONFIG_M5249 + gd->bus_clk = gd->cpu_clk / 2; +#else gd->bus_clk = gd->cpu_clk; +#endif return (0); } diff --git a/cpu/mcf52x2/start.S b/cpu/mcf52x2/start.S index cf1b97d84c..b4926e2376 100644 --- a/cpu/mcf52x2/start.S +++ b/cpu/mcf52x2/start.S @@ -110,13 +110,19 @@ _start: movec %d0, %VBR #endif -#ifdef CONFIG_M5272 +#if defined(CONFIG_M5272) || defined(CONFIG_M5249) move.l #(CFG_MBAR + 1), %d0 /* set MBAR address + valid flag */ move.c %d0, %MBAR + /*** The 5249 has MBAR2 as well ***/ +#ifdef CFG_MBAR2 + move.l #(CFG_MBAR2 + 1), %d0 /* Get MBAR2 address */ + movec %d0, #0xc0e /* Set MBAR2 */ +#endif + move.l #(CFG_INIT_RAM_ADDR + 1), %d0 movec %d0, %RAMBAR0 -#endif +#endif /* #if defined(CONFIG_M5272) || defined(CONFIG_M5249) */ #ifdef CONFIG_M5282 /* Initialize IPSBAR */ @@ -287,6 +293,28 @@ icache_enable: rts #endif +#ifdef CONFIG_M5249 + .globl icache_enable +icache_enable: + /* + * Note: The 5249 Documentation doesn't give a bit position for CINV! + * From the 5272 and the 5307 documentation, I have deduced that it is + * probably CACR[24]. Should someone say something to Motorola? + * ~Jeremy + */ + move.l #0x01000000, %d0 /* Invalidate whole cache */ + move.c %d0,%CACR + move.l #0xff00c000, %d0 /* Set FLASH cachable: always match (SM=0b10) */ + move.c %d0, %ACR0 + move.l #0x0000c000, %d0 /* Set SDRAM cachable: always match (SM=0b10) */ + move.c %d0, %ACR1 + move.l #0x90000200, %d0 /* Set cache enable cmd */ + move.c %d0,%CACR + moveq #1, %d0 + move.l %d0, icache_state + rts +#endif + .globl icache_disable icache_disable: move.l #0x00000100, %d0 /* Setup cache mask */ @@ -307,6 +335,7 @@ icache_status: icache_state: .long 1 + /*------------------------------------------------------------------------------*/ .globl version_string -- 2.25.1