ColdFire: MCF52x2 update

Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
This commit is contained in:
TsiChungLiew 2007-08-15 19:21:21 -05:00 committed by John Rigby
parent f52e78304d
commit 83ec20bc43
8 changed files with 369 additions and 1498 deletions

View File

@ -27,8 +27,8 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START =
COBJS = serial.o interrupts.o cpu.o speed.o cpu_init.o fec.o
START = start.o
COBJS = interrupts.o cpu.o speed.o cpu_init.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))

View File

@ -28,33 +28,15 @@
#include <common.h>
#include <watchdog.h>
#include <command.h>
#include <asm/immap.h>
#ifdef CONFIG_M5271
#include <asm/immap_5271.h>
#include <asm/m5271.h>
#endif
#ifdef CONFIG_M5272
#include <asm/immap_5272.h>
#include <asm/m5272.h>
#endif
#ifdef CONFIG_M5282
#include <asm/m5282.h>
#include <asm/immap_5282.h>
#endif
#ifdef CONFIG_M5249
#include <asm/m5249.h>
#endif
#ifdef CONFIG_M5271
/*
* Both MCF5270 and MCF5271 are members of the MPC5271 family. Try to
* determine which one we are running on, based on the Chip Identification
* Register (CIR).
*/
int checkcpu (void)
int checkcpu(void)
{
char buf[32];
unsigned short cir; /* Chip Identification Register */
@ -80,156 +62,164 @@ int checkcpu (void)
if (cpu_model)
printf("CPU: Freescale ColdFire MCF%s rev. %hu, at %s MHz\n",
cpu_model, prn, strmhz(buf, CFG_CLK));
cpu_model, prn, strmhz(buf, CFG_CLK));
else
printf("CPU: Unknown - Freescale ColdFire MCF5271 family"
" (PIN: 0x%x) rev. %hu, at %s MHz\n",
pin, prn, strmhz(buf, CFG_CLK));
" (PIN: 0x%x) rev. %hu, at %s MHz\n",
pin, prn, strmhz(buf, CFG_CLK));
return 0;
}
int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) {
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
{
mbar_writeByte(MCF_RCM_RCR,
MCF_RCM_RCR_SOFTRST | MCF_RCM_RCR_FRCRSTOUT);
MCF_RCM_RCR_SOFTRST | MCF_RCM_RCR_FRCRSTOUT);
return 0;
};
#if defined(CONFIG_WATCHDOG)
void watchdog_reset (void)
void watchdog_reset(void)
{
mbar_writeShort(MCF_WTM_WSR, 0x5555);
mbar_writeShort(MCF_WTM_WSR, 0xAAAA);
}
int watchdog_disable (void)
int watchdog_disable(void)
{
mbar_writeShort(MCF_WTM_WCR, 0);
return (0);
}
int watchdog_init (void)
int watchdog_init(void)
{
mbar_writeShort(MCF_WTM_WCR, MCF_WTM_WCR_EN);
return (0);
}
#endif /* #ifdef CONFIG_WATCHDOG */
#endif /* #ifdef CONFIG_WATCHDOG */
#endif
#ifdef CONFIG_M5272
int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) {
volatile wdog_t * wdp = (wdog_t *)(CFG_MBAR + MCFSIM_WRRR);
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
{
volatile wdog_t *wdp = (wdog_t *) (MMAP_WDOG);
wdp->wdog_wrrr = 0;
udelay (1000);
udelay(1000);
/* enable watchdog, set timeout to 0 and wait */
wdp->wdog_wrrr = 1;
while (1);
while (1) ;
/* we don't return! */
return 0;
};
int checkcpu(void) {
ulong *dirp = (ulong *)(CFG_MBAR + MCFSIM_DIR);
int checkcpu(void)
{
volatile sysctrl_t *sysctrl = (sysctrl_t *) (MMAP_CFG);
uchar msk;
char *suf;
char *suf;
puts ("CPU: ");
msk = (*dirp > 28) & 0xf;
puts("CPU: ");
msk = (sysctrl->sc_dir > 28) & 0xf;
switch (msk) {
case 0x2: suf = "1K75N"; break;
case 0x4: suf = "3K75N"; break;
default:
suf = NULL;
printf ("Freescale MCF5272 (Mask:%01x)\n", msk);
break;
}
case 0x2:
suf = "1K75N";
break;
case 0x4:
suf = "3K75N";
break;
default:
suf = NULL;
printf("Freescale MCF5272 (Mask:%01x)\n", msk);
break;
}
if (suf)
printf ("Freescale MCF5272 %s\n", suf);
printf("Freescale MCF5272 %s\n", suf);
return 0;
};
#if defined(CONFIG_WATCHDOG)
/* Called by macro WATCHDOG_RESET */
void watchdog_reset (void)
void watchdog_reset(void)
{
volatile immap_t * regp = (volatile immap_t *)CFG_MBAR;
regp->wdog_reg.wdog_wcr = 0;
volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG);
wdt->wdog_wcr = 0;
}
int watchdog_disable (void)
int watchdog_disable(void)
{
volatile immap_t *regp = (volatile immap_t *)CFG_MBAR;
volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG);
regp->wdog_reg.wdog_wcr = 0; /* reset watchdog counter */
regp->wdog_reg.wdog_wirr = 0; /* disable watchdog interrupt */
regp->wdog_reg.wdog_wrrr = 0; /* disable watchdog timer */
wdt->wdog_wcr = 0; /* reset watchdog counter */
wdt->wdog_wirr = 0; /* disable watchdog interrupt */
wdt->wdog_wrrr = 0; /* disable watchdog timer */
puts ("WATCHDOG:disabled\n");
puts("WATCHDOG:disabled\n");
return (0);
}
int watchdog_init (void)
int watchdog_init(void)
{
volatile immap_t *regp = (volatile immap_t *)CFG_MBAR;
volatile wdog_t *wdt = (volatile wdog_t *)(MMAP_WDOG);
regp->wdog_reg.wdog_wirr = 0; /* disable watchdog interrupt */
wdt->wdog_wirr = 0; /* disable watchdog interrupt */
/* set timeout and enable watchdog */
regp->wdog_reg.wdog_wrrr = ((CONFIG_WATCHDOG_TIMEOUT * CFG_HZ) / (32768 * 1000)) - 1;
regp->wdog_reg.wdog_wcr = 0; /* reset watchdog counter */
wdt->wdog_wrrr =
((CONFIG_WATCHDOG_TIMEOUT * CFG_HZ) / (32768 * 1000)) - 1;
wdt->wdog_wcr = 0; /* reset watchdog counter */
puts ("WATCHDOG:enabled\n");
puts("WATCHDOG:enabled\n");
return (0);
}
#endif /* #ifdef CONFIG_WATCHDOG */
#endif /* #ifdef CONFIG_M5272 */
#endif /* #ifdef CONFIG_WATCHDOG */
#endif /* #ifdef CONFIG_M5272 */
#ifdef CONFIG_M5282
int checkcpu (void)
int checkcpu(void)
{
unsigned char resetsource = MCFRESET_RSR;
printf ("CPU: Freescale Coldfire MCF5282 (PIN: %2.2x REV: %2.2x)\n",
MCFCCM_CIR>>8,MCFCCM_CIR & MCFCCM_CIR_PRN_MASK);
printf ("Reset:%s%s%s%s%s%s%s\n",
(resetsource & MCFRESET_RSR_LOL) ? " Loss of Lock" : "",
(resetsource & MCFRESET_RSR_LOC) ? " Loss of Clock" : "",
(resetsource & MCFRESET_RSR_EXT) ? " External" : "",
(resetsource & MCFRESET_RSR_POR) ? " Power On" : "",
(resetsource & MCFRESET_RSR_WDR) ? " Watchdog" : "",
(resetsource & MCFRESET_RSR_SOFT) ? " Software" : "",
(resetsource & MCFRESET_RSR_LVD) ? " Low Voltage" : ""
);
printf("CPU: Freescale Coldfire MCF5282 (PIN: %2.2x REV: %2.2x)\n",
MCFCCM_CIR >> 8, MCFCCM_CIR & MCFCCM_CIR_PRN_MASK);
printf("Reset:%s%s%s%s%s%s%s\n",
(resetsource & MCFRESET_RSR_LOL) ? " Loss of Lock" : "",
(resetsource & MCFRESET_RSR_LOC) ? " Loss of Clock" : "",
(resetsource & MCFRESET_RSR_EXT) ? " External" : "",
(resetsource & MCFRESET_RSR_POR) ? " Power On" : "",
(resetsource & MCFRESET_RSR_WDR) ? " Watchdog" : "",
(resetsource & MCFRESET_RSR_SOFT) ? " Software" : "",
(resetsource & MCFRESET_RSR_LVD) ? " Low Voltage" : "");
return 0;
}
int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
int do_reset(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
{
MCFRESET_RCR = MCFRESET_RCR_SOFTRST;
return 0;
};
#endif
#ifdef CONFIG_M5249 /* test-only: todo... */
int checkcpu (void)
#ifdef CONFIG_M5249 /* test-only: todo... */
int checkcpu(void)
{
char buf[32];
printf ("CPU: Freescale Coldfire MCF5249 at %s MHz\n", strmhz(buf, CFG_CLK));
printf("CPU: Freescale 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[]) {
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);
while (1) ;
/* we don't return! */
return 0;

View File

@ -27,28 +27,10 @@
#include <common.h>
#include <watchdog.h>
#ifdef CONFIG_M5271
#include <asm/m5271.h>
#include <asm/immap_5271.h>
#endif
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#include <asm/immap_5272.h>
#endif
#ifdef CONFIG_M5282
#include <asm/m5282.h>
#include <asm/immap_5282.h>
#endif
#ifdef CONFIG_M5249
#include <asm/m5249.h>
#endif
#include <asm/immap.h>
#if defined(CONFIG_M5271)
void cpu_init_f (void)
void cpu_init_f(void)
{
#ifndef CONFIG_WATCHDOG
/* Disable the watchdog if we aren't using it */
@ -58,25 +40,35 @@ void cpu_init_f (void)
/* Set clockspeed to 100MHz */
mbar_writeShort(MCF_FMPLL_SYNCR,
MCF_FMPLL_SYNCR_MFD(0) | MCF_FMPLL_SYNCR_RFD(0));
while (!mbar_readByte(MCF_FMPLL_SYNSR) & MCF_FMPLL_SYNSR_LOCK);
/* Enable UART pins */
mbar_writeShort(MCF_GPIO_PAR_UART, MCF_GPIO_PAR_UART_U0TXD |
MCF_GPIO_PAR_UART_U0RXD |
MCF_GPIO_PAR_UART_U1RXD_UART1 |
MCF_GPIO_PAR_UART_U1TXD_UART1);
/* Enable Ethernet pins */
mbar_writeByte(MCF_GPIO_PAR_FECI2C, CFG_FECI2C);
while (!mbar_readByte(MCF_FMPLL_SYNSR) & MCF_FMPLL_SYNSR_LOCK) ;
}
/*
* initialize higher level parts of CPU like timers
*/
int cpu_init_r (void)
int cpu_init_r(void)
{
return (0);
}
void uart_port_conf(void)
{
/* Setup Ports: */
switch (CFG_UART_PORT) {
case 0:
mbar_writeShort(MCF_GPIO_PAR_UART, MCF_GPIO_PAR_UART_U0TXD |
MCF_GPIO_PAR_UART_U0RXD);
break;
case 1:
mbar_writeShort(MCF_GPIO_PAR_UART,
MCF_GPIO_PAR_UART_U1RXD_UART1 |
MCF_GPIO_PAR_UART_U1TXD_UART1);
break;
case 2:
mbar_writeShort(MCF_GPIO_PAR_UART, 0x3000);
break;
}
}
#endif
#if defined(CONFIG_M5272)
@ -87,69 +79,68 @@ int cpu_init_r (void)
* initialize a bunch of registers,
* initialize the UPM's
*/
void cpu_init_f (void)
void cpu_init_f(void)
{
/* if we come from RAM we assume the CPU is
* already initialized.
*/
#ifndef CONFIG_MONITOR_IS_IN_RAM
volatile immap_t *regp = (immap_t *)CFG_MBAR;
volatile sysctrl_t *sysctrl = (sysctrl_t *) (CFG_MBAR);
volatile gpio_t *gpio = (gpio_t *) (MMAP_GPIO);
volatile csctrl_t *csctrl = (csctrl_t *) (MMAP_FBCS);
volatile unsigned char *mbar;
mbar = (volatile unsigned char *) CFG_MBAR;
regp->sysctrl_reg.sc_scr = CFG_SCR;
regp->sysctrl_reg.sc_spr = CFG_SPR;
sysctrl->sc_scr = CFG_SCR;
sysctrl->sc_spr = CFG_SPR;
/* Setup Ports: */
regp->gpio_reg.gpio_pacnt = CFG_PACNT;
regp->gpio_reg.gpio_paddr = CFG_PADDR;
regp->gpio_reg.gpio_padat = CFG_PADAT;
regp->gpio_reg.gpio_pbcnt = CFG_PBCNT;
regp->gpio_reg.gpio_pbddr = CFG_PBDDR;
regp->gpio_reg.gpio_pbdat = CFG_PBDAT;
regp->gpio_reg.gpio_pdcnt = CFG_PDCNT;
gpio->gpio_pacnt = CFG_PACNT;
gpio->gpio_paddr = CFG_PADDR;
gpio->gpio_padat = CFG_PADAT;
gpio->gpio_pbcnt = CFG_PBCNT;
gpio->gpio_pbddr = CFG_PBDDR;
gpio->gpio_pbdat = CFG_PBDAT;
gpio->gpio_pdcnt = CFG_PDCNT;
/* Memory Controller: */
regp->csctrl_reg.cs_br0 = CFG_BR0_PRELIM;
regp->csctrl_reg.cs_or0 = CFG_OR0_PRELIM;
csctrl->cs_br0 = CFG_BR0_PRELIM;
csctrl->cs_or0 = CFG_OR0_PRELIM;
#if (defined(CFG_OR1_PRELIM) && defined(CFG_BR1_PRELIM))
regp->csctrl_reg.cs_br1 = CFG_BR1_PRELIM;
regp->csctrl_reg.cs_or1 = CFG_OR1_PRELIM;
csctrl->cs_br1 = CFG_BR1_PRELIM;
csctrl->cs_or1 = CFG_OR1_PRELIM;
#endif
#if defined(CFG_OR2_PRELIM) && defined(CFG_BR2_PRELIM)
regp->csctrl_reg.cs_br2 = CFG_BR2_PRELIM;
regp->csctrl_reg.cs_or2 = CFG_OR2_PRELIM;
csctrl->cs_br2 = CFG_BR2_PRELIM;
csctrl->cs_or2 = CFG_OR2_PRELIM;
#endif
#if defined(CFG_OR3_PRELIM) && defined(CFG_BR3_PRELIM)
regp->csctrl_reg.cs_br3 = CFG_BR3_PRELIM;
regp->csctrl_reg.cs_or3 = CFG_OR3_PRELIM;
csctrl->cs_br3 = CFG_BR3_PRELIM;
csctrl->cs_or3 = CFG_OR3_PRELIM;
#endif
#if defined(CFG_OR4_PRELIM) && defined(CFG_BR4_PRELIM)
regp->csctrl_reg.cs_br4 = CFG_BR4_PRELIM;
regp->csctrl_reg.cs_or4 = CFG_OR4_PRELIM;
csctrl->cs_br4 = CFG_BR4_PRELIM;
csctrl->cs_or4 = CFG_OR4_PRELIM;
#endif
#if defined(CFG_OR5_PRELIM) && defined(CFG_BR5_PRELIM)
regp->csctrl_reg.cs_br5 = CFG_BR5_PRELIM;
regp->csctrl_reg.cs_or5 = CFG_OR5_PRELIM;
csctrl->cs_br5 = CFG_BR5_PRELIM;
csctrl->cs_or5 = CFG_OR5_PRELIM;
#endif
#if defined(CFG_OR6_PRELIM) && defined(CFG_BR6_PRELIM)
regp->csctrl_reg.cs_br6 = CFG_BR6_PRELIM;
regp->csctrl_reg.cs_or6 = CFG_OR6_PRELIM;
csctrl->cs_br6 = CFG_BR6_PRELIM;
csctrl->cs_or6 = CFG_OR6_PRELIM;
#endif
#if defined(CFG_OR7_PRELIM) && defined(CFG_BR7_PRELIM)
regp->csctrl_reg.cs_br7 = CFG_BR7_PRELIM;
regp->csctrl_reg.cs_or7 = CFG_OR7_PRELIM;
csctrl->cs_br7 = CFG_BR7_PRELIM;
csctrl->cs_or7 = CFG_OR7_PRELIM;
#endif
#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */
#endif /* #ifndef CONFIG_MONITOR_IS_IN_RAM */
/* enable instruction cache now */
icache_enable();
@ -159,14 +150,30 @@ void cpu_init_f (void)
/*
* initialize higher level parts of CPU like timers
*/
int cpu_init_r (void)
int cpu_init_r(void)
{
return (0);
}
#endif /* #if defined(CONFIG_M5272) */
void uart_port_conf(void)
{
volatile gpio_t *gpio = (gpio_t *) MMAP_GPIO;
#ifdef CONFIG_M5282
/* Setup Ports: */
switch (CFG_UART_PORT) {
case 0:
gpio->gpio_pbcnt &= ~(GPIO_PBCNT_PB0MSK | GPIO_PBCNT_PB1MSK);
gpio->gpio_pbcnt |= (GPIO_PBCNT_URT0_TXD | GPIO_PBCNT_URT0_RXD);
break;
case 1:
gpio->gpio_pdcnt &= ~(GPIO_PDCNT_PD1MSK | GPIO_PDCNT_PD4MSK);
gpio->gpio_pdcnt |= (GPIO_PDCNT_URT1_RXD | GPIO_PDCNT_URT1_TXD);
break;
}
}
#endif /* #if defined(CONFIG_M5272) */
#if defined(CONFIG_M5282)
/*
* Breath some life into the CPU...
*
@ -174,7 +181,7 @@ int cpu_init_r (void)
* initialize a bunch of registers,
* initialize the UPM's
*/
void cpu_init_f (void)
void cpu_init_f(void)
{
#ifndef CONFIG_WATCHDOG
/* disable watchdog if we aren't using it */
@ -183,7 +190,11 @@ void cpu_init_f (void)
#ifndef CONFIG_MONITOR_IS_IN_RAM
/* Set speed /PLL */
MCFCLOCK_SYNCR = MCFCLOCK_SYNCR_MFD(CFG_MFD) | MCFCLOCK_SYNCR_RFD(CFG_RFD);
MCFCLOCK_SYNCR =
MCFCLOCK_SYNCR_MFD(CFG_MFD) | MCFCLOCK_SYNCR_RFD(CFG_RFD);
while (!(MCFCLOCK_SYNSR & MCFCLOCK_SYNSR_LOCK)) ;
MCFGPIO_PBCDPAR = 0xc0;
/* Set up the GPIO ports */
#ifdef CFG_PEPAR
@ -228,29 +239,28 @@ void cpu_init_f (void)
defined(CFG_CS0_WIDTH) & defined(CFG_CS0_RO) & \
defined(CFG_CS0_WS)
MCFCSM_CSAR0 = (CFG_CS0_BASE >> 16) & 0xFFFF;
MCFCSM_CSAR0 = (CFG_CS0_BASE >> 16) & 0xFFFF;
#if (CFG_CS0_WIDTH == 8)
#define CFG_CS0_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS0_WIDTH == 16)
#define CFG_CS0_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS0_WIDTH == 32)
#define CFG_CS0_PS MCFCSM_CSCR_PS_32
#else
#error "CFG_CS0_WIDTH: Fault - wrong bus with for CS0"
#endif
MCFCSM_CSCR0 = MCFCSM_CSCR_WS(CFG_CS0_WS)
|CFG_CS0_PS
|MCFCSM_CSCR_AA;
#if (CFG_CS0_RO != 0)
MCFCSM_CSMR0 = MCFCSM_CSMR_BAM(CFG_CS0_SIZE-1)
|MCFCSM_CSMR_WP|MCFCSM_CSMR_V;
#else
MCFCSM_CSMR0 = MCFCSM_CSMR_BAM(CFG_CS0_SIZE-1)|MCFCSM_CSMR_V;
#endif
#if (CFG_CS0_WIDTH == 8)
#define CFG_CS0_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS0_WIDTH == 16)
#define CFG_CS0_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS0_WIDTH == 32)
#define CFG_CS0_PS MCFCSM_CSCR_PS_32
#else
#waring "Chip Select 0 are not initialized/used"
#error "CFG_CS0_WIDTH: Fault - wrong bus with for CS0"
#endif
MCFCSM_CSCR0 = MCFCSM_CSCR_WS(CFG_CS0_WS)
| CFG_CS0_PS | MCFCSM_CSCR_AA;
#if (CFG_CS0_RO != 0)
MCFCSM_CSMR0 = MCFCSM_CSMR_BAM(CFG_CS0_SIZE - 1)
| MCFCSM_CSMR_WP | MCFCSM_CSMR_V;
#else
MCFCSM_CSMR0 = MCFCSM_CSMR_BAM(CFG_CS0_SIZE - 1) | MCFCSM_CSMR_V;
#endif
#else
#waring "Chip Select 0 are not initialized/used"
#endif
#if defined(CFG_CS1_BASE) & defined(CFG_CS1_SIZE) & \
@ -259,29 +269,27 @@ void cpu_init_f (void)
MCFCSM_CSAR1 = (CFG_CS1_BASE >> 16) & 0xFFFF;
#if (CFG_CS1_WIDTH == 8)
#define CFG_CS1_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS1_WIDTH == 16)
#define CFG_CS1_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS1_WIDTH == 32)
#define CFG_CS1_PS MCFCSM_CSCR_PS_32
#else
#error "CFG_CS1_WIDTH: Fault - wrong bus with for CS1"
#endif
MCFCSM_CSCR1 = MCFCSM_CSCR_WS(CFG_CS1_WS)
|CFG_CS1_PS
|MCFCSM_CSCR_AA;
#if (CFG_CS1_RO != 0)
MCFCSM_CSMR1 = MCFCSM_CSMR_BAM(CFG_CS1_SIZE-1)
|MCFCSM_CSMR_WP
|MCFCSM_CSMR_V;
#else
MCFCSM_CSMR1 = MCFCSM_CSMR_BAM(CFG_CS1_SIZE-1)
|MCFCSM_CSMR_V;
#endif
#if (CFG_CS1_WIDTH == 8)
#define CFG_CS1_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS1_WIDTH == 16)
#define CFG_CS1_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS1_WIDTH == 32)
#define CFG_CS1_PS MCFCSM_CSCR_PS_32
#else
#warning "Chip Select 1 are not initialized/used"
#error "CFG_CS1_WIDTH: Fault - wrong bus with for CS1"
#endif
MCFCSM_CSCR1 = MCFCSM_CSCR_WS(CFG_CS1_WS)
| CFG_CS1_PS | MCFCSM_CSCR_AA;
#if (CFG_CS1_RO != 0)
MCFCSM_CSMR1 = MCFCSM_CSMR_BAM(CFG_CS1_SIZE - 1)
| MCFCSM_CSMR_WP | MCFCSM_CSMR_V;
#else
MCFCSM_CSMR1 = MCFCSM_CSMR_BAM(CFG_CS1_SIZE - 1)
| MCFCSM_CSMR_V;
#endif
#else
#warning "Chip Select 1 are not initialized/used"
#endif
#if defined(CFG_CS2_BASE) & defined(CFG_CS2_SIZE) & \
@ -290,29 +298,27 @@ void cpu_init_f (void)
MCFCSM_CSAR2 = (CFG_CS2_BASE >> 16) & 0xFFFF;
#if (CFG_CS2_WIDTH == 8)
#define CFG_CS2_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS2_WIDTH == 16)
#define CFG_CS2_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS2_WIDTH == 32)
#define CFG_CS2_PS MCFCSM_CSCR_PS_32
#else
#error "CFG_CS2_WIDTH: Fault - wrong bus with for CS2"
#endif
MCFCSM_CSCR2 = MCFCSM_CSCR_WS(CFG_CS2_WS)
|CFG_CS2_PS
|MCFCSM_CSCR_AA;
#if (CFG_CS2_RO != 0)
MCFCSM_CSMR2 = MCFCSM_CSMR_BAM(CFG_CS2_SIZE-1)
|MCFCSM_CSMR_WP
|MCFCSM_CSMR_V;
#else
MCFCSM_CSMR2 = MCFCSM_CSMR_BAM(CFG_CS2_SIZE-1)
|MCFCSM_CSMR_V;
#endif
#if (CFG_CS2_WIDTH == 8)
#define CFG_CS2_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS2_WIDTH == 16)
#define CFG_CS2_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS2_WIDTH == 32)
#define CFG_CS2_PS MCFCSM_CSCR_PS_32
#else
#warning "Chip Select 2 are not initialized/used"
#error "CFG_CS2_WIDTH: Fault - wrong bus with for CS2"
#endif
MCFCSM_CSCR2 = MCFCSM_CSCR_WS(CFG_CS2_WS)
| CFG_CS2_PS | MCFCSM_CSCR_AA;
#if (CFG_CS2_RO != 0)
MCFCSM_CSMR2 = MCFCSM_CSMR_BAM(CFG_CS2_SIZE - 1)
| MCFCSM_CSMR_WP | MCFCSM_CSMR_V;
#else
MCFCSM_CSMR2 = MCFCSM_CSMR_BAM(CFG_CS2_SIZE - 1)
| MCFCSM_CSMR_V;
#endif
#else
#warning "Chip Select 2 are not initialized/used"
#endif
#if defined(CFG_CS3_BASE) & defined(CFG_CS3_SIZE) & \
@ -321,32 +327,30 @@ void cpu_init_f (void)
MCFCSM_CSAR3 = (CFG_CS3_BASE >> 16) & 0xFFFF;
#if (CFG_CS3_WIDTH == 8)
#define CFG_CS3_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS3_WIDTH == 16)
#define CFG_CS3_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS3_WIDTH == 32)
#define CFG_CS3_PS MCFCSM_CSCR_PS_32
#else
#error "CFG_CS3_WIDTH: Fault - wrong bus with for CS1"
#endif
MCFCSM_CSCR3 = MCFCSM_CSCR_WS(CFG_CS3_WS)
|CFG_CS3_PS
|MCFCSM_CSCR_AA;
#if (CFG_CS3_RO != 0)
MCFCSM_CSMR3 = MCFCSM_CSMR_BAM(CFG_CS3_SIZE-1)
|MCFCSM_CSMR_WP
|MCFCSM_CSMR_V;
#else
MCFCSM_CSMR3 = MCFCSM_CSMR_BAM(CFG_CS3_SIZE-1)
|MCFCSM_CSMR_V;
#endif
#if (CFG_CS3_WIDTH == 8)
#define CFG_CS3_PS MCFCSM_CSCR_PS_8
#elif (CFG_CS3_WIDTH == 16)
#define CFG_CS3_PS MCFCSM_CSCR_PS_16
#elif (CFG_CS3_WIDTH == 32)
#define CFG_CS3_PS MCFCSM_CSCR_PS_32
#else
#warning "Chip Select 3 are not initialized/used"
#error "CFG_CS3_WIDTH: Fault - wrong bus with for CS1"
#endif
MCFCSM_CSCR3 = MCFCSM_CSCR_WS(CFG_CS3_WS)
| CFG_CS3_PS | MCFCSM_CSCR_AA;
#if (CFG_CS3_RO != 0)
MCFCSM_CSMR3 = MCFCSM_CSMR_BAM(CFG_CS3_SIZE - 1)
| MCFCSM_CSMR_WP | MCFCSM_CSMR_V;
#else
MCFCSM_CSMR3 = MCFCSM_CSMR_BAM(CFG_CS3_SIZE - 1)
| MCFCSM_CSMR_V;
#endif
#else
#warning "Chip Select 3 are not initialized/used"
#endif
#endif /* CONFIG_MONITOR_IS_IN_RAM */
#endif /* CONFIG_MONITOR_IS_IN_RAM */
/* defer enabling cache until boot (see do_go) */
/* icache_enable(); */
@ -355,10 +359,29 @@ void cpu_init_f (void)
/*
* initialize higher level parts of CPU like timers
*/
int cpu_init_r (void)
int cpu_init_r(void)
{
return (0);
}
void uart_port_conf(void)
{
/* Setup Ports: */
switch (CFG_UART_PORT) {
case 0:
MCFGPIO_PUAPAR &= 0xFc;
MCFGPIO_PUAPAR |= 0x03;
break;
case 1:
MCFGPIO_PUAPAR &= 0xF3;
MCFGPIO_PUAPAR |= 0x0C;
break;
case 2:
MCFGPIO_PASPAR &= 0xFF0F;
MCFGPIO_PASPAR |= 0x00A0;
break;
}
}
#endif
#if defined(CONFIG_M5249)
@ -369,7 +392,7 @@ int cpu_init_r (void)
* initialize a bunch of registers,
* initialize the UPM's
*/
void cpu_init_f (void)
void cpu_init_f(void)
{
#ifndef CFG_PLL_BYPASS
/*
@ -379,23 +402,23 @@ void cpu_init_f (void)
volatile unsigned long cpll = mbar2_readLong(MCFSIM_PLLCR);
unsigned long pllcr;
#ifdef CFG_FAST_CLK
pllcr = 0x925a3100; /* ~140MHz clock (PLL bypass = 0) */
pllcr = 0x925a3100; /* ~140MHz clock (PLL bypass = 0) */
#else
pllcr = 0x135a4140; /* ~72MHz clock (PLL bypass = 0) */
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 */
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
* (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);
@ -411,7 +434,7 @@ void cpu_init_f (void)
* ~Jeremy
*
*/
mbar_writeByte(MCFSIM_MPARK, 0x30); /* 5249 Internal Core takes priority over DMA */
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);
@ -431,7 +454,7 @@ void cpu_init_f (void)
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 */
mbar2_writeLong(MCFSIM_IDECONFIG1, 0x00000020); /* Enable a 1 cycle pre-drive cycle on CS1 */
/* Setup interrupt priorities for gpio7 */
/* mbar2_writeLong(MCFSIM_INTLEV5, 0x70000000); */
@ -459,8 +482,19 @@ void cpu_init_f (void)
/*
* initialize higher level parts of CPU like timers
*/
int cpu_init_r (void)
int cpu_init_r(void)
{
return (0);
}
#endif /* #if defined(CONFIG_M5249) */
void uart_port_conf(void)
{
/* Setup Ports: */
switch (CFG_UART_PORT) {
case 0:
break;
case 1:
break;
}
}
#endif /* #if defined(CONFIG_M5249) */

View File

@ -1,605 +0,0 @@
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <malloc.h>
#include <asm/fec.h>
#ifdef CONFIG_M5271
#include <asm/m5271.h>
#include <asm/immap_5271.h>
#endif
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#include <asm/immap_5272.h>
#endif
#ifdef CONFIG_M5282
#include <asm/m5282.h>
#include <asm/immap_5282.h>
#endif
#include <net.h>
#include <command.h>
#ifdef CONFIG_M5272
#define FEC_ADDR (CFG_MBAR + 0x840)
#endif
#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
#define FEC_ADDR (CFG_MBAR + 0x1000)
#endif
#undef ET_DEBUG
#undef MII_DEBUG
#if defined(CONFIG_CMD_NET) && defined(FEC_ENET)
#ifdef CFG_DISCOVER_PHY
#include <miiphy.h>
static void mii_discover_phy (void);
#endif
/* Ethernet Transmit and Receive Buffers */
#define DBUF_LENGTH 1520
#define TX_BUF_CNT 2
#define TOUT_LOOP 100
#define PKT_MAXBUF_SIZE 1518
#define PKT_MINBUF_SIZE 64
#define PKT_MAXBLR_SIZE 1520
static char txbuf[DBUF_LENGTH];
static uint rxIdx; /* index of the current RX buffer */
static uint txIdx; /* index of the current TX buffer */
/*
* FEC Ethernet Tx and Rx buffer descriptors allocated at the
* immr->udata_bd address on Dual-Port RAM
* Provide for Double Buffering
*/
typedef volatile struct CommonBufferDescriptor {
cbd_t rxbd[PKTBUFSRX]; /* Rx BD */
cbd_t txbd[TX_BUF_CNT]; /* Tx BD */
} RTXBD;
static RTXBD *rtx = NULL;
int eth_send (volatile void *packet, int length)
{
int j, rc;
volatile fec_t *fecp = (fec_t *) (FEC_ADDR);
/* section 16.9.23.3
* Wait for ready
*/
j = 0;
while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY)
&& (j < TOUT_LOOP)) {
udelay (1);
j++;
}
if (j >= TOUT_LOOP) {
printf ("TX not ready\n");
}
rtx->txbd[txIdx].cbd_bufaddr = (uint) packet;
rtx->txbd[txIdx].cbd_datlen = length;
rtx->txbd[txIdx].cbd_sc |= BD_ENET_TX_READY | BD_ENET_TX_LAST;
/* Activate transmit Buffer Descriptor polling */
fecp->fec_x_des_active = 0x01000000; /* Descriptor polling active */
j = 0;
while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY)
&& (j < TOUT_LOOP)) {
udelay (1);
j++;
}
if (j >= TOUT_LOOP) {
printf ("TX timeout\n");
}
#ifdef ET_DEBUG
printf ("%s[%d] %s: cycles: %d status: %x retry cnt: %d\n",
__FILE__, __LINE__, __FUNCTION__, j, rtx->txbd[txIdx].cbd_sc,
(rtx->txbd[txIdx].cbd_sc & 0x003C) >> 2);
#endif
/* return only status bits */ ;
rc = (rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_STATS);
txIdx = (txIdx + 1) % TX_BUF_CNT;
return rc;
}
int eth_rx (void)
{
int length;
volatile fec_t *fecp = (fec_t *) FEC_ADDR;
for (;;) {
/* section 16.9.23.2 */
if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) {
length = -1;
break; /* nothing received - leave for() loop */
}
length = rtx->rxbd[rxIdx].cbd_datlen;
if (rtx->rxbd[rxIdx].cbd_sc & 0x003f) {
#ifdef ET_DEBUG
printf ("%s[%d] err: %x\n",
__FUNCTION__, __LINE__,
rtx->rxbd[rxIdx].cbd_sc);
#endif
} else {
/* Pass the packet up to the protocol layers. */
NetReceive (NetRxPackets[rxIdx], length - 4);
}
/* Give the buffer back to the FEC. */
rtx->rxbd[rxIdx].cbd_datlen = 0;
/* wrap around buffer index when necessary */
if ((rxIdx + 1) >= PKTBUFSRX) {
rtx->rxbd[PKTBUFSRX - 1].cbd_sc =
(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
rxIdx = 0;
} else {
rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY;
rxIdx++;
}
/* Try to fill Buffer Descriptors */
fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
}
return length;
}
/**************************************************************
*
* FEC Ethernet Initialization Routine
*
*************************************************************/
#define FEC_ECNTRL_ETHER_EN 0x00000002
#define FEC_ECNTRL_RESET 0x00000001
#define FEC_RCNTRL_BC_REJ 0x00000010
#define FEC_RCNTRL_PROM 0x00000008
#define FEC_RCNTRL_MII_MODE 0x00000004
#define FEC_RCNTRL_DRT 0x00000002
#define FEC_RCNTRL_LOOP 0x00000001
#define FEC_TCNTRL_FDEN 0x00000004
#define FEC_TCNTRL_HBC 0x00000002
#define FEC_TCNTRL_GTS 0x00000001
#define FEC_RESET_DELAY 50000
int eth_init (bd_t * bd)
{
#ifndef CFG_ENET_BD_BASE
DECLARE_GLOBAL_DATA_PTR;
#endif
int i;
volatile fec_t *fecp = (fec_t *) (FEC_ADDR);
/* Whack a reset.
* A delay is required between a reset of the FEC block and
* initialization of other FEC registers because the reset takes
* some time to complete. If you don't delay, subsequent writes
* to FEC registers might get killed by the reset routine which is
* still in progress.
*/
fecp->fec_ecntrl = FEC_ECNTRL_RESET;
for (i = 0;
(fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
++i) {
udelay (1);
}
if (i == FEC_RESET_DELAY) {
printf ("FEC_RESET_DELAY timeout\n");
return 0;
}
/* We use strictly polling mode only
*/
fecp->fec_imask = 0;
/* Clear any pending interrupt */
fecp->fec_ievent = 0xffffffff;
/* Set station address */
#define ea bd->bi_enetaddr
fecp->fec_addr_low = (ea[0] << 24) | (ea[1] << 16) |
(ea[2] << 8) | (ea[3]);
fecp->fec_addr_high = (ea[4] << 24) | (ea[5] << 16);
#ifdef ET_DEBUG
printf ("Eth Addrs: %02x:%02x:%02x:%02x:%02x:%02x\n",
ea[0], ea[1], ea[2], ea[3], ea[4], ea[5]);
#endif
#undef ea
#ifdef CONFIG_M5271
/* Clear multicast address hash table
*/
fecp->fec_ghash_table_high = 0;
fecp->fec_ghash_table_low = 0;
/* Clear individual address hash table
*/
fecp->fec_ihash_table_high = 0;
fecp->fec_ihash_table_low = 0;
#else
/* Clear multicast address hash table
*/
#ifdef CONFIG_M5282
fecp->fec_ihash_table_high = 0;
fecp->fec_ihash_table_low = 0;
#else
fecp->fec_hash_table_high = 0;
fecp->fec_hash_table_low = 0;
#endif
#endif
/* Set maximum receive buffer size.
*/
fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
/*
* Setup Buffers and Buffer Desriptors
*/
rxIdx = 0;
txIdx = 0;
if (!rtx) {
#ifdef CFG_ENET_BD_BASE
rtx = (RTXBD *) CFG_ENET_BD_BASE;
#else
rtx = (RTXBD *) (CFG_MONITOR_BASE+gd->reloc_off -
(((PKTBUFSRX+TX_BUF_CNT)*+sizeof(cbd_t)
+0xFF)
& ~0xFF)
);
debug("set ENET_DB_BASE to %lX\n",(long) rtx);
#endif
}
/*
* Setup Receiver Buffer Descriptors (13.14.24.18)
* Settings:
* Empty, Wrap
*/
for (i = 0; i < PKTBUFSRX; i++) {
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
}
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
/*
* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
* Settings:
* Last, Tx CRC
*/
for (i = 0; i < TX_BUF_CNT; i++) {
rtx->txbd[i].cbd_sc = BD_ENET_TX_LAST | BD_ENET_TX_TC;
rtx->txbd[i].cbd_datlen = 0; /* Reset */
rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]);
}
rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP;
/* Set receive and transmit descriptor base
*/
fecp->fec_r_des_start = (unsigned int) (&rtx->rxbd[0]);
fecp->fec_x_des_start = (unsigned int) (&rtx->txbd[0]);
/* Enable MII mode
*/
#if 0 /* Full duplex mode */
fecp->fec_r_cntrl = FEC_RCNTRL_MII_MODE;
fecp->fec_x_cntrl = FEC_TCNTRL_FDEN;
#else /* Half duplex mode */
fecp->fec_r_cntrl = (PKT_MAXBUF_SIZE << 16); /* set max frame length */
fecp->fec_r_cntrl |= FEC_RCNTRL_MII_MODE | FEC_RCNTRL_DRT;
fecp->fec_x_cntrl = 0;
#endif
/* Set MII speed */
fecp->fec_mii_speed = (((CFG_CLK / 2) / (2500000 / 10)) + 5) / 10;
fecp->fec_mii_speed *= 2;
/* Configure port B for MII.
*/
/* port initialization was already made in cpu_init_f() */
/* Now enable the transmit and receive processing
*/
fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN;
#ifdef CFG_DISCOVER_PHY
/* wait for the PHY to wake up after reset */
mii_discover_phy ();
#endif
/* And last, try to fill Rx Buffer Descriptors */
fecp->fec_r_des_active = 0x01000000; /* Descriptor polling active */
return 1;
}
void eth_halt (void)
{
volatile fec_t *fecp = (fec_t *) FEC_ADDR;
fecp->fec_ecntrl = 0;
}
#if defined(CFG_DISCOVER_PHY) || defined(CONFIG_CMD_MII)
static int phyaddr = -1; /* didn't find a PHY yet */
static uint phytype;
/* Make MII read/write commands for the FEC.
*/
#define mk_mii_read(ADDR, REG) (0x60020000 | ((ADDR << 23) | \
(REG & 0x1f) << 18))
#define mk_mii_write(ADDR, REG, VAL) (0x50020000 | ((ADDR << 23) | \
(REG & 0x1f) << 18) | \
(VAL & 0xffff))
/* Interrupt events/masks.
*/
#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
#define FEC_ENET_BABR ((uint)0x40000000) /* Babbling receiver */
#define FEC_ENET_BABT ((uint)0x20000000) /* Babbling transmitter */
#define FEC_ENET_GRA ((uint)0x10000000) /* Graceful stop complete */
#define FEC_ENET_TXF ((uint)0x08000000) /* Full frame transmitted */
#define FEC_ENET_TXB ((uint)0x04000000) /* A buffer was transmitted */
#define FEC_ENET_RXF ((uint)0x02000000) /* Full frame received */
#define FEC_ENET_RXB ((uint)0x01000000) /* A buffer was received */
#define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */
#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
/* PHY identification
*/
#define PHY_ID_LXT970 0x78100000 /* LXT970 */
#define PHY_ID_LXT971 0x001378e0 /* LXT971 and 972 */
#define PHY_ID_82555 0x02a80150 /* Intel 82555 */
#define PHY_ID_QS6612 0x01814400 /* QS6612 */
#define PHY_ID_AMD79C784 0x00225610 /* AMD 79C784 */
#define PHY_ID_LSI80225 0x0016f870 /* LSI 80225 */
#define PHY_ID_LSI80225B 0x0016f880 /* LSI 80225/B */
/* send command to phy using mii, wait for result */
static uint mii_send (uint mii_cmd)
{
uint mii_reply;
volatile fec_t *ep = (fec_t *) (FEC_ADDR);
ep->fec_mii_data = mii_cmd; /* command to phy */
/* wait for mii complete */
while (!(ep->fec_ievent & FEC_ENET_MII)); /* spin until done */
mii_reply = ep->fec_mii_data; /* result from phy */
ep->fec_ievent = FEC_ENET_MII; /* clear MII complete */
#ifdef ET_DEBUG
printf ("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
__FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply);
#endif
return (mii_reply & 0xffff); /* data read from phy */
}
#endif
#if defined(CFG_DISCOVER_PHY)
static void mii_discover_phy (void)
{
#define MAX_PHY_PASSES 11
uint phyno;
int pass;
phyaddr = -1; /* didn't find a PHY yet */
for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
if (pass > 1) {
/* PHY may need more time to recover from reset.
* The LXT970 needs 50ms typical, no maximum is
* specified, so wait 10ms before try again.
* With 11 passes this gives it 100ms to wake up.
*/
udelay (10000); /* wait 10ms */
}
for (phyno = 1; phyno < 32 && phyaddr < 0; ++phyno) {
phytype = mii_send (mk_mii_read (phyno, PHY_PHYIDR1));
#ifdef ET_DEBUG
printf ("PHY type 0x%x pass %d type ", phytype, pass);
#endif
if (phytype != 0xffff) {
phyaddr = phyno;
phytype <<= 16;
phytype |= mii_send (mk_mii_read (phyno,
PHY_PHYIDR2));
#ifdef ET_DEBUG
printf ("PHY @ 0x%x pass %d type ", phyno,
pass);
switch (phytype & 0xfffffff0) {
case PHY_ID_LXT970:
printf ("LXT970\n");
break;
case PHY_ID_LXT971:
printf ("LXT971\n");
break;
case PHY_ID_82555:
printf ("82555\n");
break;
case PHY_ID_QS6612:
printf ("QS6612\n");
break;
case PHY_ID_AMD79C784:
printf ("AMD79C784\n");
break;
case PHY_ID_LSI80225B:
printf ("LSI L80225/B\n");
break;
default:
printf ("0x%08x\n", phytype);
break;
}
#endif
}
}
}
if (phyaddr < 0) {
printf ("No PHY device found.\n");
}
}
#endif /* CFG_DISCOVER_PHY */
#if defined(CONFIG_CMD_MII) && !defined(CONFIG_BITBANGMII)
static int mii_init_done = 0;
/****************************************************************************
* mii_init -- Initialize the MII for MII command without ethernet
* This function is a subset of eth_init
****************************************************************************
*/
void mii_init (void)
{
volatile fec_t *fecp = (fec_t *) (FEC_ADDR);
int i;
if (mii_init_done != 0) {
return;
}
/* Whack a reset.
* A delay is required between a reset of the FEC block and
* initialization of other FEC registers because the reset takes
* some time to complete. If you don't delay, subsequent writes
* to FEC registers might get killed by the reset routine which is
* still in progress.
*/
fecp->fec_ecntrl = FEC_ECNTRL_RESET;
for (i = 0;
(fecp->fec_ecntrl & FEC_ECNTRL_RESET) && (i < FEC_RESET_DELAY);
++i) {
udelay (1);
}
if (i == FEC_RESET_DELAY) {
printf ("FEC_RESET_DELAY timeout\n");
return;
}
/* We use strictly polling mode only
*/
fecp->fec_imask = 0;
/* Clear any pending interrupt
*/
fecp->fec_ievent = 0xffffffff;
/* Set MII speed */
fecp->fec_mii_speed = 0x0e;
/* Configure port B for MII.
*/
/* port initialization was already made in cpu_init_f() */
/* Now enable the transmit and receive processing */
fecp->fec_ecntrl = FEC_ECNTRL_ETHER_EN;
mii_init_done = 1;
}
/*****************************************************************************
* Read and write a MII PHY register, routines used by MII Utilities
*
* FIXME: These routines are expected to return 0 on success, but mii_send
* does _not_ return an error code. Maybe 0xFFFF means error, i.e.
* no PHY connected...
* For now always return 0.
* FIXME: These routines only work after calling eth_init() at least once!
* Otherwise they hang in mii_send() !!! Sorry!
*****************************************************************************/
int mcf52x2_miiphy_read (char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
short rdreg; /* register working value */
#ifdef MII_DEBUG
printf ("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
#endif
rdreg = mii_send (mk_mii_read (addr, reg));
*value = rdreg;
#ifdef MII_DEBUG
printf ("0x%04x\n", *value);
#endif
return 0;
}
int mcf52x2_miiphy_write (char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
short rdreg; /* register working value */
#ifdef MII_DEBUG
printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr);
#endif
rdreg = mii_send (mk_mii_write (addr, reg, value));
#ifdef MII_DEBUG
printf ("0x%04x\n", value);
#endif
return 0;
}
#endif
#endif
int mcf52x2_miiphy_initialize(bd_t *bis)
{
#if defined(CONFIG_CMD_NET) && defined(FEC_ENET)
#if defined(CONFIG_CMD_MII) && !defined(CONFIG_BITBANGMII)
miiphy_register("mcf52x2phy", mcf52x2_miiphy_read, mcf52x2_miiphy_write);
#endif
#endif
return 0;
}

View File

@ -26,140 +26,12 @@
#include <common.h>
#include <watchdog.h>
#include <asm/processor.h>
#ifdef CONFIG_M5271
#include <asm/m5271.h>
#include <asm/immap_5271.h>
#endif
#include <asm/immap.h>
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#include <asm/immap_5272.h>
#endif
#ifdef CONFIG_M5282
#include <asm/m5282.h>
#include <asm/immap_5282.h>
#endif
#ifdef CONFIG_M5249
#include <asm/m5249.h>
#endif
#define NR_IRQS 31
/*
* Interrupt vector functions.
*/
struct interrupt_action {
interrupt_handler_t *handler;
void *arg;
};
static struct interrupt_action irq_vecs[NR_IRQS];
static __inline__ unsigned short get_sr (void)
int interrupt_init(void)
{
unsigned short sr;
asm volatile ("move.w %%sr,%0":"=r" (sr):);
return sr;
}
static __inline__ void set_sr (unsigned short sr)
{
asm volatile ("move.w %0,%%sr"::"r" (sr));
}
/************************************************************************/
/*
* Install and free an interrupt handler
*/
void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg)
{
#ifdef CONFIG_M5272
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
#endif
int vec_base = 0;
#ifdef CONFIG_M5272
vec_base = intp->int_pivr & 0xe0;
#endif
if ((vec < vec_base) || (vec > vec_base + NR_IRQS)) {
printf ("irq_install_handler: wrong interrupt vector %d\n",
vec);
return;
}
irq_vecs[vec - vec_base].handler = handler;
irq_vecs[vec - vec_base].arg = arg;
}
void irq_free_handler (int vec)
{
#ifdef CONFIG_M5272
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
#endif
int vec_base = 0;
#ifdef CONFIG_M5272
vec_base = intp->int_pivr & 0xe0;
#endif
if ((vec < vec_base) || (vec > vec_base + NR_IRQS)) {
return;
}
irq_vecs[vec - vec_base].handler = NULL;
irq_vecs[vec - vec_base].arg = NULL;
}
void enable_interrupts (void)
{
unsigned short sr;
sr = get_sr ();
set_sr (sr & ~0x0700);
}
int disable_interrupts (void)
{
unsigned short sr;
sr = get_sr ();
set_sr (sr | 0x0700);
return ((sr & 0x0700) == 0); /* return TRUE, if interrupts were enabled before */
}
void int_handler (struct pt_regs *fp)
{
#ifdef CONFIG_M5272
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
#endif
int vec, vec_base = 0;
vec = (fp->vector >> 2) & 0xff;
#ifdef CONFIG_M5272
vec_base = intp->int_pivr & 0xe0;
#endif
if (irq_vecs[vec - vec_base].handler != NULL) {
irq_vecs[vec -
vec_base].handler (irq_vecs[vec - vec_base].arg);
} else {
printf ("\nBogus External Interrupt Vector %d\n", vec);
}
}
#ifdef CONFIG_M5272
int interrupt_init (void)
{
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
volatile intctrl_t *intp = (intctrl_t *) (MMAP_INTC);
/* disable all external interrupts */
intp->int_icr1 = 0x88888888;
@ -170,24 +42,61 @@ int interrupt_init (void)
/* initialize vector register */
intp->int_pivr = 0x40;
enable_interrupts ();
enable_interrupts();
return 0;
}
#endif
#if defined(CONFIG_MCFTMR)
void dtimer_intr_setup(void)
{
volatile intctrl_t *intp = (intctrl_t *) (CFG_INTR_BASE);
intp->int_icr1 &= ~INT_ICR1_TMR3MASK;
intp->int_icr1 |= CFG_TMRINTR_PRI;
}
#endif /* CONFIG_MCFTMR */
#endif /* CONFIG_M5272 */
#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
int interrupt_init (void)
int interrupt_init(void)
{
volatile int0_t *intp = (int0_t *) (CFG_INTR_BASE);
/* Make sure all interrupts are disabled */
intp->imrl0 |= 0x1;
enable_interrupts();
return 0;
}
#endif
#if defined(CONFIG_MCFTMR)
void dtimer_intr_setup(void)
{
volatile int0_t *intp = (int0_t *) (CFG_INTR_BASE);
intp->icr0[CFG_TMRINTR_NO] = CFG_TMRINTR_PRI;
intp->imrl0 &= ~0xFFFFFFFE;
intp->imrl0 &= ~CFG_TMRINTR_MASK;
}
#endif /* CONFIG_MCFTMR */
#endif /* CONFIG_M5282 | CONFIG_M5271 */
#ifdef CONFIG_M5249
int interrupt_init (void)
int interrupt_init(void)
{
enable_interrupts ();
enable_interrupts();
return 0;
}
#endif
#if defined(CONFIG_MCFTMR)
void dtimer_intr_setup(void)
{
mbar_writeLong(MCFSIM_IMR, mbar_readLong(MCFSIM_IMR) & ~0x00000400);
mbar_writeByte(MCFSIM_TIMER2ICR,
MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 |
MCFSIM_ICR_PRI3);
}
#endif /* CONFIG_MCFTMR */
#endif /* CONFIG_M5249 */

View File

@ -1,215 +0,0 @@
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <command.h>
#include <watchdog.h>
#include <asm/mcfuart.h>
#ifdef CONFIG_M5271
#include <asm/m5271.h>
#endif
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#endif
#ifdef CONFIG_M5282
#include <asm/m5282.h>
#endif
#ifdef CONFIG_M5249
#include <asm/m5249.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_M5249) || defined(CONFIG_M5271)
#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)
{
#if defined(CONFIG_M5272) || defined(CONFIG_M5249) || defined(CONFIG_M5271)
volatile unsigned char *uartp;
# ifndef CONFIG_M5271
double fraction;
# endif
double clock;
if (port == 0)
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
else
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
clock = DoubleClock(baudrate); /* Set baud above */
uartp[MCFUART_UBG1] = (((int)clock >> 8) & 0xff); /* set msb baud */
uartp[MCFUART_UBG2] = ((int)clock & 0xff); /* set lsb baud */
# ifndef CONFIG_M5271
fraction = ((clock - (int)clock) * 16.0) + 0.5;
uartp[MCFUART_UFPD] = ((int)fraction & 0xf); /* set baud fraction adjust */
# endif
#endif
#if defined(CONFIG_M5282)
volatile unsigned char *uartp;
long clock;
switch (port) {
case 1:
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
break;
case 2:
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE3);
break;
default:
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
}
clock = (long) CFG_CLK / ((long) 32 * baudrate); /* Set baud above */
uartp[MCFUART_UBG1] = (((int)clock >> 8) & 0xff); /* set msb baud */
uartp[MCFUART_UBG2] = ((int) clock & 0xff); /* set lsb baud */
#endif
};
void rs_serial_init (int port, int baudrate)
{
volatile unsigned char *uartp;
/*
* Reset UART, get it into known state...
*/
switch (port) {
case 1:
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE2);
break;
#if defined(CONFIG_M5282)
case 2:
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE3);
break;
#endif
default:
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
}
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETMRPTR; /* reset MR pointer */
uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETERR; /* reset Error pointer */
/*
* Set port for CONSOLE_BAUD_RATE, 8 data bits, 1 stop bit, no parity.
*/
uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8;
uartp[MCFUART_UMR] = MCFUART_MR2_STOP1;
/* Mask UART interrupts */
uartp[MCFUART_UIMR] = 0;
/* Set clock Select Register: Tx/Rx clock is timer */
uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER;
rs_serial_setbaudrate (port, baudrate);
/* Enable Tx/Rx */
uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE;
return;
}
/****************************************************************************/
/*
* Output a single character, using UART polled mode.
* This is used for console output.
*/
void rs_put_char(char ch)
{
volatile unsigned char *uartp;
int i;
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
for (i = 0; (i < 0x10000); i++) {
if (uartp[MCFUART_USR] & MCFUART_USR_TXREADY)
break;
}
uartp[MCFUART_UTB] = ch;
return;
}
int rs_is_char(void)
{
volatile unsigned char *uartp;
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
return((uartp[MCFUART_USR] & MCFUART_USR_RXREADY) ? 1 : 0);
}
int rs_get_char(void)
{
volatile unsigned char *uartp;
uartp = (volatile unsigned char *) (CFG_MBAR + MCFUART_BASE1);
return(uartp[MCFUART_URB]);
}
void serial_setbrg(void) {
rs_serial_setbaudrate(0,gd->bd->bi_baudrate);
}
int serial_init(void) {
rs_serial_init(0,gd->baudrate);
return 0;
}
void serial_putc(const char c) {
if (c == '\n')
serial_putc ('\r');
rs_put_char(c);
}
void serial_puts (const char *s) {
while (*s)
serial_putc(*s++);
}
int serial_getc(void) {
while(!rs_is_char())
WATCHDOG_RESET();
return rs_get_char();
}
int serial_tstc() {
return rs_is_char();
}

View File

@ -159,7 +159,7 @@ _copy_flash:
_flashbar_setup:
/* Initialize FLASHBAR: locate internal Flash and validate it */
move.l #(CFG_INT_FLASH_BASE + 0x21), %d0
move.l #(CFG_INT_FLASH_BASE + CFG_INT_FLASH_ENABLE), %d0
movec %d0, %RAMBAR0
jmp _after_flashbar_copy.L /* Force jump to absolute address */
_flashbar_setup_end:
@ -167,7 +167,7 @@ _flashbar_setup_end:
_after_flashbar_copy:
#else
/* Setup code to initialize FLASHBAR, if start from external Memory */
move.l #(CFG_INT_FLASH_BASE + 0x21), %d0
move.l #(CFG_INT_FLASH_BASE + CFG_INT_FLASH_ENABLE), %d0
movec %d0, %RAMBAR0
#endif /* (TEXT_BASE == CFG_INT_FLASH_BASE) */
@ -326,10 +326,10 @@ clear_bss:
/* set parameters for board_init_r */
move.l %a0,-(%sp) /* dest_addr */
move.l %d0,-(%sp) /* gd */
#if defined(DEBUG) && (TEXT_BASE != CFG_INT_FLASH_BASE) && \
defined(CFG_HALT_BEFOR_RAM_JUMP)
halt
#endif
#if defined(DEBUG) && (TEXT_BASE != CFG_INT_FLASH_BASE) && \
defined(CFG_HALT_BEFOR_RAM_JUMP)
halt
#endif
jsr (%a1)
/*------------------------------------------------------------------------------*/
@ -356,6 +356,24 @@ _int_handler:
/*------------------------------------------------------------------------------*/
/* cache functions */
#ifdef CONFIG_M5271
.globl icache_enable
icache_enable:
move.l #0x01000000, %d0 /* Invalidate cache cmd */
movec %d0, %CACR /* Invalidate cache */
move.l #(CFG_SDRAM_BASE + 0xc000), %d0 /* Setup cache mask */
movec %d0, %ACR0 /* Enable cache */
move.l #0x80000200, %d0 /* Setup cache mask */
movec %d0, %CACR /* Enable cache */
nop
move.l #(CFG_INIT_RAM_ADDR+CFG_INIT_RAM_END-8), %a1
moveq #1, %d0
move.l %d0, (%a1)
rts
#endif
#ifdef CONFIG_M5272
.globl icache_enable
icache_enable:
@ -426,13 +444,29 @@ icache_state_access_2:
.globl icache_status
icache_status:
icache_state_access_3:
move.l icache_state, %d0
move.l #(icache_state), %a0
move.l (%a0), %d0
rts
.data
icache_state:
.long 0 /* cache is diabled on inirialization */
.globl dcache_enable
dcache_enable:
/* dummy function */
rts
.globl dcache_disable
dcache_disable:
/* dummy function */
rts
.globl dcache_status
dcache_status:
/* dummy function */
rts
/*------------------------------------------------------------------------------*/
.globl version_string

View File

@ -25,288 +25,12 @@
#include <common.h>
#include <asm/mcftimer.h>
#include <asm/timer.h>
#include <asm/immap.h>
#ifdef CONFIG_M5271
#include <asm/m5271.h>
#include <asm/immap_5271.h>
#endif
#ifdef CONFIG_M5272
#include <asm/m5272.h>
#include <asm/immap_5272.h>
#endif
#ifdef CONFIG_M5282
#include <asm/m5282.h>
#endif
#ifdef CONFIG_M5249
#include <asm/m5249.h>
#include <asm/immap_5249.h>
#endif
DECLARE_GLOBAL_DATA_PTR;
static ulong timestamp;
#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
static unsigned short lastinc;
#endif
#if defined(CONFIG_M5272)
/*
* We use timer 3 which is running with a period of 1 us
*/
void udelay(unsigned long usec)
{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE3);
uint start, now, tmp;
while (usec > 0) {
if (usec > 65000)
tmp = 65000;
else
tmp = usec;
usec = usec - tmp;
/* Set up TIMER 3 as timebase clock */
timerp->timer_tmr = MCFTIMER_TMR_DISABLE;
timerp->timer_tcn = 0;
/* set period to 1 us */
timerp->timer_tmr =
(((CFG_CLK / 1000000) -
1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_FREERUN |
MCFTIMER_TMR_ENABLE;
start = now = timerp->timer_tcn;
while (now < start + tmp)
now = timerp->timer_tcn;
}
}
void mcf_timer_interrupt(void *not_used)
{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE4);
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
/* check for timer 4 interrupts */
if ((intp->int_isr & 0x01000000) != 0) {
return;
}
/* reset timer */
timerp->timer_ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
timestamp++;
}
void timer_init(void)
{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE4);
volatile intctrl_t *intp = (intctrl_t *) (CFG_MBAR + MCFSIM_ICR1);
timestamp = 0;
/* Set up TIMER 4 as clock */
timerp->timer_tmr = MCFTIMER_TMR_DISABLE;
/* initialize and enable timer 4 interrupt */
irq_install_handler(72, mcf_timer_interrupt, 0);
intp->int_icr1 |= 0x0000000d;
timerp->timer_tcn = 0;
timerp->timer_trr = 1000; /* Interrupt every ms */
/* set a period of 1us, set timer mode to restart and enable timer and interrupt */
timerp->timer_tmr =
(((CFG_CLK / 1000000) -
1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_RESTART |
MCFTIMER_TMR_ENORI | MCFTIMER_TMR_ENABLE;
}
void reset_timer(void)
{
timestamp = 0;
}
ulong get_timer(ulong base)
{
return (timestamp - base);
}
void set_timer(ulong t)
{
timestamp = t;
}
#endif
#if defined(CONFIG_M5282) || defined(CONFIG_M5271)
void udelay(unsigned long usec)
{
volatile unsigned short *timerp;
uint tmp;
timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE3);
while (usec > 0) {
if (usec > 65000)
tmp = 65000;
else
tmp = usec;
usec = usec - tmp;
/* Set up TIMER 3 as timebase clock */
timerp[MCFTIMER_PCSR] = MCFTIMER_PCSR_OVW;
timerp[MCFTIMER_PMR] = 0;
/* set period to 1 us */
timerp[MCFTIMER_PCSR] =
#ifdef CONFIG_M5271
(6 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
#else /* !CONFIG_M5271 */
(5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
#endif /* CONFIG_M5271 */
timerp[MCFTIMER_PMR] = tmp;
while (timerp[MCFTIMER_PCNTR] > 0) ;
}
}
void timer_init(void)
{
volatile unsigned short *timerp;
timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE4);
timestamp = 0;
/* Set up TIMER 4 as poll clock */
timerp[MCFTIMER_PCSR] = MCFTIMER_PCSR_OVW;
timerp[MCFTIMER_PMR] = lastinc = 0;
timerp[MCFTIMER_PCSR] =
#ifdef CONFIG_M5271
(6 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
#else /* !CONFIG_M5271 */
(5 << 8) | MCFTIMER_PCSR_EN | MCFTIMER_PCSR_OVW;
#endif /* CONFIG_M5271 */
}
void set_timer(ulong t)
{
volatile unsigned short *timerp;
timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE4);
timestamp = 0;
timerp[MCFTIMER_PMR] = lastinc = 0;
}
ulong get_timer(ulong base)
{
unsigned short now, diff;
volatile unsigned short *timerp;
timerp = (volatile unsigned short *)(CFG_MBAR + MCFTIMER_BASE4);
now = timerp[MCFTIMER_PCNTR];
diff = -(now - lastinc);
timestamp += diff;
lastinc = now;
return timestamp - base;
}
void wait_ticks(unsigned long ticks)
{
set_timer(0);
while (get_timer(0) < ticks) ;
}
#endif
#if defined(CONFIG_M5249)
/*
* We use timer 1 which is running with a period of 1 us
*/
void udelay(unsigned long usec)
{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE1);
uint start, now, tmp;
while (usec > 0) {
if (usec > 65000)
tmp = 65000;
else
tmp = usec;
usec = usec - tmp;
/* Set up TIMER 1 as timebase clock */
timerp->timer_tmr = MCFTIMER_TMR_DISABLE;
timerp->timer_tcn = 0;
/* set period to 1 us */
/* on m5249 the system clock is (cpu_clk / 2) -> divide by 2000000 */
timerp->timer_tmr =
(((CFG_CLK / 2000000) -
1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_FREERUN |
MCFTIMER_TMR_ENABLE;
start = now = timerp->timer_tcn;
while (now < start + tmp)
now = timerp->timer_tcn;
}
}
void mcf_timer_interrupt(void *not_used)
{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE2);
/* check for timer 2 interrupts */
if ((mbar_readLong(MCFSIM_IPR) & 0x00000400) == 0) {
return;
}
/* reset timer */
timerp->timer_ter = MCFTIMER_TER_CAP | MCFTIMER_TER_REF;
timestamp++;
}
void timer_init(void)
{
volatile timer_t *timerp = (timer_t *) (CFG_MBAR + MCFTIMER_BASE2);
timestamp = 0;
/* Set up TIMER 2 as clock */
timerp->timer_tmr = MCFTIMER_TMR_DISABLE;
/* initialize and enable timer 2 interrupt */
irq_install_handler(31, mcf_timer_interrupt, 0);
mbar_writeLong(MCFSIM_IMR, mbar_readLong(MCFSIM_IMR) & ~0x00000400);
mbar_writeByte(MCFSIM_TIMER2ICR,
MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 |
MCFSIM_ICR_PRI3);
timerp->timer_tcn = 0;
timerp->timer_trr = 1000; /* Interrupt every ms */
/* set a period of 1us, set timer mode to restart and enable timer and interrupt */
/* on m5249 the system clock is (cpu_clk / 2) -> divide by 2000000 */
timerp->timer_tmr =
(((CFG_CLK / 2000000) -
1) << 8) | MCFTIMER_TMR_CLK1 | MCFTIMER_TMR_RESTART |
MCFTIMER_TMR_ENORI | MCFTIMER_TMR_ENABLE;
}
void reset_timer(void)
{
timestamp = 0;
}
ulong get_timer(ulong base)
{
return (timestamp - base);
}
void set_timer(ulong t)
{
timestamp = t;
}
#endif
#if defined(CONFIG_MCFTMR)
#ifndef CFG_UDELAY_BASE