- add support for MPC8220 CPU - Add support for Alaska and Yukon boardsmaster
parent
e3c9b9f928
commit
983fda8391
@ -0,0 +1,45 @@ |
||||
# (C) Copyright 2003-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 $(TOPDIR)/config.mk |
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := $(BOARD).o flash.o extserial.o serial.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS) |
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
clean: |
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean |
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) |
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend |
||||
|
||||
#########################################################################
|
@ -0,0 +1,153 @@ |
||||
/*
|
||||
* (C) Copyright 2004, Freescale Inc. |
||||
* TsiChung Liew, Tsi-Chung.Liew@freescale.com |
||||
* |
||||
* 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 <mpc8220.h> |
||||
#include <asm/processor.h> |
||||
#include <asm/mmu.h> |
||||
|
||||
void setupBat (ulong size) |
||||
{ |
||||
ulong batu, batl; |
||||
int blocksize = 0; |
||||
|
||||
/* Flash 0 */ |
||||
#if defined (CFG_AMD_BOOT) |
||||
batu = CFG_FLASH0_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; |
||||
#else |
||||
batu = CFG_FLASH0_BASE | (BL_16M << 2) | BPP_RW | BPP_RX; |
||||
#endif |
||||
batl = CFG_FLASH0_BASE | 0x22; |
||||
write_bat (IBAT0, batu, batl); |
||||
write_bat (DBAT0, batu, batl); |
||||
|
||||
/* Flash 1 */ |
||||
#if defined (CFG_AMD_BOOT) |
||||
batu = CFG_FLASH1_BASE | (BL_16M << 2) | BPP_RW | BPP_RX; |
||||
#else |
||||
batu = CFG_FLASH1_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; |
||||
#endif |
||||
batl = CFG_FLASH1_BASE | 0x22; |
||||
write_bat (IBAT1, batu, batl); |
||||
write_bat (DBAT1, batu, batl); |
||||
|
||||
/* CPLD */ |
||||
batu = CFG_CPLD_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; |
||||
batl = CFG_CPLD_BASE | 0x22; |
||||
write_bat (IBAT2, 0, 0); |
||||
write_bat (DBAT2, batu, batl); |
||||
|
||||
/* FPGA */ |
||||
batu = CFG_FPGA_BASE | (BL_512K << 2) | BPP_RW | BPP_RX; |
||||
batl = CFG_FPGA_BASE | 0x22; |
||||
write_bat (IBAT3, 0, 0); |
||||
write_bat (DBAT3, batu, batl); |
||||
|
||||
/* MBAR - Data only */ |
||||
batu = CFG_MBAR | BPP_RW | BPP_RX; |
||||
batl = CFG_MBAR | 0x22; |
||||
mtspr (IBAT4L, 0); |
||||
mtspr (IBAT4U, 0); |
||||
mtspr (DBAT4L, batl); |
||||
mtspr (DBAT4U, batu); |
||||
|
||||
/* MBAR - SRAM */ |
||||
batu = CFG_SRAM_BASE | BPP_RW | BPP_RX; |
||||
batl = CFG_SRAM_BASE | 0x42; |
||||
mtspr (IBAT5L, batl); |
||||
mtspr (IBAT5U, batu); |
||||
mtspr (DBAT5L, batl); |
||||
mtspr (DBAT5U, batu); |
||||
|
||||
if (size <= 0x800000) /* 8MB */ |
||||
blocksize = BL_8M << 2; |
||||
else if (size <= 0x1000000) /* 16MB */ |
||||
blocksize = BL_16M << 2; |
||||
else if (size <= 0x2000000) /* 32MB */ |
||||
blocksize = BL_32M << 2; |
||||
else if (size <= 0x4000000) /* 64MB */ |
||||
blocksize = BL_64M << 2; |
||||
else if (size <= 0x8000000) /* 128MB */ |
||||
blocksize = BL_128M << 2; |
||||
else if (size <= 0x10000000) /* 256MB */ |
||||
blocksize = BL_256M << 2; |
||||
|
||||
/* Memory */ |
||||
batu = CFG_SDRAM_BASE | blocksize | BPP_RW | BPP_RX; |
||||
batl = CFG_SDRAM_BASE | 0x42; |
||||
mtspr (IBAT6L, batl); |
||||
mtspr (IBAT6U, batu); |
||||
mtspr (DBAT6L, batl); |
||||
mtspr (DBAT6U, batu); |
||||
|
||||
/* memory size is less than 256MB */ |
||||
if (size <= 0x10000000) { |
||||
/* Nothing */ |
||||
batu = 0; |
||||
batl = 0; |
||||
} else { |
||||
size -= 0x10000000; |
||||
if (size <= 0x800000) /* 8MB */ |
||||
blocksize = BL_8M << 2; |
||||
else if (size <= 0x1000000) /* 16MB */ |
||||
blocksize = BL_16M << 2; |
||||
else if (size <= 0x2000000) /* 32MB */ |
||||
blocksize = BL_32M << 2; |
||||
else if (size <= 0x4000000) /* 64MB */ |
||||
blocksize = BL_64M << 2; |
||||
else if (size <= 0x8000000) /* 128MB */ |
||||
blocksize = BL_128M << 2; |
||||
else if (size <= 0x10000000) /* 256MB */ |
||||
blocksize = BL_256M << 2; |
||||
|
||||
batu = (CFG_SDRAM_BASE + |
||||
0x10000000) | blocksize | BPP_RW | BPP_RX; |
||||
batl = (CFG_SDRAM_BASE + 0x10000000) | 0x42; |
||||
} |
||||
|
||||
mtspr (IBAT7L, batl); |
||||
mtspr (IBAT7U, batu); |
||||
mtspr (DBAT7L, batl); |
||||
mtspr (DBAT7U, batu); |
||||
} |
||||
|
||||
long int initdram (int board_type) |
||||
{ |
||||
ulong size; |
||||
|
||||
size = dramSetup (); |
||||
|
||||
/* if iCache ad dCache is defined */ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_CACHE) |
||||
/* setupBat(size);*/ |
||||
#endif |
||||
|
||||
return size; |
||||
} |
||||
|
||||
int checkboard (void) |
||||
{ |
||||
puts ("Board: Alaska MPC8220 Evaluation Board\n"); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,31 @@ |
||||
#
|
||||
# (C) Copyright 2003-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
|
||||
#
|
||||
|
||||
#
|
||||
# alaska board
|
||||
#
|
||||
|
||||
TEXT_BASE = 0xfff00000
|
||||
# TEXT_BASE = 0x00100000
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
|
@ -0,0 +1,110 @@ |
||||
/*
|
||||
* (C) Copyright 2004, Freescale, Inc |
||||
* TsiChung Liew, Tsi-Chung.Liew@freescale.com. |
||||
* |
||||
* 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 |
||||
* |
||||
*/ |
||||
|
||||
/*
|
||||
* Minimal serial functions needed to use one of the PSC ports |
||||
* as serial console interface. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
|
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
# include <ns16550.h> |
||||
|
||||
# define PADSERIAL_BAUD_115200 0x40 |
||||
# define PADSERIAL_BAUD_57600 0x20 |
||||
# define PADSERIAL_BAUD_9600 0 |
||||
# define PADCARD_FREQ 18432000 |
||||
|
||||
const NS16550_t com_port = (NS16550_t) CFG_NS16550_COM1; |
||||
|
||||
int ext_serial_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
volatile u8 *dipswitch = (volatile u8 *) (CFG_CPLD_BASE + 0x1002); |
||||
int baud_divisor; |
||||
|
||||
/* Find out the baud rate speed on debug card dip switches */ |
||||
if (*dipswitch & PADSERIAL_BAUD_115200) |
||||
gd->baudrate = 115200; |
||||
else if (*dipswitch & PADSERIAL_BAUD_57600) |
||||
gd->baudrate = 57600; |
||||
else |
||||
gd->baudrate = 9600; |
||||
|
||||
/* Debug card frequency */ |
||||
baud_divisor = PADCARD_FREQ / (16 * gd->baudrate); |
||||
|
||||
NS16550_init (com_port, baud_divisor); |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
void ext_serial_putc (const char c) |
||||
{ |
||||
if (c == '\n') |
||||
NS16550_putc (com_port, '\r'); |
||||
|
||||
NS16550_putc (com_port, c); |
||||
} |
||||
|
||||
void ext_serial_puts (const char *s) |
||||
{ |
||||
while (*s) { |
||||
serial_putc (*s++); |
||||
} |
||||
} |
||||
|
||||
int ext_serial_getc (void) |
||||
{ |
||||
return NS16550_getc (com_port); |
||||
} |
||||
|
||||
int ext_serial_tstc (void) |
||||
{ |
||||
return NS16550_tstc (com_port); |
||||
} |
||||
|
||||
void ext_serial_setbrg (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
volatile u8 *dipswitch = (volatile u8 *) (CFG_CPLD_BASE + 0x1002); |
||||
int baud_divisor; |
||||
|
||||
/* Find out the baud rate speed on debug card dip switches */ |
||||
if (*dipswitch & PADSERIAL_BAUD_115200) |
||||
gd->baudrate = 115200; |
||||
else if (*dipswitch & PADSERIAL_BAUD_57600) |
||||
gd->baudrate = 57600; |
||||
else |
||||
gd->baudrate = 9600; |
||||
|
||||
/* Debug card frequency */ |
||||
baud_divisor = PADCARD_FREQ / (16 * gd->baudrate); |
||||
|
||||
NS16550_reinit (com_port, baud_divisor); |
||||
} |
||||
#endif /* CONFIG_EXTUART_CONSOLE */ |
@ -0,0 +1,807 @@ |
||||
/*
|
||||
* (C) Copyright 2001 |
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net |
||||
* |
||||
* (C) Copyright 2001-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 <linux/byteorder/swab.h> |
||||
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ |
||||
|
||||
/* Board support for 1 or 2 flash devices */ |
||||
#define FLASH_PORT_WIDTH8 |
||||
|
||||
typedef unsigned char FLASH_PORT_WIDTH; |
||||
typedef volatile unsigned char FLASH_PORT_WIDTHV; |
||||
|
||||
#define SWAP(x) (x) |
||||
|
||||
/* Intel-compatible flash ID */ |
||||
#define INTEL_COMPAT 0x89 |
||||
#define INTEL_ALT 0xB0 |
||||
|
||||
/* Intel-compatible flash commands */ |
||||
#define INTEL_PROGRAM 0x10 |
||||
#define INTEL_ERASE 0x20 |
||||
#define INTEL_CLEAR 0x50 |
||||
#define INTEL_LOCKBIT 0x60 |
||||
#define INTEL_PROTECT 0x01 |
||||
#define INTEL_STATUS 0x70 |
||||
#define INTEL_READID 0x90 |
||||
#define INTEL_CONFIRM 0xD0 |
||||
#define INTEL_RESET 0xFF |
||||
|
||||
/* Intel-compatible flash status bits */ |
||||
#define INTEL_FINISHED 0x80 |
||||
#define INTEL_OK 0x80 |
||||
|
||||
#define FPW FLASH_PORT_WIDTH |
||||
#define FPWV FLASH_PORT_WIDTHV |
||||
|
||||
#define FLASH_CYCLE1 0x0555 |
||||
#define FLASH_CYCLE2 0x02aa |
||||
|
||||
#define WR_BLOCK 0x20 |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions |
||||
*/ |
||||
static ulong flash_get_size (FPW * addr, flash_info_t * info); |
||||
static int write_data (flash_info_t * info, ulong dest, FPW data); |
||||
static int write_data_block (flash_info_t * info, ulong src, ulong dest); |
||||
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data); |
||||
static void flash_get_offsets (ulong base, flash_info_t * info); |
||||
void inline spin_wheel (void); |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
|
||||
unsigned long flash_init (void) |
||||
{ |
||||
int i; |
||||
ulong size = 0; |
||||
ulong fsize = 0; |
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { |
||||
memset (&flash_info[i], 0, sizeof (flash_info_t)); |
||||
|
||||
switch (i) { |
||||
case 0: |
||||
flash_get_size ((FPW *) CFG_FLASH1_BASE, |
||||
&flash_info[i]); |
||||
flash_get_offsets (CFG_FLASH1_BASE, &flash_info[i]); |
||||
break; |
||||
case 1: |
||||
flash_get_size ((FPW *) CFG_FLASH1_BASE, |
||||
&flash_info[i]); |
||||
fsize = CFG_FLASH1_BASE + flash_info[i - 1].size; |
||||
flash_get_offsets (fsize, &flash_info[i]); |
||||
break; |
||||
case 2: |
||||
flash_get_size ((FPW *) CFG_FLASH0_BASE, |
||||
&flash_info[i]); |
||||
flash_get_offsets (CFG_FLASH0_BASE, &flash_info[i]); |
||||
break; |
||||
case 3: |
||||
flash_get_size ((FPW *) CFG_FLASH0_BASE, |
||||
&flash_info[i]); |
||||
fsize = CFG_FLASH0_BASE + flash_info[i - 1].size; |
||||
flash_get_offsets (fsize, &flash_info[i]); |
||||
break; |
||||
default: |
||||
panic ("configured to many flash banks!\n"); |
||||
break; |
||||
} |
||||
size += flash_info[i].size; |
||||
} |
||||
|
||||
/* Protect monitor and environment sectors
|
||||
*/ |
||||
#if defined (CFG_AMD_BOOT) |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_MONITOR_BASE, |
||||
CFG_MONITOR_BASE + monitor_flash_len - 1, |
||||
&flash_info[2]); |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_INTEL_BASE, |
||||
CFG_INTEL_BASE + monitor_flash_len - 1, |
||||
&flash_info[1]); |
||||
#else |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_MONITOR_BASE, |
||||
CFG_MONITOR_BASE + monitor_flash_len - 1, |
||||
&flash_info[3]); |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_AMD_BASE, |
||||
CFG_AMD_BASE + monitor_flash_len - 1, &flash_info[0]); |
||||
#endif |
||||
|
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_ENV1_ADDR, |
||||
CFG_ENV1_ADDR + CFG_ENV1_SIZE - 1, &flash_info[1]); |
||||
flash_protect (FLAG_PROTECT_SET, |
||||
CFG_ENV_ADDR, |
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[3]); |
||||
|
||||
return size; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
static void flash_get_offsets (ulong base, flash_info_t * info) |
||||
{ |
||||
int i; |
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) |
||||
return; |
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) { |
||||
for (i = 0; i < info->sector_count; i++) { |
||||
info->start[i] = base + (i * PHYS_AMD_SECT_SIZE); |
||||
info->protect[i] = 0; |
||||
} |
||||
} |
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { |
||||
for (i = 0; i < info->sector_count; i++) { |
||||
info->start[i] = base + (i * PHYS_INTEL_SECT_SIZE); |
||||
info->protect[i] = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
void flash_print_info (flash_info_t * info) |
||||
{ |
||||
int i; |
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) { |
||||
printf ("missing or unknown FLASH type\n"); |
||||
return; |
||||
} |
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) { |
||||
case FLASH_MAN_INTEL: |
||||
printf ("INTEL "); |
||||
break; |
||||
case FLASH_MAN_AMD: |
||||
printf ("AMD "); |
||||
break; |
||||
default: |
||||
printf ("Unknown Vendor "); |
||||
break; |
||||
} |
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) { |
||||
case FLASH_28F128J3A: |
||||
printf ("28F128J3A\n"); |
||||
break; |
||||
|
||||
case FLASH_AM040: |
||||
printf ("AMD29F040B\n"); |
||||
break; |
||||
|
||||
default: |
||||
printf ("Unknown Chip Type\n"); |
||||
break; |
||||
} |
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n", |
||||
info->size >> 20, info->sector_count); |
||||
|
||||
printf (" Sector Start Addresses:"); |
||||
for (i = 0; i < info->sector_count; ++i) { |
||||
if ((i % 5) == 0) |
||||
printf ("\n "); |
||||
printf (" %08lX%s", |
||||
info->start[i], info->protect[i] ? " (RO)" : " "); |
||||
} |
||||
printf ("\n"); |
||||
return; |
||||
} |
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH! |
||||
*/ |
||||
static ulong flash_get_size (FPW * addr, flash_info_t * info) |
||||
{ |
||||
FPWV value; |
||||
static int amd = 0; |
||||
|
||||
/* Write auto select command: read Manufacturer ID */ |
||||
/* Write auto select command sequence and test FLASH answer */ |
||||
addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* for AMD, Intel ignores this */ |
||||
__asm__ ("sync"); |
||||
addr[FLASH_CYCLE2] = (FPW) 0x00550055; /* for AMD, Intel ignores this */ |
||||
__asm__ ("sync"); |
||||
addr[FLASH_CYCLE1] = (FPW) 0x00900090; /* selects Intel or AMD */ |
||||
__asm__ ("sync"); |
||||
|
||||
udelay (100); |
||||
|
||||
switch (addr[0] & 0xff) { |
||||
|
||||
case (uchar) AMD_MANUFACT: |
||||
info->flash_id = FLASH_MAN_AMD; |
||||
value = addr[1]; |
||||
break; |
||||
|
||||
case (uchar) INTEL_MANUFACT: |
||||
info->flash_id = FLASH_MAN_INTEL; |
||||
value = addr[2]; |
||||
break; |
||||
|
||||
default: |
||||
printf ("unknown\n"); |
||||
info->flash_id = FLASH_UNKNOWN; |
||||
info->sector_count = 0; |
||||
info->size = 0; |
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ |
||||
return (0); /* no or unknown flash */ |
||||
} |
||||
|
||||
switch (value) { |
||||
|
||||
case (FPW) INTEL_ID_28F128J3A: |
||||
info->flash_id += FLASH_28F128J3A; |
||||
info->sector_count = 64; |
||||
info->size = 0x00800000; /* => 16 MB */ |
||||
break; |
||||
|
||||
case (FPW) AMD_ID_LV040B: |
||||
info->flash_id += FLASH_AM040; |
||||
if (amd == 0) { |
||||
info->sector_count = 7; |
||||
info->size = 0x00070000; /* => 448 KB */ |
||||
amd = 1; |
||||
} else { |
||||
/* for Environment settings */ |
||||
info->sector_count = 1; |
||||
info->size = PHYS_AMD_SECT_SIZE; /* => 64 KB */ |
||||
amd = 0; |
||||
} |
||||
break; |
||||
|
||||
default: |
||||
info->flash_id = FLASH_UNKNOWN; |
||||
break; |
||||
} |
||||
|
||||
if (info->sector_count > CFG_MAX_FLASH_SECT) { |
||||
printf ("** ERROR: sector count %d > max (%d) **\n", |
||||
info->sector_count, CFG_MAX_FLASH_SECT); |
||||
info->sector_count = CFG_MAX_FLASH_SECT; |
||||
} |
||||
|
||||
if (value == (FPW) INTEL_ID_28F128J3A) |
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */ |
||||
else |
||||
addr[0] = (FPW) 0x00F000F0; /* restore read mode */ |
||||
|
||||
return (info->size); |
||||
} |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/ |
||||
int flash_erase (flash_info_t * info, int s_first, int s_last) |
||||
{ |
||||
int flag, prot, sect; |
||||
ulong type, start, last; |
||||
int rcode = 0, intel = 0; |
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) { |
||||
if (info->flash_id == FLASH_UNKNOWN) |
||||
printf ("- missing\n"); |
||||
else |
||||
printf ("- no sectors to erase\n"); |
||||
return 1; |
||||
} |
||||
|
||||
type = (info->flash_id & FLASH_VENDMASK); |
||||
if ((type != FLASH_MAN_INTEL)) { |
||||
type = (info->flash_id & FLASH_VENDMASK); |
||||
if ((type != FLASH_MAN_AMD)) { |
||||
printf ("Can't erase unknown flash type %08lx - aborted\n", |
||||
info->flash_id); |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
if (type == FLASH_MAN_INTEL) |
||||
intel = 1; |
||||
|
||||
prot = 0; |
||||
for (sect = s_first; sect <= s_last; ++sect) { |
||||
if (info->protect[sect]) { |
||||
prot++; |
||||
} |
||||
} |
||||
|
||||
if (prot) { |
||||
printf ("- Warning: %d protected sectors will not be erased!\n", prot); |
||||
} else { |
||||
printf ("\n"); |
||||
} |
||||
|
||||
start = get_timer (0); |
||||
last = start; |
||||
|
||||
/* Disable interrupts which might cause a timeout here */ |
||||
flag = disable_interrupts (); |
||||
|
||||
/* Start erase on unprotected sectors */ |
||||
for (sect = s_first; sect <= s_last; sect++) { |
||||
if (info->protect[sect] == 0) { /* not protected */ |
||||
FPWV *addr = (FPWV *) (info->start[sect]); |
||||
FPW status; |
||||
|
||||
printf ("Erasing sector %2d ... ", sect); |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
start = get_timer (0); |
||||
|
||||
if (intel) { |
||||
*addr = (FPW) 0x00500050; /* clear status register */ |
||||
*addr = (FPW) 0x00200020; /* erase setup */ |
||||
*addr = (FPW) 0x00D000D0; /* erase confirm */ |
||||
} else { |
||||
FPWV *base; /* first address in bank */ |
||||
|
||||
base = (FPWV *) (CFG_AMD_BASE); |
||||
base[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* unlock */ |
||||
base[FLASH_CYCLE2] = (FPW) 0x00550055; /* unlock */ |
||||
base[FLASH_CYCLE1] = (FPW) 0x00800080; /* erase mode */ |
||||
base[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* unlock */ |
||||
base[FLASH_CYCLE2] = (FPW) 0x00550055; /* unlock */ |
||||
*addr = (FPW) 0x00300030; /* erase sector */ |
||||
} |
||||
|
||||
while (((status = |
||||
*addr) & (FPW) 0x00800080) != |
||||
(FPW) 0x00800080) { |
||||
if (get_timer (start) > CFG_FLASH_ERASE_TOUT) { |
||||
printf ("Timeout\n"); |
||||
if (intel) { |
||||
*addr = (FPW) 0x00B000B0; /* suspend erase */ |
||||
*addr = (FPW) 0x00FF00FF; /* reset to read mode */ |
||||
} else |
||||
*addr = (FPW) 0x00F000F0; /* reset to read mode */ |
||||
|
||||
rcode = 1; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (intel) { |
||||
*addr = (FPW) 0x00500050; /* clear status register cmd. */ |
||||
*addr = (FPW) 0x00FF00FF; /* resest to read mode */ |
||||
} else |
||||
*addr = (FPW) 0x00F000F0; /* reset to read mode */ |
||||
|
||||
printf (" done\n"); |
||||
} |
||||
} |
||||
return rcode; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns: |
||||
* 0 - OK |
||||
* 1 - write timeout |
||||
* 2 - Flash not erased |
||||
* 4 - Flash not identified |
||||
*/ |
||||
|
||||
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) |
||||
{ |
||||
if (info->flash_id == FLASH_UNKNOWN) { |
||||
return 4; |
||||
} |
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) { |
||||
case FLASH_MAN_AMD: |
||||
{ |
||||
FPW data = 0; /* 16 or 32 bit word, matches flash bus width */ |
||||
int bytes; /* number of bytes to program in current word */ |
||||
int left; /* number of bytes left to program */ |
||||
int i, res; |
||||
|
||||
for (left = cnt, res = 0; |
||||
left > 0 && res == 0; |
||||
addr += sizeof (data), left -= |
||||
sizeof (data) - bytes) { |
||||
|
||||
bytes = addr & (sizeof (data) - 1); |
||||
addr &= ~(sizeof (data) - 1); |
||||
|
||||
/* combine source and destination data so can program
|
||||
* an entire word of 16 or 32 bits |
||||
*/ |
||||
for (i = 0; i < sizeof (data); i++) { |
||||
data <<= 8; |
||||
if (i < bytes || i - bytes >= left) |
||||
data += *((uchar *) addr + i); |
||||
else |
||||
data += *src++; |
||||
} |
||||
|
||||
res = write_word_amd (info, (FPWV *) addr, |
||||
data); |
||||
} |
||||
return res; |
||||
} /* case FLASH_MAN_AMD */ |
||||
|
||||
case FLASH_MAN_INTEL: |
||||
{ |
||||
ulong cp, wp; |
||||
FPW data; |
||||
int count, i, l, rc, port_width; |
||||
|
||||
/* get lower word aligned address */ |
||||
wp = addr; |
||||
port_width = 1; |
||||
|
||||
/*
|
||||
* handle unaligned start bytes |
||||
*/ |
||||
if ((l = addr - wp) != 0) { |
||||
data = 0; |
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) { |
||||
data = (data << 8) | (*(uchar *) cp); |
||||
} |
||||
|
||||
for (; i < port_width && cnt > 0; ++i) { |
||||
data = (data << 8) | *src++; |
||||
--cnt; |
||||
++cp; |
||||
} |
||||
|
||||
for (; cnt == 0 && i < port_width; ++i, ++cp) |
||||
data = (data << 8) | (*(uchar *) cp); |
||||
|
||||
if ((rc = |
||||
write_data (info, wp, SWAP (data))) != 0) |
||||
return (rc); |
||||
wp += port_width; |
||||
} |
||||
|
||||
if (cnt > WR_BLOCK) { |
||||
/*
|
||||
* handle word aligned part |
||||
*/ |
||||
count = 0; |
||||
while (cnt >= WR_BLOCK) { |
||||
|
||||
if ((rc = |
||||
write_data_block (info, |
||||
(ulong) src, |
||||
wp)) != 0) |
||||
return (rc); |
||||
|
||||
wp += WR_BLOCK; |
||||
src += WR_BLOCK; |
||||
cnt -= WR_BLOCK; |
||||
|
||||
if (count++ > 0x800) { |
||||
spin_wheel (); |
||||
count = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (cnt < WR_BLOCK) { |
||||
/*
|
||||
* handle word aligned part |
||||
*/ |
||||
count = 0; |
||||
while (cnt >= port_width) { |
||||
data = 0; |
||||
for (i = 0; i < port_width; ++i) |
||||
data = (data << 8) | *src++; |
||||
|
||||
if ((rc = |
||||
write_data (info, wp, |
||||
SWAP (data))) != 0) |
||||
return (rc); |
||||
|
||||
wp += port_width; |
||||
cnt -= port_width; |
||||
if (count++ > 0x800) { |
||||
spin_wheel (); |
||||
count = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (cnt == 0) |
||||
return (0); |
||||
|
||||
/*
|
||||
* handle unaligned tail bytes |
||||
*/ |
||||
data = 0; |
||||
for (i = 0, cp = wp; i < port_width && cnt > 0; |
||||
++i, ++cp) { |
||||
data = (data << 8) | *src++; |
||||
--cnt; |
||||
} |
||||
|
||||
for (; i < port_width; ++i, ++cp) |
||||
data = (data << 8) | (*(uchar *) cp); |
||||
|
||||
return (write_data (info, wp, SWAP (data))); |
||||
} /* case FLASH_MAN_INTEL */ |
||||
|
||||
} /* switch */ |
||||
return (0); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word or halfword to Flash, returns: |
||||
* 0 - OK |
||||
* 1 - write timeout |
||||
* 2 - Flash not erased |
||||
*/ |
||||
static int write_data (flash_info_t * info, ulong dest, FPW data) |
||||
{ |
||||
FPWV *addr = (FPWV *) dest; |
||||
ulong start; |
||||
int flag; |
||||
|
||||
/* Check if Flash is (sufficiently) erased */ |
||||
if ((*addr & data) != data) { |
||||
printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr); |
||||
return (2); |
||||
} |
||||
/* Disable interrupts which might cause a timeout here */ |
||||
flag = disable_interrupts (); |
||||
|
||||
*addr = (FPW) 0x00400040; /* write setup */ |
||||
*addr = data; |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
start = get_timer (0); |
||||
|
||||
/* wait while polling the status register */ |
||||
while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) { |
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { |
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */ |
||||
return (1); |
||||
} |
||||
} |
||||
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */ |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word or halfword to Flash, returns: |
||||
* 0 - OK |
||||
* 1 - write timeout |
||||
* 2 - Flash not erased |
||||
*/ |
||||
static int write_data_block (flash_info_t * info, ulong src, ulong dest) |
||||
{ |
||||
FPWV *srcaddr = (FPWV *) src; |
||||
FPWV *dstaddr = (FPWV *) dest; |
||||
ulong start; |
||||
int flag, i; |
||||
|
||||
/* Check if Flash is (sufficiently) erased */ |
||||
for (i = 0; i < WR_BLOCK; i++) |
||||
if ((*dstaddr++ & 0xff) != 0xff) { |
||||
printf ("not erased at %08lx (%lx)\n", |
||||
(ulong) dstaddr, *dstaddr); |
||||
return (2); |
||||
} |
||||
|
||||
dstaddr = (FPWV *) dest; |
||||
|
||||
/* Disable interrupts which might cause a timeout here */ |
||||
flag = disable_interrupts (); |
||||
|
||||
*dstaddr = (FPW) 0x00e800e8; /* write block setup */ |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
start = get_timer (0); |
||||
|
||||
/* wait while polling the status register */ |
||||
while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) { |
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { |
||||
*dstaddr = (FPW) 0x00FF00FF; /* restore read mode */ |
||||
return (1); |
||||
} |
||||
} |
||||
|
||||
*dstaddr = (FPW) 0x001f001f; /* write 32 to buffer */ |
||||
for (i = 0; i < WR_BLOCK; i++) |
||||
*dstaddr++ = *srcaddr++; |
||||
|
||||
dstaddr -= 1; |
||||
*dstaddr = (FPW) 0x00d000d0; /* write 32 to buffer */ |
||||
|
||||
/* arm simple, non interrupt dependent timer */ |
||||
start = get_timer (0); |
||||
|
||||
/* wait while polling the status register */ |
||||
while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) { |
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { |
||||
*dstaddr = (FPW) 0x00FF00FF; /* restore read mode */ |
||||
return (1); |
||||
} |
||||
} |
||||
|
||||
*dstaddr = (FPW) 0x00FF00FF; /* restore read mode */ |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash for AMD FLASH |
||||
* A word is 16 or 32 bits, whichever the bus width of the flash bank |
||||
* (not an individual chip) is. |
||||
* |
||||
* returns: |
||||
* 0 - OK |
||||
* 1 - write timeout |
||||
* 2 - Flash not erased |
||||
*/ |
||||
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data) |
||||
{ |
||||
ulong start; |
||||
int flag; |
||||
int res = 0; /* result, assume success */ |
||||
FPWV *base; /* first address in flash bank */ |
||||
|
||||
/* Check if Flash is (sufficiently) erased */ |
||||
if ((*dest & data) != data) { |
||||
return (2); |
||||
} |
||||
|
||||
base = (FPWV *) (CFG_AMD_BASE); |
||||
|
||||
/* Disable interrupts which might cause a timeout here */ |
||||
flag = disable_interrupts (); |
||||
|
||||
base[FLASH_CYCLE1] = (FPW) 0x00AA00AA; /* unlock */ |
||||
base[FLASH_CYCLE2] = (FPW) 0x00550055; /* unlock */ |
||||
base[FLASH_CYCLE1] = (FPW) 0x00A000A0; /* selects program mode */ |
||||
|
||||
*dest = data; /* start programming the data */ |
||||
|
||||
/* re-enable interrupts if necessary */ |
||||
if (flag) |
||||
enable_interrupts (); |
||||
|
||||
start = get_timer (0); |
||||
|
||||
/* data polling for D7 */ |
||||
while (res == 0 |
||||
&& (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) { |
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) { |
||||
*dest = (FPW) 0x00F000F0; /* reset bank */ |
||||
res = 1; |
||||
} |
||||
} |
||||
|
||||
return (res); |
||||
} |
||||
|
||||
void inline spin_wheel (void) |
||||
{ |
||||
static int p = 0; |
||||
static char w[] = "\\/-"; |
||||
|
||||
printf ("\010%c", w[p]); |
||||
(++p == 3) ? (p = 0) : 0; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Set/Clear sector's lock bit, returns: |
||||
* 0 - OK |
||||
* 1 - Error (timeout, voltage problems, etc.) |
||||
*/ |
||||
int flash_real_protect (flash_info_t * info, long sector, int prot) |
||||
{ |
||||
ulong start; |
||||
int i; |
||||
int rc = 0; |
||||
FPWV *addr = (FPWV *) (info->start[sector]); |
||||
int flag = disable_interrupts (); |
||||
|
||||
/*
|
||||
* 29F040B AMD flash does not support software protection/unprotection, |
||||
* the only way to protect the AMD flash is marked it as prot bit. |
||||
* This flash only support hardware protection, by supply or not supply |
||||
* 12vpp to the flash |
||||
*/ |
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) { |
||||
info->protect[sector] = prot; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
*addr = INTEL_CLEAR; /* Clear status register */ |
||||
if (prot) { /* Set sector lock bit */ |
||||
*addr = INTEL_LOCKBIT; /* Sector lock bit */ |
||||
*addr = INTEL_PROTECT; /* set */ |
||||
} else { /* Clear sector lock bit */ |
||||
*addr = INTEL_LOCKBIT; /* All sectors lock bits */ |
||||
*addr = INTEL_CONFIRM; /* clear */ |
||||
} |
||||
|
||||
start = get_timer (0); |
||||
|
||||
while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) { |
||||
if (get_timer (start) > CFG_FLASH_UNLOCK_TOUT) { |
||||
printf ("Flash lock bit operation timed out\n"); |
||||
rc = 1; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (*addr != INTEL_OK) { |
||||
printf ("Flash lock bit operation failed at %08X, CSR=%08X\n", |
||||
(uint) addr, (uint) * addr); |
||||
rc = 1; |
||||
} |
||||
|
||||
if (!rc) |
||||
info->protect[sector] = prot; |
||||
|
||||
/*
|
||||
* Clear lock bit command clears all sectors lock bits, so |
||||
* we have to restore lock bits of protected sectors. |
||||
*/ |
||||
if (!prot) { |
||||
for (i = 0; i < info->sector_count; i++) { |
||||
if (info->protect[i]) { |
||||
start = get_timer (0); |
||||
addr = (FPWV *) (info->start[i]); |
||||
*addr = INTEL_LOCKBIT; /* Sector lock bit */ |
||||
*addr = INTEL_PROTECT; /* set */ |
||||
while ((*addr & INTEL_FINISHED) != |
||||
INTEL_FINISHED) { |
||||
if (get_timer (start) > |
||||
CFG_FLASH_UNLOCK_TOUT) { |
||||
printf ("Flash lock bit operation timed out\n"); |
||||
rc = 1; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (flag) |
||||
enable_interrupts (); |
||||
|
||||
*addr = INTEL_RESET; /* Reset to read array mode */ |
||||
|
||||
return rc; |
||||
} |
@ -0,0 +1,131 @@ |
||||
/*
|
||||
* (C) Copyright 2004, Freescale, Inc |
||||
* TsiChung Liew, Tsi-Chung.Liew@freescale.com. |
||||
* |
||||
* 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 |
||||
* |
||||
*/ |
||||
|
||||
/*
|
||||
* Minimal serial functions needed to use one of the PSC ports |
||||
* as serial console interface. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
|
||||
int serial_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
volatile uchar *cpld = (volatile uchar *) CFG_CPLD_BASE; |
||||
#endif |
||||
|
||||
/* Check CPLD Switch 2 whether is external or internal */ |
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
if ((*cpld & 0x02) == 0x02) { |
||||
gd->bExtUart = 1; |
||||
return ext_serial_init (); |
||||
} else |
||||
#endif |
||||
{ |
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
gd->bExtUart = 0; |
||||
return psc_serial_init (); |
||||
#endif |
||||
} |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
void serial_putc (const char c) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
if (gd->bExtUart) { |
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
ext_serial_putc (c); |
||||
#endif |
||||
} else { |
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
psc_serial_putc (c); |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
void serial_puts (const char *s) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
if (gd->bExtUart) { |
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
ext_serial_puts (s); |
||||
#endif |
||||
} else { |
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
psc_serial_puts (s); |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
int serial_getc (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
if (gd->bExtUart) { |
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
return ext_serial_getc (); |
||||
#endif |
||||
} else { |
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
return psc_serial_getc (); |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
int serial_tstc (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
if (gd->bExtUart) { |
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
return ext_serial_tstc (); |
||||
#endif |
||||
} else { |
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
return psc_serial_tstc (); |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
void serial_setbrg (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
if (gd->bExtUart) { |
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
ext_serial_setbrg (); |
||||
#endif |
||||
} else { |
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
psc_serial_setbrg (); |
||||
#endif |
||||
} |
||||
} |
@ -0,0 +1,122 @@ |
||||
/* |
||||
* (C) Copyright 2003-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 |
||||
*/ |
||||
|
||||
OUTPUT_ARCH(powerpc) |
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); |
||||
/* Do we need any of these for elf? |
||||
__DYNAMIC = 0; */ |
||||
SECTIONS |
||||
{ |
||||
/* Read-only sections, merged into text segment: */ |
||||
. = + SIZEOF_HEADERS; |
||||
.interp : { *(.interp) } |
||||
.hash : { *(.hash) } |
||||
.dynsym : { *(.dynsym) } |
||||
.dynstr : { *(.dynstr) } |
||||
.rel.text : { *(.rel.text) } |
||||
.rela.text : { *(.rela.text) } |
||||
.rel.data : { *(.rel.data) } |
||||
.rela.data : { *(.rela.data) } |
||||
.rel.rodata : { *(.rel.rodata) } |
||||
.rela.rodata : { *(.rela.rodata) } |
||||
.rel.got : { *(.rel.got) } |
||||
.rela.got : { *(.rela.got) } |
||||
.rel.ctors : { *(.rel.ctors) } |
||||
.rela.ctors : { *(.rela.ctors) } |
||||
.rel.dtors : { *(.rel.dtors) } |
||||
.rela.dtors : { *(.rela.dtors) } |
||||
.rel.bss : { *(.rel.bss) } |
||||
.rela.bss : { *(.rela.bss) } |
||||
.rel.plt : { *(.rel.plt) } |
||||
.rela.plt : { *(.rela.plt) } |
||||
.init : { *(.init) } |
||||
.plt : { *(.plt) } |
||||
.text : |
||||
{ |
||||
cpu/mpc8220/start.o (.text) |
||||
*(.text) |
||||
*(.fixup) |
||||
*(.got1) |
||||
. = ALIGN(16); |
||||
*(.rodata) |
||||
*(.rodata1) |
||||
*(.rodata.str1.4) |
||||
} |
||||
.fini : { *(.fini) } =0 |
||||
.ctors : { *(.ctors) } |
||||
.dtors : { *(.dtors) } |
||||
|
||||
/* Read-write section, merged into data segment: */ |
||||
. = (. + 0x0FFF) & 0xFFFFF000; |
||||
_erotext = .; |
||||
PROVIDE (erotext = .); |
||||
.reloc : |
||||
{ |
||||
*(.got) |
||||
_GOT2_TABLE_ = .; |
||||
*(.got2) |
||||
_FIXUP_TABLE_ = .; |
||||
*(.fixup) |
||||
} |
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; |
||||
__fixup_entries = (. - _FIXUP_TABLE_) >> 2; |
||||
|
||||
.data : |
||||
{ |
||||
*(.data) |
||||
*(.data1) |
||||
*(.sdata) |
||||
*(.sdata2) |
||||
*(.dynamic) |
||||
CONSTRUCTORS |
||||
} |
||||
_edata = .; |
||||
PROVIDE (edata = .); |
||||
|
||||
__u_boot_cmd_start = .; |
||||
.u_boot_cmd : { *(.u_boot_cmd) } |
||||
__u_boot_cmd_end = .; |
||||
|
||||
|
||||
__start___ex_table = .; |
||||
__ex_table : { *(__ex_table) } |
||||
__stop___ex_table = .; |
||||
|
||||
. = ALIGN(4096); |
||||
__init_begin = .; |
||||
.text.init : { *(.text.init) } |
||||
.data.init : { *(.data.init) } |
||||
. = ALIGN(4096); |
||||
__init_end = .; |
||||
|
||||
__bss_start = .; |
||||
.bss : |
||||
{ |
||||
*(.sbss) *(.scommon) |
||||
*(.dynbss) |
||||
*(.bss) |
||||
*(COMMON) |
||||
} |
||||
_end = . ; |
||||
PROVIDE (end = .); |
||||
} |
@ -0,0 +1,45 @@ |
||||
#
|
||||
# (C) Copyright 2003
|
||||
# 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 $(TOPDIR)/config.mk |
||||
|
||||
LIB = lib$(CPU).a
|
||||
|
||||
START = start.o
|
||||
ASOBJS = io.o fec_dma_tasks.o
|
||||
OBJS = i2c.o traps.o cpu.o cpu_init.o fec.o dramSetup.o interrupts.o \
|
||||
loadtask.o uart.o speed.o
|
||||
|
||||
all: .depend $(START) $(ASOBJS) $(LIB) |
||||
|
||||
$(LIB): $(OBJS) |
||||
$(AR) crv $@ $(ASOBJS) $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(START:.o=.S) $(OBJS:.o=.c) |
||||
$(CC) -M $(CFLAGS) $(START:.o=.S) $(ASOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend |
||||
|
||||
#########################################################################
|
@ -0,0 +1,27 @@ |
||||
#
|
||||
# (C) Copyright 2003
|
||||
# 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
|
||||
#
|
||||
|
||||
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
|
||||
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_MPC8220 -ffixed-r2 -ffixed-r29 \
|
||||
-mstring -mcpu=603e -mmultiple
|
@ -0,0 +1,93 @@ |
||||
/*
|
||||
* (C) Copyright 2000-2003 |
||||
* 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 |
||||
*/ |
||||
|
||||
/*
|
||||
* CPU specific code for the MPC8220 CPUs |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <watchdog.h> |
||||
#include <command.h> |
||||
#include <mpc8220.h> |
||||
#include <asm/processor.h> |
||||
|
||||
int checkcpu (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
ulong clock = gd->cpu_clk; |
||||
char buf[32]; |
||||
|
||||
puts ("CPU: "); |
||||
|
||||
printf (CPU_ID_STR); |
||||
|
||||
printf (" (JTAG ID %08lx)", *(vu_long *) (CFG_MBAR + 0x50)); |
||||
|
||||
printf (" at %s MHz\n", strmhz (buf, clock)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
||||
|
||||
int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) |
||||
{ |
||||
volatile gptmr8220_t *gptmr = (volatile gptmr8220_t *) MMAP_GPTMR; |
||||
ulong msr; |
||||
|
||||
/* Interrupts and MMU off */ |
||||
__asm__ __volatile__ ("mfmsr %0":"=r" (msr):); |
||||
|
||||
msr &= ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR); |
||||
__asm__ __volatile__ ("mtmsr %0"::"r" (msr)); |
||||
|
||||
/* Charge the watchdog timer */ |
||||
gptmr->Prescl = 10; |
||||
gptmr->Count = 1; |
||||
|
||||
gptmr->Mode = GPT_TMS_SGPIO; |
||||
|
||||
gptmr->Control = GPT_CTRL_WDEN | GPT_CTRL_CE; |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
||||
|
||||
/*
|
||||
* Get timebase clock frequency (like cpu_clk in Hz) |
||||
* |
||||
*/ |
||||
unsigned long get_tbclk (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
ulong tbclk; |
||||
|
||||
tbclk = (gd->bus_clk + 3L) / 4L; |
||||
|
||||
return (tbclk); |
||||
} |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
@ -0,0 +1,130 @@ |
||||
/*
|
||||
* (C) Copyright 2000-2003 |
||||
* 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 <mpc8220.h> |
||||
|
||||
/*
|
||||
* Breath some life into the CPU... |
||||
* |
||||
* Set up the memory map, |
||||
* initialize a bunch of registers. |
||||
*/ |
||||
void cpu_init_f (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
volatile flexbus8220_t *flexbus = (volatile flexbus8220_t *) MMAP_FB; |
||||
volatile pcfg8220_t *portcfg = (volatile pcfg8220_t *) MMAP_PCFG; |
||||
volatile xlbarb8220_t *xlbarb = (volatile xlbarb8220_t *) MMAP_XLBARB; |
||||
|
||||
/* Pointer is writable since we allocated a register for it */ |
||||
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); |
||||
|
||||
/* Clear initial global data */ |
||||
memset ((void *) gd, 0, sizeof (gd_t)); |
||||
|
||||
/* Clear all port configuration */ |
||||
portcfg->pcfg0 = 0; |
||||
portcfg->pcfg1 = 0; |
||||
portcfg->pcfg2 = 0; |
||||
portcfg->pcfg3 = 0; |
||||
|
||||
/*
|
||||
* Flexbus Controller: configure chip selects and enable them |
||||
*/ |
||||
#if defined (CFG_CS0_BASE) |
||||
flexbus->csar0 = CFG_CS0_BASE; |
||||
flexbus->cscr0 = CFG_CS0_CTRL; |
||||
flexbus->csmr0 = ((CFG_CS0_MASK - 1) & 0xffff0000) | 1; |
||||
__asm__ volatile ("sync"); |
||||
#endif |
||||
#if defined (CFG_CS1_BASE) |
||||
flexbus->csar1 = CFG_CS1_BASE; |
||||
flexbus->cscr1 = CFG_CS1_CTRL; |
||||
flexbus->csmr1 = ((CFG_CS1_MASK - 1) & 0xffff0000) | 1; |
||||
__asm__ volatile ("sync"); |
||||
#endif |
||||
#if defined (CFG_CS2_BASE) |
||||
flexbus->csar2 = CFG_CS2_BASE; |
||||
flexbus->cscr2 = CFG_CS2_CTRL; |
||||
flexbus->csmr2 = ((CFG_CS2_MASK - 1) & 0xffff0000) | 1; |
||||
portcfg->pcfg3 |= CFG_CS2_PORT3_CONFIG; |
||||
__asm__ volatile ("sync"); |
||||
#endif |
||||
#if defined (CFG_CS3_BASE) |
||||
flexbus->csar3 = CFG_CS3_BASE; |
||||
flexbus->cscr3 = CFG_CS3_CTRL; |
||||
flexbus->csmr3 = ((CFG_CS3_MASK - 1) & 0xffff0000) | 1; |
||||
portcfg->pcfg3 |= CFG_CS3_PORT3_CONFIG; |
||||
__asm__ volatile ("sync"); |
||||
#endif |
||||
#if defined (CFG_CS4_BASE) |
||||
flexbus->csar4 = CFG_CS4_BASE; |
||||
flexbus->cscr4 = CFG_CS4_CTRL; |
||||
flexbus->csmr4 = ((CFG_CS4_MASK - 1) & 0xffff0000) | 1; |
||||
portcfg->pcfg3 |= CFG_CS4_PORT3_CONFIG; |
||||
__asm__ volatile ("sync"); |
||||
#endif |
||||
#if defined (CFG_CS5_BASE) |
||||
flexbus->csar5 = CFG_CS5_BASE; |
||||
flexbus->cscr5 = CFG_CS5_CTRL; |
||||
flexbus->csmr5 = ((CFG_CS5_MASK - 1) & 0xffff0000) | 1; |
||||
portcfg->pcfg3 |= CFG_CS5_PORT3_CONFIG; |
||||
__asm__ volatile ("sync"); |
||||
#endif |
||||
|
||||
/* This section of the code cannot place in cpu_init_r(),
|
||||
it will cause the system to hang */ |
||||
/* enable timebase */ |
||||
xlbarb->config = 0x00002000; |
||||
|
||||
xlbarb->addrTenTimeOut = 0x1000; |
||||
xlbarb->dataTenTimeOut = 0x1000; |
||||
xlbarb->busActTimeOut = 0x2000; |
||||
|
||||
/* Master Priority Enable */ |
||||
xlbarb->mastPriEn = 0x1f; |
||||
xlbarb->mastPriority = 0; |
||||
} |
||||
|
||||
/*
|
||||
* initialize higher level parts of CPU like time base and timers |
||||
*/ |
||||
int cpu_init_r (void) |
||||
{ |
||||
/* this may belongs to disable interrupt section */ |
||||
/* mask all interrupts */ |
||||
*(vu_long *) 0xf0000700 = 0xfffffc00; |
||||
*(vu_long *) 0xf0000714 |= 0x0001ffff; |
||||
*(vu_long *) 0xf0000710 &= ~0x00000f00; |
||||
|
||||
/* route critical ints to normal ints */ |
||||
*(vu_long *) 0xf0000710 |= 0x00000001; |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC8220_FEC) |
||||
/* load FEC microcode */ |
||||
loadtask (0, 2); |
||||
#endif |
||||
return (0); |
||||
} |
@ -0,0 +1,68 @@ |
||||
/*
|
||||
* (C) Copyright 2003 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* This file is based on code |
||||
* (C) Copyright Motorola, Inc., 2000 |
||||
* |
||||
* MPC8220 dma header file |
||||
*/ |
||||
|
||||
#ifndef __MPC8220_DMA_H |
||||
#define __MPC8220_DMA_H |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
|
||||
/* Task number assignment */ |
||||
#define FEC_RECV_TASK_NO 0 |
||||
#define FEC_XMIT_TASK_NO 1 |
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* Stuff for Ethernet Tx/Rx tasks |
||||
*--------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
/* Layout of Ethernet controller Parameter SRAM area:
|
||||
* ---------------------------------------------------------------- |
||||
* 0x00: TBD_BASE, base address of TX BD ring |
||||
* 0x04: TBD_NEXT, address of next TX BD to be processed |
||||
* 0x08: RBD_BASE, base address of RX BD ring |
||||
* 0x0C: RBD_NEXT, address of next RX BD to be processed |
||||
* --------------------------------------------------------------- |
||||
* ALL PARAMETERS ARE ALL LONGWORDS (FOUR BYTES EACH). |
||||
*/ |
||||
|
||||
/* base address of SRAM area to store parameters used by Ethernet tasks */ |
||||
#define FEC_PARAM_BASE (MMAP_SRAM + 0x5b00) |
||||
|
||||
/* base address of SRAM area for buffer descriptors */ |
||||
#define FEC_BD_BASE (MMAP_SRAM + 0x5b20) |
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* common shortcuts used by driver C code |
||||
*--------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
/* Disable SmartDMA task */ |
||||
#define DMA_TASK_DISABLE(tasknum) \ |
||||
{ \
|
||||
volatile ushort *tcr = (ushort *)(MMAP_DMA + 0x0000001c + 2 * tasknum); \
|
||||
*tcr = (*tcr) & (~0x8000); \
|
||||
} |
||||
|
||||
/* Enable SmartDMA task */ |
||||
#define DMA_TASK_ENABLE(tasknum) \ |
||||
{ \
|
||||
volatile ushort *tcr = (ushort *) (MMAP_DMA + 0x0000001c + 2 * tasknum);\
|
||||
*tcr = (*tcr) | 0x8000; \
|
||||
} |
||||
|
||||
/* Clear interrupt pending bits */ |
||||
#define DMA_CLEAR_IEVENT(tasknum) \ |
||||
{ \
|
||||
struct mpc8220_dma *dma = (struct mpc8220_dma *)MMAP_DMA; \
|
||||
dma->IntPend = (1 << tasknum); \
|
||||
} |
||||
|
||||
#endif /* __MPC8220_DMA_H */ |
@ -0,0 +1,755 @@ |
||||
/*
|
||||
* (C) Copyright 2004, Freescale, Inc |
||||
* TsiChung Liew, Tsi-Chung.Liew@freescale.com |
||||
* |
||||
* 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 |
||||
*/ |
||||
|
||||
/*
|
||||
DESCRIPTION |
||||
Read Dram spd and base on its information to calculate the memory size, |
||||
characteristics to initialize the dram on MPC8220 |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
#include "i2cCore.h" |
||||
#include "dramSetup.h" |
||||
|
||||
#define SPD_SIZE 0x40 |
||||
#define DRAM_SPD 0xA2 /* on Board SPD eeprom */ |
||||
#define TOTAL_BANK 2 |
||||
|
||||
int spd_status (volatile i2c8220_t * pi2c, u8 sta_bit, u8 truefalse) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < I2C_POLL_COUNT; i++) { |
||||
if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0)) |
||||
return (OK); |
||||
} |
||||
|
||||
return (ERROR); |
||||
} |
||||
|
||||
int spd_clear (volatile i2c8220_t * pi2c) |
||||
{ |
||||
pi2c->adr = 0; |
||||
pi2c->fdr = 0; |
||||
pi2c->cr = 0; |
||||
pi2c->sr = 0; |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
int spd_stop (volatile i2c8220_t * pi2c) |
||||
{ |
||||
pi2c->cr &= ~I2C_CTL_STA; /* Generate stop signal */ |
||||
if (spd_status (pi2c, I2C_STA_BB, 0) != OK) |
||||
return ERROR; |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
int spd_readbyte (volatile i2c8220_t * pi2c, u8 * readb, int *index) |
||||
{ |
||||
pi2c->sr &= ~I2C_STA_IF; /* Clear Interrupt Bit */ |
||||
*readb = pi2c->dr; /* Read a byte */ |
||||
|
||||
/*
|
||||
Set I2C_CTRL_TXAK will cause Transfer pending and |
||||
set I2C_CTRL_STA will cause Interrupt pending |
||||
*/ |
||||
if (*index != 2) { |
||||
if (spd_status (pi2c, I2C_STA_CF, 1) != OK) /* Transfer not complete? */ |
||||
return ERROR; |
||||
} |
||||
|
||||
if (*index != 1) { |
||||
if (spd_status (pi2c, I2C_STA_IF, 1) != OK) |
||||
return ERROR; |
||||
} |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
int readSpdData (u8 * spdData) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
volatile i2c8220_t *pi2cReg; |
||||
volatile pcfg8220_t *pcfg; |
||||
u8 slvAdr = DRAM_SPD; |
||||
u8 Tmp; |
||||
int Length = SPD_SIZE; |
||||
int i = 0; |
||||
|
||||
/* Enable Port Configuration for SDA and SDL signals */ |
||||
pcfg = (volatile pcfg8220_t *) (MMAP_PCFG); |
||||
__asm__ ("sync"); |
||||
pcfg->pcfg3 &= ~CFG_I2C_PORT3_CONFIG; |
||||
__asm__ ("sync"); |
||||
|
||||
/* Points the structure to I2c mbar memory offset */ |
||||
pi2cReg = (volatile i2c8220_t *) (MMAP_I2C); |
||||
|
||||
|
||||
/* Clear FDR, ADR, SR and CR reg */ |
||||
pi2cReg->adr = 0; |
||||
pi2cReg->fdr = 0; |
||||
pi2cReg->cr = 0; |
||||
pi2cReg->sr = 0; |
||||
|
||||
/* Set for fix XLB Bus Frequency */ |
||||
switch (gd->bus_clk) { |
||||
case 60000000: |
||||
pi2cReg->fdr = 0x15; |
||||
break; |
||||
case 70000000: |
||||
pi2cReg->fdr = 0x16; |
||||
break; |
||||
case 80000000: |
||||
pi2cReg->fdr = 0x3a; |
||||
break; |
||||
case 90000000: |
||||
pi2cReg->fdr = 0x17; |
||||
break; |
||||
case 100000000: |
||||
pi2cReg->fdr = 0x3b; |
||||
break; |
||||
case 110000000: |
||||
pi2cReg->fdr = 0x18; |
||||
break; |
||||
case 120000000: |
||||
pi2cReg->fdr = 0x19; |
||||
break; |
||||
case 130000000: |
||||
pi2cReg->fdr = 0x1a; |
||||
break; |
||||
} |
||||
|
||||
pi2cReg->adr = 0x90; /* I2C device address */ |
||||
|
||||
pi2cReg->cr = I2C_CTL_EN; /* Set Enable */ |
||||
|
||||
/*
|
||||
The I2C bus should be in Idle state. If the bus is busy, |
||||
clear the STA bit in control register |
||||
*/ |
||||
if (spd_status (pi2cReg, I2C_STA_BB, 0) != OK) { |
||||
if ((pi2cReg->cr & I2C_CTL_STA) == I2C_CTL_STA) |
||||
pi2cReg->cr &= ~I2C_CTL_STA; |
||||
|
||||
/* Check again if it is still busy, return error if found */ |
||||
if (spd_status (pi2cReg, I2C_STA_BB, 1) == OK) |
||||
return ERROR; |
||||
} |
||||
|
||||
pi2cReg->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack */ |
||||
pi2cReg->cr |= I2C_CTL_STA; /* Generate start signal */ |
||||
|
||||
if (spd_status (pi2cReg, I2C_STA_BB, 1) != OK) |
||||
return ERROR; |
||||
|
||||
|
||||
/* Write slave address */ |
||||
pi2cReg->sr &= ~I2C_STA_IF; /* Clear Interrupt */ |
||||
pi2cReg->dr = slvAdr; /* Write a byte */ |
||||
|
||||
if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) { /* Transfer not complete? */ |
||||
spd_stop (pi2cReg); |
||||
return ERROR; |
||||
} |
||||
|
||||
if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) { |
||||
spd_stop (pi2cReg); |
||||
return ERROR; |
||||
} |
||||
|
||||
|
||||
/* Issue the offset to start */ |
||||
pi2cReg->sr &= ~I2C_STA_IF; /* Clear Interrupt */ |
||||
pi2cReg->dr = 0; /* Write a byte */ |
||||
|
||||
if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) { /* Transfer not complete? */ |
||||
spd_stop (pi2cReg); |
||||
return ERROR; |
||||
} |
||||
|
||||
if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) { |
||||
spd_stop (pi2cReg); |
||||
return ERROR; |
||||
} |
||||
|
||||
|
||||
/* Set repeat start */ |
||||
pi2cReg->cr |= I2C_CTL_RSTA; /* Repeat Start */ |
||||
|
||||
pi2cReg->sr &= ~I2C_STA_IF; /* Clear Interrupt */ |
||||
pi2cReg->dr = slvAdr | 1; /* Write a byte */ |
||||
|
||||
if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) { /* Transfer not complete? */ |
||||
spd_stop (pi2cReg); |
||||
return ERROR; |
||||
} |
||||
|
||||
if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) { |
||||
spd_stop (pi2cReg); |
||||
return ERROR; |
||||
} |
||||
|
||||
if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01)) |
||||
return ERROR; |
||||
|
||||
pi2cReg->cr &= ~I2C_CTL_TX; /* Set receive mode */ |
||||
|
||||
if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01)) |
||||
return ERROR; |
||||
|
||||
/* Dummy Read */ |
||||
if (spd_readbyte (pi2cReg, &Tmp, &i) != OK) { |
||||
spd_stop (pi2cReg); |
||||
return ERROR; |
||||
} |
||||
|
||||
i = 0; |
||||
while (Length) { |
||||
if (Length == 2) |
||||
pi2cReg->cr |= I2C_CTL_TXAK; |
||||
|
||||
if (Length == 1) |
||||
pi2cReg->cr &= ~I2C_CTL_STA; |
||||
|
||||
if (spd_readbyte (pi2cReg, spdData, &Length) != OK) { |
||||
return spd_stop (pi2cReg); |
||||
} |
||||
i++; |
||||
Length--; |
||||
spdData++; |
||||
} |
||||
|
||||
/* Stop the service */ |
||||
spd_stop (pi2cReg); |
||||
|
||||
return OK; |
||||
} |
||||
|
||||
int getBankInfo (int bank, draminfo_t * pBank) |
||||
{ |
||||
int status; |
||||
int checksum; |
||||
int count; |
||||
u8 spdData[SPD_SIZE]; |
||||
|
||||
|
||||
if (bank > 2 || pBank == 0) { |
||||
/* illegal values */ |
||||
return (-42); |
||||
} |
||||
|
||||
status = readSpdData (&spdData[0]); |
||||
if (status < 0) |
||||
return (-1); |
||||
|
||||
/* check the checksum */ |
||||
for (count = 0, checksum = 0; count < LOC_CHECKSUM; count++) |
||||
checksum += spdData[count]; |
||||
|
||||
checksum = checksum - ((checksum / 256) * 256); |
||||
|
||||
if (checksum != spdData[LOC_CHECKSUM]) |
||||
return (-2); |
||||
|
||||
/* Get the memory type */ |
||||
if (! |
||||
((spdData[LOC_TYPE] == TYPE_DDR) |
||||
|| (spdData[LOC_TYPE] == TYPE_SDR))) |
||||
/* not one of the types we support */ |
||||
return (-3); |
||||
|
||||
pBank->type = spdData[LOC_TYPE]; |
||||
|
||||
/* Set logical banks */ |
||||
pBank->banks = spdData[LOC_LOGICAL_BANKS]; |
||||
|
||||
/* Check that we have enough physical banks to cover the bank we are
|
||||
* figuring out. Odd-numbered banks correspond to the second bank |
||||
* on the device. |
||||
*/ |
||||
if (bank & 1) { |
||||
/* Second bank of a "device" */ |
||||
if (spdData[LOC_PHYS_BANKS] < 2) |
||||
/* this bank doesn't exist on the "device" */ |
||||
return (-4); |
||||
|
||||
if (spdData[LOC_ROWS] & 0xf0) |
||||
/* Two asymmetric banks */ |
||||
pBank->rows = spdData[LOC_ROWS] >> 4; |
||||
else |
||||
pBank->rows = spdData[LOC_ROWS]; |
||||
|
||||
if (spdData[LOC_COLS] & 0xf0) |
||||
/* Two asymmetric banks */ |
||||
pBank->cols = spdData[LOC_COLS] >> 4; |
||||
else |
||||
pBank->cols = spdData[LOC_COLS]; |
||||
} else { |
||||
/* First bank of a "device" */ |
||||
pBank->rows = spdData[LOC_ROWS]; |
||||
pBank->cols = spdData[LOC_COLS]; |
||||
} |
||||
|
||||
pBank->width = spdData[LOC_WIDTH_HIGH] << 8 | spdData[LOC_WIDTH_LOW]; |
||||
pBank->bursts = spdData[LOC_BURSTS]; |
||||
pBank->CAS = spdData[LOC_CAS]; |
||||
pBank->CS = spdData[LOC_CS]; |
||||
pBank->WE = spdData[LOC_WE]; |
||||
pBank->Trp = spdData[LOC_Trp]; |
||||
pBank->Trcd = spdData[LOC_Trcd]; |
||||
pBank->buffered = spdData[LOC_Buffered] & 1; |
||||
pBank->refresh = spdData[LOC_REFRESH]; |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
|
||||
/* checkMuxSetting -- given a row/column device geometry, return a mask
|
||||
* of the valid DRAM controller addr_mux settings for |
||||
* that geometry. |
||||
* |
||||
* Arguments: u8 rows: number of row addresses in this device |
||||
* u8 columns: number of column addresses in this device |
||||
* |
||||
* Returns: a mask of the allowed addr_mux settings for this |
||||
* geometry. Each bit in the mask represents a |
||||
* possible addr_mux settings (for example, the |
||||
* (1<<2) bit in the mask represents the 0b10 setting)/ |
||||
* |
||||
*/ |
||||
u8 checkMuxSetting (u8 rows, u8 columns) |
||||
{ |
||||
muxdesc_t *pIdx, *pMux; |
||||
u8 mask; |
||||
int lrows, lcolumns; |
||||
u32 mux[4] = { 0x00080c04, 0x01080d03, 0x02080e02, 0xffffffff }; |
||||
|
||||
/* Setup MuxDescriptor in SRAM space */ |
||||
/* MUXDESC AddressRuns [] = {
|
||||
{ 0, 8, 12, 4 }, / setting, columns, rows, extra columns / |
||||
{ 1, 8, 13, 3 }, / setting, columns, rows, extra columns / |
||||
{ 2, 8, 14, 2 }, / setting, columns, rows, extra columns / |
||||
{ 0xff } / list terminator / |
||||
}; */ |
||||
|
||||
pIdx = (muxdesc_t *) & mux[0]; |
||||
|
||||
/* Check rows x columns against each possible address mux setting */ |
||||
for (pMux = pIdx, mask = 0;; pMux++) { |
||||
lrows = rows; |
||||
lcolumns = columns; |
||||
|
||||
if (pMux->MuxValue == 0xff) |
||||
break; /* end of list */ |
||||
|
||||
/* For a given mux setting, since we want all the memory in a
|
||||
* device to be contiguous, we want the device "use up" the |
||||
* address lines such that there are no extra column or row |
||||
* address lines on the device. |
||||
*/ |
||||
|
||||
lcolumns -= pMux->Columns; |
||||
if (lcolumns < 0) |
||||
/* Not enough columns to get to the rows */ |
||||
continue; |
||||
|
||||
lrows -= pMux->Rows; |
||||
if (lrows > 0) |
||||
/* we have extra rows left -- can't do that! */ |
||||
continue; |
||||
|
||||
/* At this point, we either have to have used up all the
|
||||
* rows or we have to have no columns left. |
||||
*/ |
||||
|
||||
if (lcolumns != 0 && lrows != 0) |
||||
/* rows AND columns are left. Bad! */ |
||||
continue; |
||||
|
||||
lcolumns -= pMux->MoreColumns; |
||||
|
||||
if (lcolumns <= 0) |
||||
mask |= (1 << pMux->MuxValue); |
||||
} |
||||
|
||||
return (mask); |
||||
} |
||||
|
||||
|
||||
u32 dramSetup (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
draminfo_t DramInfo[TOTAL_BANK]; |
||||
draminfo_t *pDramInfo; |
||||
u32 size, temp, cfg_value, mode_value, refresh; |
||||
u8 *ptr; |
||||
u8 bursts, Trp, Trcd, type, buffered; |
||||
u8 muxmask, rows, columns; |
||||
int count, banknum; |
||||
u32 *prefresh, *pIdx; |
||||
u32 refrate[8] = { 15625, 3900, 7800, 31300, |
||||
62500, 125000, 0xffffffff, 0xffffffff |
||||
}; |
||||
volatile sysconf8220_t *sysconf; |
||||
volatile memctl8220_t *memctl; |
||||
|
||||
sysconf = (volatile sysconf8220_t *) MMAP_MBAR; |
||||
memctl = (volatile memctl8220_t *) MMAP_MEMCTL; |
||||
|
||||
/* Set everything in the descriptions to zero */ |
||||
ptr = (u8 *) & DramInfo[0]; |
||||
for (count = 0; count < sizeof (DramInfo); count++) |
||||
*ptr++ = 0; |
||||
|
||||
for (banknum = 0; banknum < TOTAL_BANK; banknum++) |
||||
sysconf->cscfg[banknum]; |
||||
|
||||
/* Descriptions of row/column address muxing for various
|
||||
* addr_mux settings. |
||||
*/ |
||||
|
||||
pIdx = prefresh = (u32 *) & refrate[0]; |
||||
|
||||
/* Get all the info for all three logical banks */ |
||||
bursts = 0xff; |
||||
Trp = 0; |
||||
Trcd = 0; |
||||
type = 0; |
||||
buffered = 0xff; |
||||
refresh = 0xffffffff; |
||||
muxmask = 0xff; |
||||
|
||||
/* Two bank, CS0 and CS1 */ |
||||
for (banknum = 0, pDramInfo = &DramInfo[0]; |
||||
banknum < TOTAL_BANK; banknum++, pDramInfo++) { |
||||
pDramInfo->ordinal = banknum; /* initial sorting */ |
||||
if (getBankInfo (banknum, pDramInfo) < 0) |
||||
continue; |
||||
|
||||
/* get cumulative parameters of all three banks */ |
||||
if (type && pDramInfo->type != type) |
||||
return 0; |
||||
|
||||
type = pDramInfo->type; |
||||
rows = pDramInfo->rows; |
||||
columns = pDramInfo->cols; |
||||
|
||||
/* This chip only supports 13 DRAM memory lines, but some devices
|
||||
* have 14 rows. To deal with this, ignore the 14th address line |
||||
* by limiting the number of rows (and columns) to 13. This will |
||||
* mean that for 14-row devices we will only be able to use |
||||
* half of the memory, but it's better than nothing. |
||||
*/ |
||||
if (rows > 13) |
||||
rows = 13; |
||||
if (columns > 13) |
||||
columns = 13; |
||||
|
||||
pDramInfo->size = |
||||
((1 << (rows + columns)) * pDramInfo->width); |
||||
pDramInfo->size *= pDramInfo->banks; |
||||
pDramInfo->size >>= 3; |
||||
|
||||
/* figure out which addr_mux configurations will support this device */ |
||||
muxmask &= checkMuxSetting (rows, columns); |
||||
if (muxmask == 0) |
||||
return 0; |
||||
|
||||
buffered = pDramInfo->buffered; |
||||
bursts &= pDramInfo->bursts; /* union of all bursts */ |
||||
if (pDramInfo->Trp > Trp) /* worst case (longest) Trp */ |
||||
Trp = pDramInfo->Trp; |
||||
|
||||
if (pDramInfo->Trcd > Trcd) /* worst case (longest) Trcd */ |
||||
Trcd = pDramInfo->Trcd; |
||||
|
||||
prefresh = pIdx; |
||||
/* worst case (shortest) Refresh period */ |
||||
if (refresh > prefresh[pDramInfo->refresh & 7]) |
||||
refresh = prefresh[pDramInfo->refresh & 7]; |
||||
|
||||
} /* for loop */ |
||||
|
||||
|
||||
/* We only allow a burst length of 8! */ |
||||
if (!(bursts & 8)) |
||||
bursts = 8; |
||||
|
||||
/* Sort the devices. In order to get each chip select region
|
||||
* aligned properly, put the biggest device at the lowest address. |
||||
* A simple bubble sort will do the trick. |
||||
*/ |
||||
for (banknum = 0, pDramInfo = &DramInfo[0]; |
||||
banknum < TOTAL_BANK; banknum++, pDramInfo++) { |
||||
int i; |
||||
|
||||
for (i = 0; i < TOTAL_BANK; i++) { |
||||
if (pDramInfo->size < DramInfo[i].size && |
||||
pDramInfo->ordinal < DramInfo[i].ordinal) { |
||||
/* If the current bank is smaller, but if the ordinal is also
|
||||
* smaller, swap the ordinals |
||||
*/ |
||||
u8 temp8; |
||||
|
||||
temp8 = DramInfo[i].ordinal; |
||||
DramInfo[i].ordinal = pDramInfo->ordinal; |
||||
pDramInfo->ordinal = temp8; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/* Now figure out the base address for each bank. While
|
||||
* we're at it, figure out how much memory there is. |
||||
* |
||||
*/ |
||||
size = 0; |
||||
for (banknum = 0; banknum < TOTAL_BANK; banknum++) { |
||||
int i; |
||||
|
||||
for (i = 0; i < TOTAL_BANK; i++) { |
||||
if (DramInfo[i].ordinal == banknum |
||||
&& DramInfo[i].size != 0) { |
||||
DramInfo[i].base = size; |
||||
size += DramInfo[i].size; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Set up the Drive Strength register */ |
||||
temp = ((DRIVE_STRENGTH_LOW << SDRAMDS_SBE_SHIFT) |
||||
| (DRIVE_STRENGTH_HIGH << SDRAMDS_SBC_SHIFT) |
||||
| (DRIVE_STRENGTH_LOW << SDRAMDS_SBA_SHIFT) |
||||
| (DRIVE_STRENGTH_OFF << SDRAMDS_SBS_SHIFT) |
||||
| (DRIVE_STRENGTH_LOW << SDRAMDS_SBD_SHIFT)); |
||||
sysconf->sdramds = temp; |
||||
|
||||
/* ********************** Cfg 1 ************************* */ |
||||
|
||||
/* Set the single read to read/write/precharge delay */ |
||||
cfg_value = CFG1_SRD2RWP ((type == TYPE_DDR) ? 7 : 0xb); |
||||
|
||||
/* Set the single write to read/write/precharge delay.
|
||||
* This may or may not be correct. The controller spec |
||||
* says "tWR", but "tWR" does not appear in the SPD. It |
||||
* always seems to be 15nsec for the class of device we're |
||||
* using, which turns out to be 2 clock cycles at 133MHz, |
||||
* so that's what we're going to use. |
||||
* |
||||
* HOWEVER, because of a bug in the controller, for DDR |
||||
* we need to set this to be the same as the value |
||||
* calculated for bwt2rwp. |
||||
*/ |
||||
cfg_value |= CFG1_SWT2RWP ((type == TYPE_DDR) ? 7 : 2); |
||||
|
||||
/* Set the Read CAS latency. We're going to use a CL of
|
||||
* 2 for DDR and SDR. |
||||
*/ |
||||
cfg_value |= CFG1_RLATENCY ((type == TYPE_DDR) ? 7 : 2); |
||||
|
||||
|
||||
/* Set the Active to Read/Write delay. This depends
|
||||
* on Trcd which is reported as nanoseconds times 4. |
||||
* We want to calculate Trcd (in nanoseconds) times XLB clock (in Hz) |
||||
* which gives us a dimensionless quantity. Play games with |
||||
* the divisions so we don't run out of dynamic ranges. |
||||
*/ |
||||
/* account for megaherz and the times 4 */ |
||||
temp = (Trcd * (gd->bus_clk / 1000000)) / 4; |
||||
|
||||
/* account for nanoseconds and round up, with a minimum value of 2 */ |
||||
temp = ((temp + 999) / 1000) - 1; |
||||
if (temp < 2) |
||||
temp = 2; |
||||
|
||||
cfg_value |= CFG1_ACT2WR (temp); |
||||
|
||||
/* Set the precharge to active delay. This depends
|
||||
* on Trp which is reported as nanoseconds times 4. |
||||
* We want to calculate Trp (in nanoseconds) times XLB clock (in Hz) |
||||
* which gives us a dimensionless quantity. Play games with |
||||
* the divisions so we don't run out of dynamic ranges. |
||||
*/ |
||||
/* account for megaherz and the times 4 */ |
||||
temp = (Trp * (gd->bus_clk / 1000000)) / 4; |
||||
|
||||
/* account for nanoseconds and round up, then subtract 1, with a
|
||||
* minumum value of 1 and a maximum value of 7. |
||||
*/ |
||||
temp = (((temp + 999) / 1000) - 1) & 7; |
||||
if (temp < 1) |
||||
temp = 1; |
||||
|
||||
cfg_value |= CFG1_PRE2ACT (temp); |
||||
|
||||
/* Set refresh to active delay. This depends
|
||||
* on Trfc which is not reported in the SPD. |
||||
* We'll use a nominal value of 75nsec which is |
||||
* what the controller spec uses. |
||||
*/ |
||||
temp = (75 * (gd->bus_clk / 1000000)); |
||||
/* account for nanoseconds and round up, then subtract 1 */ |
||||
cfg_value |= CFG1_REF2ACT (((temp + 999) / 1000) - 1); |
||||
|
||||
/* Set the write latency, using the values given in the controller spec */ |
||||
cfg_value |= CFG1_WLATENCY ((type == TYPE_DDR) ? 3 : 0); |
||||
memctl->cfg1 = cfg_value; /* cfg 1 */ |
||||
asm volatile ("sync"); |
||||
|
||||
|
||||
/* ********************** Cfg 2 ************************* */ |
||||
|
||||
/* Set the burst read to read/precharge delay */ |
||||
cfg_value = CFG2_BRD2RP ((type == TYPE_DDR) ? 5 : 8); |
||||
|
||||
/* Set the burst write to read/precharge delay. Semi-magic numbers
|
||||
* based on the controller spec recommendations, assuming tWR is |
||||
* two clock cycles. |
||||
*/ |
||||
cfg_value |= CFG2_BWT2RWP ((type == TYPE_DDR) ? 7 : 10); |
||||
|
||||
/* Set the Burst read to write delay. Semi-magic numbers
|
||||
* based on the DRAM controller documentation. |
||||
*/ |
||||
cfg_value |= CFG2_BRD2WT ((type == TYPE_DDR) ? 7 : 0xb); |
||||
|
||||
/* Set the burst length -- must be 8!! Well, 7, actually, becuase
|
||||
* it's burst lenght minus 1. |
||||
*/ |
||||
cfg_value |= CFG2_BURSTLEN (7); |
||||
memctl->cfg2 = cfg_value; /* cfg 2 */ |
||||
asm volatile ("sync"); |
||||
|
||||
|
||||
/* ********************** mode ************************* */ |
||||
|
||||
/* Set enable bit, CKE high/low bits, and the DDR/SDR mode bit,
|
||||
* disable automatic refresh. |
||||
*/ |
||||
cfg_value = CTL_MODE_ENABLE | CTL_CKE_HIGH | |
||||
((type == TYPE_DDR) ? CTL_DDR_MODE : 0); |
||||
|
||||
/* Set the address mux based on whichever setting(s) is/are common
|
||||
* to all the devices we have. If there is more than one, choose |
||||
* one arbitrarily. |
||||
*/ |
||||
if (muxmask & 0x4) |
||||
cfg_value |= CTL_ADDRMUX (2); |
||||
else if (muxmask & 0x2) |
||||
cfg_value |= CTL_ADDRMUX (1); |
||||
else |
||||
cfg_value |= CTL_ADDRMUX (0); |
||||
|
||||
/* Set the refresh interval. */ |
||||
temp = ((refresh * (gd->bus_clk / 1000000)) / (1000 * 64)) - 1; |
||||
cfg_value |= CTL_REFRESH_INTERVAL (temp); |
||||
|
||||
/* Set buffered/non-buffered memory */ |
||||
if (buffered) |
||||
cfg_value |= CTL_BUFFERED; |
||||
|
||||
memctl->ctrl = cfg_value; /* ctrl */ |
||||
asm volatile ("sync"); |
||||
|
||||
if (type == TYPE_DDR) { |
||||
/* issue precharge all */ |
||||
temp = cfg_value | CTL_PRECHARGE_CMD; |
||||
memctl->ctrl = temp; /* ctrl */ |
||||
asm volatile ("sync"); |
||||
} |
||||
|
||||
|
||||
/* Set up mode value for CAS latency == 2 */ |
||||
mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) | |
||||
MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2) | MODE_CMD); |
||||
|
||||
asm volatile ("sync"); |
||||
|
||||
/* Write Extended Mode - enable DLL */ |
||||
if (type == TYPE_DDR) { |
||||
temp = MODE_EXTENDED | MODE_X_DLL_ENABLE | |
||||
MODE_X_DS_NORMAL | MODE_CMD; |
||||
memctl->mode = (temp >> 16); /* mode */ |
||||
asm volatile ("sync"); |
||||
|
||||
/* Write Mode - reset DLL, set CAS latency == 2 */ |
||||
temp = mode_value | MODE_OPMODE (MODE_OPMODE_RESETDLL); |
||||
memctl->mode = (temp >> 16); /* mode */ |
||||
asm volatile ("sync"); |
||||
} |
||||
|
||||
/* Program the chip selects. */ |
||||
for (banknum = 0; banknum < TOTAL_BANK; banknum++) { |
||||
if (DramInfo[banknum].size != 0) { |
||||
u32 mask; |
||||
int i; |
||||
|
||||
for (i = 0, mask = 1; i < 32; mask <<= 1, i++) { |
||||
if (DramInfo[banknum].size & mask) |
||||
break; |
||||
} |
||||
temp = (DramInfo[banknum].base & 0xfff00000) | (i - |
||||
1); |
||||
|
||||
sysconf->cscfg[banknum] = temp; |
||||
asm volatile ("sync"); |
||||
} |
||||
} |
||||
|
||||
/* Wait for DLL lock */ |
||||
udelay (200); |
||||
|
||||
temp = cfg_value | CTL_PRECHARGE_CMD; /* issue precharge all */ |
||||
memctl->ctrl = temp; /* ctrl */ |
||||
asm volatile ("sync"); |
||||
|
||||
temp = cfg_value | CTL_REFRESH_CMD; /* issue precharge all */ |
||||
memctl->ctrl = temp; /* ctrl */ |
||||
asm volatile ("sync"); |
||||
|
||||
memctl->ctrl = temp; /* ctrl */ |
||||
asm volatile ("sync"); |
||||
|
||||
/* Write Mode - DLL normal */ |
||||
temp = mode_value | MODE_OPMODE (MODE_OPMODE_NORMAL); |
||||
memctl->mode = (temp >> 16); /* mode */ |
||||
asm volatile ("sync"); |
||||
|
||||
/* Enable refresh, enable DQS's (if DDR), and lock the control register */ |
||||
cfg_value &= ~CTL_MODE_ENABLE; /* lock register */ |
||||
cfg_value |= CTL_REFRESH_ENABLE; /* enable refresh */ |
||||
|
||||
if (type == TYPE_DDR) |
||||
cfg_value |= CTL_DQSOEN (0xf); /* enable DQS's for DDR */ |
||||
|
||||
memctl->ctrl = cfg_value; /* ctrl */ |
||||
asm volatile ("sync"); |
||||
|
||||
return size; |
||||
} |
@ -0,0 +1,108 @@ |
||||
/*
|
||||
* dramSetup.h |
||||
* |
||||
* Prototypes, etc. for the Motorola MPC8220 |
||||
* embedded cpu chips |
||||
* |
||||
* 2004 (c) Freescale, Inc. |
||||
* Author: TsiChung Liew <Tsi-Chung.Liew@freescale.com> |
||||
* |
||||
* 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 |
||||
*/ |
||||
#ifndef __INCdramsetuph |
||||
#define __INCdramsetuph |
||||
#ifndef __ASSEMBLY__ |
||||
/* Where various things are in the SPD */ |
||||
#define LOC_TYPE 2 |
||||
#define LOC_CHECKSUM 63 |
||||
#define LOC_PHYS_BANKS 5 |
||||
#define LOC_LOGICAL_BANKS 17 |
||||
#define LOC_ROWS 3 |
||||
#define LOC_COLS 4 |
||||
#define LOC_WIDTH_HIGH 7 |
||||
#define LOC_WIDTH_LOW 6 |
||||
#define LOC_REFRESH 12 |
||||
#define LOC_BURSTS 16 |
||||
#define LOC_CAS 18 |
||||
#define LOC_CS 19 |
||||
#define LOC_WE 20 |
||||
#define LOC_Tcyc 9 |
||||
#define LOC_Tac 10 |
||||
#define LOC_Trp 27 |
||||
#define LOC_Trrd 28 |
||||
#define LOC_Trcd 29 |
||||
#define LOC_Tras 30 |
||||
#define LOC_Buffered 21 |
||||
/* Types of memory the SPD can tell us about.
|
||||
* We can actually only use SDRAM and DDR. |
||||
*/ |
||||
#define TYPE_DRAM 1 /* plain old dram */ |
||||
#define TYPE_EDO 2 /* EDO dram */ |
||||
#define TYPE_Nibble 3 /* serial nibble memory */ |
||||
#define TYPE_SDR 4 /* SDRAM */ |
||||
#define TYPE_ROM 5 /* */ |
||||
#define TYPE_SGRRAM 6 /* graphics memory */ |
||||
#define TYPE_DDR 7 /* DDR sdram */ |
||||
#define SDRAMDS_MASK 0x3 /* each field is 2 bits wide */ |
||||
#define SDRAMDS_SBE_SHIFT 8 /* Clock enable drive strength */ |
||||
#define SDRAMDS_SBC_SHIFT 6 /* Clocks drive strength */ |
||||
#define SDRAMDS_SBA_SHIFT 4 /* Address drive strength */ |
||||
#define SDRAMDS_SBS_SHIFT 2 /* SDR DQS drive strength */ |
||||
#define SDRAMDS_SBD_SHIFT 0 /* Data and DQS drive strength */ |
||||
#define DRIVE_STRENGTH_HIGH 0 |
||||
#define DRIVE_STRENGTH_MED 1 |
||||
#define DRIVE_STRENGTH_LOW 2 |
||||
#define DRIVE_STRENGTH_OFF 3 |
||||
|
||||
#define OK 0 |
||||
#define ERROR -1 |
||||
/* Structure to hold information about address muxing. */ |
||||
typedef struct tagMuxDescriptor { |
||||
u8 MuxValue; |
||||
u8 Columns; |
||||
u8 Rows; |
||||
u8 MoreColumns; |
||||
} muxdesc_t; |
||||
|
||||
/* Structure to define one physical bank of
|
||||
* memory. Note that dram size in bytes is |
||||
* (2^^(rows+columns)) * width * banks / 8 |
||||
*/ |
||||
typedef struct tagDramInfo { |
||||
u32 size; /* size in bytes */ |
||||
u32 base; /* base address */ |
||||
u8 ordinal; /* where in the memory map will we put this */ |
||||
u8 type; |
||||
u8 rows; |
||||
u8 cols; |
||||
u16 width; /* width of each chip in bits */ |
||||
u8 banks; /* number of chips, aka logical banks */ |
||||
u8 bursts; /* bit-encoded allowable burst length */ |
||||
u8 CAS; /* bit-encoded CAS latency values */ |
||||
u8 CS; /* bit-encoded CS latency values */ |
||||
u8 WE; /* bit-encoded WE latency values */ |
||||
u8 Trp; /* bit-encoded row precharge time */ |
||||
u8 Trcd; /* bit-encoded RAS to CAS delay */ |
||||
u8 buffered; /* buffered or not */ |
||||
u8 refresh; /* encoded refresh rate */ |
||||
} draminfo_t; |
||||
|
||||
#endif /* __ASSEMBLY__ */ |
||||
|
||||
#endif /* __INCdramsetuph */ |
@ -0,0 +1,993 @@ |
||||
/*
|
||||
* (C) Copyright 2003 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* This file is based on mpc4200fec.c, |
||||
* (C) Copyright Motorola, Inc., 2000 |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
#include <malloc.h> |
||||
#include <net.h> |
||||
#include <miiphy.h> |
||||
#include "dma.h" |
||||
#include "fec.h" |
||||
|
||||
#define DEBUG 0 |
||||
/*tbd - rtm */ |
||||
/*#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
|
||||
defined(CONFIG_MPC8220_FEC)*/ |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NET) |
||||
|
||||
#if (DEBUG & 0x60) |
||||
static void tfifo_print (mpc8220_fec_priv * fec); |
||||
static void rfifo_print (mpc8220_fec_priv * fec); |
||||
#endif /* DEBUG */ |
||||
|
||||
#if (DEBUG & 0x40) |
||||
static u32 local_crc32 (char *string, unsigned int crc_value, int len); |
||||
#endif |
||||
|
||||
typedef struct { |
||||
u8 data[1500]; /* actual data */ |
||||
int length; /* actual length */ |
||||
int used; /* buffer in use or not */ |
||||
u8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */ |
||||
} NBUF; |
||||
|
||||
/********************************************************************/ |
||||
#if (DEBUG & 0x2) |
||||
static void mpc8220_fec_phydump (void) |
||||
{ |
||||
u16 phyStatus, i; |
||||
u8 phyAddr = CONFIG_PHY_ADDR; |
||||
u8 reg_mask[] = { |
||||
#if CONFIG_PHY_TYPE == 0x79c874 /* AMD Am79C874 */ |
||||
/* regs to print: 0...7, 16...19, 21, 23, 24 */ |
||||
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, |
||||
#else |
||||
/* regs to print: 0...8, 16...20 */ |
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, |
||||
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
#endif |
||||
}; |
||||
|
||||
for (i = 0; i < 32; i++) { |
||||
if (reg_mask[i]) { |
||||
miiphy_read (phyAddr, i, &phyStatus); |
||||
printf ("Mii reg %d: 0x%04x\n", i, phyStatus); |
||||
} |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
/********************************************************************/ |
||||
static int mpc8220_fec_rbd_init (mpc8220_fec_priv * fec) |
||||
{ |
||||
int ix; |
||||
char *data; |
||||
static int once = 0; |
||||
|
||||
for (ix = 0; ix < FEC_RBD_NUM; ix++) { |
||||
if (!once) { |
||||
data = (char *) malloc (FEC_MAX_PKT_SIZE); |
||||
if (data == NULL) { |
||||
printf ("RBD INIT FAILED\n"); |
||||
return -1; |
||||
} |
||||
fec->rbdBase[ix].dataPointer = (u32) data; |
||||
} |
||||
fec->rbdBase[ix].status = FEC_RBD_EMPTY; |
||||
fec->rbdBase[ix].dataLength = 0; |
||||
} |
||||
once++; |
||||
|
||||
/*
|
||||
* have the last RBD to close the ring |
||||
*/ |
||||
fec->rbdBase[ix - 1].status |= FEC_RBD_WRAP; |
||||
fec->rbdIndex = 0; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc8220_fec_tbd_init (mpc8220_fec_priv * fec) |
||||
{ |
||||
int ix; |
||||
|
||||
for (ix = 0; ix < FEC_TBD_NUM; ix++) { |
||||
fec->tbdBase[ix].status = 0; |
||||
} |
||||
|
||||
/*
|
||||
* Have the last TBD to close the ring |
||||
*/ |
||||
fec->tbdBase[ix - 1].status |= FEC_TBD_WRAP; |
||||
|
||||
/*
|
||||
* Initialize some indices |
||||
*/ |
||||
fec->tbdIndex = 0; |
||||
fec->usedTbdIndex = 0; |
||||
fec->cleanTbdNum = FEC_TBD_NUM; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc8220_fec_rbd_clean (mpc8220_fec_priv * fec, FEC_RBD * pRbd) |
||||
{ |
||||
/*
|
||||
* Reset buffer descriptor as empty |
||||
*/ |
||||
if ((fec->rbdIndex) == (FEC_RBD_NUM - 1)) |
||||
pRbd->status = (FEC_RBD_WRAP | FEC_RBD_EMPTY); |
||||
else |
||||
pRbd->status = FEC_RBD_EMPTY; |
||||
|
||||
pRbd->dataLength = 0; |
||||
|
||||
/*
|
||||
* Now, we have an empty RxBD, restart the SmartDMA receive task |
||||
*/ |
||||
DMA_TASK_ENABLE (FEC_RECV_TASK_NO); |
||||
|
||||
/*
|
||||
* Increment BD count |
||||
*/ |
||||
fec->rbdIndex = (fec->rbdIndex + 1) % FEC_RBD_NUM; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc8220_fec_tbd_scrub (mpc8220_fec_priv * fec) |
||||
{ |
||||
FEC_TBD *pUsedTbd; |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("tbd_scrub: fec->cleanTbdNum = %d, fec->usedTbdIndex = %d\n", |
||||
fec->cleanTbdNum, fec->usedTbdIndex); |
||||
#endif |
||||
|
||||
/*
|
||||
* process all the consumed TBDs |
||||
*/ |
||||
while (fec->cleanTbdNum < FEC_TBD_NUM) { |
||||
pUsedTbd = &fec->tbdBase[fec->usedTbdIndex]; |
||||
if (pUsedTbd->status & FEC_TBD_READY) { |
||||
#if (DEBUG & 0x20) |
||||
printf ("Cannot clean TBD %d, in use\n", |
||||
fec->cleanTbdNum); |
||||
#endif |
||||
return; |
||||
} |
||||
|
||||
/*
|
||||
* clean this buffer descriptor |
||||
*/ |
||||
if (fec->usedTbdIndex == (FEC_TBD_NUM - 1)) |
||||
pUsedTbd->status = FEC_TBD_WRAP; |
||||
else |
||||
pUsedTbd->status = 0; |
||||
|
||||
/*
|
||||
* update some indeces for a correct handling of the TBD ring |
||||
*/ |
||||
fec->cleanTbdNum++; |
||||
fec->usedTbdIndex = (fec->usedTbdIndex + 1) % FEC_TBD_NUM; |
||||
} |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc8220_fec_set_hwaddr (mpc8220_fec_priv * fec, char *mac) |
||||
{ |
||||
u8 currByte; /* byte for which to compute the CRC */ |
||||
int byte; /* loop - counter */ |
||||
int bit; /* loop - counter */ |
||||
u32 crc = 0xffffffff; /* initial value */ |
||||
|
||||
/*
|
||||
* The algorithm used is the following: |
||||
* we loop on each of the six bytes of the provided address, |
||||
* and we compute the CRC by left-shifting the previous |
||||
* value by one position, so that each bit in the current |
||||
* byte of the address may contribute the calculation. If |
||||
* the latter and the MSB in the CRC are different, then |
||||
* the CRC value so computed is also ex-ored with the |
||||
* "polynomium generator". The current byte of the address |
||||
* is also shifted right by one bit at each iteration. |
||||
* This is because the CRC generatore in hardware is implemented |
||||
* as a shift-register with as many ex-ores as the radixes |
||||
* in the polynomium. This suggests that we represent the |
||||
* polynomiumm itself as a 32-bit constant. |
||||
*/ |
||||
for (byte = 0; byte < 6; byte++) { |
||||
currByte = mac[byte]; |
||||
for (bit = 0; bit < 8; bit++) { |
||||
if ((currByte & 0x01) ^ (crc & 0x01)) { |
||||
crc >>= 1; |
||||
crc = crc ^ 0xedb88320; |
||||
} else { |
||||
crc >>= 1; |
||||
} |
||||
currByte >>= 1; |
||||
} |
||||
} |
||||
|
||||
crc = crc >> 26; |
||||
|
||||
/*
|
||||
* Set individual hash table register |
||||
*/ |
||||
if (crc >= 32) { |
||||
fec->eth->iaddr1 = (1 << (crc - 32)); |
||||
fec->eth->iaddr2 = 0; |
||||
} else { |
||||
fec->eth->iaddr1 = 0; |
||||
fec->eth->iaddr2 = (1 << crc); |
||||
} |
||||
|
||||
/*
|
||||
* Set physical address |
||||
*/ |
||||
fec->eth->paddr1 = |
||||
(mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3]; |
||||
fec->eth->paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static int mpc8220_fec_init (struct eth_device *dev, bd_t * bis) |
||||
{ |
||||
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv; |
||||
struct mpc8220_dma *dma = (struct mpc8220_dma *) MMAP_DMA; |
||||
const u8 phyAddr = CONFIG_PHY_ADDR; /* Only one PHY */ |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("mpc8220_fec_init... Begin\n"); |
||||
#endif |
||||
|
||||
/*
|
||||
* Initialize RxBD/TxBD rings |
||||
*/ |
||||
mpc8220_fec_rbd_init (fec); |
||||
mpc8220_fec_tbd_init (fec); |
||||
|
||||
/*
|
||||
* Set up Pin Muxing for FEC 1 |
||||
*/ |
||||
*(vu_long *) MMAP_PCFG = 0; |
||||
*(vu_long *) (MMAP_PCFG + 4) = 0; |
||||
/*
|
||||
* Clear FEC-Lite interrupt event register(IEVENT) |
||||
*/ |
||||
fec->eth->ievent = 0xffffffff; |
||||
|
||||
/*
|
||||
* Set interrupt mask register |
||||
*/ |
||||
fec->eth->imask = 0x00000000; |
||||
|
||||
/*
|
||||
* Set FEC-Lite receive control register(R_CNTRL): |
||||
*/ |
||||
if (fec->xcv_type == SEVENWIRE) { |
||||
/*
|
||||
* Frame length=1518; 7-wire mode |
||||
*/ |
||||
fec->eth->r_cntrl = 0x05ee0020; /*0x05ee0000;FIXME */ |
||||
} else { |
||||
/*
|
||||
* Frame length=1518; MII mode; |
||||
*/ |
||||
fec->eth->r_cntrl = 0x05ee0024; /*0x05ee0004;FIXME */ |
||||
} |
||||
|
||||
fec->eth->x_cntrl = 0x00000000; /* half-duplex, heartbeat disabled */ |
||||
if (fec->xcv_type != SEVENWIRE) { |
||||
/*
|
||||
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock |
||||
* and do not drop the Preamble. |
||||
*/ |
||||
/* tbd - rtm */ |
||||
/*fec->eth->mii_speed = (((gd->ipb_clk >> 20) / 5) << 1); */ |
||||
/* No MII for 7-wire mode */ |
||||
fec->eth->mii_speed = 0x00000030; |
||||
} |
||||
|
||||
/*
|
||||
* Set Opcode/Pause Duration Register |
||||
*/ |
||||
fec->eth->op_pause = 0x00010020; /*FIXME0xffff0020; */ |
||||
|
||||
/*
|
||||
* Set Rx FIFO alarm and granularity value |
||||
*/ |
||||
fec->eth->rfifo_cntrl = 0x0c000000; |
||||
fec->eth->rfifo_alarm = 0x0000030c; |
||||
#if (DEBUG & 0x22) |
||||
if (fec->eth->rfifo_status & 0x00700000) { |
||||
printf ("mpc8220_fec_init() RFIFO error\n"); |
||||
} |
||||
#endif |
||||
|
||||
/*
|
||||
* Set Tx FIFO granularity value |
||||
*/ |
||||
/*fec->eth->tfifo_cntrl = 0x0c000000; */ /*tbd - rtm */ |
||||
fec->eth->tfifo_cntrl = 0x0e000000; |
||||
#if (DEBUG & 0x2) |
||||
printf ("tfifo_status: 0x%08x\n", fec->eth->tfifo_status); |
||||
printf ("tfifo_alarm: 0x%08x\n", fec->eth->tfifo_alarm); |
||||
#endif |
||||
|
||||
/*
|
||||
* Set transmit fifo watermark register(X_WMRK), default = 64 |
||||
*/ |
||||
fec->eth->tfifo_alarm = 0x00000080; |
||||
fec->eth->x_wmrk = 0x2; |
||||
|
||||
/*
|
||||
* Set individual address filter for unicast address |
||||
* and set physical address registers. |
||||
*/ |
||||
mpc8220_fec_set_hwaddr (fec, dev->enetaddr); |
||||
|
||||
/*
|
||||
* Set multicast address filter |
||||
*/ |
||||
fec->eth->gaddr1 = 0x00000000; |
||||
fec->eth->gaddr2 = 0x00000000; |
||||
|
||||
/*
|
||||
* Turn ON cheater FSM: ???? |
||||
*/ |
||||
fec->eth->xmit_fsm = 0x03000000; |
||||
|
||||
#if 1 |
||||
/*#if defined(CONFIG_MPC5200)*/ |
||||
/*
|
||||
* Turn off COMM bus prefetch in the MGT5200 BestComm. It doesn't |
||||
* work w/ the current receive task. |
||||
*/ |
||||
dma->PtdCntrl |= 0x00000001; |
||||
#endif |
||||
|
||||
/*
|
||||
* Set priority of different initiators |
||||
*/ |
||||
dma->IPR0 = 7; /* always */ |
||||
dma->IPR3 = 6; /* Eth RX */ |
||||
dma->IPR4 = 5; /* Eth Tx */ |
||||
|
||||
/*
|
||||
* Clear SmartDMA task interrupt pending bits |
||||
*/ |
||||
DMA_CLEAR_IEVENT (FEC_RECV_TASK_NO); |
||||
|
||||
/*
|
||||
* Initialize SmartDMA parameters stored in SRAM |
||||
*/ |
||||
*(int *) FEC_TBD_BASE = (int) fec->tbdBase; |
||||
*(int *) FEC_RBD_BASE = (int) fec->rbdBase; |
||||
*(int *) FEC_TBD_NEXT = (int) fec->tbdBase; |
||||
*(int *) FEC_RBD_NEXT = (int) fec->rbdBase; |
||||
|
||||
if (fec->xcv_type != SEVENWIRE) { |
||||
/*
|
||||
* Initialize PHY(LXT971A): |
||||
* |
||||
* Generally, on power up, the LXT971A reads its configuration |
||||
* pins to check for forced operation, If not cofigured for |
||||
* forced operation, it uses auto-negotiation/parallel detection |
||||
* to automatically determine line operating conditions. |
||||
* If the PHY device on the other side of the link supports |
||||
* auto-negotiation, the LXT971A auto-negotiates with it |
||||
* using Fast Link Pulse(FLP) Bursts. If the PHY partner does not |
||||
* support auto-negotiation, the LXT971A automatically detects |
||||
* the presence of either link pulses(10Mbps PHY) or Idle |
||||
* symbols(100Mbps) and sets its operating conditions accordingly. |
||||
* |
||||
* When auto-negotiation is controlled by software, the following |
||||
* steps are recommended. |
||||
* |
||||
* Note: |
||||
* The physical address is dependent on hardware configuration. |
||||
* |
||||
*/ |
||||
int timeout = 1; |
||||
u16 phyStatus; |
||||
|
||||
/*
|
||||
* Reset PHY, then delay 300ns |
||||
*/ |
||||
miiphy_write (phyAddr, 0x0, 0x8000); |
||||
udelay (1000); |
||||
|
||||
if (fec->xcv_type == MII10) { |
||||
/*
|
||||
* Force 10Base-T, FDX operation |
||||
*/ |
||||
#if (DEBUG & 0x2) |
||||
printf ("Forcing 10 Mbps ethernet link... "); |
||||
#endif |
||||
miiphy_read (phyAddr, 0x1, &phyStatus); |
||||
/*
|
||||
miiphy_write(fec, phyAddr, 0x0, 0x0100); |
||||
*/ |
||||
miiphy_write (phyAddr, 0x0, 0x0180); |
||||
|
||||
timeout = 20; |
||||
do { /* wait for link status to go down */ |
||||
udelay (10000); |
||||
if ((timeout--) == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("hmmm, should not have waited..."); |
||||
#endif |
||||
break; |
||||
} |
||||
miiphy_read (phyAddr, 0x1, &phyStatus); |
||||
#if (DEBUG & 0x2) |
||||
printf ("="); |
||||
#endif |
||||
} while ((phyStatus & 0x0004)); /* !link up */ |
||||
|
||||
timeout = 1000; |
||||
do { /* wait for link status to come back up */ |
||||
udelay (10000); |
||||
if ((timeout--) == 0) { |
||||
printf ("failed. Link is down.\n"); |
||||
break; |
||||
} |
||||
miiphy_read (phyAddr, 0x1, &phyStatus); |
||||
#if (DEBUG & 0x2) |
||||
printf ("+"); |
||||
#endif |
||||
} while (!(phyStatus & 0x0004)); /* !link up */ |
||||
|
||||
#if (DEBUG & 0x2) |
||||
printf ("done.\n"); |
||||
#endif |
||||
} else { /* MII100 */ |
||||
/*
|
||||
* Set the auto-negotiation advertisement register bits |
||||
*/ |
||||
miiphy_write (phyAddr, 0x4, 0x01e1); |
||||
|
||||
/*
|
||||
* Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation |
||||
*/ |
||||
miiphy_write (phyAddr, 0x0, 0x1200); |
||||
|
||||
/*
|
||||
* Wait for AN completion |
||||
*/ |
||||
timeout = 5000; |
||||
do { |
||||
udelay (1000); |
||||
|
||||
if ((timeout--) == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("PHY auto neg 0 failed...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
if (miiphy_read (phyAddr, 0x1, &phyStatus) != |
||||
0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("PHY auto neg 1 failed 0x%04x...\n", phyStatus); |
||||
#endif |
||||
return -1; |
||||
} |
||||
} while (!(phyStatus & 0x0004)); |
||||
|
||||
#if (DEBUG & 0x2) |
||||
printf ("PHY auto neg complete! \n"); |
||||
#endif |
||||
} |
||||
|
||||
} |
||||
|
||||
/*
|
||||
* Enable FEC-Lite controller |
||||
*/ |
||||
fec->eth->ecntrl |= 0x00000006; |
||||
|
||||
#if (DEBUG & 0x2) |
||||
if (fec->xcv_type != SEVENWIRE) |
||||
mpc8220_fec_phydump (); |
||||
#endif |
||||
|
||||
/*
|
||||
* Enable SmartDMA receive task |
||||
*/ |
||||
DMA_TASK_ENABLE (FEC_RECV_TASK_NO); |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("mpc8220_fec_init... Done \n"); |
||||
#endif |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
static void mpc8220_fec_halt (struct eth_device *dev) |
||||
{ |
||||
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv; |
||||
int counter = 0xffff; |
||||
|
||||
#if (DEBUG & 0x2) |
||||
if (fec->xcv_type != SEVENWIRE) |
||||
mpc8220_fec_phydump (); |
||||
#endif |
||||
|
||||
/*
|
||||
* mask FEC chip interrupts |
||||
*/ |
||||
fec->eth->imask = 0; |
||||
|
||||
/*
|
||||
* issue graceful stop command to the FEC transmitter if necessary |
||||
*/ |
||||
fec->eth->x_cntrl |= 0x00000001; |
||||
|
||||
/*
|
||||
* wait for graceful stop to register |
||||
*/ |
||||
while ((counter--) && (!(fec->eth->ievent & 0x10000000))); |
||||
|
||||
/*
|
||||
* Disable SmartDMA tasks |
||||
*/ |
||||
DMA_TASK_DISABLE (FEC_XMIT_TASK_NO); |
||||
DMA_TASK_DISABLE (FEC_RECV_TASK_NO); |
||||
|
||||
/*
|
||||
* Disable the Ethernet Controller |
||||
*/ |
||||
fec->eth->ecntrl &= 0xfffffffd; |
||||
|
||||
/*
|
||||
* Clear FIFO status registers |
||||
*/ |
||||
fec->eth->rfifo_status &= 0x00700000; |
||||
fec->eth->tfifo_status &= 0x00700000; |
||||
|
||||
fec->eth->reset_cntrl = 0x01000000; |
||||
|
||||
/*
|
||||
* Issue a reset command to the FEC chip |
||||
*/ |
||||
fec->eth->ecntrl |= 0x1; |
||||
|
||||
/*
|
||||
* wait at least 16 clock cycles |
||||
*/ |
||||
udelay (10); |
||||
|
||||
#if (DEBUG & 0x3) |
||||
printf ("Ethernet task stopped\n"); |
||||
#endif |
||||
} |
||||
|
||||
#if (DEBUG & 0x60) |
||||
/********************************************************************/ |
||||
|
||||
static void tfifo_print (mpc8220_fec_priv * fec) |
||||
{ |
||||
u16 phyAddr = CONFIG_PHY_ADDR; |
||||
u16 phyStatus; |
||||
|
||||
if ((fec->eth->tfifo_lrf_ptr != fec->eth->tfifo_lwf_ptr) |
||||
|| (fec->eth->tfifo_rdptr != fec->eth->tfifo_wrptr)) { |
||||
|
||||
miiphy_read (phyAddr, 0x1, &phyStatus); |
||||
printf ("\nphyStatus: 0x%04x\n", phyStatus); |
||||
printf ("ecntrl: 0x%08x\n", fec->eth->ecntrl); |
||||
printf ("ievent: 0x%08x\n", fec->eth->ievent); |
||||
printf ("x_status: 0x%08x\n", fec->eth->x_status); |
||||
printf ("tfifo: status 0x%08x\n", fec->eth->tfifo_status); |
||||
|
||||
printf (" control 0x%08x\n", fec->eth->tfifo_cntrl); |
||||
printf (" lrfp 0x%08x\n", fec->eth->tfifo_lrf_ptr); |
||||
printf (" lwfp 0x%08x\n", fec->eth->tfifo_lwf_ptr); |
||||
printf (" alarm 0x%08x\n", fec->eth->tfifo_alarm); |
||||
printf (" readptr 0x%08x\n", fec->eth->tfifo_rdptr); |
||||
printf (" writptr 0x%08x\n", fec->eth->tfifo_wrptr); |
||||
} |
||||
} |
||||
|
||||
static void rfifo_print (mpc8220_fec_priv * fec) |
||||
{ |
||||
u16 phyAddr = CONFIG_PHY_ADDR; |
||||
u16 phyStatus; |
||||
|
||||
if ((fec->eth->rfifo_lrf_ptr != fec->eth->rfifo_lwf_ptr) |
||||
|| (fec->eth->rfifo_rdptr != fec->eth->rfifo_wrptr)) { |
||||
|
||||
miiphy_read (phyAddr, 0x1, &phyStatus); |
||||
printf ("\nphyStatus: 0x%04x\n", phyStatus); |
||||
printf ("ecntrl: 0x%08x\n", fec->eth->ecntrl); |
||||
printf ("ievent: 0x%08x\n", fec->eth->ievent); |
||||
printf ("x_status: 0x%08x\n", fec->eth->x_status); |
||||
printf ("rfifo: status 0x%08x\n", fec->eth->rfifo_status); |
||||
|
||||
printf (" control 0x%08x\n", fec->eth->rfifo_cntrl); |
||||
printf (" lrfp 0x%08x\n", fec->eth->rfifo_lrf_ptr); |
||||
printf (" lwfp 0x%08x\n", fec->eth->rfifo_lwf_ptr); |
||||
printf (" alarm 0x%08x\n", fec->eth->rfifo_alarm); |
||||
printf (" readptr 0x%08x\n", fec->eth->rfifo_rdptr); |
||||
printf (" writptr 0x%08x\n", fec->eth->rfifo_wrptr); |
||||
} |
||||
} |
||||
#endif /* DEBUG */ |
||||
|
||||
/********************************************************************/ |
||||
|
||||
static int mpc8220_fec_send (struct eth_device *dev, volatile void *eth_data, |
||||
int data_length) |
||||
{ |
||||
/*
|
||||
* This routine transmits one frame. This routine only accepts |
||||
* 6-byte Ethernet addresses. |
||||
*/ |
||||
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv; |
||||
FEC_TBD *pTbd; |
||||
|
||||
#if (DEBUG & 0x20) |
||||
printf ("tbd status: 0x%04x\n", fec->tbdBase[0].status); |
||||
tfifo_print (fec); |
||||
#endif |
||||
|
||||
/*
|
||||
* Clear Tx BD ring at first |
||||
*/ |
||||
mpc8220_fec_tbd_scrub (fec); |
||||
|
||||
/*
|
||||
* Check for valid length of data. |
||||
*/ |
||||
if ((data_length > 1500) || (data_length <= 0)) { |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* Check the number of vacant TxBDs. |
||||
*/ |
||||
if (fec->cleanTbdNum < 1) { |
||||
#if (DEBUG & 0x20) |
||||
printf ("No available TxBDs ...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* Get the first TxBD to send the mac header |
||||
*/ |
||||
pTbd = &fec->tbdBase[fec->tbdIndex]; |
||||
pTbd->dataLength = data_length; |
||||
pTbd->dataPointer = (u32) eth_data; |
||||
pTbd->status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY; |
||||
fec->tbdIndex = (fec->tbdIndex + 1) % FEC_TBD_NUM; |
||||
|
||||
#if (DEBUG & 0x100) |
||||
printf ("DMA_TASK_ENABLE, fec->tbdIndex = %d \n", fec->tbdIndex); |
||||
#endif |
||||
|
||||
/*
|
||||
* Kick the MII i/f |
||||
*/ |
||||
if (fec->xcv_type != SEVENWIRE) { |
||||
u16 phyStatus; |
||||
|
||||
miiphy_read (0, 0x1, &phyStatus); |
||||
} |
||||
|
||||
/*
|
||||
* Enable SmartDMA transmit task |
||||
*/ |
||||
|
||||
#if (DEBUG & 0x20) |
||||
tfifo_print (fec); |
||||
#endif |
||||
|
||||
DMA_TASK_ENABLE (FEC_XMIT_TASK_NO); |
||||
|
||||
#if (DEBUG & 0x20) |
||||
tfifo_print (fec); |
||||
#endif |
||||
|
||||
#if (DEBUG & 0x8) |
||||
printf ("+"); |
||||
#endif |
||||
|
||||
fec->cleanTbdNum -= 1; |
||||
|
||||
#if (DEBUG & 0x129) && (DEBUG & 0x80000000) |
||||
printf ("smartDMA ethernet Tx task enabled\n"); |
||||
#endif |
||||
/*
|
||||
* wait until frame is sent . |
||||
*/ |
||||
while (pTbd->status & FEC_TBD_READY) { |
||||
udelay (10); |
||||
#if (DEBUG & 0x8) |
||||
printf ("TDB status = %04x\n", pTbd->status); |
||||
#endif |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/********************************************************************/ |
||||
static int mpc8220_fec_recv (struct eth_device *dev) |
||||
{ |
||||
/*
|
||||
* This command pulls one frame from the card |
||||
*/ |
||||
mpc8220_fec_priv *fec = (mpc8220_fec_priv *) dev->priv; |
||||
FEC_RBD *pRbd = &fec->rbdBase[fec->rbdIndex]; |
||||
unsigned long ievent; |
||||
int frame_length, len = 0; |
||||
NBUF *frame; |
||||
|
||||
#if (DEBUG & 0x1) |
||||
printf ("mpc8220_fec_recv %d Start...\n", fec->rbdIndex); |
||||
#endif |
||||
#if (DEBUG & 0x8) |
||||
printf ("-"); |
||||
#endif |
||||
|
||||
/*
|
||||
* Check if any critical events have happened |
||||
*/ |
||||
ievent = fec->eth->ievent; |
||||
fec->eth->ievent = ievent; |
||||
if (ievent & 0x20060000) { |
||||
/* BABT, Rx/Tx FIFO errors */ |
||||
mpc8220_fec_halt (dev); |
||||
mpc8220_fec_init (dev, NULL); |
||||
return 0; |
||||
} |
||||
if (ievent & 0x80000000) { |
||||
/* Heartbeat error */ |
||||
fec->eth->x_cntrl |= 0x00000001; |
||||
} |
||||
if (ievent & 0x10000000) { |
||||
/* Graceful stop complete */ |
||||
if (fec->eth->x_cntrl & 0x00000001) { |
||||
mpc8220_fec_halt (dev); |
||||
fec->eth->x_cntrl &= ~0x00000001; |
||||
mpc8220_fec_init (dev, NULL); |
||||
} |
||||
} |
||||
|
||||
if (!(pRbd->status & FEC_RBD_EMPTY)) { |
||||
if ((pRbd->status & FEC_RBD_LAST) |
||||
&& !(pRbd->status & FEC_RBD_ERR) |
||||
&& ((pRbd->dataLength - 4) > 14)) { |
||||
|
||||
/*
|
||||
* Get buffer address and size |
||||
*/ |
||||
frame = (NBUF *) pRbd->dataPointer; |
||||
frame_length = pRbd->dataLength - 4; |
||||
|
||||
#if (0) |
||||
{ |
||||
int i; |
||||
|
||||
printf ("recv data hdr:"); |
||||
for (i = 0; i < 14; i++) |
||||
printf ("%x ", *(frame->head + i)); |
||||
printf ("\n"); |
||||
} |
||||
#endif |
||||
/*
|
||||
* Fill the buffer and pass it to upper layers |
||||
*/ |
||||
/* memcpy(buff, frame->head, 14);
|
||||
memcpy(buff + 14, frame->data, frame_length);*/ |
||||
NetReceive ((volatile uchar *) pRbd->dataPointer, |
||||
frame_length); |
||||
len = frame_length; |
||||
} |
||||
/*
|
||||
* Reset buffer descriptor as empty |
||||
*/ |
||||
mpc8220_fec_rbd_clean (fec, pRbd); |
||||
} |
||||
DMA_CLEAR_IEVENT (FEC_RECV_TASK_NO); |
||||
return len; |
||||
} |
||||
|
||||
|
||||
/********************************************************************/ |
||||
int mpc8220_fec_initialize (bd_t * bis) |
||||
{ |
||||
mpc8220_fec_priv *fec; |
||||
|
||||
#ifdef CONFIG_ETH1ADDR |
||||
mpc8220_fec_priv *fec2; |
||||
#endif |
||||
struct eth_device *dev; |
||||
char *tmp, *end; |
||||
char env_enetaddr[6]; |
||||
|
||||
#ifdef CONFIG_ETH1ADDR |
||||
char env_enet1addr[6]; |
||||
#endif |
||||
int i; |
||||
|
||||
fec = (mpc8220_fec_priv *) malloc (sizeof (*fec)); |
||||
dev = (struct eth_device *) malloc (sizeof (*dev)); |
||||
memset (dev, 0, sizeof *dev); |
||||
|
||||
fec->eth = (ethernet_regs *) MMAP_FEC1; |
||||
#ifdef CONFIG_ETH1ADDR |
||||
fec2 = (mpc8220_fec_priv *) malloc (sizeof (*fec)); |
||||
fec2->eth = (ethernet_regs *) MMAP_FEC2; |
||||
#endif |
||||
fec->tbdBase = (FEC_TBD *) FEC_BD_BASE; |
||||
fec->rbdBase = |
||||
(FEC_RBD *) (FEC_BD_BASE + FEC_TBD_NUM * sizeof (FEC_TBD)); |
||||
fec->xcv_type = MII100; |
||||
|
||||
dev->priv = (void *) fec; |
||||
dev->iobase = MMAP_FEC1; |
||||
dev->init = mpc8220_fec_init; |
||||
dev->halt = mpc8220_fec_halt; |
||||
dev->send = mpc8220_fec_send; |
||||
dev->recv = mpc8220_fec_recv; |
||||
|
||||
sprintf (dev->name, "FEC ETHERNET"); |
||||
eth_register (dev); |
||||
|
||||
/*
|
||||
* Try to set the mac address now. The fec mac address is |
||||
* a garbage after reset. When not using fec for booting |
||||
* the Linux fec driver will try to work with this garbage. |
||||
*/ |
||||
tmp = getenv ("ethaddr"); |
||||
if (tmp) { |
||||
for (i = 0; i < 6; i++) { |
||||
env_enetaddr[i] = |
||||
tmp ? simple_strtoul (tmp, &end, 16) : 0; |
||||
if (tmp) |
||||
tmp = (*end) ? end + 1 : end; |
||||
} |
||||
mpc8220_fec_set_hwaddr (fec, env_enetaddr); |
||||
} |
||||
#ifdef CONFIG_ETH1ADDR |
||||
tmp = getenv ("eth1addr"); |
||||
if (tmp) { |
||||
for (i = 0; i < 6; i++) { |
||||
env_enet1addr[i] = |
||||
tmp ? simple_strtoul (tmp, &end, 16) : 0; |
||||
if (tmp) |
||||
tmp = (*end) ? end + 1 : end; |
||||
} |
||||
mpc8220_fec_set_hwaddr (fec2, env_enet1addr); |
||||
} |
||||
#endif |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
/* MII-interface related functions */ |
||||
/********************************************************************/ |
||||
int miiphy_read (u8 phyAddr, u8 regAddr, u16 * retVal) |
||||
{ |
||||
ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1; |
||||
u32 reg; /* convenient holder for the PHY register */ |
||||
u32 phy; /* convenient holder for the PHY */ |
||||
int timeout = 0xffff; |
||||
|
||||
/*
|
||||
* reading from any PHY's register is done by properly |
||||
* programming the FEC's MII data register. |
||||
*/ |
||||
reg = regAddr << FEC_MII_DATA_RA_SHIFT; |
||||
phy = phyAddr << FEC_MII_DATA_PA_SHIFT; |
||||
|
||||
eth->mii_data = |
||||
(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA | phy |
||||
| reg); |
||||
|
||||
/*
|
||||
* wait for the related interrupt |
||||
*/ |
||||
while ((timeout--) && (!(eth->ievent & 0x00800000))); |
||||
|
||||
if (timeout == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("Read MDIO failed...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* clear mii interrupt bit |
||||
*/ |
||||
eth->ievent = 0x00800000; |
||||
|
||||
/*
|
||||
* it's now safe to read the PHY's register |
||||
*/ |
||||
*retVal = (u16) eth->mii_data; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/********************************************************************/ |
||||
int miiphy_write (u8 phyAddr, u8 regAddr, u16 data) |
||||
{ |
||||
ethernet_regs *eth = (ethernet_regs *) MMAP_FEC1; |
||||
u32 reg; /* convenient holder for the PHY register */ |
||||
u32 phy; /* convenient holder for the PHY */ |
||||
int timeout = 0xffff; |
||||
|
||||
reg = regAddr << FEC_MII_DATA_RA_SHIFT; |
||||
phy = phyAddr << FEC_MII_DATA_PA_SHIFT; |
||||
|
||||
eth->mii_data = (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | |
||||
FEC_MII_DATA_TA | phy | reg | data); |
||||
|
||||
/*
|
||||
* wait for the MII interrupt |
||||
*/ |
||||
while ((timeout--) && (!(eth->ievent & 0x00800000))); |
||||
|
||||
if (timeout == 0) { |
||||
#if (DEBUG & 0x2) |
||||
printf ("Write MDIO failed...\n"); |
||||
#endif |
||||
return -1; |
||||
} |
||||
|
||||
/*
|
||||
* clear MII interrupt bit |
||||
*/ |
||||
eth->ievent = 0x00800000; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
#if (DEBUG & 0x40) |
||||
static u32 local_crc32 (char *string, unsigned int crc_value, int len) |
||||
{ |
||||
int i; |
||||
char c; |
||||
unsigned int crc, count; |
||||
|
||||
/*
|
||||
* crc32 algorithm |
||||
*/ |
||||
/*
|
||||
* crc = 0xffffffff; * The initialized value should be 0xffffffff |
||||
*/ |
||||
crc = crc_value; |
||||
|
||||
for (i = len; --i >= 0;) { |
||||
c = *string++; |
||||
for (count = 0; count < 8; count++) { |
||||
if ((c & 0x01) ^ (crc & 0x01)) { |
||||
crc >>= 1; |
||||
crc = crc ^ 0xedb88320; |
||||
} else { |
||||
crc >>= 1; |
||||
} |
||||
c >>= 1; |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* In big endian system, do byte swaping for crc value |
||||
*/ |
||||
return crc; |
||||
} |
||||
#endif /* DEBUG */ |
||||
|
||||
#endif /* CONFIG_MPC8220_FEC */ |
@ -0,0 +1,283 @@ |
||||
/*
|
||||
* (C) Copyright 2003-2004 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* This file is based on mpc4200fec.h |
||||
* (C) Copyright Motorola, Inc., 2000 |
||||
* |
||||
* odin ethernet header file |
||||
*/ |
||||
|
||||
#ifndef __MPC8220_FEC_H |
||||
#define __MPC8220_FEC_H |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
#include "dma.h" |
||||
|
||||
typedef struct ethernet_register_set { |
||||
|
||||
/* [10:2]addr = 00 */ |
||||
|
||||
/* Control and status Registers (offset 000-1FF) */ |
||||
|
||||
volatile u32 fec_id; /* MBAR_ETH + 0x000 */ |
||||
volatile u32 ievent; /* MBAR_ETH + 0x004 */ |
||||
volatile u32 imask; /* MBAR_ETH + 0x008 */ |
||||
|
||||
volatile u32 RES0[1]; /* MBAR_ETH + 0x00C */ |
||||
volatile u32 r_des_active; /* MBAR_ETH + 0x010 */ |
||||
volatile u32 x_des_active; /* MBAR_ETH + 0x014 */ |
||||
volatile u32 r_des_active_cl; /* MBAR_ETH + 0x018 */ |
||||
volatile u32 x_des_active_cl; /* MBAR_ETH + 0x01C */ |
||||
volatile u32 ivent_set; /* MBAR_ETH + 0x020 */ |
||||
volatile u32 ecntrl; /* MBAR_ETH + 0x024 */ |
||||
|
||||
volatile u32 RES1[6]; /* MBAR_ETH + 0x028-03C */ |
||||
volatile u32 mii_data; /* MBAR_ETH + 0x040 */ |
||||
volatile u32 mii_speed; /* MBAR_ETH + 0x044 */ |
||||
volatile u32 mii_status; /* MBAR_ETH + 0x048 */ |
||||
|
||||
volatile u32 RES2[5]; /* MBAR_ETH + 0x04C-05C */ |
||||
volatile u32 mib_data; /* MBAR_ETH + 0x060 */ |
||||
volatile u32 mib_control; /* MBAR_ETH + 0x064 */ |
||||
|
||||
volatile u32 RES3[6]; /* MBAR_ETH + 0x068-7C */ |
||||
volatile u32 r_activate; /* MBAR_ETH + 0x080 */ |
||||
volatile u32 r_cntrl; /* MBAR_ETH + 0x084 */ |
||||
volatile u32 r_hash; /* MBAR_ETH + 0x088 */ |
||||
volatile u32 r_data; /* MBAR_ETH + 0x08C */ |
||||
volatile u32 ar_done; /* MBAR_ETH + 0x090 */ |
||||
volatile u32 r_test; /* MBAR_ETH + 0x094 */ |
||||
volatile u32 r_mib; /* MBAR_ETH + 0x098 */ |
||||
volatile u32 r_da_low; /* MBAR_ETH + 0x09C */ |
||||
volatile u32 r_da_high; /* MBAR_ETH + 0x0A0 */ |
||||
|
||||
volatile u32 RES4[7]; /* MBAR_ETH + 0x0A4-0BC */ |
||||
volatile u32 x_activate; /* MBAR_ETH + 0x0C0 */ |
||||
volatile u32 x_cntrl; /* MBAR_ETH + 0x0C4 */ |
||||
volatile u32 backoff; /* MBAR_ETH + 0x0C8 */ |
||||
volatile u32 x_data; /* MBAR_ETH + 0x0CC */ |
||||
volatile u32 x_status; /* MBAR_ETH + 0x0D0 */ |
||||
volatile u32 x_mib; /* MBAR_ETH + 0x0D4 */ |
||||
volatile u32 x_test; /* MBAR_ETH + 0x0D8 */ |
||||
volatile u32 fdxfc_da1; /* MBAR_ETH + 0x0DC */ |
||||
volatile u32 fdxfc_da2; /* MBAR_ETH + 0x0E0 */ |
||||
volatile u32 paddr1; /* MBAR_ETH + 0x0E4 */ |
||||
volatile u32 paddr2; /* MBAR_ETH + 0x0E8 */ |
||||
volatile u32 op_pause; /* MBAR_ETH + 0x0EC */ |
||||
|
||||
volatile u32 RES5[4]; /* MBAR_ETH + 0x0F0-0FC */ |
||||
volatile u32 instr_reg; /* MBAR_ETH + 0x100 */ |
||||
volatile u32 context_reg; /* MBAR_ETH + 0x104 */ |
||||
volatile u32 test_cntrl; /* MBAR_ETH + 0x108 */ |
||||
volatile u32 acc_reg; /* MBAR_ETH + 0x10C */ |
||||
volatile u32 ones; /* MBAR_ETH + 0x110 */ |
||||
volatile u32 zeros; /* MBAR_ETH + 0x114 */ |
||||
volatile u32 iaddr1; /* MBAR_ETH + 0x118 */ |
||||
volatile u32 iaddr2; /* MBAR_ETH + 0x11C */ |
||||
volatile u32 gaddr1; /* MBAR_ETH + 0x120 */ |
||||
volatile u32 gaddr2; /* MBAR_ETH + 0x124 */ |
||||
volatile u32 random; /* MBAR_ETH + 0x128 */ |
||||
volatile u32 rand1; /* MBAR_ETH + 0x12C */ |
||||
volatile u32 tmp; /* MBAR_ETH + 0x130 */ |
||||
|
||||
volatile u32 RES6[3]; /* MBAR_ETH + 0x134-13C */ |
||||
volatile u32 fifo_id; /* MBAR_ETH + 0x140 */ |
||||
volatile u32 x_wmrk; /* MBAR_ETH + 0x144 */ |
||||
volatile u32 fcntrl; /* MBAR_ETH + 0x148 */ |
||||
volatile u32 r_bound; /* MBAR_ETH + 0x14C */ |
||||
volatile u32 r_fstart; /* MBAR_ETH + 0x150 */ |
||||
volatile u32 r_count; /* MBAR_ETH + 0x154 */ |
||||
volatile u32 r_lag; /* MBAR_ETH + 0x158 */ |
||||
volatile u32 r_read; /* MBAR_ETH + 0x15C */ |
||||
volatile u32 r_write; /* MBAR_ETH + 0x160 */ |
||||
volatile u32 x_count; /* MBAR_ETH + 0x164 */ |
||||
volatile u32 x_lag; /* MBAR_ETH + 0x168 */ |
||||
volatile u32 x_retry; /* MBAR_ETH + 0x16C */ |
||||
volatile u32 x_write; /* MBAR_ETH + 0x170 */ |
||||
volatile u32 x_read; /* MBAR_ETH + 0x174 */ |
||||
|
||||
volatile u32 RES7[2]; /* MBAR_ETH + 0x178-17C */ |
||||
volatile u32 fm_cntrl; /* MBAR_ETH + 0x180 */ |
||||
volatile u32 rfifo_data; /* MBAR_ETH + 0x184 */ |
||||
volatile u32 rfifo_status; /* MBAR_ETH + 0x188 */ |
||||
volatile u32 rfifo_cntrl; /* MBAR_ETH + 0x18C */ |
||||
volatile u32 rfifo_lrf_ptr; /* MBAR_ETH + 0x190 */ |
||||
volatile u32 rfifo_lwf_ptr; /* MBAR_ETH + 0x194 */ |
||||
volatile u32 rfifo_alarm; /* MBAR_ETH + 0x198 */ |
||||
volatile u32 rfifo_rdptr; /* MBAR_ETH + 0x19C */ |
||||
volatile u32 rfifo_wrptr; /* MBAR_ETH + 0x1A0 */ |
||||
volatile u32 tfifo_data; /* MBAR_ETH + 0x1A4 */ |
||||
volatile u32 tfifo_status; /* MBAR_ETH + 0x1A8 */ |
||||
volatile u32 tfifo_cntrl; /* MBAR_ETH + 0x1AC */ |
||||
volatile u32 tfifo_lrf_ptr; /* MBAR_ETH + 0x1B0 */ |
||||
volatile u32 tfifo_lwf_ptr; /* MBAR_ETH + 0x1B4 */ |
||||
volatile u32 tfifo_alarm; /* MBAR_ETH + 0x1B8 */ |
||||
volatile u32 tfifo_rdptr; /* MBAR_ETH + 0x1BC */ |
||||
volatile u32 tfifo_wrptr; /* MBAR_ETH + 0x1C0 */ |
||||
|
||||
volatile u32 reset_cntrl; /* MBAR_ETH + 0x1C4 */ |
||||
volatile u32 xmit_fsm; /* MBAR_ETH + 0x1C8 */ |
||||
|
||||
volatile u32 RES8[3]; /* MBAR_ETH + 0x1CC-1D4 */ |
||||
volatile u32 rdes_data0; /* MBAR_ETH + 0x1D8 */ |
||||
volatile u32 rdes_data1; /* MBAR_ETH + 0x1DC */ |
||||
volatile u32 r_length; /* MBAR_ETH + 0x1E0 */ |
||||
volatile u32 x_length; /* MBAR_ETH + 0x1E4 */ |
||||
volatile u32 x_addr; /* MBAR_ETH + 0x1E8 */ |
||||
volatile u32 cdes_data; /* MBAR_ETH + 0x1EC */ |
||||
volatile u32 status; /* MBAR_ETH + 0x1F0 */ |
||||
volatile u32 dma_control; /* MBAR_ETH + 0x1F4 */ |
||||
volatile u32 des_cmnd; /* MBAR_ETH + 0x1F8 */ |
||||
volatile u32 data; /* MBAR_ETH + 0x1FC */ |
||||
|
||||
/* MIB COUNTERS (Offset 200-2FF) */ |
||||
|
||||
volatile u32 rmon_t_drop; /* MBAR_ETH + 0x200 */ |
||||
volatile u32 rmon_t_packets; /* MBAR_ETH + 0x204 */ |
||||
volatile u32 rmon_t_bc_pkt; /* MBAR_ETH + 0x208 */ |
||||
volatile u32 rmon_t_mc_pkt; /* MBAR_ETH + 0x20C */ |
||||
volatile u32 rmon_t_crc_align; /* MBAR_ETH + 0x210 */ |
||||
volatile u32 rmon_t_undersize; /* MBAR_ETH + 0x214 */ |
||||
volatile u32 rmon_t_oversize; /* MBAR_ETH + 0x218 */ |
||||
volatile u32 rmon_t_frag; /* MBAR_ETH + 0x21C */ |
||||
volatile u32 rmon_t_jab; /* MBAR_ETH + 0x220 */ |
||||
volatile u32 rmon_t_col; /* MBAR_ETH + 0x224 */ |
||||
volatile u32 rmon_t_p64; /* MBAR_ETH + 0x228 */ |
||||
volatile u32 rmon_t_p65to127; /* MBAR_ETH + 0x22C */ |
||||
volatile u32 rmon_t_p128to255; /* MBAR_ETH + 0x230 */ |
||||
volatile u32 rmon_t_p256to511; /* MBAR_ETH + 0x234 */ |
||||
volatile u32 rmon_t_p512to1023; /* MBAR_ETH + 0x238 */ |
||||
volatile u32 rmon_t_p1024to2047;/* MBAR_ETH + 0x23C */ |
||||
volatile u32 rmon_t_p_gte2048; /* MBAR_ETH + 0x240 */ |
||||
volatile u32 rmon_t_octets; /* MBAR_ETH + 0x244 */ |
||||
volatile u32 ieee_t_drop; /* MBAR_ETH + 0x248 */ |
||||
volatile u32 ieee_t_frame_ok; /* MBAR_ETH + 0x24C */ |
||||
volatile u32 ieee_t_1col; /* MBAR_ETH + 0x250 */ |
||||
volatile u32 ieee_t_mcol; /* MBAR_ETH + 0x254 */ |
||||
volatile u32 ieee_t_def; /* MBAR_ETH + 0x258 */ |
||||
volatile u32 ieee_t_lcol; /* MBAR_ETH + 0x25C */ |
||||
volatile u32 ieee_t_excol; /* MBAR_ETH + 0x260 */ |
||||
volatile u32 ieee_t_macerr; /* MBAR_ETH + 0x264 */ |
||||
volatile u32 ieee_t_cserr; /* MBAR_ETH + 0x268 */ |
||||
volatile u32 ieee_t_sqe; /* MBAR_ETH + 0x26C */ |
||||
volatile u32 t_fdxfc; /* MBAR_ETH + 0x270 */ |
||||
volatile u32 ieee_t_octets_ok; /* MBAR_ETH + 0x274 */ |
||||
|
||||
volatile u32 RES9[2]; /* MBAR_ETH + 0x278-27C */ |
||||
volatile u32 rmon_r_drop; /* MBAR_ETH + 0x280 */ |
||||
volatile u32 rmon_r_packets; /* MBAR_ETH + 0x284 */ |
||||
volatile u32 rmon_r_bc_pkt; /* MBAR_ETH + 0x288 */ |
||||
volatile u32 rmon_r_mc_pkt; /* MBAR_ETH + 0x28C */ |
||||
volatile u32 rmon_r_crc_align; /* MBAR_ETH + 0x290 */ |
||||
volatile u32 rmon_r_undersize; /* MBAR_ETH + 0x294 */ |
||||
volatile u32 rmon_r_oversize; /* MBAR_ETH + 0x298 */ |
||||
volatile u32 rmon_r_frag; /* MBAR_ETH + 0x29C */ |
||||
volatile u32 rmon_r_jab; /* MBAR_ETH + 0x2A0 */ |
||||
|
||||
volatile u32 rmon_r_resvd_0; /* MBAR_ETH + 0x2A4 */ |
||||
|
||||
volatile u32 rmon_r_p64; /* MBAR_ETH + 0x2A8 */ |
||||
volatile u32 rmon_r_p65to127; /* MBAR_ETH + 0x2AC */ |
||||
volatile u32 rmon_r_p128to255; /* MBAR_ETH + 0x2B0 */ |
||||
volatile u32 rmon_r_p256to511; /* MBAR_ETH + 0x2B4 */ |
||||
volatile u32 rmon_r_p512to1023; /* MBAR_ETH + 0x2B8 */ |
||||
volatile u32 rmon_r_p1024to2047;/* MBAR_ETH + 0x2BC */ |
||||
volatile u32 rmon_r_p_gte2048; /* MBAR_ETH + 0x2C0 */ |
||||
volatile u32 rmon_r_octets; /* MBAR_ETH + 0x2C4 */ |
||||
volatile u32 ieee_r_drop; /* MBAR_ETH + 0x2C8 */ |
||||
volatile u32 ieee_r_frame_ok; /* MBAR_ETH + 0x2CC */ |
||||
volatile u32 ieee_r_crc; /* MBAR_ETH + 0x2D0 */ |
||||
volatile u32 ieee_r_align; /* MBAR_ETH + 0x2D4 */ |
||||
volatile u32 r_macerr; /* MBAR_ETH + 0x2D8 */ |
||||
volatile u32 r_fdxfc; /* MBAR_ETH + 0x2DC */ |
||||
volatile u32 ieee_r_octets_ok; /* MBAR_ETH + 0x2E0 */ |
||||
|
||||
volatile u32 RES10[6]; /* MBAR_ETH + 0x2E4-2FC */ |
||||
|
||||
volatile u32 RES11[64]; /* MBAR_ETH + 0x300-3FF */ |
||||
} ethernet_regs; |
||||
|
||||
/* Receive & Transmit Buffer Descriptor definitions */ |
||||
typedef struct BufferDescriptor { |
||||
u16 status; |
||||
u16 dataLength; |
||||
u32 dataPointer; |
||||
} FEC_RBD; |
||||
|
||||
typedef struct { |
||||
u16 status; |
||||
u16 dataLength; |
||||
u32 dataPointer; |
||||
} FEC_TBD; |
||||
|
||||
/* private structure */ |
||||
typedef enum { |
||||
SEVENWIRE, /* 7-wire */ |
||||
MII10, /* MII 10Mbps */ |
||||
MII100 /* MII 100Mbps */ |
||||
} xceiver_type; |
||||
|
||||
typedef struct { |
||||
ethernet_regs *eth; |
||||
xceiver_type xcv_type; /* transceiver type */ |
||||
FEC_RBD *rbdBase; /* RBD ring */ |
||||
FEC_TBD *tbdBase; /* TBD ring */ |
||||
u16 rbdIndex; /* next receive BD to read */ |
||||
u16 tbdIndex; /* next transmit BD to send */ |
||||
u16 usedTbdIndex; /* next transmit BD to clean */ |
||||
u16 cleanTbdNum; /* the number of available transmit BDs */ |
||||
} mpc8220_fec_priv; |
||||
|
||||
/* Ethernet parameter area */ |
||||
#define FEC_TBD_BASE (FEC_PARAM_BASE + 0x00) |
||||
#define FEC_TBD_NEXT (FEC_PARAM_BASE + 0x04) |
||||
#define FEC_RBD_BASE (FEC_PARAM_BASE + 0x08) |
||||
#define FEC_RBD_NEXT (FEC_PARAM_BASE + 0x0c) |
||||
|
||||
/* BD Numer definitions */ |
||||
#define FEC_TBD_NUM 48 /* The user can adjust this value */ |
||||
#define FEC_RBD_NUM 32 /* The user can adjust this value */ |
||||
|
||||
/* packet size limit */ |
||||
#define FEC_MAX_PKT_SIZE 1536 |
||||
|
||||
/* RBD bits definitions */ |
||||
#define FEC_RBD_EMPTY 0x8000 /* Buffer is empty */ |
||||
#define FEC_RBD_WRAP 0x2000 /* Last BD in ring */ |
||||
#define FEC_RBD_INT 0x1000 /* Interrupt */ |
||||
#define FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */ |
||||
#define FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */ |
||||
#define FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */ |
||||
#define FEC_RBD_MC 0x0040 /* The received frame is multicast frame */ |
||||
#define FEC_RBD_LG 0x0020 /* Frame length violation */ |
||||
#define FEC_RBD_NO 0x0010 /* Nonoctet align frame */ |
||||
#define FEC_RBD_SH 0x0008 /* Short frame */ |
||||
#define FEC_RBD_CR 0x0004 /* CRC error */ |
||||
#define FEC_RBD_OV 0x0002 /* Receive FIFO overrun */ |
||||
#define FEC_RBD_TR 0x0001 /* Frame is truncated */ |
||||
#define FEC_RBD_ERR (FEC_RBD_LG | FEC_RBD_NO | FEC_RBD_CR | \ |
||||
FEC_RBD_OV | FEC_RBD_TR) |
||||
|
||||
/* TBD bits definitions */ |
||||
#define FEC_TBD_READY 0x8000 /* Buffer is ready */ |
||||
#define FEC_TBD_WRAP 0x2000 /* Last BD in ring */ |
||||
#define FEC_TBD_INT 0x1000 /* Interrupt */ |
||||
#define FEC_TBD_LAST 0x0800 /* Buffer is last in frame */ |
||||
#define FEC_TBD_TC 0x0400 /* Transmit the CRC */ |
||||
#define FEC_TBD_ABC 0x0200 /* Append bad CRC */ |
||||
|
||||
/* MII-related definitios */ |
||||
#define FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ |
||||
#define FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ |
||||
#define FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ |
||||
#define FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ |
||||
#define FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ |
||||
#define FEC_MII_DATA_TA 0x00020000 /* Turnaround */ |
||||
#define FEC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ |
||||
|
||||
#define FEC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ |
||||
#define FEC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ |
||||
|
||||
#endif /* __MPC8220_FEC_H */ |
@ -0,0 +1,363 @@ |
||||
/* |
||||
* Copyright (C) 2004, Freescale Semiconductor, Inc. |
||||
* |
||||
* This file contains microcode for the FEC controller of the MPC8220. |
||||
*/ |
||||
|
||||
#include <config.h> |
||||
|
||||
#if defined(CONFIG_MPC8220) |
||||
|
||||
/* sas/sccg, gas target */ |
||||
.section smartdmaInitData,"aw",@progbits /* Initialized data for task variables */
|
||||
.section smartdmaTaskTable,"aw",@progbits /* Task tables */
|
||||
.align 9
|
||||
.globl taskTable
|
||||
taskTable: |
||||
.globl scEthernetRecv_Entry
|
||||
scEthernetRecv_Entry: /* Task 0 */ |
||||
.long scEthernetRecv_TDT - taskTable /* Task 0 Descriptor Table */ |
||||
.long scEthernetRecv_TDT - taskTable + 0x00000094 |
||||
.long scEthernetRecv_VarTab - taskTable /* Task 0 Variable Table */ |
||||
.long scEthernetRecv_FDT - taskTable + 0x03 /* Task 0 Function Descriptor Table & Flags */ |
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long scEthernetRecv_CSave - taskTable /* Task 0 context save space */ |
||||
.long 0xf0000000
|
||||
.globl scEthernetXmit_Entry
|
||||
scEthernetXmit_Entry: /* Task 1 */ |
||||
.long scEthernetXmit_TDT - taskTable /* Task 1 Descriptor Table */ |
||||
.long scEthernetXmit_TDT - taskTable + 0x000000e0 |
||||
.long scEthernetXmit_VarTab - taskTable /* Task 1 Variable Table */ |
||||
.long scEthernetXmit_FDT - taskTable + 0x03 /* Task 1 Function Descriptor Table & Flags */ |
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long scEthernetXmit_CSave - taskTable /* Task 1 context save space */ |
||||
.long 0xf0000000
|
||||
|
||||
|
||||
.globl scEthernetRecv_TDT
|
||||
scEthernetRecv_TDT: /* Task 0 Descriptor Table */ |
||||
.long 0xc4c50000 /* 0000(153): LCDEXT: idx0 = var9 + var10; idx0 once var0; idx0 += inc0 */ |
||||
.long 0x84c5e000 /* 0004(153): LCD: idx1 = var9 + var11; ; idx1 += inc0 */ |
||||
.long 0x10001f08 /* 0008(156): DRD1A: var7 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x10000380 /* 000C(157): DRD1A: var0 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x00000f88 /* 0010(158): DRD1A: var3 = *idx1; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0x81980000 /* 0014(162): LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */ |
||||
.long 0x10000780 /* 0018(164): DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x60000000 /* 001C(165): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ |
||||
.long 0x010cf04c /* 0020(165): DRD2B1: var4 = EU3(); EU3(var1,var12) */ |
||||
.long 0x82180349 /* 0024(169): LCD: idx0 = var4; idx0 != var13; idx0 += inc1 */ |
||||
.long 0x81c68004 /* 0028(172): LCD: idx1 = var3 + var13 + 4; idx1 once var0; idx1 += inc0 */ |
||||
.long 0x70000000 /* 002C(174): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ |
||||
.long 0x018cf04e /* 0030(174): DRD2B1: var6 = EU3(); EU3(var1,var14) */ |
||||
.long 0x70000000 /* 0034(175): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ |
||||
.long 0x020cf04f /* 0038(175): DRD2B1: var8 = EU3(); EU3(var1,var15) */ |
||||
.long 0x00000b88 /* 003C(176): DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0x80025184 /* 0040(205): LCDEXT: idx1 = 0xf0009184; ; */ |
||||
.long 0x86810412 /* 0044(205): LCD: idx2 = var13, idx3 = var2; idx2 < var16; idx2 += inc2, idx3 += inc2 */ |
||||
.long 0x0200cf88 /* 0048(209): DRD1A: *idx3 = *idx1; FN=0 init=16 WS=0 RS=0 */ |
||||
.long 0x80025184 /* 004C(217): LCDEXT: idx1 = 0xf0009184; ; */ |
||||
.long 0x8681845b /* 0050(217): LCD: idx2 = var13, idx3 = var3; idx2 < var17; idx2 += inc3, idx3 += inc3 */ |
||||
.long 0x0000cf88 /* 0054(221): DRD1A: *idx3 = *idx1; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0xc31883a4 /* 0058(225): LCDEXT: idx1 = var6; idx1 == var14; idx1 += inc4 */ |
||||
.long 0x80190000 /* 005C(225): LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */ |
||||
.long 0x04008468 /* 0060(227): DRD1A: idx1 = var13; FN=0 INT init=0 WS=0 RS=0 */ |
||||
.long 0xc4038360 /* 0064(232): LCDEXT: idx1 = var8, idx2 = var7; idx1 == var13; idx1 += inc4, idx2 += inc0 */ |
||||
.long 0x81c50000 /* 0068(233): LCD: idx3 = var3 + var10; idx3 once var0; idx3 += inc0 */ |
||||
.long 0x1000cb18 /* 006C(235): DRD1A: *idx2 = idx3; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x00000f18 /* 0070(236): DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0xc418836d /* 0074(238): LCDEXT: idx1 = var8; idx1 > var13; idx1 += inc5 */ |
||||
.long 0x83990000 /* 0078(238): LCD: idx2 = var7; idx2 once var0; idx2 += inc0 */ |
||||
.long 0x10000c00 /* 007C(240): DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x0000c800 /* 0080(241): DRD1A: *idx2 = var0; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0x81988000 /* 0084(245): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ |
||||
.long 0x10000788 /* 0088(247): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x60000000 /* 008C(248): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ |
||||
.long 0x080cf04c /* 0090(248): DRD2B1: idx0 = EU3(); EU3(var1,var12) */ |
||||
.long 0x000001f8 /* 0094(:0): NOP */ |
||||
|
||||
|
||||
.globl scEthernetXmit_TDT
|
||||
scEthernetXmit_TDT: /* Task 1 Descriptor Table */ |
||||
.long 0x80095b00 /* 0000(280): LCDEXT: idx0 = 0xf0025b00; ; */ |
||||
.long 0x85c60004 /* 0004(280): LCD: idx1 = var11 + var12 + 4; idx1 once var0; idx1 += inc0 */ |
||||
.long 0x10002308 /* 0008(283): DRD1A: var8 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x10000f88 /* 000C(284): DRD1A: var3 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x00000380 /* 0010(285): DRD1A: var0 = *idx0; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0x81980000 /* 0014(288): LCD: idx0 = var3; idx0 once var0; idx0 += inc0 */ |
||||
.long 0x10000780 /* 0018(290): DRD1A: var1 = *idx0; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x60000000 /* 001C(291): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ |
||||
.long 0x024cf04d /* 0020(291): DRD2B1: var9 = EU3(); EU3(var1,var13) */ |
||||
.long 0x84980309 /* 0024(294): LCD: idx0 = var9; idx0 != var12; idx0 += inc1 */ |
||||
.long 0xc0004003 /* 0028(297): LCDEXT: idx1 = 0x00000003; ; */ |
||||
.long 0x81c60004 /* 002C(297): LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */ |
||||
.long 0x70000000 /* 0030(299): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ |
||||
.long 0x010cf04e /* 0034(299): DRD2B1: var4 = EU3(); EU3(var1,var14) */ |
||||
.long 0x70000000 /* 0038(300): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ |
||||
.long 0x014cf04f /* 003C(300): DRD2B1: var5 = EU3(); EU3(var1,var15) */ |
||||
.long 0x70000000 /* 0040(301): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ |
||||
.long 0x028cf050 /* 0044(301): DRD2B1: var10 = EU3(); EU3(var1,var16) */ |
||||
.long 0x70000000 /* 0048(302): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT MORE init=0 WS=0 RS=0 */ |
||||
.long 0x018cf051 /* 004C(302): DRD2B1: var6 = EU3(); EU3(var1,var17) */ |
||||
.long 0x10000b90 /* 0050(303): DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x60000000 /* 0054(304): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ |
||||
.long 0x01ccf0a1 /* 0058(304): DRD2B1: var7 = EU3(); EU3(var2,idx1) */ |
||||
.long 0xc2988312 /* 005C(308): LCDEXT: idx1 = var5; idx1 > var12; idx1 += inc2 */ |
||||
.long 0x83490000 /* 0060(308): LCD: idx2 = var6 + var18; idx2 once var0; idx2 += inc0 */ |
||||
.long 0x00001b10 /* 0064(310): DRD1A: var6 = idx2; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0x800251a4 /* 0068(315): LCDEXT: idx1 = 0xf00091a4; ; */ |
||||
.long 0xc30104dc /* 006C(315): LCDEXT: idx2 = var6, idx3 = var2; idx2 >= var19; idx2 += inc3, idx3 += inc4 */ |
||||
.long 0x839a032d /* 0070(316): LCD: idx4 = var7; idx4 == var12; idx4 += inc5 */ |
||||
.long 0x0220c798 /* 0074(321): DRD1A: *idx1 = *idx3; FN=0 init=17 WS=0 RS=0 */ |
||||
.long 0x800251a4 /* 0078(329): LCDEXT: idx1 = 0xf00091a4; ; */ |
||||
.long 0x99198337 /* 007C(329): LCD: idx2 = idx2, idx3 = idx3; idx2 > var12; idx2 += inc6, idx3 += inc7 */ |
||||
.long 0x022ac798 /* 0080(333): DRD1A: *idx1 = *idx3; FN=0 init=17 WS=1 RS=1 */ |
||||
.long 0x800251a4 /* 0084(350): LCDEXT: idx1 = 0xf00091a4; ; */ |
||||
.long 0xc1430000 /* 0088(350): LCDEXT: idx2 = var2 + var6; idx2 once var0; idx2 += inc0 */ |
||||
.long 0x82998312 /* 008C(351): LCD: idx3 = var5; idx3 > var12; idx3 += inc2 */ |
||||
.long 0x0a2ac790 /* 0090(354): DRD1A: *idx1 = *idx2; FN=0 TFD init=17 WS=1 RS=1 */ |
||||
.long 0x81988000 /* 0094(359): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ |
||||
.long 0x60000002 /* 0098(361): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */ |
||||
.long 0x0c4cfc4d /* 009C(361): DRD2B1: *idx1 = EU3(); EU3(*idx1,var13) */ |
||||
.long 0xc21883ad /* 00A0(365): LCDEXT: idx1 = var4; idx1 == var14; idx1 += inc5 */ |
||||
.long 0x80190000 /* 00A4(365): LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */ |
||||
.long 0x04008460 /* 00A8(367): DRD1A: idx1 = var12; FN=0 INT init=0 WS=0 RS=0 */ |
||||
.long 0xc4052305 /* 00AC(371): LCDEXT: idx1 = var8, idx2 = var10; idx2 == var12; idx1 += inc0, idx2 += inc5 */ |
||||
.long 0x81ca0000 /* 00B0(372): LCD: idx3 = var3 + var20; idx3 once var0; idx3 += inc0 */ |
||||
.long 0x1000c718 /* 00B4(374): DRD1A: *idx1 = idx3; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x00000f18 /* 00B8(375): DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0xc4188000 /* 00BC(378): LCDEXT: idx1 = var8; idx1 once var0; idx1 += inc0 */ |
||||
.long 0x85190312 /* 00C0(378): LCD: idx2 = var10; idx2 > var12; idx2 += inc2 */ |
||||
.long 0x10000c00 /* 00C4(380): DRD1A: var3 = var0; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x1000c400 /* 00C8(381): DRD1A: *idx1 = var0; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x00008860 /* 00CC(382): DRD1A: idx2 = var12; FN=0 init=0 WS=0 RS=0 */ |
||||
.long 0x81988000 /* 00D0(386): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ |
||||
.long 0x10000788 /* 00D4(388): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ |
||||
.long 0x60000000 /* 00D8(389): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=0 WS=0 RS=0 */ |
||||
.long 0x080cf04d /* 00DC(389): DRD2B1: idx0 = EU3(); EU3(var1,var13) */ |
||||
.long 0x000001f8 /* 00E0(:0): NOP */ |
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetRecv_VarTab
|
||||
scEthernetRecv_VarTab: /* Task 0 Variable Table */ |
||||
.long 0x00000000 /* var[0] */ |
||||
.long 0x00000000 /* var[1] */ |
||||
.long 0x00000000 /* var[2] */ |
||||
.long 0x00000000 /* var[3] */ |
||||
.long 0x00000000 /* var[4] */ |
||||
.long 0x00000000 /* var[5] */ |
||||
.long 0x00000000 /* var[6] */ |
||||
.long 0x00000000 /* var[7] */ |
||||
.long 0x00000000 /* var[8] */ |
||||
.long 0xf0025b00 /* var[9] */ |
||||
.long 0x00000008 /* var[10] */ |
||||
.long 0x0000000c /* var[11] */ |
||||
.long 0x80000000 /* var[12] */ |
||||
.long 0x00000000 /* var[13] */ |
||||
.long 0x10000000 /* var[14] */ |
||||
.long 0x20000000 /* var[15] */ |
||||
.long 0x00000800 /* var[16] */ |
||||
.long 0x00000001 /* var[17] */ |
||||
.long 0x00000000 /* var[18] */ |
||||
.long 0x00000000 /* var[19] */ |
||||
.long 0x00000000 /* var[20] */ |
||||
.long 0x00000000 /* var[21] */ |
||||
.long 0x00000000 /* var[22] */ |
||||
.long 0x00000000 /* var[23] */ |
||||
.long 0x00000000 /* inc[0] */ |
||||
.long 0x60000000 /* inc[1] */ |
||||
.long 0x20000004 /* inc[2] */ |
||||
.long 0x20000001 /* inc[3] */ |
||||
.long 0x80000000 /* inc[4] */ |
||||
.long 0x40000000 /* inc[5] */ |
||||
.long 0x00000000 /* inc[6] */ |
||||
.long 0x00000000 /* inc[7] */ |
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetXmit_VarTab
|
||||
scEthernetXmit_VarTab: /* Task 1 Variable Table */ |
||||
.long 0x00000000 /* var[0] */ |
||||
.long 0x00000000 /* var[1] */ |
||||
.long 0x00000000 /* var[2] */ |
||||
.long 0x00000000 /* var[3] */ |
||||
.long 0x00000000 /* var[4] */ |
||||
.long 0x00000000 /* var[5] */ |
||||
.long 0x00000000 /* var[6] */ |
||||
.long 0x00000000 /* var[7] */ |
||||
.long 0x00000000 /* var[8] */ |
||||
.long 0x00000000 /* var[9] */ |
||||
.long 0x00000000 /* var[10] */ |
||||
.long 0xf0025b00 /* var[11] */ |
||||
.long 0x00000000 /* var[12] */ |
||||
.long 0x80000000 /* var[13] */ |
||||
.long 0x10000000 /* var[14] */ |
||||
.long 0x08000000 /* var[15] */ |
||||
.long 0x20000000 /* var[16] */ |
||||
.long 0x0000ffff /* var[17] */ |
||||
.long 0xffffffff /* var[18] */ |
||||
.long 0x00000004 /* var[19] */ |
||||
.long 0x00000008 /* var[20] */ |
||||
.long 0x00000000 /* var[21] */ |
||||
.long 0x00000000 /* var[22] */ |
||||
.long 0x00000000 /* var[23] */ |
||||
.long 0x00000000 /* inc[0] */ |
||||
.long 0x60000000 /* inc[1] */ |
||||
.long 0x40000000 /* inc[2] */ |
||||
.long 0xc000fffc /* inc[3] */ |
||||
.long 0xe0000004 /* inc[4] */ |
||||
.long 0x80000000 /* inc[5] */ |
||||
.long 0x4000ffff /* inc[6] */ |
||||
.long 0xe0000001 /* inc[7] */ |
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetRecv_FDT
|
||||
scEthernetRecv_FDT: /* Task 0 Function Descriptor Table */ |
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x21800000 /* and(), EU# 3 */ |
||||
.long 0x21e00000 /* or(), EU# 3 */ |
||||
.long 0x21400000 /* andn(), EU# 3 */ |
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
|
||||
.align 8
|
||||
|
||||
.globl scEthernetXmit_FDT
|
||||
scEthernetXmit_FDT: /* Task 1 Function Descriptor Table */ |
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x21800000 /* and(), EU# 3 */ |
||||
.long 0x21e00000 /* or(), EU# 3 */ |
||||
.long 0x21400000 /* andn(), EU# 3 */ |
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
.long 0x00000000
|
||||
|
||||
|
||||
.globl scEthernetRecv_CSave
|
||||
scEthernetRecv_CSave: /* Task 0 context save space */ |
||||
.space 128, 0x0 |
||||
|
||||
|
||||
.globl scEthernetXmit_CSave
|
||||
scEthernetXmit_CSave: /* Task 1 context save space */ |
||||
.space 128, 0x0 |
||||
|
||||
#endif |
@ -0,0 +1,403 @@ |
||||
/*
|
||||
* (C) Copyright 2004, Freescale, Inc |
||||
* TsiChung Liew, Tsi-Chung.Liew@freescale.com. |
||||
* |
||||
* 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> |
||||
|
||||
#ifdef CONFIG_HARD_I2C |
||||
|
||||
#include <mpc8220.h> |
||||
#include <i2c.h> |
||||
|
||||
typedef struct mpc8220_i2c { |
||||
volatile u32 adr; /* I2Cn + 0x00 */ |
||||
volatile u32 fdr; /* I2Cn + 0x04 */ |
||||
volatile u32 cr; /* I2Cn + 0x08 */ |
||||
volatile u32 sr; /* I2Cn + 0x0C */ |
||||
volatile u32 dr; /* I2Cn + 0x10 */ |
||||
} i2c_t; |
||||
|
||||
/* I2Cn control register bits */ |
||||
#define I2C_EN 0x80 |
||||
#define I2C_IEN 0x40 |
||||
#define I2C_STA 0x20 |
||||
#define I2C_TX 0x10 |
||||
#define I2C_TXAK 0x08 |
||||
#define I2C_RSTA 0x04 |
||||
#define I2C_INIT_MASK (I2C_EN | I2C_STA | I2C_TX | I2C_RSTA) |
||||
|
||||
/* I2Cn status register bits */ |
||||
#define I2C_CF 0x80 |
||||
#define I2C_AAS 0x40 |
||||
#define I2C_BB 0x20 |
||||
#define I2C_AL 0x10 |
||||
#define I2C_SRW 0x04 |
||||
#define I2C_IF 0x02 |
||||
#define I2C_RXAK 0x01 |
||||
|
||||
#define I2C_TIMEOUT 100 |
||||
#define I2C_RETRIES 1 |
||||
|
||||
struct mpc8220_i2c_tap { |
||||
int scl2tap; |
||||
int tap2tap; |
||||
}; |
||||
|
||||
static int mpc_reg_in (volatile u32 * reg); |
||||
static void mpc_reg_out (volatile u32 * reg, int val, int mask); |
||||
static int wait_for_bb (void); |
||||
static int wait_for_pin (int *status); |
||||
static int do_address (uchar chip, char rdwr_flag); |
||||
static int send_bytes (uchar chip, char *buf, int len); |
||||
static int receive_bytes (uchar chip, char *buf, int len); |
||||
static int mpc_get_fdr (int); |
||||
|
||||
static int mpc_reg_in (volatile u32 * reg) |
||||
{ |
||||
return *reg >> 24; |
||||
__asm__ __volatile__ ("eieio"); |
||||
} |
||||
|
||||
static void mpc_reg_out (volatile u32 * reg, int val, int mask) |
||||
{ |
||||
int tmp; |
||||
|
||||
if (!mask) { |
||||
*reg = val << 24; |
||||
} else { |
||||
tmp = mpc_reg_in (reg); |
||||
*reg = ((tmp & ~mask) | (val & mask)) << 24; |
||||
} |
||||
__asm__ __volatile__ ("eieio"); |
||||
|
||||
return; |
||||
} |
||||
|
||||
static int wait_for_bb (void) |
||||
{ |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int timeout = I2C_TIMEOUT; |
||||
int status; |
||||
|
||||
status = mpc_reg_in (®s->sr); |
||||
|
||||
while (timeout-- && (status & I2C_BB)) { |
||||
#if 1 |
||||
volatile int temp; |
||||
|
||||
mpc_reg_out (®s->cr, I2C_STA, I2C_STA); |
||||
temp = mpc_reg_in (®s->dr); |
||||
mpc_reg_out (®s->cr, 0, I2C_STA); |
||||
mpc_reg_out (®s->cr, 0, 0); |
||||
mpc_reg_out (®s->cr, I2C_EN, 0); |
||||
#endif |
||||
udelay (1000); |
||||
status = mpc_reg_in (®s->sr); |
||||
} |
||||
|
||||
return (status & I2C_BB); |
||||
} |
||||
|
||||
static int wait_for_pin (int *status) |
||||
{ |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int timeout = I2C_TIMEOUT; |
||||
|
||||
*status = mpc_reg_in (®s->sr); |
||||
|
||||
while (timeout-- && !(*status & I2C_IF)) { |
||||
udelay (1000); |
||||
*status = mpc_reg_in (®s->sr); |
||||
} |
||||
|
||||
if (!(*status & I2C_IF)) { |
||||
return -1; |
||||
} |
||||
|
||||
mpc_reg_out (®s->sr, 0, I2C_IF); |
||||
return 0; |
||||
} |
||||
|
||||
static int do_address (uchar chip, char rdwr_flag) |
||||
{ |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int status; |
||||
|
||||
chip <<= 1; |
||||
|
||||
if (rdwr_flag) |
||||
chip |= 1; |
||||
|
||||
mpc_reg_out (®s->cr, I2C_TX, I2C_TX); |
||||
mpc_reg_out (®s->dr, chip, 0); |
||||
|
||||
if (wait_for_pin (&status)) |
||||
return -2; |
||||
if (status & I2C_RXAK) |
||||
return -3; |
||||
return 0; |
||||
} |
||||
|
||||
static int send_bytes (uchar chip, char *buf, int len) |
||||
{ |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int wrcount; |
||||
int status; |
||||
|
||||
for (wrcount = 0; wrcount < len; ++wrcount) { |
||||
|
||||
mpc_reg_out (®s->dr, buf[wrcount], 0); |
||||
|
||||
if (wait_for_pin (&status)) |
||||
break; |
||||
|
||||
if (status & I2C_RXAK) |
||||
break; |
||||
|
||||
} |
||||
|
||||
return !(wrcount == len); |
||||
return 0; |
||||
} |
||||
|
||||
static int receive_bytes (uchar chip, char *buf, int len) |
||||
{ |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int dummy = 1; |
||||
int rdcount = 0; |
||||
int status; |
||||
int i; |
||||
|
||||
mpc_reg_out (®s->cr, 0, I2C_TX); |
||||
|
||||
for (i = 0; i < len; ++i) { |
||||
buf[rdcount] = mpc_reg_in (®s->dr); |
||||
|
||||
if (dummy) |
||||
dummy = 0; |
||||
else |
||||
rdcount++; |
||||
|
||||
if (wait_for_pin (&status)) |
||||
return -4; |
||||
} |
||||
|
||||
mpc_reg_out (®s->cr, I2C_TXAK, I2C_TXAK); |
||||
buf[rdcount++] = mpc_reg_in (®s->dr); |
||||
|
||||
if (wait_for_pin (&status)) |
||||
return -5; |
||||
|
||||
mpc_reg_out (®s->cr, 0, I2C_TXAK); |
||||
return 0; |
||||
} |
||||
|
||||
/**************** I2C API ****************/ |
||||
|
||||
void i2c_init (int speed, int saddr) |
||||
{ |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
|
||||
mpc_reg_out (®s->cr, 0, 0); |
||||
mpc_reg_out (®s->adr, saddr << 1, 0); |
||||
|
||||
/* Set clock
|
||||
*/ |
||||
mpc_reg_out (®s->fdr, mpc_get_fdr (speed), 0); |
||||
|
||||
/* Enable module
|
||||
*/ |
||||
mpc_reg_out (®s->cr, I2C_EN, I2C_INIT_MASK); |
||||
mpc_reg_out (®s->sr, 0, I2C_IF); |
||||
return; |
||||
} |
||||
|
||||
static int mpc_get_fdr (int speed) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
static int fdr = -1; |
||||
|
||||
if (fdr == -1) { |
||||
ulong best_speed = 0; |
||||
ulong divider; |
||||
ulong ipb, scl; |
||||
ulong bestmatch = 0xffffffffUL; |
||||
int best_i = 0, best_j = 0, i, j; |
||||
int SCL_Tap[] = { 9, 10, 12, 15, 5, 6, 7, 8 }; |
||||
struct mpc8220_i2c_tap scltap[] = { |
||||
{4, 1}, |
||||
{4, 2}, |
||||
{6, 4}, |
||||
{6, 8}, |
||||
{14, 16}, |
||||
{30, 32}, |
||||
{62, 64}, |
||||
{126, 128} |
||||
}; |
||||
|
||||
ipb = gd->bus_clk; |
||||
for (i = 7; i >= 0; i--) { |
||||
for (j = 7; j >= 0; j--) { |
||||
scl = 2 * (scltap[j].scl2tap + |
||||
(SCL_Tap[i] - |
||||
1) * scltap[j].tap2tap + 2); |
||||
if (ipb <= speed * scl) { |
||||
if ((speed * scl - ipb) < bestmatch) { |
||||
bestmatch = speed * scl - ipb; |
||||
best_i = i; |
||||
best_j = j; |
||||
best_speed = ipb / scl; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
divider = (best_i & 3) | ((best_i & 4) << 3) | (best_j << 2); |
||||
if (gd->flags & GD_FLG_RELOC) { |
||||
fdr = divider; |
||||
} else { |
||||
printf ("%ld kHz, ", best_speed / 1000); |
||||
return divider; |
||||
} |
||||
} |
||||
|
||||
return fdr; |
||||
} |
||||
|
||||
int i2c_probe (uchar chip) |
||||
{ |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int i; |
||||
|
||||
for (i = 0; i < I2C_RETRIES; i++) { |
||||
mpc_reg_out (®s->cr, I2C_STA, I2C_STA); |
||||
|
||||
if (!do_address (chip, 0)) { |
||||
mpc_reg_out (®s->cr, 0, I2C_STA); |
||||
break; |
||||
} |
||||
|
||||
mpc_reg_out (®s->cr, 0, I2C_STA); |
||||
udelay (50); |
||||
} |
||||
|
||||
return (i == I2C_RETRIES); |
||||
} |
||||
|
||||
int i2c_read (uchar chip, uint addr, int alen, uchar * buf, int len) |
||||
{ |
||||
uchar xaddr[4]; |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int ret = -1; |
||||
|
||||
xaddr[0] = (addr >> 24) & 0xFF; |
||||
xaddr[1] = (addr >> 16) & 0xFF; |
||||
xaddr[2] = (addr >> 8) & 0xFF; |
||||
xaddr[3] = addr & 0xFF; |
||||
|
||||
if (wait_for_bb ()) { |
||||
printf ("i2c_read: bus is busy\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
mpc_reg_out (®s->cr, I2C_STA, I2C_STA); |
||||
if (do_address (chip, 0)) { |
||||
printf ("i2c_read: failed to address chip\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (send_bytes (chip, &xaddr[4 - alen], alen)) { |
||||
printf ("i2c_read: send_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
mpc_reg_out (®s->cr, I2C_RSTA, I2C_RSTA); |
||||
if (do_address (chip, 1)) { |
||||
printf ("i2c_read: failed to address chip\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (receive_bytes (chip, buf, len)) { |
||||
printf ("i2c_read: receive_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
ret = 0; |
||||
Done: |
||||
mpc_reg_out (®s->cr, 0, I2C_STA); |
||||
return ret; |
||||
} |
||||
|
||||
int i2c_write (uchar chip, uint addr, int alen, uchar * buf, int len) |
||||
{ |
||||
uchar xaddr[4]; |
||||
i2c_t *regs = (i2c_t *) MMAP_I2C; |
||||
int ret = -1; |
||||
|
||||
xaddr[0] = (addr >> 24) & 0xFF; |
||||
xaddr[1] = (addr >> 16) & 0xFF; |
||||
xaddr[2] = (addr >> 8) & 0xFF; |
||||
xaddr[3] = addr & 0xFF; |
||||
|
||||
if (wait_for_bb ()) { |
||||
printf ("i2c_write: bus is busy\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
mpc_reg_out (®s->cr, I2C_STA, I2C_STA); |
||||
if (do_address (chip, 0)) { |
||||
printf ("i2c_write: failed to address chip\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (send_bytes (chip, &xaddr[4 - alen], alen)) { |
||||
printf ("i2c_write: send_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
if (send_bytes (chip, buf, len)) { |
||||
printf ("i2c_write: send_bytes failed\n"); |
||||
goto Done; |
||||
} |
||||
|
||||
ret = 0; |
||||
Done: |
||||
mpc_reg_out (®s->cr, 0, I2C_STA); |
||||
return ret; |
||||
} |
||||
|
||||
uchar i2c_reg_read (uchar chip, uchar reg) |
||||
{ |
||||
char buf; |
||||
|
||||
i2c_read (chip, reg, 1, &buf, 1); |
||||
|
||||
return buf; |
||||
} |
||||
|
||||
void i2c_reg_write (uchar chip, uchar reg, uchar val) |
||||
{ |
||||
i2c_write (chip, reg, 1, &val, 1); |
||||
|
||||
return; |
||||
} |
||||
|
||||
#endif /* CONFIG_HARD_I2C */ |
@ -0,0 +1,627 @@ |
||||
/* I2cCore.c - MPC8220 PPC I2C Library */ |
||||
|
||||
/* Copyright 2004 Freescale Semiconductor, Inc. */ |
||||
|
||||
/*
|
||||
modification history |
||||
-------------------- |
||||
01c,29jun04,tcl 1.3 removed CR. Added two bytes offset support. |
||||
01b,19jan04,tcl 1.2 removed i2cMsDelay and sysDecGet. renamed i2cMsDelay |
||||
back to sysMsDelay |
||||
01a,19jan04,tcl 1.1 created and seperated from i2c.c |
||||
*/ |
||||
|
||||
/*
|
||||
DESCRIPTION |
||||
This file contain I2C low level handling library functions |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <vxWorks.h> |
||||
#include <sysLib.h> |
||||
#include <iosLib.h> |
||||
#include <logLib.h> |
||||
#include <tickLib.h> |
||||
|
||||
/* BSP Includes */ |
||||
#include "config.h" |
||||
#include "mpc8220.h" |
||||
#include "i2cCore.h" |
||||
|
||||
#ifdef DEBUG_I2CCORE |
||||
int I2CCDbg = 0; |
||||
#endif |
||||
|
||||
#define ABS(x) ((x < 0)? -x : x) |
||||
|
||||
char *I2CERR[16] = { |
||||
"Transfer in Progress\n", /* 0 */ |
||||
"Transfer complete\n", |
||||
"Not Addressed\n", /* 2 */ |
||||
"Addressed as a slave\n", |
||||
"Bus is Idle\n", /* 4 */ |
||||
"Bus is busy\n", |
||||
"Arbitration Lost\n", /* 6 */ |
||||
"Arbitration on Track\n", |
||||
"Slave receive, master writing to slave\n", /* 8 */ |
||||
"Slave transmit, master reading from slave\n", |
||||
"Interrupt is pending\n", /* 10 */ |
||||
"Interrupt complete\n", |
||||
"Acknowledge received\n", /* 12 */ |
||||
"No acknowledge received\n", |
||||
"Unknown status\n", /* 14 */ |
||||
"\n" |
||||
}; |
||||
|
||||
/******************************************************************************
|
||||
* |
||||
* chk_status - Check I2C status bit |
||||
* |
||||
* RETURNS: OK, or ERROR if the bit encounter |
||||
* |
||||
*/ |
||||
|
||||
STATUS chk_status (PSI2C pi2c, UINT8 sta_bit, UINT8 truefalse) |
||||
{ |
||||
int i, status = 0; |
||||
|
||||
for (i = 0; i < I2C_POLL_COUNT; i++) { |
||||
if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0)) |
||||
return (OK); |
||||
} |
||||
|
||||
I2CCDBG (L2, ("--- sr %x stabit %x truefalse %d\n", |
||||
pi2c->sr, sta_bit, truefalse, 0, 0, 0)); |
||||
|
||||
if (i == I2C_POLL_COUNT) { |
||||
switch (sta_bit) { |
||||
case I2C_STA_CF: |
||||
status = 0; |
||||
break; |
||||
case I2C_STA_AAS: |
||||
status = 2; |
||||
break; |
||||
case I2C_STA_BB: |
||||
status = 4; |
||||
break; |
||||
case I2C_STA_AL: |
||||
status = 6; |
||||
break; |
||||
case I2C_STA_SRW: |
||||
status = 8; |
||||
break; |
||||
case I2C_STA_IF: |
||||
status = 10; |
||||
break; |
||||
case I2C_STA_RXAK: |
||||
status = 12; |
||||
break; |
||||
default: |
||||
status = 14; |
||||
break; |
||||
} |
||||
|
||||
if (!truefalse) |
||||
status++; |
||||
|
||||
I2CCDBG (NO, ("--- status %d\n", status, 0, 0, 0, 0, 0)); |
||||
I2CCDBG (NO, (I2CERR[status], 0, 0, 0, 0, 0, 0)); |
||||
} |
||||
|
||||
return (ERROR); |
||||
} |
||||
|
||||
/******************************************************************************
|
||||
* |
||||
* I2C Enable - Enable the I2C Controller |
||||
* |
||||
*/ |
||||
STATUS i2c_enable (SI2C * pi2c, PI2CSET pi2cSet) |
||||
{ |
||||
int fdr = pi2cSet->bit_rate; |
||||
UINT8 adr = pi2cSet->i2c_adr; |
||||
|
||||
I2CCDBG (L2, ("i2c_enable fdr %d adr %x\n", fdr, adr, 0, 0, 0, 0)); |
||||
|
||||
i2c_clear (pi2c); /* Clear FDR, ADR, SR and CR reg */ |
||||
|
||||
SetI2cFDR (pi2c, fdr); /* Frequency */ |
||||
pi2c->adr = adr; |
||||
|
||||
pi2c->cr = I2C_CTL_EN; /* Set Enable */ |
||||
|
||||
/*
|
||||
The I2C bus should be in Idle state. If the bus is busy, |
||||
clear the STA bit in control register |
||||
*/ |
||||
if (chk_status (pi2c, I2C_STA_BB, 0) != OK) { |
||||
if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA) |
||||
pi2c->cr &= ~I2C_CTL_STA; |
||||
|
||||
/* Check again if it is still busy, return error if found */ |
||||
if (chk_status (pi2c, I2C_STA_BB, 1) == OK) |
||||
return ERROR; |
||||
} |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
/******************************************************************************
|
||||
* |
||||
* I2C Disable - Disable the I2C Controller |
||||
* |
||||
*/ |
||||
STATUS i2c_disable (PSI2C pi2c) |
||||
{ |
||||
i2c_clear (pi2c); |
||||
|
||||
pi2c->cr &= I2C_CTL_EN; /* Disable I2c */ |
||||
|
||||
if ((pi2c->cr & I2C_CTL_STA) == I2C_CTL_STA) |
||||
pi2c->cr &= ~I2C_CTL_STA; |
||||
|
||||
if (chk_status (pi2c, I2C_STA_BB, 0) != OK) |
||||
return ERROR; |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
/******************************************************************************
|
||||
* |
||||
* I2C Clear - Clear the I2C Controller |
||||
* |
||||
*/ |
||||
STATUS i2c_clear (PSI2C pi2c) |
||||
{ |
||||
pi2c->adr = 0; |
||||
pi2c->fdr = 0; |
||||
pi2c->cr = 0; |
||||
pi2c->sr = 0; |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
|
||||
STATUS i2c_start (PSI2C pi2c, PI2CSET pi2cSet) |
||||
{ |
||||
#ifdef TWOBYTES |
||||
UINT16 ByteOffset = pi2cSet->str_adr; |
||||
#else |
||||
UINT8 ByteOffset = pi2cSet->str_adr; |
||||
#endif |
||||
#if 1 |
||||
UINT8 tmp = 0; |
||||
#endif |
||||
UINT8 Addr = pi2cSet->slv_adr; |
||||
|
||||
pi2c->cr |= I2C_CTL_STA; /* Generate start signal */ |
||||
|
||||
if (chk_status (pi2c, I2C_STA_BB, 1) != OK) |
||||
return ERROR; |
||||
|
||||
/* Write slave address */ |
||||
if (i2c_writebyte (pi2c, &Addr) != OK) { |
||||
i2c_stop (pi2c); /* Disable I2c */ |
||||
return ERROR; |
||||
} |
||||
#ifdef TWOBYTES |
||||
# if 0 |
||||
/* Issue the offset to start */ |
||||
if (i2c_write2byte (pi2c, &ByteOffset) != OK) { |
||||
i2c_stop (pi2c); /* Disable I2c */ |
||||
return ERROR; |
||||
} |
||||
#endif |
||||
tmp = (ByteOffset >> 8) & 0xff; |
||||
if (i2c_writebyte (pi2c, &tmp) != OK) { |
||||
i2c_stop (pi2c); /* Disable I2c */ |
||||
return ERROR; |
||||
} |
||||
tmp = ByteOffset & 0xff; |
||||
if (i2c_writebyte (pi2c, &tmp) != OK) { |
||||
i2c_stop (pi2c); /* Disable I2c */ |
||||
return ERROR; |
||||
} |
||||
#else |
||||
if (i2c_writebyte (pi2c, &ByteOffset) != OK) { |
||||
i2c_stop (pi2c); /* Disable I2c */ |
||||
return ERROR; |
||||
} |
||||
#endif |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
STATUS i2c_stop (PSI2C pi2c) |
||||
{ |
||||
pi2c->cr &= ~I2C_CTL_STA; /* Generate stop signal */ |
||||
if (chk_status (pi2c, I2C_STA_BB, 0) != OK) |
||||
return ERROR; |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
/******************************************************************************
|
||||
* |
||||
* Read Len bytes to the location pointed to by *Data from the device |
||||
* with address Addr. |
||||
*/ |
||||
int i2c_readblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data) |
||||
{ |
||||
int i = 0; |
||||
UINT8 Tmp; |
||||
|
||||
/* UINT8 ByteOffset = pi2cSet->str_adr; not used? */ |
||||
UINT8 Addr = pi2cSet->slv_adr; |
||||
int Length = pi2cSet->xfer_size; |
||||
|
||||
I2CCDBG (L1, ("i2c_readblock addr %x data 0x%08x len %d offset %d\n", |
||||
Addr, (int) Data, Length, ByteOffset, 0, 0)); |
||||
|
||||
if (pi2c->sr & I2C_STA_AL) { /* Check if Arbitration lost */ |
||||
I2CCDBG (FN, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0)); |
||||
pi2c->sr &= ~I2C_STA_AL; /* Clear Arbitration status bit */ |
||||
return ERROR; |
||||
} |
||||
|
||||
pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack */ |
||||
|
||||
if (i2c_start (pi2c, pi2cSet) == ERROR) |
||||
return ERROR; |
||||
|
||||
pi2c->cr |= I2C_CTL_RSTA; /* Repeat Start */ |
||||
|
||||
Tmp = Addr | 1; |
||||
|
||||
if (i2c_writebyte (pi2c, &Tmp) != OK) { |
||||
i2c_stop (pi2c); /* Disable I2c */ |
||||
return ERROR; |
||||
} |
||||
|
||||
if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01)) |
||||
return ERROR; |
||||
|
||||
pi2c->cr &= ~I2C_CTL_TX; /* Set receive mode */ |
||||
|
||||
if (((pi2c->sr & 0x07) == 0x07) || (pi2c->sr & 0x01)) |
||||
return ERROR; |
||||
|
||||
/* Dummy Read */ |
||||
if (i2c_readbyte (pi2c, &Tmp, &i) != OK) { |
||||
i2c_stop (pi2c); /* Disable I2c */ |
||||
return ERROR; |
||||
} |
||||
|
||||
i = 0; |
||||
while (Length) { |
||||
if (Length == 2) |
||||
pi2c->cr |= I2C_CTL_TXAK; |
||||
|
||||
if (Length == 1) |
||||
pi2c->cr &= ~I2C_CTL_STA; |
||||
|
||||
if (i2c_readbyte (pi2c, Data, &Length) != OK) { |
||||
return i2c_stop (pi2c); |
||||
} |
||||
i++; |
||||
Length--; |
||||
Data++; |
||||
} |
||||
|
||||
if (i2c_stop (pi2c) == ERROR) |
||||
return ERROR; |
||||
|
||||
return i; |
||||
} |
||||
|
||||
STATUS i2c_writeblock (SI2C * pi2c, PI2CSET pi2cSet, UINT8 * Data) |
||||
{ |
||||
int Length = pi2cSet->xfer_size; |
||||
|
||||
#ifdef TWOBYTES |
||||
UINT16 ByteOffset = pi2cSet->str_adr; |
||||
#else |
||||
UINT8 ByteOffset = pi2cSet->str_adr; |
||||
#endif |
||||
int j, k; |
||||
|
||||
I2CCDBG (L2, ("i2c_writeblock\n", 0, 0, 0, 0, 0, 0)); |
||||
|
||||
if (pi2c->sr & I2C_STA_AL) { |
||||
/* Check if arbitration lost */ |
||||
I2CCDBG (L2, ("Arbitration lost\n", 0, 0, 0, 0, 0, 0)); |
||||
pi2c->sr &= ~I2C_STA_AL; /* Clear the condition */ |
||||
return ERROR; |
||||
} |
||||
|
||||
pi2c->cr |= I2C_CTL_TX; /* Enable the I2c for TX, Ack */ |
||||
|
||||
/* Do the not even offset first */ |
||||
if ((ByteOffset % 8) != 0) { |
||||
int remain; |
||||
|
||||
if (Length > 8) { |
||||
remain = 8 - (ByteOffset % 8); |
||||
Length -= remain; |
||||
|
||||
pi2cSet->str_adr = ByteOffset; |
||||
|
||||
if (i2c_start (pi2c, pi2cSet) == ERROR) |
||||
return ERROR; |
||||
|
||||
for (j = ByteOffset; j < remain; j++) { |
||||
if (i2c_writebyte (pi2c, Data++) != OK) |
||||
return ERROR; |
||||
} |
||||
|
||||
if (i2c_stop (pi2c) == ERROR) |
||||
return ERROR; |
||||
|
||||
sysMsDelay (32); |
||||
|
||||
/* Update the new ByteOffset */ |
||||
ByteOffset += remain; |
||||
} |
||||
} |
||||
|
||||
for (j = ByteOffset, k = 0; j < (Length + ByteOffset); j++) { |
||||
if ((j % 8) == 0) { |
||||
pi2cSet->str_adr = j; |
||||
if (i2c_start (pi2c, pi2cSet) == ERROR) |
||||
return ERROR; |
||||
} |
||||
|
||||
k++; |
||||
|
||||
if (i2c_writebyte (pi2c, Data++) != OK) |
||||
return ERROR; |
||||
|
||||
if ((j == (Length - 1)) || ((k % 8) == 0)) { |
||||
if (i2c_stop (pi2c) == ERROR) |
||||
return ERROR; |
||||
|
||||
sysMsDelay (50); |
||||
} |
||||
|
||||
} |
||||
|
||||
return k; |
||||
} |
||||
|
||||
STATUS i2c_readbyte (SI2C * pi2c, UINT8 * readb, int *index) |
||||
{ |
||||
pi2c->sr &= ~I2C_STA_IF; /* Clear Interrupt Bit */ |
||||
*readb = pi2c->dr; /* Read a byte */ |
||||
|
||||
/*
|
||||
Set I2C_CTRL_TXAK will cause Transfer pending and |
||||
set I2C_CTRL_STA will cause Interrupt pending |
||||
*/ |
||||
if (*index != 2) { |
||||
if (chk_status (pi2c, I2C_STA_CF, 1) != OK) /* Transfer not complete? */ |
||||
return ERROR; |
||||
} |
||||
|
||||
if (*index != 1) { |
||||
if (chk_status (pi2c, I2C_STA_IF, 1) != OK) |
||||
return ERROR; |
||||
} |
||||
|
||||
return (OK); |
||||
} |
||||
|
||||
|
||||
STATUS i2c_writebyte (SI2C * pi2c, UINT8 * writeb) |
||||
{ |
||||
pi2c->sr &= ~I2C_STA_IF; /* Clear Interrupt */ |
||||
pi2c->dr = *writeb; /* Write a byte */ |
||||
|
||||
if (chk_status (pi2c, I2C_STA_CF, 1) != OK) /* Transfer not complete? */ |
||||
return ERROR; |
||||
|
||||
if (chk_status (pi2c, I2C_STA_IF, 1) != OK) |
||||
return ERROR; |
||||
|
||||
return OK; |
||||
} |
||||
|
||||
STATUS i2c_write2byte (SI2C * pi2c, UINT16 * writeb) |
||||
{ |
||||
UINT8 data; |
||||
|
||||
data = (UINT8) ((*writeb >> 8) & 0xff); |
||||
if (i2c_writebyte (pi2c, &data) != OK) |
||||
return ERROR; |
||||
data = (UINT8) (*writeb & 0xff); |
||||
if (i2c_writebyte (pi2c, &data) != OK) |
||||
return ERROR; |
||||
return OK; |
||||
} |
||||
|
||||
/* FDR table base on 33Mhz - more detail please refer to Odini2c_dividers.xls
|
||||
FDR FDR scl sda scl2tap2 |
||||
510 432 tap tap tap tap scl_per sda_hold I2C Freq 0 1 2 3 4 5 |
||||
000 000 9 3 4 1 28 Clocks 9 Clocks 1190 KHz 0 0 0 0 0 0 |
||||
000 001 9 3 4 2 44 Clocks 11 Clocks 758 KHz 0 0 1 0 0 0 |
||||
000 010 9 3 6 4 80 Clocks 17 Clocks 417 KHz 0 0 0 1 0 0 |
||||
000 011 9 3 6 8 144 Clocks 25 Clocks 231 KHz 0 0 1 1 0 0 |
||||
000 100 9 3 14 16 288 Clocks 49 Clocks 116 KHz 0 0 0 0 1 0 |
||||
000 101 9 3 30 32 576 Clocks 97 Clocks 58 KHz 0 0 1 0 1 0 |
||||
000 110 9 3 62 64 1152 Clocks 193 Clocks 29 KHz 0 0 0 1 1 0 |
||||
000 111 9 3 126 128 2304 Clocks 385 Clocks 14 KHz 0 0 1 1 1 0 |
||||
001 000 10 3 4 1 30 Clocks 9 Clocks 1111 KHz1 0 0 0 0 0 |
||||
001 001 10 3 4 2 48 Clocks 11 Clocks 694 KHz 1 0 1 0 0 0 |
||||
001 010 10 3 6 4 88 Clocks 17 Clocks 379 KHz 1 0 0 1 0 0 |
||||
001 011 10 3 6 8 160 Clocks 25 Clocks 208 KHz 1 0 1 1 0 0 |
||||
001 100 10 3 14 16 320 Clocks 49 Clocks 104 KHz 1 0 0 0 1 0 |
||||
001 101 10 3 30 32 640 Clocks 97 Clocks 52 KHz 1 0 1 0 1 0 |
||||
001 110 10 3 62 64 1280 Clocks 193 Clocks 26 KHz 1 0 0 1 1 0 |
||||
001 111 10 3 126 128 2560 Clocks 385 Clocks 13 KHz 1 0 1 1 1 0 |
||||
010 000 12 4 4 1 34 Clocks 10 Clocks 980 KHz 0 1 0 0 0 0 |
||||
010 001 12 4 4 2 56 Clocks 13 Clocks 595 KHz 0 1 1 0 0 0 |
||||
010 010 12 4 6 4 104 Clocks 21 Clocks 321 KHz 0 1 0 1 0 0 |
||||
010 011 12 4 6 8 192 Clocks 33 Clocks 174 KHz 0 1 1 1 0 0 |
||||
010 100 12 4 14 16 384 Clocks 65 Clocks 87 KHz 0 1 0 0 1 0 |
||||
010 101 12 4 30 32 768 Clocks 129 Clocks 43 KHz 0 1 1 0 1 0 |
||||
010 110 12 4 62 64 1536 Clocks 257 Clocks 22 KHz 0 1 0 1 1 0 |
||||
010 111 12 4 126 128 3072 Clocks 513 Clocks 11 KHz 0 1 1 1 1 0 |
||||
011 000 15 4 4 1 40 Clocks 10 Clocks 833 KHz 1 1 0 0 0 0 |
||||
011 001 15 4 4 2 68 Clocks 13 Clocks 490 KHz 1 1 1 0 0 0 |
||||
011 010 15 4 6 4 128 Clocks 21 Clocks 260 KHz 1 1 0 1 0 0 |
||||
011 011 15 4 6 8 240 Clocks 33 Clocks 139 KHz 1 1 1 1 0 0 |
||||
011 100 15 4 14 16 480 Clocks 65 Clocks 69 KHz 1 1 0 0 1 0 |
||||
011 101 15 4 30 32 960 Clocks 129 Clocks 35 KHz 1 1 1 0 1 0 |
||||
011 110 15 4 62 64 1920 Clocks 257 Clocks 17 KHz 1 1 0 1 1 0 |
||||
011 111 15 4 126 128 3840 Clocks 513 Clocks 9 KHz 1 1 1 1 1 0 |
||||
100 000 5 1 4 1 20 Clocks 7 Clocks 1667 KHz 0 0 0 0 0 1 |
||||
100 001 5 1 4 2 28 Clocks 7 Clocks 1190 KHz 0 0 1 0 0 1 |
||||
100 010 5 1 6 4 48 Clocks 9 Clocks 694 KHz 0 0 0 1 0 1 |
||||
100 011 5 1 6 8 80 Clocks 9 Clocks 417 KHz 0 0 1 1 0 1 |
||||
100 100 5 1 14 16 160 Clocks 17 Clocks 208 KHz 0 0 0 0 1 1 |
||||
100 101 5 1 30 32 320 Clocks 33 Clocks 104 KHz 0 0 1 0 1 1 |
||||
100 110 5 1 62 64 640 Clocks 65 Clocks 52 KHz 0 0 0 1 1 1 |
||||
100 111 5 1 126 128 1280 Clocks 129 Clocks 26 KHz 0 0 1 1 1 1 |
||||
101 000 6 1 4 1 22 Clocks 7 Clocks 1515 KHz 1 0 0 0 0 1 |
||||
101 001 6 1 4 2 32 Clocks 7 Clocks 1042 KHz 1 0 1 0 0 1 |
||||
101 010 6 1 6 4 56 Clocks 9 Clocks 595 KHz 1 0 0 1 0 1 |
||||
101 011 6 1 6 8 96 Clocks 9 Clocks 347 KHz 1 0 1 1 0 1 |
||||
101 100 6 1 14 16 192 Clocks 17 Clocks 174 KHz 1 0 0 0 1 1 |
||||
101 101 6 1 30 32 384 Clocks 33 Clocks 87 KHz 1 0 1 0 1 1 |
||||
101 110 6 1 62 64 768 Clocks 65 Clocks 43 KHz 1 0 0 1 1 1 |
||||
101 111 6 1 126 128 1536 Clocks 129 Clocks 22 KHz 1 0 1 1 1 1 |
||||
110 000 7 2 4 1 24 Clocks 8 Clocks 1389 KHz 0 1 0 0 0 1 |
||||
110 001 7 2 4 2 36 Clocks 9 Clocks 926 KHz 0 1 1 0 0 1 |
||||
110 010 7 2 6 4 64 Clocks 13 Clocks 521 KHz 0 1 0 1 0 1 |
||||
110 011 7 2 6 8 112 Clocks 17 Clocks 298 KHz 0 1 1 1 0 1 |
||||
110 100 7 2 14 16 224 Clocks 33 Clocks 149 KHz 0 1 0 0 1 1 |
||||
110 101 7 2 30 32 448 Clocks 65 Clocks 74 KHz 0 1 1 0 1 1 |
||||
110 110 7 2 62 64 896 Clocks 129 Clocks 37 KHz 0 1 0 1 1 1 |
||||
110 111 7 2 126 128 1792 Clocks 257 Clocks 19 KHz 0 1 1 1 1 1 |
||||
111 000 8 2 4 1 26 Clocks 8 Clocks 1282 KHz 1 1 0 0 0 1 |
||||
111 001 8 2 4 2 40 Clocks 9 Clocks 833 KHz 1 1 1 0 0 1 |
||||
111 010 8 2 6 4 72 Clocks 13 Clocks 463 KHz 1 1 0 1 0 1 |
||||
111 011 8 2 6 8 128 Clocks 17 Clocks 260 KHz 1 1 1 1 0 1 |
||||
111 100 8 2 14 16 256 Clocks 33 Clocks 130 KHz 1 1 0 0 1 1 |
||||
111 101 8 2 30 32 512 Clocks 65 Clocks 65 KHz 1 1 1 0 1 1 |
||||
111 110 8 2 62 64 1024 Clocks 129 Clocks 33 KHz 1 1 0 1 1 1 |
||||
111 111 8 2 126 128 2048 Clocks 257 Clocks 16 KHz 1 1 1 1 1 1 |
||||
*/ |
||||
STATUS SetI2cFDR (PSI2C pi2cRegs, int bitrate) |
||||
{ |
||||
/* Constants */ |
||||
const UINT8 div_hold[8][3] = { {9, 3}, {10, 3}, |
||||
{12, 4}, {15, 4}, |
||||
{5, 1}, {6, 1}, |
||||
{7, 2}, {8, 2} |
||||
}; |
||||
|
||||
const UINT8 scl_tap[8][2] = { {4, 1}, {4, 2}, |
||||
{6, 4}, {6, 8}, |
||||
{14, 16}, {30, 32}, |
||||
{62, 64}, {126, 128} |
||||
}; |
||||
|
||||
UINT8 mfdr_bits; |
||||
|
||||
int i = 0; |
||||
int j = 0; |
||||
|
||||
int Diff, min; |
||||
int WhichFreq, iRec, jRec; |
||||
int SCL_Period; |
||||
int SCL_Hold; |
||||
int I2C_Freq; |
||||
|
||||
I2CCDBG (L2, ("Entering getBitRate: bitrate %d pi2cRegs 0x%08x\n", |
||||
bitrate, (int) pi2cRegs, 0, 0, 0, 0)); |
||||
|
||||
if (bitrate < 0) { |
||||
I2CCDBG (NO, ("Invalid bitrate\n", 0, 0, 0, 0, 0, 0)); |
||||
return ERROR; |
||||
} |
||||
|
||||
/* Initialize */ |
||||
mfdr_bits = 0; |
||||
min = 0x7fffffff; |
||||
WhichFreq = iRec = jRec = 0; |
||||
|
||||
for (i = 0; i < 8; i++) { |
||||
for (j = 0; j < 8; j++) { |
||||
/* SCL Period = 2 * (scl2tap + [(SCL_Tap - 1) * tap2tap] + 2)
|
||||
* SCL Hold = scl2tap + ((SDA_Tap - 1) * tap2tap) + 3 |
||||
* Bit Rate (I2C Freq) = System Freq / SCL Period |
||||
*/ |
||||
SCL_Period = |
||||
2 * (scl_tap[i][0] + |
||||
((div_hold[j][0] - 1) * scl_tap[i][1]) + |
||||
2); |
||||
|
||||
/* Now get the I2C Freq */ |
||||
I2C_Freq = DEV_CLOCK_FREQ / SCL_Period; |
||||
|
||||
/* Take equal or slower */ |
||||
if (I2C_Freq > bitrate) |
||||
continue; |
||||
|
||||
/* Take the differences */ |
||||
Diff = I2C_Freq - bitrate; |
||||
|
||||
Diff = ABS (Diff); |
||||
|
||||
/* Find the closer value */ |
||||
if (Diff < min) { |
||||
min = Diff; |
||||
WhichFreq = I2C_Freq; |
||||
iRec = i; |
||||
jRec = j; |
||||
} |
||||
|
||||
I2CCDBG (L2, |
||||
("--- (%d,%d) I2C_Freq %d minDiff %d min %d\n", |
||||
i, j, I2C_Freq, Diff, min, 0)); |
||||
} |
||||
} |
||||
|
||||
SCL_Period = |
||||
2 * (scl_tap[iRec][0] + |
||||
((div_hold[jRec][0] - 1) * scl_tap[iRec][1]) + 2); |
||||
|
||||
I2CCDBG (L2, ("\nmin %d WhichFreq %d iRec %d jRec %d\n", |
||||
min, WhichFreq, iRec, jRec, 0, 0)); |
||||
I2CCDBG (L2, ("--- scl2tap %d SCL_Tap %d tap2tap %d\n", |
||||
scl_tap[iRec][0], div_hold[jRec][0], scl_tap[iRec][1], |
||||
0, 0, 0)); |
||||
|
||||
/* This may no require */ |
||||
SCL_Hold = |
||||
scl_tap[iRec][0] + |
||||
((div_hold[jRec][1] - 1) * scl_tap[iRec][1]) + 3; |
||||
I2CCDBG (L2, |
||||
("--- SCL_Period %d SCL_Hold %d\n", SCL_Period, SCL_Hold, 0, |
||||
0, 0, 0)); |
||||
|
||||
I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0)); |
||||
|
||||
/* FDR 4,3,2 */ |
||||
if ((iRec & 1) == 1) |
||||
mfdr_bits |= 0x04; /* FDR 2 */ |
||||
if ((iRec & 2) == 2) |
||||
mfdr_bits |= 0x08; /* FDR 3 */ |
||||
if ((iRec & 4) == 4) |
||||
mfdr_bits |= 0x10; /* FDR 4 */ |
||||
/* FDR 5,1,0 */ |
||||
if ((jRec & 1) == 1) |
||||
mfdr_bits |= 0x01; /* FDR 0 */ |
||||
if ((jRec & 2) == 2) |
||||
mfdr_bits |= 0x02; /* FDR 1 */ |
||||
if ((jRec & 4) == 4) |
||||
mfdr_bits |= 0x20; /* FDR 5 */ |
||||
|
||||
I2CCDBG (L2, ("--- mfdr_bits %x\n", mfdr_bits, 0, 0, 0, 0, 0)); |
||||
|
||||
pi2cRegs->fdr = mfdr_bits; |
||||
|
||||
return OK; |
||||
} |
@ -0,0 +1,103 @@ |
||||
/*
|
||||
* i2cCore.h |
||||
* |
||||
* Prototypes, etc. for the Motorola MPC8220 |
||||
* embedded cpu chips |
||||
* |
||||
* 2004 (c) Freescale, Inc. |
||||
* Author: TsiChung Liew <Tsi-Chung.Liew@freescale.com> |
||||
* |
||||
* 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 |
||||
*/ |
||||
#ifndef __INCi2ccoreh |
||||
#define __INCi2ccoreh |
||||
#ifndef __ASSEMBLY__ |
||||
/* device types */ |
||||
#define I2C_DEVICE_TYPE_EEPROM 0 |
||||
#define I2C_EEPROM_ADRS 0xa0 |
||||
#define I2C_CTRL_ADRS I2C_EEPROM_ADRS |
||||
#define EEPROM_ADDR0 0xA2 /* on Dimm SPD eeprom */ |
||||
#define EEPROM_ADDR1 0xA4 /* on Board SPD eeprom */ |
||||
#define EEPROM_ADDR2 0xD2 /* non-standard eeprom - clock generator */ |
||||
/* Control Register */ |
||||
#define I2C_CTL_EN 0x80 /* I2C Enable */ |
||||
#define I2C_CTL_IEN 0x40 /* I2C Interrupt Enable */ |
||||
#define I2C_CTL_STA 0x20 /* Master/Slave Mode select */ |
||||
#define I2C_CTL_TX 0x10 /* Transmit/Receive Mode Select */ |
||||
#define I2C_CTL_TXAK 0x08 /* Transmit Acknowledge Enable */ |
||||
#define I2C_CTL_RSTA 0x04 /* Repeat Start */ |
||||
/* Status Register */ |
||||
#define I2C_STA_CF 0x80 /* Data Transfer */ |
||||
#define I2C_STA_AAS 0x40 /* Adressed As Slave */ |
||||
#define I2C_STA_BB 0x20 /* Bus Busy */ |
||||
#define I2C_STA_AL 0x10 /* Arbitration Lost */ |
||||
#define I2C_STA_SRW 0x04 /* Slave Read/Write */ |
||||
#define I2C_STA_IF 0x02 /* I2C Interrupt */ |
||||
#define I2C_STA_RXAK 0x01 /* Receive Acknowledge */ |
||||
/* Interrupt Contol Register */ |
||||
#define I2C_INT_BNBE2 0x80 /* Bus Not Busy Enable 2 */ |
||||
#define I2C_INT_TE2 0x40 /* Transmit Enable 2 */ |
||||
#define I2C_INT_RE2 0x20 /* Receive Enable 2 */ |
||||
#define I2C_INT_IE2 0x10 /* Interrupt Enable 2 */ |
||||
#define I2C_INT_BNBE1 0x08 /* Bus Not Busy Enable 1 */ |
||||
#define I2C_INT_TE1 0x04 /* Transmit Enable 1 */ |
||||
#define I2C_INT_RE1 0x02 /* Receive Enable 1 */ |
||||
#define I2C_INT_IE1 0x01 /* Interrupt Enable 1 */ |
||||
#define I2C_POLL_COUNT 0x100000 |
||||
#define I2C_ENABLE 0x00000001 |
||||
#define I2C_DISABLE 0x00000002 |
||||
#define I2C_START 0x00000004 |
||||
#define I2C_REPSTART 0x00000008 |
||||
#define I2C_STOP 0x00000010 |
||||
#define I2C_BITRATE 0x00000020 |
||||
#define I2C_SLAVEADR 0x00000040 |
||||
#define I2C_STARTADR 0x00000080 |
||||
#undef TWOBYTES |
||||
typedef struct i2c_settings { |
||||
/* Device settings */ |
||||
int bit_rate; /* Device bit rate */ |
||||
u8 i2c_adr; /* I2C address */ |
||||
u8 slv_adr; /* Slave address */ |
||||
#ifdef TWOBYTES |
||||
u16 str_adr; /* Start address */ |
||||
#else |
||||
u8 str_adr; /* Start address */ |
||||
#endif |
||||
int xfer_size; /* Transfer Size */ |
||||
|
||||
int bI2c_en; /* Enable or Disable */ |
||||
int cmdFlag; /* I2c Command Flags */ |
||||
} i2cset_t; |
||||
|
||||
/*
|
||||
int check_status(PSI2C pi2c, u8 sta_bit, u8 truefalse); |
||||
int i2c_enable(PSI2C pi2c, PI2CSET pi2cSet); |
||||
int i2c_disable(PSI2C pi2c); |
||||
int i2c_start(PSI2C pi2c, PI2CSET pi2cSet); |
||||
int i2c_stop(PSI2C pi2c); |
||||
int i2c_clear(PSI2C pi2c); |
||||
int i2c_readblock (PSI2C pi2c, PI2CSET pi2cSet, u8 *Data); |
||||
int i2c_writeblock (PSI2C pi2c, PI2CSET pi2cSet, u8 *Data); |
||||
int i2c_readbyte(PSI2C pi2c, u8 *readb, int *index); |
||||
int i2c_writebyte(PSI2C pi2c, u8 *writeb); |
||||
int SetI2cFDR( PSI2C pi2cRegs, int bitrate ); |
||||
*/ |
||||
#endif /* __ASSEMBLY__ */ |
||||
|
||||
#endif /* __INCi2ccoreh */ |
@ -0,0 +1,80 @@ |
||||
/*
|
||||
* (C) Copyright -2003 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* (C) Copyright 2001 |
||||
* Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc. |
||||
* |
||||
* 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 |
||||
*/ |
||||
|
||||
/*
|
||||
* interrupts.c - just enough support for the decrementer/timer |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/processor.h> |
||||
#include <command.h> |
||||
|
||||
int interrupt_init_cpu (ulong * decrementer_count) |
||||
{ |
||||
*decrementer_count = get_tbclk () / CFG_HZ; |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
/*
|
||||
* Handle external interrupts |
||||
*/ |
||||
void external_interrupt (struct pt_regs *regs) |
||||
{ |
||||
puts ("external_interrupt (oops!)\n"); |
||||
} |
||||
|
||||
void timer_interrupt_cpu (struct pt_regs *regs) |
||||
{ |
||||
/* nothing to do here */ |
||||
return; |
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
/*
|
||||
* Install and free a interrupt handler. |
||||
*/ |
||||
|
||||
void irq_install_handler (int vec, interrupt_handler_t * handler, void *arg) |
||||
{ |
||||
|
||||
} |
||||
|
||||
void irq_free_handler (int vec) |
||||
{ |
||||
|
||||
} |
||||
|
||||
/****************************************************************************/ |
||||
|
||||
void |
||||
do_irqinfo (cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[]) |
||||
{ |
||||
puts ("IRQ related functions are unimplemented currently.\n"); |
||||
} |
@ -0,0 +1,128 @@ |
||||
/* |
||||
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
|
||||
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> |
||||
* Copyright (C) 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> |
||||
* Andreas Heppel <aheppel@sysgo.de>
|
||||
* Copyright (C) 2003 Wolfgang Denk <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 <config.h> |
||||
#include <ppc_asm.tmpl> |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: in8 */ |
||||
/* Description: Input 8 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl in8
|
||||
in8: |
||||
lbz r3,0(r3) |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: in16 */ |
||||
/* Description: Input 16 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl in16
|
||||
in16: |
||||
lhz r3,0(r3) |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: in16r */ |
||||
/* Description: Input 16 bits and byte reverse */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl in16r
|
||||
in16r: |
||||
lhbrx r3,0,r3 |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: in32 */ |
||||
/* Description: Input 32 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl in32
|
||||
in32: |
||||
lwz 3,0(3) |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: in32r */ |
||||
/* Description: Input 32 bits and byte reverse */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl in32r
|
||||
in32r: |
||||
lwbrx r3,0,r3 |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: out8 */ |
||||
/* Description: Output 8 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl out8
|
||||
out8: |
||||
stb r4,0(r3) |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: out16 */ |
||||
/* Description: Output 16 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl out16
|
||||
out16: |
||||
sth r4,0(r3) |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: out16r */ |
||||
/* Description: Byte reverse and output 16 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl out16r
|
||||
out16r: |
||||
sthbrx r4,0,r3 |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: out32 */ |
||||
/* Description: Output 32 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl out32
|
||||
out32: |
||||
stw r4,0(r3) |
||||
sync |
||||
blr |
||||
|
||||
/* ------------------------------------------------------------------------------- */ |
||||
/* Function: out32r */ |
||||
/* Description: Byte reverse and output 32 bits */ |
||||
/* ------------------------------------------------------------------------------- */ |
||||
.globl out32r
|
||||
out32r: |
||||
stwbrx r4,0,r3 |
||||
sync |
||||
blr |
@ -0,0 +1,78 @@ |
||||
/*
|
||||
* (C) Copyright 2003 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* This file is based on code |
||||
* (C) Copyright Motorola, Inc., 2000 |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
|
||||
/* Multichannel DMA microcode */ |
||||
extern int taskTable; |
||||
|
||||
void loadtask (int basetask, int tasks) |
||||
{ |
||||
int *sram = (int *) (MMAP_SRAM + 512); |
||||
int *task_org = &taskTable; |
||||
unsigned int start, offset, end; |
||||
int i; |
||||
|
||||
#ifdef DEBUG |
||||
printf ("basetask = %d, tasks = %d\n", basetask, tasks); |
||||
printf ("task_org = 0x%08x\n", (unsigned int) task_org); |
||||
#endif |
||||
|
||||
/* setup TaskBAR register */ |
||||
*(vu_long *) MMAP_DMA = (MMAP_SRAM + 512); |
||||
|
||||
/* relocate task table entries */ |
||||
offset = (unsigned int) sram; |
||||
for (i = basetask; i < basetask + tasks; i++) { |
||||
sram[i * 8 + 0] = task_org[i * 8 + 0] + offset; |
||||
sram[i * 8 + 1] = task_org[i * 8 + 1] + offset; |
||||
sram[i * 8 + 2] = task_org[i * 8 + 2] + offset; |
||||
sram[i * 8 + 3] = task_org[i * 8 + 3] + offset; |
||||
sram[i * 8 + 4] = task_org[i * 8 + 4]; |
||||
sram[i * 8 + 5] = task_org[i * 8 + 5]; |
||||
sram[i * 8 + 6] = task_org[i * 8 + 6] + offset; |
||||
sram[i * 8 + 7] = task_org[i * 8 + 7]; |
||||
} |
||||
|
||||
/* relocate task descriptors */ |
||||
start = (sram[basetask * 8] - (unsigned int) sram); |
||||
end = (sram[(basetask + tasks - 1) * 8 + 1] - (unsigned int) sram); |
||||
|
||||
#ifdef DEBUG |
||||
printf ("TDT start = 0x%08x, end = 0x%08x\n", start, end); |
||||
#endif |
||||
|
||||
start /= 4; |
||||
end /= 4; |
||||
for (i = start; i <= end; i++) { |
||||
sram[i] = task_org[i]; |
||||
} |
||||
|
||||
/* relocate variables */ |
||||
start = (sram[basetask * 8 + 2] - (unsigned int) sram); |
||||
end = (sram[(basetask + tasks - 1) * 8 + 2] + 256 - |
||||
(unsigned int) sram); |
||||
start /= 4; |
||||
end /= 4; |
||||
for (i = start; i < end; i++) { |
||||
sram[i] = task_org[i]; |
||||
} |
||||
|
||||
/* relocate function decriptors */ |
||||
start = ((sram[basetask * 8 + 3] & 0xfffffffc) - (unsigned int) sram); |
||||
end = ((sram[(basetask + tasks - 1) * 8 + 3] & 0xfffffffc) + 256 - |
||||
(unsigned int) sram); |
||||
start /= 4; |
||||
end /= 4; |
||||
for (i = start; i < end; i++) { |
||||
sram[i] = task_org[i]; |
||||
} |
||||
|
||||
asm volatile ("sync"); |
||||
} |
@ -0,0 +1,119 @@ |
||||
/*
|
||||
* (C) Copyright 2004, Freescale, Inc |
||||
* TsiChung Liew, Tsi-Chung.Liew@freescale.com. |
||||
* |
||||
* 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 <mpc8220.h> |
||||
#include <asm/processor.h> |
||||
|
||||
typedef struct pllmultiplier { |
||||
u8 hid1; |
||||
int multi; |
||||
int vco_div; |
||||
} pllcfg_t; |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
||||
|
||||
/*
|
||||
* |
||||
*/ |
||||
|
||||
int get_clocks (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
pllcfg_t bus2core[] = { |
||||
{0x10, 2, 8}, /* 1 */ |
||||
{0x08, 2, 4}, |
||||
{0x60, 3, 8}, /* 1.5 */ |
||||
{0x00, 3, 4}, |
||||
{0xc0, 3, 2}, |
||||
{0x28, 4, 4}, /* 2 */ |
||||
{0x20, 4, 2}, |
||||
{0x88, 5, 4}, /* 2.5 */ |
||||
{0x30, 5, 2}, |
||||
{0x80, 6, 4}, /* 3 */ |
||||
{0x40, 6, 2}, |
||||
{0x70, 7, 2}, /* 3.5 */ |
||||
{0x50, 8, 2}, /* 4 */ |
||||
{0x38, 9, 2}, /* 4.5 */ |
||||
{0x58, 10, 2}, /* 5 */ |
||||
{0x48, 11, 2}, /* 5.5 */ |
||||
{0x68, 12, 2}, /* 6 */ |
||||
{0x90, 13, 2}, /* 6.5 */ |
||||
{0xa0, 14, 2}, /* 7 */ |
||||
{0xb0, 15, 2}, /* 7.5 */ |
||||
{0xe0, 16, 2} /* 8 */ |
||||
}; |
||||
u32 hid1; |
||||
int i, size; |
||||
|
||||
#if !defined(CFG_MPC8220_CLKIN) |
||||
#error clock measuring not implemented yet - define CFG_MPC8220_CLKIN |
||||
#endif |
||||
|
||||
gd->inp_clk = CFG_MPC8220_CLKIN; |
||||
|
||||
/* Bus clock is fixed at 120Mhz for now */ |
||||
/* will do dynamic in the future */ |
||||
gd->bus_clk = CFG_MPC8220_CLKIN * 4; |
||||
|
||||
/* PCI clock is same as input clock */ |
||||
gd->pci_clk = CFG_MPC8220_CLKIN; |
||||
|
||||
/* FlexBus is temporary set as the same as input clock */ |
||||
/* will do dynamic in the future */ |
||||
gd->flb_clk = CFG_MPC8220_CLKIN; |
||||
|
||||
/* CPU Clock - Read HID1 */ |
||||
asm volatile ("mfspr %0, 1009":"=r" (hid1):); |
||||
|
||||
size = sizeof (bus2core) / sizeof (pllcfg_t); |
||||
hid1 >>= 24; |
||||
|
||||
for (i = 0; i < size; i++) |
||||
if (hid1 == bus2core[i].hid1) { |
||||
gd->cpu_clk = (bus2core[i].multi * gd->bus_clk) >> 1; |
||||
/* Input Multiplier is determined by MPLL,
|
||||
hardcoded for now at 16 */ |
||||
gd->vco_clk = gd->pci_clk * 16; |
||||
break; |
||||
} |
||||
|
||||
/* hardcoded 81MHz for now */ |
||||
gd->pev_clk = 81000000; |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
int prt_mpc8220_clks (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
printf (" Bus %ld MHz, CPU %ld MHz, PCI %ld MHz, VCO %ld MHz\n", |
||||
gd->bus_clk / 1000000, gd->cpu_clk / 1000000, |
||||
gd->pci_clk / 1000000, gd->vco_clk / 1000000); |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
/* ------------------------------------------------------------------------- */ |
@ -0,0 +1,774 @@ |
||||
/* |
||||
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
|
||||
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> |
||||
* Copyright (C) 2000 - 2003 Wolfgang Denk <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 |
||||
*/ |
||||
|
||||
/* |
||||
* U-Boot - Startup Code for MPC8220 CPUs |
||||
*/ |
||||
#include <config.h> |
||||
#include <mpc8220.h> |
||||
#include <version.h> |
||||
|
||||
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ |
||||
|
||||
#include <ppc_asm.tmpl> |
||||
#include <ppc_defs.h> |
||||
|
||||
#include <asm/cache.h> |
||||
#include <asm/mmu.h> |
||||
|
||||
#ifndef CONFIG_IDENT_STRING |
||||
#define CONFIG_IDENT_STRING "" |
||||
#endif |
||||
|
||||
/* We don't want the MMU yet. |
||||
*/ |
||||
#undef MSR_KERNEL |
||||
/* Floating Point enable, Machine Check and Recoverable Interr. */ |
||||
#ifdef DEBUG |
||||
#define MSR_KERNEL (MSR_FP|MSR_RI) |
||||
#else |
||||
#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI) |
||||
#endif |
||||
|
||||
/* |
||||
* Set up GOT: Global Offset Table |
||||
* |
||||
* Use r14 to access the GOT |
||||
*/ |
||||
START_GOT |
||||
GOT_ENTRY(_GOT2_TABLE_) |
||||
GOT_ENTRY(_FIXUP_TABLE_) |
||||
|
||||
GOT_ENTRY(_start) |
||||
GOT_ENTRY(_start_of_vectors) |
||||
GOT_ENTRY(_end_of_vectors) |
||||
GOT_ENTRY(transfer_to_handler) |
||||
|
||||
GOT_ENTRY(__init_end) |
||||
GOT_ENTRY(_end) |
||||
GOT_ENTRY(__bss_start) |
||||
END_GOT |
||||
|
||||
/* |
||||
* Version string |
||||
*/ |
||||
.data |
||||
.globl version_string
|
||||
version_string: |
||||
.ascii U_BOOT_VERSION
|
||||
.ascii " (", __DATE__, " - ", __TIME__, ")" |
||||
.ascii CONFIG_IDENT_STRING, "\0" |
||||
|
||||
/* |
||||
* Exception vectors |
||||
*/ |
||||
.text |
||||
. = EXC_OFF_SYS_RESET |
||||
.globl _start
|
||||
_start: |
||||
li r21, BOOTFLAG_COLD /* Normal Power-On */ |
||||
nop |
||||
b boot_cold |
||||
|
||||
. = EXC_OFF_SYS_RESET + 0x10 |
||||
|
||||
.globl _start_warm
|
||||
_start_warm: |
||||
li r21, BOOTFLAG_WARM /* Software reboot */ |
||||
b boot_warm |
||||
|
||||
boot_cold: |
||||
boot_warm: |
||||
mfmsr r5 /* save msr contents */ |
||||
|
||||
/* replace default MBAR base address from 0x80000000 |
||||
to 0xf0000000 */ |
||||
|
||||
#if defined(CFG_DEFAULT_MBAR) && !defined(CFG_RAMBOOT) |
||||
lis r3, CFG_MBAR@h
|
||||
ori r3, r3, CFG_MBAR@l
|
||||
|
||||
/* MBAR is mirrored into the MBAR SPR */ |
||||
mtspr MBAR,r3 |
||||
lis r4, CFG_DEFAULT_MBAR@h
|
||||
stw r3, 0(r4) |
||||
#endif /* CFG_DEFAULT_MBAR */ |
||||
|
||||
/* Initialise the MPC8220 processor core */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
bl init_8220_core |
||||
|
||||
/* initialize some things that are hard to access from C */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
/* set up stack in on-chip SRAM */ |
||||
lis r3, CFG_INIT_RAM_ADDR@h
|
||||
ori r3, r3, CFG_INIT_RAM_ADDR@l
|
||||
ori r1, r3, CFG_INIT_SP_OFFSET |
||||
|
||||
li r0, 0 /* Make room for stack frame header and */ |
||||
stwu r0, -4(r1) /* clear final stack frame so that */ |
||||
stwu r0, -4(r1) /* stack backtraces terminate cleanly */ |
||||
|
||||
/* let the C-code set up the rest */ |
||||
/* */ |
||||
/* Be careful to keep code relocatable ! */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
GET_GOT /* initialize GOT access */ |
||||
|
||||
/* r3: IMMR */ |
||||
bl cpu_init_f /* run low-level CPU init code (in Flash)*/ |
||||
|
||||
mr r3, r21 |
||||
/* r3: BOOTFLAG */ |
||||
bl board_init_f /* run 1st part of board init code (in Flash)*/ |
||||
|
||||
/* |
||||
* Vector Table |
||||
*/ |
||||
|
||||
.globl _start_of_vectors
|
||||
_start_of_vectors: |
||||
|
||||
/* Machine check */ |
||||
STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) |
||||
|
||||
/* Data Storage exception. */ |
||||
STD_EXCEPTION(0x300, DataStorage, UnknownException) |
||||
|
||||
/* Instruction Storage exception. */ |
||||
STD_EXCEPTION(0x400, InstStorage, UnknownException) |
||||
|
||||
/* External Interrupt exception. */ |
||||
STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt) |
||||
|
||||
/* Alignment exception. */ |
||||
. = 0x600 |
||||
Alignment: |
||||
EXCEPTION_PROLOG |
||||
mfspr r4,DAR |
||||
stw r4,_DAR(r21) |
||||
mfspr r5,DSISR |
||||
stw r5,_DSISR(r21) |
||||
addi r3,r1,STACK_FRAME_OVERHEAD |
||||
li r20,MSR_KERNEL |
||||
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ |
||||
rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */ |
||||
lwz r6,GOT(transfer_to_handler) |
||||
mtlr r6 |
||||
blrl |
||||
.L_Alignment: |
||||
.long AlignmentException - _start + EXC_OFF_SYS_RESET |
||||
.long int_return - _start + EXC_OFF_SYS_RESET |
||||
|
||||
/* Program check exception */ |
||||
. = 0x700 |
||||
ProgramCheck: |
||||
EXCEPTION_PROLOG |
||||
addi r3,r1,STACK_FRAME_OVERHEAD |
||||
li r20,MSR_KERNEL |
||||
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ |
||||
rlwimi r20,r23,0,25,25 /* copy IP bit from saved MSR */ |
||||
lwz r6,GOT(transfer_to_handler) |
||||
mtlr r6 |
||||
blrl |
||||
.L_ProgramCheck: |
||||
.long ProgramCheckException - _start + EXC_OFF_SYS_RESET |
||||
.long int_return - _start + EXC_OFF_SYS_RESET |
||||
|
||||
STD_EXCEPTION(0x800, FPUnavailable, UnknownException) |
||||
|
||||
/* I guess we could implement decrementer, and may have |
||||
* to someday for timekeeping. |
||||
*/ |
||||
STD_EXCEPTION(0x900, Decrementer, timer_interrupt) |
||||
|
||||
STD_EXCEPTION(0xa00, Trap_0a, UnknownException) |
||||
STD_EXCEPTION(0xb00, Trap_0b, UnknownException) |
||||
STD_EXCEPTION(0xc00, SystemCall, UnknownException) |
||||
STD_EXCEPTION(0xd00, SingleStep, UnknownException) |
||||
|
||||
STD_EXCEPTION(0xe00, Trap_0e, UnknownException) |
||||
STD_EXCEPTION(0xf00, Trap_0f, UnknownException) |
||||
|
||||
STD_EXCEPTION(0x1000, InstructionTLBMiss, UnknownException) |
||||
STD_EXCEPTION(0x1100, DataLoadTLBMiss, UnknownException) |
||||
STD_EXCEPTION(0x1200, DataStoreTLBMiss, UnknownException) |
||||
#ifdef DEBUG |
||||
. = 0x1300 |
||||
/* |
||||
* This exception occurs when the program counter matches the |
||||
* Instruction Address Breakpoint Register (IABR). |
||||
* |
||||
* I want the cpu to halt if this occurs so I can hunt around |
||||
* with the debugger and look at things. |
||||
* |
||||
* When DEBUG is defined, both machine check enable (in the MSR) |
||||
* and checkstop reset enable (in the reset mode register) are |
||||
* turned off and so a checkstop condition will result in the cpu |
||||
* halting. |
||||
* |
||||
* I force the cpu into a checkstop condition by putting an illegal |
||||
* instruction here (at least this is the theory). |
||||
* |
||||
* well - that didnt work, so just do an infinite loop! |
||||
*/ |
||||
1: b 1b |
||||
#else |
||||
STD_EXCEPTION(0x1300, InstructionBreakpoint, DebugException) |
||||
#endif |
||||
STD_EXCEPTION(0x1400, SMI, UnknownException) |
||||
|
||||
STD_EXCEPTION(0x1500, Trap_15, UnknownException) |
||||
STD_EXCEPTION(0x1600, Trap_16, UnknownException) |
||||
STD_EXCEPTION(0x1700, Trap_17, UnknownException) |
||||
STD_EXCEPTION(0x1800, Trap_18, UnknownException) |
||||
STD_EXCEPTION(0x1900, Trap_19, UnknownException) |
||||
STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) |
||||
STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) |
||||
STD_EXCEPTION(0x1c00, Trap_1c, UnknownException) |
||||
STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) |
||||
STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) |
||||
STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) |
||||
STD_EXCEPTION(0x2000, Trap_20, UnknownException) |
||||
STD_EXCEPTION(0x2100, Trap_21, UnknownException) |
||||
STD_EXCEPTION(0x2200, Trap_22, UnknownException) |
||||
STD_EXCEPTION(0x2300, Trap_23, UnknownException) |
||||
STD_EXCEPTION(0x2400, Trap_24, UnknownException) |
||||
STD_EXCEPTION(0x2500, Trap_25, UnknownException) |
||||
STD_EXCEPTION(0x2600, Trap_26, UnknownException) |
||||
STD_EXCEPTION(0x2700, Trap_27, UnknownException) |
||||
STD_EXCEPTION(0x2800, Trap_28, UnknownException) |
||||
STD_EXCEPTION(0x2900, Trap_29, UnknownException) |
||||
STD_EXCEPTION(0x2a00, Trap_2a, UnknownException) |
||||
STD_EXCEPTION(0x2b00, Trap_2b, UnknownException) |
||||
STD_EXCEPTION(0x2c00, Trap_2c, UnknownException) |
||||
STD_EXCEPTION(0x2d00, Trap_2d, UnknownException) |
||||
STD_EXCEPTION(0x2e00, Trap_2e, UnknownException) |
||||
STD_EXCEPTION(0x2f00, Trap_2f, UnknownException) |
||||
|
||||
|
||||
.globl _end_of_vectors
|
||||
_end_of_vectors: |
||||
|
||||
. = 0x3000 |
||||
|
||||
/* |
||||
* This code finishes saving the registers to the exception frame |
||||
* and jumps to the appropriate handler for the exception. |
||||
* Register r21 is pointer into trap frame, r1 has new stack pointer. |
||||
*/ |
||||
.globl transfer_to_handler
|
||||
transfer_to_handler: |
||||
stw r22,_NIP(r21) |
||||
lis r22,MSR_POW@h
|
||||
andc r23,r23,r22 |
||||
stw r23,_MSR(r21) |
||||
SAVE_GPR(7, r21) |
||||
SAVE_4GPRS(8, r21) |
||||
SAVE_8GPRS(12, r21) |
||||
SAVE_8GPRS(24, r21) |
||||
mflr r23 |
||||
andi. r24,r23,0x3f00 /* get vector offset */ |
||||
stw r24,TRAP(r21) |
||||
li r22,0 |
||||
stw r22,RESULT(r21) |
||||
lwz r24,0(r23) /* virtual address of handler */ |
||||
lwz r23,4(r23) /* where to go when done */ |
||||
mtspr SRR0,r24 |
||||
mtspr SRR1,r20 |
||||
mtlr r23 |
||||
SYNC |
||||
rfi /* jump to handler, enable MMU */ |
||||
|
||||
int_return: |
||||
mfmsr r28 /* Disable interrupts */ |
||||
li r4,0 |
||||
ori r4,r4,MSR_EE |
||||
andc r28,r28,r4 |
||||
SYNC /* Some chip revs need this... */ |
||||
mtmsr r28 |
||||
SYNC |
||||
lwz r2,_CTR(r1) |
||||
lwz r0,_LINK(r1) |
||||
mtctr r2 |
||||
mtlr r0 |
||||
lwz r2,_XER(r1) |
||||
lwz r0,_CCR(r1) |
||||
mtspr XER,r2 |
||||
mtcrf 0xFF,r0 |
||||
REST_10GPRS(3, r1) |
||||
REST_10GPRS(13, r1) |
||||
REST_8GPRS(23, r1) |
||||
REST_GPR(31, r1) |
||||
lwz r2,_NIP(r1) /* Restore environment */ |
||||
lwz r0,_MSR(r1) |
||||
mtspr SRR0,r2 |
||||
mtspr SRR1,r0 |
||||
lwz r0,GPR0(r1) |
||||
lwz r2,GPR2(r1) |
||||
lwz r1,GPR1(r1) |
||||
SYNC |
||||
rfi |
||||
|
||||
/* |
||||
* This code initialises the MPC8220 processor core |
||||
* (conforms to PowerPC 603e spec) |
||||
* Note: expects original MSR contents to be in r5. |
||||
*/ |
||||
|
||||
.globl init_8220_core
|
||||
init_8220_core: |
||||
|
||||
/* Initialize machine status; enable machine check interrupt */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
li r3, MSR_KERNEL /* Set ME and RI flags */ |
||||
rlwimi r3, r5, 0, 25, 25 /* preserve IP bit set by HRCW */ |
||||
#ifdef DEBUG |
||||
rlwimi r3, r5, 0, 21, 22 /* debugger might set SE & BE bits */ |
||||
#endif |
||||
SYNC /* Some chip revs need this... */ |
||||
mtmsr r3 |
||||
SYNC |
||||
mtspr SRR1, r3 /* Make SRR1 match MSR */ |
||||
|
||||
/* Initialize the Hardware Implementation-dependent Registers */ |
||||
/* HID0 also contains cache control */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
lis r3, CFG_HID0_INIT@h
|
||||
ori r3, r3, CFG_HID0_INIT@l
|
||||
SYNC |
||||
mtspr HID0, r3 |
||||
|
||||
lis r3, CFG_HID0_FINAL@h
|
||||
ori r3, r3, CFG_HID0_FINAL@l
|
||||
SYNC |
||||
mtspr HID0, r3 |
||||
|
||||
/* Enable Extra BATs */ |
||||
mfspr r3, 1011 /* HID2 */ |
||||
lis r4, 0x0004 |
||||
ori r4, r4, 0x0000 |
||||
or r4, r4, r3 |
||||
mtspr 1011, r4 |
||||
sync |
||||
|
||||
/* clear all BAT's */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
li r0, 0 |
||||
mtspr DBAT0U, r0 |
||||
mtspr DBAT0L, r0 |
||||
mtspr DBAT1U, r0 |
||||
mtspr DBAT1L, r0 |
||||
mtspr DBAT2U, r0 |
||||
mtspr DBAT2L, r0 |
||||
mtspr DBAT3U, r0 |
||||
mtspr DBAT3L, r0 |
||||
mtspr DBAT4U, r0 |
||||
mtspr DBAT4L, r0 |
||||
mtspr DBAT5U, r0 |
||||
mtspr DBAT5L, r0 |
||||
mtspr DBAT6U, r0 |
||||
mtspr DBAT6L, r0 |
||||
mtspr DBAT7U, r0 |
||||
mtspr DBAT7L, r0 |
||||
mtspr IBAT0U, r0 |
||||
mtspr IBAT0L, r0 |
||||
mtspr IBAT1U, r0 |
||||
mtspr IBAT1L, r0 |
||||
mtspr IBAT2U, r0 |
||||
mtspr IBAT2L, r0 |
||||
mtspr IBAT3U, r0 |
||||
mtspr IBAT3L, r0 |
||||
mtspr IBAT4U, r0 |
||||
mtspr IBAT4L, r0 |
||||
mtspr IBAT5U, r0 |
||||
mtspr IBAT5L, r0 |
||||
mtspr IBAT6U, r0 |
||||
mtspr IBAT6L, r0 |
||||
mtspr IBAT7U, r0 |
||||
mtspr IBAT7L, r0 |
||||
SYNC |
||||
|
||||
/* invalidate all tlb's */ |
||||
/* */ |
||||
/* From the 603e User Manual: "The 603e provides the ability to */ |
||||
/* invalidate a TLB entry. The TLB Invalidate Entry (tlbie) */ |
||||
/* instruction invalidates the TLB entry indexed by the EA, and */ |
||||
/* operates on both the instruction and data TLBs simultaneously*/ |
||||
/* invalidating four TLB entries (both sets in each TLB). The */ |
||||
/* index corresponds to bits 15-19 of the EA. To invalidate all */ |
||||
/* entries within both TLBs, 32 tlbie instructions should be */ |
||||
/* issued, incrementing this field by one each time." */ |
||||
/* */ |
||||
/* "Note that the tlbia instruction is not implemented on the */ |
||||
/* 603e." */ |
||||
/* */ |
||||
/* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000 */ |
||||
/* incrementing by 0x1000 each time. The code below is sort of */ |
||||
/* based on code in "flush_tlbs" from arch/ppc/kernel/head.S */ |
||||
/* */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
li r3, 32 |
||||
mtctr r3 |
||||
li r3, 0 |
||||
1: tlbie r3 |
||||
addi r3, r3, 0x1000 |
||||
bdnz 1b |
||||
SYNC |
||||
|
||||
/* Done! */ |
||||
/*--------------------------------------------------------------*/ |
||||
|
||||
blr |
||||
|
||||
/* Cache functions. |
||||
* |
||||
* Note: requires that all cache bits in |
||||
* HID0 are in the low half word. |
||||
*/ |
||||
.globl icache_enable
|
||||
icache_enable: |
||||
lis r4, 0 |
||||
ori r4, r4, CFG_HID0_INIT /* set ICE & ICFI bit */ |
||||
rlwinm r3, r4, 0, 21, 19 /* clear the ICFI bit */ |
||||
|
||||
/* |
||||
* The setting of the instruction cache enable (ICE) bit must be |
||||
* preceded by an isync instruction to prevent the cache from being |
||||
* enabled or disabled while an instruction access is in progress. |
||||
*/ |
||||
isync |
||||
mtspr HID0, r4 /* Enable Instr Cache & Inval cache */ |
||||
mtspr HID0, r3 /* using 2 consec instructions */ |
||||
isync |
||||
blr |
||||
|
||||
.globl icache_disable
|
||||
icache_disable: |
||||
mfspr r3, HID0 |
||||
rlwinm r3, r3, 0, 17, 15 /* clear the ICE bit */ |
||||
mtspr HID0, r3 |
||||
isync |
||||
blr |
||||
|
||||
.globl icache_status
|
||||
icache_status: |
||||
mfspr r3, HID0 |
||||
rlwinm r3, r3, HID0_ICE_BITPOS + 1, 31, 31 |
||||
blr |
||||
|
||||
.globl dcache_enable
|
||||
dcache_enable: |
||||
lis r4, 0 |
||||
ori r4, r4, HID0_DCE|HID0_DCFI /* set DCE & DCFI bit */ |
||||
rlwinm r3, r4, 0, 22, 20 /* clear the DCFI bit */ |
||||
|
||||
/* Enable address translation in MSR bit */ |
||||
mfmsr r5 |
||||
ori r5, r5, 0x |
||||
|
||||
|
||||
/* |
||||
* The setting of the instruction cache enable (ICE) bit must be |
||||
* preceded by an isync instruction to prevent the cache from being |
||||
* enabled or disabled while an instruction access is in progress. |
||||
*/ |
||||
isync |
||||
mtspr HID0, r4 /* Enable Data Cache & Inval cache*/ |
||||
mtspr HID0, r3 /* using 2 consec instructions */ |
||||
isync |
||||
blr |
||||
|
||||
.globl dcache_disable
|
||||
dcache_disable: |
||||
mfspr r3, HID0 |
||||
rlwinm r3, r3, 0, 18, 16 /* clear the DCE bit */ |
||||
mtspr HID0, r3 |
||||
isync |
||||
blr |
||||
|
||||
.globl dcache_status
|
||||
dcache_status: |
||||
mfspr r3, HID0 |
||||
rlwinm r3, r3, HID0_DCE_BITPOS + 1, 31, 31 |
||||
blr |
||||
|
||||
.globl get_pvr
|
||||
get_pvr: |
||||
mfspr r3, PVR |
||||
blr |
||||
|
||||
/*------------------------------------------------------------------------------*/ |
||||
|
||||
/* |
||||
* void relocate_code (addr_sp, gd, addr_moni) |
||||
* |
||||
* This "function" does not return, instead it continues in RAM |
||||
* after relocating the monitor code. |
||||
* |
||||
* r3 = dest |
||||
* r4 = src |
||||
* r5 = length in bytes |
||||
* r6 = cachelinesize |
||||
*/ |
||||
.globl relocate_code
|
||||
relocate_code: |
||||
mr r1, r3 /* Set new stack pointer */ |
||||
mr r9, r4 /* Save copy of Global Data pointer */ |
||||
mr r10, r5 /* Save copy of Destination Address */ |
||||
|
||||
mr r3, r5 /* Destination Address */ |
||||
lis r4, CFG_MONITOR_BASE@h /* Source Address */
|
||||
ori r4, r4, CFG_MONITOR_BASE@l
|
||||
lwz r5, GOT(__init_end) |
||||
sub r5, r5, r4 |
||||
li r6, CFG_CACHELINE_SIZE /* Cache Line Size */ |
||||
|
||||
/* |
||||
* Fix GOT pointer: |
||||
* |
||||
* New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address |
||||
* |
||||
* Offset: |
||||
*/ |
||||
sub r15, r10, r4 |
||||
|
||||
/* First our own GOT */ |
||||
add r14, r14, r15 |
||||
/* then the one used by the C code */ |
||||
add r30, r30, r15 |
||||
|
||||
/* |
||||
* Now relocate code |
||||
*/ |
||||
|
||||
cmplw cr1,r3,r4 |
||||
addi r0,r5,3 |
||||
srwi. r0,r0,2 |
||||
beq cr1,4f /* In place copy is not necessary */ |
||||
beq 7f /* Protect against 0 count */ |
||||
mtctr r0 |
||||
bge cr1,2f |
||||
|
||||
la r8,-4(r4) |
||||
la r7,-4(r3) |
||||
1: lwzu r0,4(r8) |
||||
stwu r0,4(r7) |
||||
bdnz 1b |
||||
b 4f |
||||
|
||||
2: slwi r0,r0,2 |
||||
add r8,r4,r0 |
||||
add r7,r3,r0 |
||||
3: lwzu r0,-4(r8) |
||||
stwu r0,-4(r7) |
||||
bdnz 3b |
||||
|
||||
/* |
||||
* Now flush the cache: note that we must start from a cache aligned |
||||
* address. Otherwise we might miss one cache line. |
||||
*/ |
||||
4: cmpwi r6,0 |
||||
add r5,r3,r5 |
||||
beq 7f /* Always flush prefetch queue in any case */ |
||||
subi r0,r6,1 |
||||
andc r3,r3,r0 |
||||
mfspr r7,HID0 /* don't do dcbst if dcache is disabled */ |
||||
rlwinm r7,r7,HID0_DCE_BITPOS+1,31,31 |
||||
cmpwi r7,0 |
||||
beq 9f |
||||
mr r4,r3 |
||||
5: dcbst 0,r4 |
||||
add r4,r4,r6 |
||||
cmplw r4,r5 |
||||
blt 5b |
||||
sync /* Wait for all dcbst to complete on bus */ |
||||
9: mfspr r7,HID0 /* don't do icbi if icache is disabled */ |
||||
rlwinm r7,r7,HID0_ICE_BITPOS+1,31,31 |
||||
cmpwi r7,0 |
||||
beq 7f |
||||
mr r4,r3 |
||||
6: icbi 0,r4 |
||||
add r4,r4,r6 |
||||
cmplw r4,r5 |
||||
blt 6b |
||||
7: sync /* Wait for all icbi to complete on bus */ |
||||
isync |
||||
|
||||
/* |
||||
* We are done. Do not return, instead branch to second part of board |
||||
* initialization, now running from RAM. |
||||
*/ |
||||
|
||||
addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET |
||||
mtlr r0 |
||||
blr |
||||
|
||||
in_ram: |
||||
|
||||
/* |
||||
* Relocation Function, r14 point to got2+0x8000 |
||||
* |
||||
* Adjust got2 pointers, no need to check for 0, this code |
||||
* already puts a few entries in the table. |
||||
*/ |
||||
li r0,__got2_entries@sectoff@l
|
||||
la r3,GOT(_GOT2_TABLE_) |
||||
lwz r11,GOT(_GOT2_TABLE_) |
||||
mtctr r0 |
||||
sub r11,r3,r11 |
||||
addi r3,r3,-4 |
||||
1: lwzu r0,4(r3) |
||||
add r0,r0,r11 |
||||
stw r0,0(r3) |
||||
bdnz 1b |
||||
|
||||
/* |
||||
* Now adjust the fixups and the pointers to the fixups |
||||
* in case we need to move ourselves again. |
||||
*/ |
||||
2: li r0,__fixup_entries@sectoff@l
|
||||
lwz r3,GOT(_FIXUP_TABLE_) |
||||
cmpwi r0,0 |
||||
mtctr r0 |
||||
addi r3,r3,-4 |
||||
beq 4f |
||||
3: lwzu r4,4(r3) |
||||
lwzux r0,r4,r11 |
||||
add r0,r0,r11 |
||||
stw r10,0(r3) |
||||
stw r0,0(r4) |
||||
bdnz 3b |
||||
4: |
||||
clear_bss: |
||||
/* |
||||
* Now clear BSS segment |
||||
*/ |
||||
lwz r3,GOT(__bss_start) |
||||
lwz r4,GOT(_end) |
||||
|
||||
cmplw 0, r3, r4 |
||||
beq 6f |
||||
|
||||
li r0, 0 |
||||
5: |
||||
stw r0, 0(r3) |
||||
addi r3, r3, 4 |
||||
cmplw 0, r3, r4 |
||||
bne 5b |
||||
6: |
||||
|
||||
mr r3, r9 /* Global Data pointer */ |
||||
mr r4, r10 /* Destination Address */ |
||||
bl board_init_r |
||||
|
||||
/* |
||||
* Copy exception vector code to low memory |
||||
* |
||||
* r3: dest_addr |
||||
* r7: source address, r8: end address, r9: target address |
||||
*/ |
||||
.globl trap_init
|
||||
trap_init: |
||||
lwz r7, GOT(_start) |
||||
lwz r8, GOT(_end_of_vectors) |
||||
|
||||
li r9, 0x100 /* reset vector always at 0x100 */ |
||||
|
||||
cmplw 0, r7, r8 |
||||
bgelr /* return if r7>=r8 - just in case */ |
||||
|
||||
mflr r4 /* save link register */ |
||||
1: |
||||
lwz r0, 0(r7) |
||||
stw r0, 0(r9) |
||||
addi r7, r7, 4 |
||||
addi r9, r9, 4 |
||||
cmplw 0, r7, r8 |
||||
bne 1b |
||||
|
||||
/* |
||||
* relocate `hdlr' and `int_return' entries |
||||
*/ |
||||
li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET |
||||
li r8, Alignment - _start + EXC_OFF_SYS_RESET |
||||
2: |
||||
bl trap_reloc |
||||
addi r7, r7, 0x100 /* next exception vector */ |
||||
cmplw 0, r7, r8 |
||||
blt 2b |
||||
|
||||
li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET |
||||
bl trap_reloc |
||||
|
||||
li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET |
||||
bl trap_reloc |
||||
|
||||
li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET |
||||
li r8, SystemCall - _start + EXC_OFF_SYS_RESET |
||||
3: |
||||
bl trap_reloc |
||||
addi r7, r7, 0x100 /* next exception vector */ |
||||
cmplw 0, r7, r8 |
||||
blt 3b |
||||
|
||||
li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET |
||||
li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET |
||||
4: |
||||
bl trap_reloc |
||||
addi r7, r7, 0x100 /* next exception vector */ |
||||
cmplw 0, r7, r8 |
||||
blt 4b |
||||
|
||||
mfmsr r3 /* now that the vectors have */ |
||||
lis r7, MSR_IP@h /* relocated into low memory */
|
||||
ori r7, r7, MSR_IP@l /* MSR[IP] can be turned off */
|
||||
andc r3, r3, r7 /* (if it was on) */ |
||||
SYNC /* Some chip revs need this... */ |
||||
mtmsr r3 |
||||
SYNC |
||||
|
||||
mtlr r4 /* restore link register */ |
||||
blr |
||||
|
||||
/* |
||||
* Function: relocate entries for one exception vector |
||||
*/ |
||||
trap_reloc: |
||||
lwz r0, 0(r7) /* hdlr ... */ |
||||
add r0, r0, r3 /* ... += dest_addr */ |
||||
stw r0, 0(r7) |
||||
|
||||
lwz r0, 4(r7) /* int_return ... */ |
||||
add r0, r0, r3 /* ... += dest_addr */ |
||||
stw r0, 4(r7) |
||||
|
||||
blr |
@ -0,0 +1,239 @@ |
||||
/*
|
||||
* linux/arch/ppc/kernel/traps.c |
||||
* |
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
||||
* |
||||
* Modified by Cort Dougan (cort@cs.nmt.edu) |
||||
* and Paul Mackerras (paulus@cs.anu.edu.au) |
||||
* fixed Machine Check Reasons by Reinhard Meyer (r.meyer@emk-elektronik.de) |
||||
* |
||||
* (C) Copyright 2000-2003 |
||||
* 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 |
||||
*/ |
||||
|
||||
/*
|
||||
* This file handles the architecture-dependent parts of hardware exceptions |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <asm/processor.h> |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
int (*debugger_exception_handler) (struct pt_regs *) = 0; |
||||
#endif |
||||
|
||||
/* Returns 0 if exception not found and fixup otherwise. */ |
||||
extern unsigned long search_exception_table (unsigned long); |
||||
|
||||
/* THIS NEEDS CHANGING to use the board info structure.
|
||||
*/ |
||||
#define END_OF_MEM 0x02000000 |
||||
|
||||
/*
|
||||
* Trap & Exception support |
||||
*/ |
||||
|
||||
void print_backtrace (unsigned long *sp) |
||||
{ |
||||
int cnt = 0; |
||||
unsigned long i; |
||||
|
||||
printf ("Call backtrace: "); |
||||
while (sp) { |
||||
if ((uint) sp > END_OF_MEM) |
||||
break; |
||||
|
||||
i = sp[1]; |
||||
if (cnt++ % 7 == 0) |
||||
printf ("\n"); |
||||
printf ("%08lX ", i); |
||||
if (cnt > 32) |
||||
break; |
||||
sp = (unsigned long *) *sp; |
||||
} |
||||
printf ("\n"); |
||||
} |
||||
|
||||
void show_regs (struct pt_regs *regs) |
||||
{ |
||||
int i; |
||||
|
||||
printf ("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n", |
||||
regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar); |
||||
printf ("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", |
||||
regs->msr, |
||||
regs->msr & MSR_EE ? 1 : 0, regs->msr & MSR_PR ? 1 : 0, |
||||
regs->msr & MSR_FP ? 1 : 0, regs->msr & MSR_ME ? 1 : 0, |
||||
regs->msr & MSR_IR ? 1 : 0, regs->msr & MSR_DR ? 1 : 0); |
||||
|
||||
printf ("\n"); |
||||
for (i = 0; i < 32; i++) { |
||||
if ((i % 8) == 0) { |
||||
printf ("GPR%02d: ", i); |
||||
} |
||||
|
||||
printf ("%08lX ", regs->gpr[i]); |
||||
if ((i % 8) == 7) { |
||||
printf ("\n"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
void _exception (int signr, struct pt_regs *regs) |
||||
{ |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *) regs->gpr[1]); |
||||
panic ("Exception in kernel pc %lx signal %d", regs->nip, signr); |
||||
} |
||||
|
||||
void MachineCheckException (struct pt_regs *regs) |
||||
{ |
||||
unsigned long fixup; |
||||
|
||||
/* Probing PCI using config cycles cause this exception
|
||||
* when a device is not present. Catch it and return to |
||||
* the PCI exception handler. |
||||
*/ |
||||
if ((fixup = search_exception_table (regs->nip)) != 0) { |
||||
regs->nip = fixup; |
||||
return; |
||||
} |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler |
||||
&& (*debugger_exception_handler) (regs)) |
||||
return; |
||||
#endif |
||||
|
||||
printf ("Machine check in kernel mode.\n"); |
||||
printf ("Caused by (from msr): "); |
||||
printf ("regs %p ", regs); |
||||
/* refer to 603e Manual (MPC603EUM/AD), chapter 4.5.2.1 */ |
||||
switch (regs->msr & 0x000F0000) { |
||||
case (0x80000000 >> 12): |
||||
printf ("Machine check signal - probably due to mm fault\n" |
||||
"with mmu off\n"); |
||||
break; |
||||
case (0x80000000 >> 13): |
||||
printf ("Transfer error ack signal\n"); |
||||
break; |
||||
case (0x80000000 >> 14): |
||||
printf ("Data parity signal\n"); |
||||
break; |
||||
case (0x80000000 >> 15): |
||||
printf ("Address parity signal\n"); |
||||
break; |
||||
default: |
||||
printf ("Unknown values in msr\n"); |
||||
} |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *) regs->gpr[1]); |
||||
panic ("machine check"); |
||||
} |
||||
|
||||
void AlignmentException (struct pt_regs *regs) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler |
||||
&& (*debugger_exception_handler) (regs)) |
||||
return; |
||||
#endif |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *) regs->gpr[1]); |
||||
panic ("Alignment Exception"); |
||||
} |
||||
|
||||
void ProgramCheckException (struct pt_regs *regs) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler |
||||
&& (*debugger_exception_handler) (regs)) |
||||
return; |
||||
#endif |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *) regs->gpr[1]); |
||||
panic ("Program Check Exception"); |
||||
} |
||||
|
||||
void SoftEmuException (struct pt_regs *regs) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler |
||||
&& (*debugger_exception_handler) (regs)) |
||||
return; |
||||
#endif |
||||
show_regs (regs); |
||||
print_backtrace ((unsigned long *) regs->gpr[1]); |
||||
panic ("Software Emulation Exception"); |
||||
} |
||||
|
||||
|
||||
void UnknownException (struct pt_regs *regs) |
||||
{ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
if (debugger_exception_handler |
||||
&& (*debugger_exception_handler) (regs)) |
||||
return; |
||||
#endif |
||||
printf ("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", |
||||
regs->nip, regs->msr, regs->trap); |
||||
_exception (0, regs); |
||||
} |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) |
||||
extern void do_bedbug_breakpoint (struct pt_regs *); |
||||
#endif |
||||
|
||||
void DebugException (struct pt_regs *regs) |
||||
{ |
||||
|
||||
printf ("Debugger trap at @ %lx\n", regs->nip); |
||||
show_regs (regs); |
||||
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) |
||||
do_bedbug_breakpoint (regs); |
||||
#endif |
||||
} |
||||
|
||||
/* Probe an address by reading. If not present, return -1, otherwise
|
||||
* return 0. |
||||
*/ |
||||
int addr_probe (uint * addr) |
||||
{ |
||||
#if 0 |
||||
int retval; |
||||
|
||||
__asm__ __volatile__ ("1: lwz %0,0(%1)\n" |
||||
" eieio\n" |
||||
" li %0,0\n" |
||||
"2:\n" |
||||
".section .fixup,\"ax\"\n" |
||||
"3: li %0,-1\n" |
||||
" b 2b\n" |
||||
".section __ex_table,\"a\"\n" |
||||
" .align 2\n" |
||||
" .long 1b,3b\n" |
||||
".text":"=r" (retval):"r" (addr)); |
||||
|
||||
return (retval); |
||||
#endif |
||||
return 0; |
||||
} |
@ -0,0 +1,128 @@ |
||||
/*
|
||||
* (C) Copyright 2004, Freescale, Inc |
||||
* TsiChung Liew, Tsi-Chung.Liew@freescale.com. |
||||
* |
||||
* 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 |
||||
* |
||||
*/ |
||||
|
||||
/*
|
||||
* Minimal serial functions needed to use one of the PSC ports |
||||
* as serial console interface. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc8220.h> |
||||
|
||||
#define PSC_BASE MMAP_PSC1 |
||||
|
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
int psc_serial_init (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; |
||||
u32 counter; |
||||
|
||||
/* write to SICR: SIM2 = uart mode,dcd does not affect rx */ |
||||
psc->cr = 0; |
||||
psc->ipcr_acr = 0; |
||||
psc->isr_imr = 0; |
||||
|
||||
/* write to CSR: RX/TX baud rate from timers */ |
||||
psc->sr_csr = 0xdd000000; |
||||
|
||||
psc->mr1_2 = PSC_MR1_BITS_CHAR_8 | PSC_MR1_NO_PARITY | PSC_MR1_RX_RTS; |
||||
psc->mr1_2 = PSC_MR2_STOP_BITS_1 | PSC_MR2_TX_CTS; |
||||
|
||||
/* Setting up BaudRate */ |
||||
counter = ((gd->bus_clk / gd->baudrate)) >> 5; |
||||
counter++; |
||||
|
||||
/* write to CTUR: divide counter upper byte */ |
||||
psc->ctur = ((counter & 0xff00) << 16); |
||||
/* write to CTLR: divide counter lower byte */ |
||||
psc->ctlr = ((counter & 0x00ff) << 24); |
||||
|
||||
psc->cr = PSC_CR_RST_RX_CMD; |
||||
psc->cr = PSC_CR_RST_TX_CMD; |
||||
psc->cr = PSC_CR_RST_ERR_STS_CMD; |
||||
psc->cr = PSC_CR_RST_BRK_INT_CMD; |
||||
psc->cr = PSC_CR_RST_MR_PTR_CMD; |
||||
|
||||
psc->cr = PSC_CR_RX_ENABLE | PSC_CR_TX_ENABLE; |
||||
return (0); |
||||
} |
||||
|
||||
void psc_serial_putc (const char c) |
||||
{ |
||||
volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; |
||||
|
||||
if (c == '\n') |
||||
serial_putc ('\r'); |
||||
|
||||
/* Wait for last character to go. */ |
||||
while (!(psc->sr_csr & PSC_SR_TXEMT)); |
||||
|
||||
psc->xmitbuf[0] = c; |
||||
} |
||||
|
||||
void psc_serial_puts (const char *s) |
||||
{ |
||||
while (*s) { |
||||
serial_putc (*s++); |
||||
} |
||||
} |
||||
|
||||
int psc_serial_getc (void) |
||||
{ |
||||
volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; |
||||
|
||||
/* Wait for a character to arrive. */ |
||||
while (!(psc->sr_csr & PSC_SR_RXRDY)); |
||||
return psc->xmitbuf[2]; |
||||
} |
||||
|
||||
int psc_serial_tstc (void) |
||||
{ |
||||
volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; |
||||
|
||||
return (psc->sr_csr & PSC_SR_RXRDY); |
||||
} |
||||
|
||||
void psc_serial_setbrg (void) |
||||
{ |
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
volatile psc8220_t *psc = (psc8220_t *) PSC_BASE; |
||||
u32 counter; |
||||
|
||||
counter = ((gd->bus_clk / gd->baudrate)) >> 5; |
||||
counter++; |
||||
|
||||
/* write to CTUR: divide counter upper byte */ |
||||
psc->ctur = ((counter & 0xff00) << 16); |
||||
/* write to CTLR: divide counter lower byte */ |
||||
psc->ctlr = ((counter & 0x00ff) << 24); |
||||
|
||||
psc->cr = PSC_CR_RST_RX_CMD; |
||||
psc->cr = PSC_CR_RST_TX_CMD; |
||||
|
||||
psc->cr = PSC_CR_RX_ENABLE | PSC_CR_TX_ENABLE; |
||||
} |
||||
#endif /* CONFIG_PSC_CONSOLE */ |
@ -0,0 +1,482 @@ |
||||
Freescale Alaska MPC8220 board |
||||
============================== |
||||
|
||||
TsiChung Liew(Tsi-Chung.Liew@freescale.com) |
||||
Created 9/21/04 |
||||
=========================================== |
||||
|
||||
|
||||
Changed files: |
||||
============== |
||||
|
||||
- Makefile added MPC8220 and Alaska8220_config |
||||
- MAKEALL added MPC8220 and Alaska8220 |
||||
- README added CONFIG_MPC8220, Alaska8220_config |
||||
|
||||
- common/cmd_bdinfo.c added board information members for MPC8220 |
||||
- common/cmd_bootm.c added clocks for MPC8220 in do_bootm_linux() |
||||
|
||||
- include/common.h added CONFIG_MPC8220 |
||||
|
||||
- include/asm-ppc/u-boot.h added board information members for MPC8220 |
||||
- include/asm-ppc/global_data.h added global variables - inp_clk, pci_clk, |
||||
vco_clk, pev_clk, flb_clk, and bExtUart |
||||
|
||||
- lib_ppc/board.c added CONFIG_MPC8220 support |
||||
|
||||
- net/eth.c added FEC support for MPC8220 |
||||
|
||||
Added files: |
||||
============ |
||||
- board/alaska directory for Alaska MPC8220 |
||||
- board/alaska/alaska.c Alaska dram and BATs setup |
||||
- board/alaska/extserial.c external serial (debug card serial) support |
||||
- board/alaska/flash.c Socket (AMD) and Onboard (INTEL) flash support |
||||
- board/alaska/serial.c to determine which int/ext serial to use |
||||
- board/alaska/Makefile Makefile |
||||
- board/alaska/config.mk config make |
||||
- board/alaska/u-boot.lds Linker description |
||||
|
||||
- cpu/mpc8220/dma.h multi-channel dma header file |
||||
- cpu/mpc8220/dramSetup.h dram setup header file |
||||
- cpu/mpc8220/fec.h MPC8220 FEC header file |
||||
- cpu/mpc8220/cpu.c cpu specific code |
||||
- cpu/mpc8220/cpu_init.c Flexbus ChipSelect and Mux pins setup |
||||
- cpu/mpc8220/dramSetup.c MPC8220 DDR SDRAM setup |
||||
- cpu/mpc8220/fec.c MPC8220 FEC driver |
||||
- cpu/mpc8220/i2c.c MPC8220 I2C driver |
||||
- cpu/mpc8220/interrupts.c interrupt support (not enable) |
||||
- cpu/mpc8220/loadtask.c load dma |
||||
- cpu/mpc8220/speed.c system, pci, flexbus, pev, and cpu clock |
||||
- cpu/mpc8220/traps.c exception |
||||
- cpu/mpc8220/uart.c MPC8220 UART driver |
||||
- cpu/mpc8220/Makefile Makefile |
||||
- cpu/mpc8220/config.mk config make |
||||
- cpu/mpc8220/fec_dma_task.S MPC8220 FEC multi-channel dma program |
||||
- cpu/mpc8220/io.S io functions |
||||
- cpu/mpc8220/start.S start up |
||||
|
||||
- include/mpc8220.h |
||||
|
||||
- include/asm-ppc/immap_8220.h |
||||
|
||||
- include/configs/Alaska8220.h |
||||
|
||||
|
||||
1. SWITCH SETTINGS |
||||
================== |
||||
1.1 SW1: 0 - Boot from Socket Flash (AMD) or 1 - Onboard Flash (INTEL) |
||||
SW2: 0 - Select MPC8220 UART or 1 - Debug Card UART |
||||
SW3: unsed |
||||
SW4: 0 - 1284 or 1 - FEC1 |
||||
SW5: 0 - PEV or 1 - FEC2 |
||||
|
||||
|
||||
2. MEMORY MAP UNDER U-BOOT AND LINUX KERNEL |
||||
=========================================== |
||||
2.1. For the initial bringup, we adopted a consistent memory scheme between u-boot and |
||||
linux kernel, you can customize it based on your system requirements: |
||||
DDR: 0x00000000-0x1fffffff (max 512MB) |
||||
MBAR: 0xf0000000-0xf0027fff (128KB) |
||||
CPLD: 0xf1000000-0xf103ffff (256KB) |
||||
FPGA: 0xf2000000-0xf203ffff (256KB) |
||||
Flash: 0xfe000000-0xffffffff (max 32MB) |
||||
|
||||
3. DEFINITIONS AND COMPILATION |
||||
============================== |
||||
3.1 Explanation on NEW definitions in include/configs/alaska8220.h |
||||
CONFIG_MPC8220 MPC8220 specific |
||||
CONFIG_ALASKA8220 Alaska board specific |
||||
CFG_MPC8220_CLKIN Define Alaska Input Clock |
||||
CONFIG_PSC_CONSOLE Enable MPC8220 UART |
||||
CONFIG_EXTUART_CONSOLE Enable External 16552 UART |
||||
CFG_AMD_BOOT To determine the u-boot is booted from AMD or Intel |
||||
CFG_MBAR MBAR base address |
||||
CFG_DEFAULT_MBAR Reset MBAR base address |
||||
|
||||
3.2 Compilation |
||||
export CROSS_COMPILE=cross-compile-prefix |
||||
cd u-boot-1-1-x |
||||
make distclean |
||||
make Alaska8220_config |
||||
make |
||||
|
||||
|
||||
4. SCREEN DUMP |
||||
============== |
||||
4.1 Alaska MPC8220 board |
||||
Boot from AMD (NOTE: May not show exactly the same) |
||||
|
||||
U-Boot 1.1.1 (Sep 22 2004 - 22:14:41) |
||||
|
||||
CPU: MPC8220 (JTAG ID 1640301d) at 300 MHz |
||||
Bus 120 MHz, CPU 300 MHz, PCI 30 MHz, VCO 480 MHz |
||||
Board: Alaska MPC8220 Evaluation Board |
||||
I2C: 93 kHz, ready |
||||
DRAM: 256 MB |
||||
Reserving 167k for U-Boot at: 0ffd6000 |
||||
FLASH: 16.5 MB |
||||
*** Warning - bad CRC, using default environment |
||||
|
||||
In: serial |
||||
Out: serial |
||||
Err: serial |
||||
Net: FEC ETHERNET |
||||
=> flinfo |
||||
|
||||
Bank # 1: INTEL 28F128J3A |
||||
Size: 8 MB in 64 Sectors |
||||
Sector Start Addresses: |
||||
FE000000 FE020000 FE040000 FE060000 FE080000 |
||||
FE0A0000 FE0C0000 FE0E0000 FE100000 FE120000 |
||||
FE140000 FE160000 FE180000 FE1A0000 FE1C0000 |
||||
FE1E0000 FE200000 FE220000 FE240000 FE260000 |
||||
FE280000 FE2A0000 FE2C0000 FE2E0000 FE300000 |
||||
FE320000 FE340000 FE360000 FE380000 FE3A0000 |
||||
FE3C0000 FE3E0000 FE400000 FE420000 FE440000 |
||||
FE460000 FE480000 FE4A0000 FE4C0000 FE4E0000 |
||||
FE500000 FE520000 FE540000 FE560000 FE580000 |
||||
FE5A0000 FE5C0000 FE5E0000 FE600000 FE620000 |
||||
FE640000 FE660000 FE680000 FE6A0000 FE6C0000 |
||||
FE6E0000 FE700000 FE720000 FE740000 FE760000 |
||||
FE780000 FE7A0000 FE7C0000 FE7E0000 |
||||
|
||||
Bank # 2: INTEL 28F128J3A |
||||
Size: 8 MB in 64 Sectors |
||||
Sector Start Addresses: |
||||
FE800000 FE820000 FE840000 FE860000 FE880000 |
||||
FE8A0000 FE8C0000 FE8E0000 FE900000 FE920000 |
||||
FE940000 FE960000 FE980000 FE9A0000 FE9C0000 |
||||
FE9E0000 FEA00000 FEA20000 FEA40000 FEA60000 |
||||
FEA80000 FEAA0000 FEAC0000 FEAE0000 FEB00000 |
||||
FEB20000 FEB40000 FEB60000 FEB80000 FEBA0000 |
||||
FEBC0000 FEBE0000 FEC00000 FEC20000 FEC40000 |
||||
FEC60000 FEC80000 FECA0000 FECC0000 FECE0000 |
||||
FED00000 FED20000 FED40000 FED60000 FED80000 |
||||
FEDA0000 FEDC0000 FEDE0000 FEE00000 FEE20000 |
||||
FEE40000 FEE60000 FEE80000 FEEA0000 FEEC0000 |
||||
FEEE0000 FEF00000 (RO) FEF20000 (RO) FEF40000 FEF60000 |
||||
FEF80000 FEFA0000 FEFC0000 FEFE0000 (RO) |
||||
|
||||
Bank # 3: AMD AMD29F040B |
||||
Size: 0 MB in 7 Sectors |
||||
Sector Start Addresses: |
||||
FFF00000 (RO) FFF10000 (RO) FFF20000 (RO) FFF30000 FFF40000 |
||||
FFF50000 FFF60000 |
||||
|
||||
Bank # 4: AMD AMD29F040B |
||||
Size: 0 MB in 1 Sectors |
||||
Sector Start Addresses: |
||||
FFF70000 (RO) |
||||
=> bdinfo |
||||
|
||||
memstart = 0xF0009800 |
||||
memsize = 0x10000000 |
||||
flashstart = 0xFFF00000 |
||||
flashsize = 0x01080000 |
||||
flashoffset = 0x00025000 |
||||
sramstart = 0xF0020000 |
||||
sramsize = 0x00008000 |
||||
bootflags = 0x00000001 |
||||
intfreq = 300 MHz |
||||
busfreq = 120 MHz |
||||
inpfreq = 30 MHz |
||||
flbfreq = 30 MHz |
||||
pcifreq = 30 MHz |
||||
vcofreq = 480 MHz |
||||
pevfreq = 81 MHz |
||||
ethaddr = 00:E0:0C:BC:E0:60 |
||||
eth1addr = 00:E0:0C:BC:E0:61 |
||||
IP addr = 192.162.1.2 |
||||
baudrate = 115200 bps |
||||
=> printenv |
||||
bootargs=root=/dev/ram rw |
||||
bootdelay=5 |
||||
baudrate=115200 |
||||
ethaddr=00:e0:0c:bc:e0:60 |
||||
eth1addr=00:e0:0c:bc:e0:61 |
||||
ipaddr=192.162.1.2 |
||||
serverip=192.162.1.1 |
||||
gatewayip=192.162.1.1 |
||||
netmask=255.255.255.0 |
||||
hostname=Alaska |
||||
stdin=serial |
||||
stdout=serial |
||||
stderr=serial |
||||
ethact=FEC ETHERNET |
||||
|
||||
Environment size: 268/65532 bytes |
||||
=> setenv ipaddr 192.160.1.2 |
||||
=> setenv serverip 192.160.1.1 |
||||
=> setenv gatewayip 192.160.1.1 |
||||
=> saveenv |
||||
Saving Environment to Flash... |
||||
|
||||
. |
||||
Un-Protected 1 sectors |
||||
Erasing Flash... |
||||
Erasing sector 0 ... done |
||||
Erased 1 sectors |
||||
Writing to Flash... done |
||||
|
||||
. |
||||
Protected 1 sectors |
||||
=> tftp 0x10000 linux.elf |
||||
Using FEC ETHERNET device |
||||
TFTP from server 192.160.1.1; our IP address is 192.160.1.2; sending through gateway 192.160.1.1 |
||||
Filename 'linux.elf'. |
||||
Load address: 0x10000 |
||||
Loading: invalid RARP header |
||||
################################################################# |
||||
################################################################# |
||||
################################################################# |
||||
################################################################# |
||||
################################################################# |
||||
################################################################# |
||||
################################################################# |
||||
################################################################# |
||||
################################################## |
||||
done |
||||
Bytes transferred = 2917494 (2c8476 hex) |
||||
=> bootelf |
||||
Loading .text @ 0x00a00000 (23820 bytes) |
||||
Loading .data @ 0x00a06000 (2752512 bytes) |
||||
Clearing .bss @ 0x00ca6000 (12764 bytes) |
||||
## Starting application at 0x00a00000 ... |
||||
|
||||
Collect some entropy from RAM........done |
||||
loaded at: 00A00000 00CA91DC |
||||
zimage at: 00A06A93 00AD7756 |
||||
initrd at: 00AD8000 00CA5565 |
||||
avail ram: 00CAA000 014AA000 |
||||
|
||||
Linux/PPC load: ip=off console=ttyS0,115200 |
||||
Uncompressing Linux...done. |
||||
Now booting the kernel |
||||
Total memory in system: 256 MB |
||||
Memory BAT mapping: BAT2=256Mb, BAT3=0Mb, residual: 0Mb |
||||
Linux version 2.4.21-rc1 (r61688@bluesocks.sps.mot.com) (gcc version 3.3.1) #17 Wed Sep 8 11:49:16 CDT 2004 |
||||
Motorola Alaska port (C) 2003 Motorola, Inc. |
||||
CPLD rev 3 |
||||
CPLD switches 0x1b |
||||
Set Pin Mux for FEC1 |
||||
Set Pin Mux for FEC2 |
||||
Alaska Pin Multiplexing: |
||||
Port Configuration Register 0 = 0 |
||||
Port Configuration Register 1 = 0 |
||||
Port Configuration Register 2 = 0 |
||||
Port Configuration Register 3 = 50000000 |
||||
Port Configuration Register 3 - PCI = 51400180 |
||||
Setup Alaska FPGA PIC: |
||||
Interrupt Enable Register *(u32) = 0 |
||||
Interrupt Status Register = 2f0000 |
||||
Interrupt Enable Register in_be32 = 0 |
||||
Interrupt Status Register = 2f0000 |
||||
Interrupt Enable Register in_le32 = 0 |
||||
Interrupt Status Register = 2f00 |
||||
Interrupt Enable Register readl = 0 |
||||
Interrupt Status Register = 2f00 |
||||
Interrupt Enable Register = 0 |
||||
Interrupt Status Register = 2f0000 |
||||
Setup Alaska PCI Controller: |
||||
On node 0 totalpages: 65536 |
||||
zone(0): 65536 pages. |
||||
zone(1): 0 pages. |
||||
zone(2): 0 pages. |
||||
Kernel command line: ip=off console=ttyS0,115200 |
||||
Using XLB clock (120.00 MHz) to set up decrementer |
||||
Calibrating delay loop... 199.88 BogoMIPS |
||||
Memory: 254792k available (1476k kernel code, 708k data, 228k init, 0k highmem) |
||||
Dentry cache hash table entries: 32768 (order: 6, 262144 bytes) |
||||
Inode cache hash table entries: 16384 (order: 5, 131072 bytes) |
||||
Mount cache hash table entries: 512 (order: 0, 4096 bytes) |
||||
Buffer-cache hash table entries: 16384 (order: 4, 65536 bytes) |
||||
Page-cache hash table entries: 65536 (order: 6, 262144 bytes) |
||||
POSIX conformance testing by UNIFIX |
||||
PCI: Probing PCI hardware |
||||
PCI: (pcibios_init) Global-Hose = 0xc029d000 |
||||
Scanning bus 00 |
||||
Fixups for bus 00 |
||||
Bus scan for 00 returning with max=00 |
||||
PCI: (pcibios_init) finished pci_scan_bus(hose->first_busno = 0, hose->ops = c01a1a74, hose = c029d000) |
||||
PCI: (pcibios_init) PCI Bus Count = 0 =?= Next Bus# = 1 |
||||
PCI: (pcibios_init@pci_fixup_irqs) finished machine dependent PCI interrupt routing! |
||||
PCI: bridge rsrc 81000000..81ffffff (100), parent c01a7f88 |
||||
PCI: bridge rsrc 84000000..87ffffff (200), parent c01a7fa4 |
||||
PCI: (pcibios_init) finished allocating and assigning resources! |
||||
initDma! |
||||
Using 90 DMA buffer descriptors |
||||
descUsed f0023600, descriptors f002360c freeSram f0024140 |
||||
unmask SDMA tasks: 0xf0008018 = 0x6f000000 |
||||
Linux NET4.0 for Linux 2.4 |
||||
Based upon Swansea University Computer Society NET3.039 |
||||
Initializing RT netlink socket |
||||
Starting kswapd |
||||
Journalled Block Device driver loaded |
||||
JFFS version 1.0, (C) 1999, 2000 Axis Communications AB |
||||
JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB. |
||||
pty: 256 Unix98 ptys configured |
||||
tracek: Copyright (C) Motorola, 2003. |
||||
Serial driver version 5.05c (2001-07-08) with MANY_PORTS SHARE_IRQ SERIAL_PCI enabled |
||||
ttyS00 at 0xf1001008 (irq = 73) is a ST16650 |
||||
ttyS01 at 0xf1001010 (irq = 74) is a ST16650 |
||||
elp-fpanel: Copyright (C) Motorola, 2003. |
||||
fpanel: fpanelWait timeout |
||||
elp-engine: Copyright (C) Motorola, 2003. |
||||
Video disabled due to configuration switch 4 |
||||
Alpine 1284 driver: Copyright (C) Motorola, 2003. |
||||
1284 disabled due to configuration switch 5 |
||||
Alpine USB driver: Copyright (C) Motorola, 2003. |
||||
OK |
||||
USB: Descriptor download completed OK |
||||
enable_irq(41) unbalanced |
||||
enable_irq(75) unbalanced |
||||
elp-dmaram: Copyright (C) Motorola, 2003. |
||||
Total memory in system: 256 MB |
||||
elp_dmaram: offset is 0x10000000, size is 0 |
||||
Xicor NVRAM driver: Copyright (C) Motorola, 2003. |
||||
elp-video: Copyright (C) Motorola, 2003. |
||||
Video disabled due to configuration switch 4 |
||||
elp-pfm: Copyright (C) Motorola, 2003. |
||||
paddle: Copyright (C) Motorola, 2001, present. |
||||
RAMDISK driver initialized: 16 RAM disks of 12288K size 1024 blocksize |
||||
loop: loaded (max 8 devices) |
||||
PPP generic driver version 2.4.2 |
||||
PPP Deflate Compression module registered |
||||
Uniform Multi-Platform E-IDE driver Revision: 7.00beta-2.4 |
||||
ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx |
||||
init_alaska_mtd: chip probing count 0 |
||||
cfi_cmdset_0001: Erase suspend on write enabled |
||||
Using buffer write method |
||||
init_alaska_mtd: bank1, name:ALASKA0, size:16777216bytes |
||||
ALASKA flash0: Using Static image partition definition |
||||
Creating 3 MTD partitions on "ALASKA0": |
||||
0x00000000-0x00280000 : "kernel" |
||||
0x00280000-0x00fe0000 : "user" |
||||
0x00fe0000-0x01000000 : "signature" |
||||
mgt_fec_module_init |
||||
mgt_fec_init() |
||||
mgt_fec_init |
||||
mgt_init_fec_dev(0xc05f6000,0) |
||||
dev c05f6000 fec_priv c05f6160 fec f0009000 |
||||
mgt_init_fec_dev(0xc05f6800,1) |
||||
dev c05f6800 fec_priv c05f6960 fec f0009800 |
||||
NET4: Linux TCP/IP 1.0 for NET4.0 |
||||
IP Protocols: ICMP, UDP, TCP, IGMP |
||||
IP: routing cache hash table of 2048 buckets, 16Kbytes |
||||
TCP: Hash tables configured (established 16384 bind 32768) |
||||
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. |
||||
RAMDISK: Compressed image found at block 0 |
||||
Freeing initrd memory: 1845k freed |
||||
JFFS: Trying to mount a non-mtd device. |
||||
VFS: Mounted root (romfs filesystem) readonly. |
||||
Freeing unused kernel memory: 228k init |
||||
INIT: version 2.78 booting |
||||
INIT: Entering runlevel: 1 |
||||
"Space, a great big place of unknown stuff." -Dexter, for our MotD. |
||||
[01/Jan/1970:00:00:01 +0000] boa: server version Boa/0.94.8.3 |
||||
[01/Jan/1970:00:00:01 +0000] boa: server built Sep 7 2004 at 17:40:55. |
||||
[01/Jan/1970:00:00:01 +0000] boa: starting server pid=28, port 80 |
||||
Mounting flash filesystem, will take a minute... |
||||
/etc/rc: line 30: /dev/lp0: No such devish-2.05b# |
||||
sh-2.05b# ifup eth0 |
||||
client (v0.9.9-pre) started |
||||
adapter index 2 |
||||
adapter hardware address 00:e0:0c:bc:e0:60 |
||||
execle'ing /usr/share/udhcpc/default.script |
||||
/sbin/ifconfig eth0 |
||||
eth0 Link encap:Ethernet HWaddr 00:E0:0C:BC:E0:60 |
||||
BROADCAST MULTICAST MTU:1500 Metric:1 |
||||
mgt_fec_open |
||||
Rfec request irq |
||||
X fec_open: rcv_ring_size 8, xmt_ring_size 8 |
||||
packmgt_fec_open(): call netif_start_queue() |
||||
ets:0 errors:0 dropped:0 overruns:0 frame:0 |
||||
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 |
||||
collisions:0 txqueuelen:100 |
||||
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b) |
||||
Base address:0x9000 |
||||
|
||||
/sbin/ifconfig eth0 up |
||||
entering raw listen mode |
||||
Opening raw socket on ifindex 2 |
||||
adding option 0x35 |
||||
adding option 0x3d |
||||
adding option 0x3c |
||||
Sending discover... |
||||
Waiting on select... |
||||
unrelated/bogus packet |
||||
Waiting on select... |
||||
oooooh!!! got some! |
||||
adding option 0x35 |
||||
adding option 0x3d |
||||
adding option 0x3c |
||||
adding option 0x32 |
||||
adding option 0x36 |
||||
Sending select for 163.12.48.146... |
||||
Waiting on select... |
||||
oooooh!!! got some! |
||||
Waiting on select... |
||||
oooooh!!! got some! |
||||
Lease of 163.12.48.146 obtained, lease time 345600 |
||||
execle'ing /usr/share/udhcpc/default.script |
||||
/sbin/ifconfig eth0 163.12.48.146 netmask 255.255.254.0 |
||||
/sbin/ifconfig eth0 up |
||||
deleting routers |
||||
/sbin/route del default |
||||
/sbin/route add default gw 163.12.49.254 dev eth0 |
||||
adding dns 163.12.252.230 |
||||
adding dns 192.55.22.4 |
||||
adding dns 192.5.249.4 |
||||
entering none listen mode |
||||
sh-2.05b# |
||||
|
||||
5. REPROGRAM U-BOOT |
||||
=================== |
||||
5.1 Reprogram u-boot (boot from AMD) |
||||
1. Unprotect the boot sector |
||||
=> protect off bank 3 |
||||
2. Download new u-boot binary file |
||||
=> tftp 0x10000 u-boot.bin |
||||
3. Erase bootsector (max 7 sectors) |
||||
=> erase 0xfff00000 0xfff6ffff |
||||
4. Program the u-boot to flash |
||||
=> cp.b 0x10000 0xfff00000 |
||||
5. Reset for the new u-boot to take place |
||||
=> reset |
||||
|
||||
5.2 Reprogram u-boot (boot from AMD program at INTEL) |
||||
1. Unprotect the boot sector |
||||
=> protect off bank 2 |
||||
2. Download new u-boot binary file |
||||
=> tftp 0x10000 u-boot.bin |
||||
3. Erase bootsector (max 7 sectors) |
||||
=> erase 0xfef00000 0xfefdffff |
||||
4. Program the u-boot to flash |
||||
=> cp.b 0x10000 0xfef00000 |
||||
5. Reset for the new u-boot to take place |
||||
=> reset |
||||
|
||||
5.3 Reprogram u-boot (boot from INTEL) |
||||
1. Unprotect the boot sector |
||||
=> protect off bank 4 |
||||
2. Download new u-boot binary file |
||||
=> tftp 0x10000 u-boot.bin |
||||
3. Erase bootsector (max 7 sectors) |
||||
=> erase 0xfff00000 0xfffdffff |
||||
4. Program the u-boot to flash |
||||
=> cp.b 0x10000 0xfff00000 |
||||
5. Reset for the new u-boot to take place |
||||
=> reset |
||||
|
||||
5.4 Reprogram u-boot (boot from INTEL program at AMD) |
||||
1. Unprotect the boot sector |
||||
=> protect off bank 1 |
||||
2. Download new u-boot binary file |
||||
=> tftp 0x10000 u-boot.bin |
||||
3. Erase bootsector (max 7 sectors) |
||||
=> erase 0xfe080000 0xfe0effff |
||||
4. Program the u-boot to flash |
||||
=> cp.b 0x10000 0xfe080000 |
||||
5. Reset for the new u-boot to take place |
||||
=> reset |
@ -0,0 +1,246 @@ |
||||
/*
|
||||
* MPC8220 Internal Memory Map |
||||
* Copyright (c) 2004 TsiChung Liew (Tsi-Chung.Liew@freescale.com) |
||||
* |
||||
* The Internal Memory Map of the 8220. |
||||
* |
||||
*/ |
||||
#ifndef __IMMAP_MPC8220__ |
||||
#define __IMMAP_MPC8220__ |
||||
|
||||
/*
|
||||
* System configuration registers. |
||||
*/ |
||||
typedef struct sys_conf { |
||||
u16 mbar; /* 0x00 */ |
||||
u16 res1; |
||||
|
||||
u16 res2; /* 0x04 */ |
||||
u16 sdramds; |
||||
|
||||
u32 res3[6]; /* 0x08 */ |
||||
|
||||
u32 cscfg[6]; /* 0x20 */ |
||||
|
||||
u32 res4[2]; /* 0x38 */ |
||||
|
||||
u8 res5[3]; /* 0x40 */ |
||||
u8 rstctrl; |
||||
|
||||
u8 res6[3]; /* 0x44 */ |
||||
u8 rststat; |
||||
|
||||
u32 res7[2]; /* 0x48 */ |
||||
|
||||
u32 jtagid; /* 0x50 */ |
||||
} sysconf8220_t; |
||||
|
||||
|
||||
/*
|
||||
* Memory controller registers. |
||||
*/ |
||||
typedef struct mem_ctlr { |
||||
ushort mode; /* 0x100 */ |
||||
ushort res1; |
||||
u32 ctrl; /* 0x104 */ |
||||
u32 cfg1; /* 0x108 */ |
||||
u32 cfg2; /* 0x10c */ |
||||
} memctl8220_t; |
||||
|
||||
/*
|
||||
* XLB Arbitration registers |
||||
*/ |
||||
typedef struct xlb_arb |
||||
{ |
||||
uint res1[16]; /* 0x200 */ |
||||
uint config; /* 0x240 */ |
||||
uint version; /* 0x244 */ |
||||
uint status; /* 0x248 */ |
||||
uint intEnable; /* 0x24c */ |
||||
uint addrCap; /* 0x250 */ |
||||
uint busSigCap; /* 0x254 */ |
||||
uint addrTenTimeOut; /* 0x258 */ |
||||
uint dataTenTimeOut; /* 0x25c */ |
||||
uint busActTimeOut; /* 0x260 */ |
||||
uint mastPriEn; /* 0x264 */ |
||||
uint mastPriority; /* 0x268 */ |
||||
uint baseAddr; /* 0x26c */ |
||||
} xlbarb8220_t; |
||||
|
||||
/*
|
||||
* Flexbus registers |
||||
*/ |
||||
typedef struct flexbus |
||||
{ |
||||
ushort csar0; /* 0x00 */ |
||||
ushort res1; |
||||
uint csmr0; /* 0x04 */ |
||||
uint cscr0; /* 0x08 */ |
||||
|
||||
ushort csar1; /* 0x0c */ |
||||
ushort res2; |
||||
uint csmr1; /* 0x10 */ |
||||
uint cscr1; /* 0x14 */ |
||||
|
||||
ushort csar2; /* 0x18 */ |
||||
ushort res3; |
||||
uint csmr2; /* 0x1c */ |
||||
uint cscr2; /* 0x20 */ |
||||
|
||||
ushort csar3; /* 0x24 */ |
||||
ushort res4; |
||||
uint csmr3; /* 0x28 */ |
||||
uint cscr3; /* 0x2c */ |
||||
|
||||
ushort csar4; /* 0x30 */ |
||||
ushort res5; |
||||
uint csmr4; /* 0x34 */ |
||||
uint cscr4; /* 0x38 */ |
||||
|
||||
ushort csar5; /* 0x3c */ |
||||
ushort res6; |
||||
uint csmr5; /* 0x40 */ |
||||
uint cscr5; /* 0x44 */ |
||||
} flexbus8220_t; |
||||
|
||||
/*
|
||||
* GPIO registers |
||||
*/ |
||||
typedef struct gpio |
||||
{ |
||||
u32 out; /* 0x00 */ |
||||
u32 obs; /* 0x04 */ |
||||
u32 obc; /* 0x08 */ |
||||
u32 obt; /* 0x0c */ |
||||
u32 en; /* 0x10 */ |
||||
u32 ebs; /* 0x14 */ |
||||
u32 ebc; /* 0x18 */ |
||||
u32 ebt; /* 0x1c */ |
||||
u32 mc; /* 0x20 */ |
||||
u32 st; /* 0x24 */ |
||||
u32 intr; /* 0x28 */ |
||||
} gpio8220_t; |
||||
|
||||
/*
|
||||
* General Purpose Timer registers |
||||
*/ |
||||
typedef struct gptimer |
||||
{ |
||||
u8 OCPW; |
||||
u8 OctIct; |
||||
u8 Control; |
||||
u8 Mode; |
||||
|
||||
u16 Prescl; /* Prescale */ |
||||
u16 Count; /* Count */ |
||||
|
||||
u16 PwmWid; /* PWM Width */ |
||||
u8 PwmOp; /* Output Polarity */ |
||||
u8 PwmLd; /* Immediate Update */ |
||||
|
||||
u16 Capture; /* Capture internal counter */ |
||||
u8 OvfPin; /* Ovf and Pin */ |
||||
u8 Int; /* Interrupts */ |
||||
} gptmr8220_t; |
||||
|
||||
/*
|
||||
* PSC registers |
||||
*/ |
||||
typedef struct psc |
||||
{ |
||||
u32 mr1_2; /* 0x00 Mode reg 1 & 2 */ |
||||
u32 sr_csr; /* 0x04 Status/Clock Select reg */ |
||||
u32 cr; /* 0x08 Command reg */ |
||||
u8 xmitbuf[4]; /* 0x0c Receive/Transmit Buffer */ |
||||
u32 ipcr_acr; /* 0x10 Input Port Change/Auxiliary Control reg */ |
||||
u32 isr_imr; /* 0x14 Interrupt Status/Mask reg */ |
||||
u32 ctur; /* 0x18 Counter Timer Upper reg */ |
||||
u32 ctlr; /* 0x1c Counter Timer Lower reg */ |
||||
u32 rsvd1[4]; /* 0x20 ... 0x2c */ |
||||
u32 ivr; /* 0x30 Interrupt Vector reg */ |
||||
u32 ipr; /* 0x34 Input Port reg */ |
||||
u32 opsetr; /* 0x38 Output Port Set reg */ |
||||
u32 opresetr; /* 0x3c Output Port Reset reg */ |
||||
u32 sicr; /* 0x40 PSC/IrDA control reg */ |
||||
u32 ircr1; /* 0x44 IrDA control reg 1*/ |
||||
u32 ircr2; /* 0x48 IrDA control reg 2*/ |
||||
u32 irsdr; /* 0x4c IrDA SIR Divide reg */ |
||||
u32 irmdr; /* 0x50 IrDA MIR Divide reg */ |
||||
u32 irfdr; /* 0x54 PSC IrDA FIR Divide reg */ |
||||
u32 rfnum; /* 0x58 RX-FIFO counter */ |
||||
u32 txnum; /* 0x5c TX-FIFO counter */ |
||||
u32 rfdata; /* 0x60 RX-FIFO data */ |
||||
u32 rfstat; /* 0x64 RX-FIFO status */ |
||||
u32 rfcntl; /* 0x68 RX-FIFO control */ |
||||
u32 rfalarm; /* 0x6c RX-FIFO alarm */ |
||||
u32 rfrptr; /* 0x70 RX-FIFO read pointer */ |
||||
u32 rfwptr; /* 0x74 RX-FIFO write pointer */ |
||||
u32 rflfrptr; /* 0x78 RX-FIFO last read frame pointer */ |
||||
u32 rflfwptr; /* 0x7c RX-FIFO last write frame pointer */ |
||||
|
||||
u32 tfdata; /* 0x80 TX-FIFO data */ |
||||
u32 tfstat; /* 0x84 TX-FIFO status */ |
||||
u32 tfcntl; /* 0x88 TX-FIFO control */ |
||||
u32 tfalarm; /* 0x8c TX-FIFO alarm */ |
||||
u32 tfrptr; /* 0x90 TX-FIFO read pointer */ |
||||
u32 tfwptr; /* 0x94 TX-FIFO write pointer */ |
||||
u32 tflfrptr; /* 0x98 TX-FIFO last read frame pointer */ |
||||
u32 tflfwptr; /* 0x9c TX-FIFO last write frame pointer */ |
||||
} psc8220_t; |
||||
|
||||
/*
|
||||
* Interrupt Controller registers |
||||
*/ |
||||
typedef struct interrupt_controller { |
||||
} intctl8220_t; |
||||
|
||||
|
||||
/* Fast controllers
|
||||
*/ |
||||
|
||||
/*
|
||||
* I2C registers |
||||
*/ |
||||
typedef struct i2c |
||||
{ |
||||
u8 adr; /* 0x00 */ |
||||
u8 res1[3]; |
||||
u8 fdr; /* 0x04 */ |
||||
u8 res2[3]; |
||||
u8 cr; /* 0x08 */ |
||||
u8 res3[3]; |
||||
u8 sr; /* 0x0C */ |
||||
u8 res4[3]; |
||||
u8 dr; /* 0x10 */ |
||||
u8 res5[3]; |
||||
u32 reserved0; /* 0x14 */ |
||||
u32 reserved1; /* 0x18 */ |
||||
u32 reserved2; /* 0x1c */ |
||||
u8 icr; /* 0x20 */ |
||||
u8 res6[3]; |
||||
} i2c8220_t; |
||||
|
||||
/*
|
||||
* Port Configuration Registers |
||||
*/ |
||||
typedef struct pcfg |
||||
{ |
||||
uint pcfg0; /* 0x00 */ |
||||
uint pcfg1; /* 0x04 */ |
||||
uint pcfg2; /* 0x08 */ |
||||
uint pcfg3; /* 0x0c */ |
||||
} pcfg8220_t; |
||||
|
||||
/* ...and the whole thing wrapped up....
|
||||
*/ |
||||
typedef struct immap { |
||||
sysconf8220_t im_sysconf; /* System Configuration */ |
||||
memctl8220_t im_memctl; /* Memory Controller */ |
||||
xlbarb8220_t im_xlbarb; /* XLB Arbitration */ |
||||
psc8220_t im_psc; /* PSC controller */ |
||||
flexbus8220_t im_fb; /* FlexBus Controller */ |
||||
i2c8220_t im_i2c; /* I2C control/status */ |
||||
pcfg8220_t im_pcfg; /* Port configuration */ |
||||
} immap_t; |
||||
|
||||
#endif /* __IMMAP_MPC8220__ */ |
@ -0,0 +1,309 @@ |
||||
/*
|
||||
* (C) Copyright 2004 |
||||
* TsiChung Liew, Freescale Software Engineering, Tsi-Chung.Liew@freescale. |
||||
* |
||||
* 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 |
||||
*/ |
||||
|
||||
#ifndef __CONFIG_H |
||||
#define __CONFIG_H |
||||
|
||||
/*
|
||||
* High Level Configuration Options |
||||
* (easy to change) |
||||
*/ |
||||
#define CONFIG_MPC8220 1 |
||||
#define CONFIG_ALASKA8220 1 /* ... on Alaska board */ |
||||
|
||||
/* Input clock running at 30Mhz, read Hid1 for the CPU multiplier to
|
||||
determine the CPU speed. */ |
||||
#define CFG_MPC8220_CLKIN 30000000/* ... running at 30MHz */ |
||||
|
||||
#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ |
||||
#define BOOTFLAG_WARM 0x02 /* Software reboot */ |
||||
|
||||
#define CFG_CACHELINE_SIZE 32 /* For MPC8220 CPUs */ |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
# define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ |
||||
#endif |
||||
|
||||
/*
|
||||
* Serial console configuration |
||||
*/ |
||||
#define CONFIG_PSC_CONSOLE 1 /* console is on PSC */ |
||||
#define CONFIG_EXTUART_CONSOLE 1 |
||||
|
||||
#ifdef CONFIG_EXTUART_CONSOLE |
||||
# define CFG_NS16550 |
||||
# define CFG_NS16550_REG_SIZE 1 |
||||
# define CFG_NS16550_COM1 (CFG_CPLD_BASE + 0x1008) |
||||
#endif |
||||
|
||||
#define CONFIG_BAUDRATE 115200 /* ... at 115200 bps */ |
||||
|
||||
|
||||
#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, 230400 } |
||||
|
||||
/*
|
||||
* Supported commands |
||||
*/ |
||||
/* CONFIG_CMD_DFL includes CFG_CMD_BDI (bdinfo), CFG_CMD_LOADS (loads),
|
||||
CFG_CMD_LOADB (loadb), CFG_CMD_IMI (iminfo), CFG_CMD_FLASH |
||||
(flinfo, erase, protect), CFG_CMD_MEMORY (md, mm, nm, mw, cp, cmp, |
||||
crc, base, loop, mtest), CFG_CMD_ENV (printenv, setenv, saveenv), |
||||
CFG_CMD_BOOTD (bootd), CFG_CMD_CONSOLE (coninfo), CFG_CMD_NET (bootp, |
||||
tftpboot, rarpboot), CFG_CMD_RUN, CFG_CMD_MISC (sleep, etc), |
||||
CFG_CMD_BSP, CFG_CMD_IMLS, CFG_CMD_FPGA */ |
||||
|
||||
#define CONFIG_COMMANDS (CONFIG_CMD_DFL | \ |
||||
CFG_CMD_BOOTD | \
|
||||
CFG_CMD_CACHE | \
|
||||
CFG_CMD_DIAG | \
|
||||
CFG_CMD_EEPROM | \
|
||||
CFG_CMD_ELF | \
|
||||
CFG_CMD_I2C | \
|
||||
CFG_CMD_NET | \
|
||||
CFG_CMD_PING | \
|
||||
CFG_CMD_REGINFO | \
|
||||
CFG_CMD_SDRAM \
|
||||
) |
||||
/* CFG_CMD_DHCP | \ */ |
||||
/* CFG_CMD_MII | \ */ |
||||
/* CFG_CMD_PCI | \ */ |
||||
/* CFG_CMD_USB */ |
||||
|
||||
# define CONFIG_NET_MULTI |
||||
/*#if (CONFIG_COMMANDS & CFG_CMD_NET)
|
||||
# define CONFIG_NET_MULTI |
||||
#else |
||||
# undef CONFIG_NET_MULTI |
||||
#endif*/ |
||||
|
||||
|
||||
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ |
||||
#include <cmd_confdefs.h> |
||||
|
||||
/*
|
||||
* Autobooting |
||||
*/ |
||||
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */ |
||||
#define CONFIG_BOOTARGS "root=/dev/ram rw" |
||||
#define CONFIG_ETHADDR 00:e0:0c:bc:e0:60 |
||||
#define CONFIG_ETH1ADDR 00:e0:0c:bc:e0:61 |
||||
#define CONFIG_IPADDR 192.162.1.2 |
||||
#define CONFIG_NETMASK 255.255.255.0 |
||||
#define CONFIG_SERVERIP 192.162.1.1 |
||||
#define CONFIG_GATEWAYIP 192.162.1.1 |
||||
#define CONFIG_HOSTNAME Alaska |
||||
#define CONFIG_OVERWRITE_ETHADDR_ONCE |
||||
|
||||
|
||||
/*
|
||||
* I2C configuration |
||||
*/ |
||||
#define CONFIG_HARD_I2C 1 |
||||
#define CFG_I2C_MODULE 1 |
||||
|
||||
#define CFG_I2C_SPEED 100000 /* 100 kHz */ |
||||
#define CFG_I2C_SLAVE 0x7F |
||||
|
||||
/*
|
||||
* EEPROM configuration |
||||
*/ |
||||
#define CFG_I2C_EEPROM_ADDR 0x52 /* 1011000xb */ |
||||
#define CFG_I2C_EEPROM_ADDR_LEN 1 |
||||
#define CFG_EEPROM_PAGE_WRITE_BITS 3 |
||||
#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 70 |
||||
/*
|
||||
#define CFG_ENV_IS_IN_EEPROM 1 |
||||
#define CFG_ENV_OFFSET 0 |
||||
#define CFG_ENV_SIZE 256 |
||||
*/ |
||||
|
||||
/* If CFG_AMD_BOOT is defined, the the system will boot from AMD.
|
||||
else undefined it will boot from Intel Strata flash */ |
||||
#define CFG_AMD_BOOT 1 |
||||
|
||||
/*
|
||||
* Flexbus Chipselect configuration |
||||
*/ |
||||
#if defined (CFG_AMD_BOOT) |
||||
#define CFG_CS0_BASE 0xfff0 |
||||
#define CFG_CS0_MASK 0x00080000 /* 512 KB */ |
||||
#define CFG_CS0_CTRL 0x003f0d40 |
||||
|
||||
#define CFG_CS1_BASE 0xfe00 |
||||
#define CFG_CS1_MASK 0x01000000 /* 16 MB */ |
||||
#define CFG_CS1_CTRL 0x003f1540 |
||||
#else |
||||
#define CFG_CS0_BASE 0xff00 |
||||
#define CFG_CS0_MASK 0x01000000 /* 16 MB */ |
||||
#define CFG_CS0_CTRL 0x003f1540 |
||||
|
||||
#define CFG_CS1_BASE 0xfe08 |
||||
#define CFG_CS1_MASK 0x00080000 /* 512 KB */ |
||||
#define CFG_CS1_CTRL 0x003f0d40 |
||||
#endif |
||||
|
||||
#define CFG_CS2_BASE 0xf100 |
||||
#define CFG_CS2_MASK 0x00040000 |
||||
#define CFG_CS2_CTRL 0x003f1140 |
||||
|
||||
#define CFG_CS3_BASE 0xf200 |
||||
#define CFG_CS3_MASK 0x00040000 |
||||
#define CFG_CS3_CTRL 0x003f1100 |
||||
|
||||
|
||||
#define CFG_FLASH0_BASE (CFG_CS0_BASE << 16) |
||||
#define CFG_FLASH1_BASE (CFG_CS1_BASE << 16) |
||||
|
||||
#if defined (CFG_AMD_BOOT) |
||||
#define CFG_AMD_BASE CFG_FLASH0_BASE |
||||
#define CFG_INTEL_BASE CFG_FLASH1_BASE + 0xf00000 |
||||
#define CFG_FLASH_BASE CFG_AMD_BASE |
||||
#else |
||||
#define CFG_INTEL_BASE CFG_FLASH0_BASE + 0xf00000 |
||||
#define CFG_AMD_BASE CFG_FLASH1_BASE |
||||
#define CFG_FLASH_BASE CFG_INTEL_BASE |
||||
#endif |
||||
|
||||
#define CFG_CPLD_BASE (CFG_CS2_BASE << 16) |
||||
#define CFG_FPGA_BASE (CFG_CS3_BASE << 16) |
||||
|
||||
|
||||
#define CFG_MAX_FLASH_BANKS 4 /* max num of memory banks */ |
||||
#define CFG_MAX_FLASH_SECT 128 /* max num of sects on one chip */ |
||||
|
||||
#define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */ |
||||
#define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ |
||||
#define CFG_FLASH_LOCK_TOUT 5 /* Timeout for Flash Set Lock Bit (in ms) */ |
||||
#define CFG_FLASH_UNLOCK_TOUT 10000 /* Timeout for Flash Clear Lock Bits (in ms) */ |
||||
#define CFG_FLASH_PROTECTION /* "Real" (hardware) sectors protection */ |
||||
|
||||
#define PHYS_AMD_SECT_SIZE 0x00010000 /* 64 KB sectors (x2) */ |
||||
#define PHYS_INTEL_SECT_SIZE 0x00020000 /* 128 KB sectors (x2) */ |
||||
|
||||
#define CFG_FLASH_CHECKSUM |
||||
/*
|
||||
* Environment settings |
||||
*/ |
||||
#define CFG_ENV_IS_IN_FLASH 1 |
||||
#if defined (CFG_AMD_BOOT) |
||||
#define CFG_ENV_ADDR (CFG_FLASH0_BASE + CFG_CS0_MASK - PHYS_AMD_SECT_SIZE) |
||||
#define CFG_ENV_SIZE PHYS_AMD_SECT_SIZE |
||||
#define CFG_ENV_SECT_SIZE PHYS_AMD_SECT_SIZE |
||||
#define CFG_ENV1_ADDR (CFG_FLASH1_BASE + CFG_CS1_MASK - PHYS_INTEL_SECT_SIZE) |
||||
#define CFG_ENV1_SIZE PHYS_INTEL_SECT_SIZE |
||||
#define CFG_ENV1_SECT_SIZE PHYS_INTEL_SECT_SIZE |
||||
#else |
||||
#define CFG_ENV_ADDR (CFG_FLASH0_BASE + CFG_CS0_MASK - PHYS_INTEL_SECT_SIZE) |
||||
#define CFG_ENV_SIZE PHYS_INTEL_SECT_SIZE |
||||
#define CFG_ENV_SECT_SIZE PHYS_INTEL_SECT_SIZE |
||||
#define CFG_ENV1_ADDR (CFG_FLASH1_BASE + CFG_CS1_MASK - PHYS_AMD_SECT_SIZE) |
||||
#define CFG_ENV1_SIZE PHYS_AMD_SECT_SIZE |
||||
#define CFG_ENV1_SECT_SIZE PHYS_AMD_SECT_SIZE |
||||
#endif |
||||
|
||||
#define CONFIG_ENV_OVERWRITE 1 |
||||
|
||||
#if defined CFG_ENV_IS_IN_FLASH |
||||
#undef CFG_ENV_IS_IN_NVRAM |
||||
#undef CFG_ENV_IS_IN_EEPROM |
||||
#elif defined CFG_ENV_IS_IN_NVRAM |
||||
#undef CFG_ENV_IS_IN_FLASH |
||||
#undef CFG_ENV_IS_IN_EEPROM |
||||
#elif defined CFG_ENV_IS_IN_EEPROM |
||||
#undef CFG_ENV_IS_IN_NVRAM |
||||
#undef CFG_ENV_IS_IN_FLASH |
||||
#endif |
||||
|
||||
#ifndef CFG_JFFS2_FIRST_SECTOR |
||||
#define CFG_JFFS2_FIRST_SECTOR 0 |
||||
#endif |
||||
#ifndef CFG_JFFS2_FIRST_BANK |
||||
#define CFG_JFFS2_FIRST_BANK 0 |
||||
#endif |
||||
#ifndef CFG_JFFS2_NUM_BANKS |
||||
#define CFG_JFFS2_NUM_BANKS 1 |
||||
#endif |
||||
#define CFG_JFFS2_LAST_BANK (CFG_JFFS2_FIRST_BANK + CFG_JFFS2_NUM_BANKS - 1) |
||||
|
||||
/*
|
||||
* Memory map |
||||
*/ |
||||
#define CFG_MBAR 0xF0000000 |
||||
#define CFG_SDRAM_BASE 0x00000000 |
||||
#define CFG_DEFAULT_MBAR 0x80000000 |
||||
#define CFG_SRAM_BASE (CFG_MBAR + 0x20000) |
||||
#define CFG_SRAM_SIZE 0x8000 |
||||
|
||||
/* Use SRAM until RAM will be available */ |
||||
#define CFG_INIT_RAM_ADDR (CFG_MBAR + 0x20000) |
||||
#define CFG_INIT_RAM_END 0x8000 /* End of used area in DPRAM */ |
||||
|
||||
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ |
||||
#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) |
||||
#define CFG_INIT_SP_OFFSET CFG_GBL_DATA_OFFSET |
||||
|
||||
#define CFG_MONITOR_BASE TEXT_BASE |
||||
#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) |
||||
# define CFG_RAMBOOT 1 |
||||
#endif |
||||
|
||||
#define CFG_MONITOR_LEN (256 << 10) /* Reserve 256 kB for Monitor */ |
||||
#define CFG_MALLOC_LEN (128 << 10) /* Reserve 128 kB for malloc() */ |
||||
#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ |
||||
|
||||
/*
|
||||
* Ethernet configuration |
||||
*/ |
||||
#define CONFIG_MPC8220_FEC 1 |
||||
#define CONFIG_FEC_10MBIT 1 /* Workaround for FEC 100Mbit problem */ |
||||
#define CONFIG_PHY_ADDR 0x18 |
||||
|
||||
|
||||
/*
|
||||
* Miscellaneous configurable options |
||||
*/ |
||||
#define CFG_LONGHELP /* undef to save memory */ |
||||
#define CFG_PROMPT "=> " /* Monitor Command Prompt */ |
||||
#if (CONFIG_COMMANDS & CFG_CMD_KGDB) |
||||
#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ |
||||
#else |
||||
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ |
||||
#endif |
||||
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ |
||||
#define CFG_MAXARGS 16 /* max number of command args */ |
||||
#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ |
||||
|
||||
#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ |
||||
#define CFG_MEMTEST_END 0x00f00000 /* 1 ... 15 MB in DRAM */ |
||||
|
||||
#define CFG_LOAD_ADDR 0x100000 /* default load address */ |
||||
|
||||
#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ |
||||
|
||||
/*
|
||||
* Various low-level settings |
||||
*/ |
||||
#define CFG_HID0_INIT HID0_ICE | HID0_ICFI |
||||
#define CFG_HID0_FINAL HID0_ICE |
||||
|
||||
#endif /* __CONFIG_H */ |
@ -0,0 +1,551 @@ |
||||
/*
|
||||
* include/mpc8220.h |
||||
* |
||||
* Prototypes, etc. for the Motorola MPC8220 |
||||
* embedded cpu chips |
||||
* |
||||
* 2004 (c) Freescale, Inc. |
||||
* Author: TsiChung Liew <Tsi-Chung.Liew@freescale.com> |
||||
* |
||||
* 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 |
||||
*/ |
||||
#ifndef __MPC8220_H__ |
||||
#define __MPC8220_H__ |
||||
|
||||
/* Processor name */ |
||||
#if defined(CONFIG_MPC8220) |
||||
#define CPU_ID_STR "MPC8220" |
||||
#endif |
||||
|
||||
/* Exception offsets (PowerPC standard) */ |
||||
#define EXC_OFF_SYS_RESET 0x0100 |
||||
|
||||
/* Internal memory map */ |
||||
/* MPC8220 Internal Register MMAP */ |
||||
#define MMAP_MBAR (CFG_MBAR + 0x00000000) /* chip selects */ |
||||
#define MMAP_MEMCTL (CFG_MBAR + 0x00000100) /* sdram controller */ |
||||
#define MMAP_XLBARB (CFG_MBAR + 0x00000200) /* xlb arbitration control */ |
||||
#define MMAP_CDM (CFG_MBAR + 0x00000300) /* clock distribution module */ |
||||
#define MMAP_VDOPLL (CFG_MBAR + 0x00000400) /* video PLL */ |
||||
#define MMAP_FB (CFG_MBAR + 0x00000500) /* flex bus controller */ |
||||
#define MMAP_PCFG (CFG_MBAR + 0x00000600) /* port config */ |
||||
#define MMAP_ICTL (CFG_MBAR + 0x00000700) /* interrupt controller */ |
||||
#define MMAP_GPTMR (CFG_MBAR + 0x00000800) /* general purpose timers */ |
||||
#define MMAP_SLTMR (CFG_MBAR + 0x00000900) /* slice timers */ |
||||
#define MMAP_GPIO (CFG_MBAR + 0x00000A00) /* gpio module */ |
||||
#define MMAP_XCPCI (CFG_MBAR + 0x00000B00) /* pci controller */ |
||||
#define MMAP_PCIARB (CFG_MBAR + 0x00000C00) /* pci arbiter */ |
||||
#define MMAP_EXTDMA1 (CFG_MBAR + 0x00000D00) /* external dma1 */ |
||||
#define MMAP_EXTDMA2 (CFG_MBAR + 0x00000E00) /* external dma1 */ |
||||
#define MMAP_USBH (CFG_MBAR + 0x00001000) /* usb host */ |
||||
#define MMAP_CMTMR (CFG_MBAR + 0x00007f00) /* comm timers */ |
||||
#define MMAP_DMA (CFG_MBAR + 0x00008000) /* dma */ |
||||
#define MMAP_USBD (CFG_MBAR + 0x00008200) /* usb device */ |
||||
#define MMAP_COMMPCI (CFG_MBAR + 0x00008400) /* pci comm Bus regs */ |
||||
#define MMAP_1284 (CFG_MBAR + 0x00008500) /* 1284 */ |
||||
#define MMAP_PEV (CFG_MBAR + 0x00008600) /* print engine video */ |
||||
#define MMAP_PSC1 (CFG_MBAR + 0x00008800) /* psc1 block */ |
||||
#define MMAP_I2C (CFG_MBAR + 0x00008f00) /* i2c controller */ |
||||
#define MMAP_FEC1 (CFG_MBAR + 0x00009000) /* fast ethernet 1 */ |
||||
#define MMAP_FEC2 (CFG_MBAR + 0x00009800) /* fast ethernet 2 */ |
||||
#define MMAP_JBIGRAM (CFG_MBAR + 0x0000a000) /* jbig RAM */ |
||||
#define MMAP_JBIG (CFG_MBAR + 0x0000c000) /* jbig */ |
||||
#define MMAP_PDLA (CFG_MBAR + 0x00010000) /* */ |
||||
#define MMAP_SRAMCFG (CFG_MBAR + 0x0001ff00) /* SRAM config */ |
||||
#define MMAP_SRAM (CFG_MBAR + 0x00020000) /* SRAM */ |
||||
|
||||
#define SRAM_SIZE 0x8000 /* 32 KB */ |
||||
|
||||
/* ------------------------------------------------------------------------ */ |
||||
/*
|
||||
* Macro for Programmable Serial Channel |
||||
*/ |
||||
/* equates for mode reg. 1 for channel A or B */ |
||||
#define PSC_MR1_RX_RTS 0x80000000 /* receiver RTS enabled */ |
||||
#define PSC_MR1_RX_INT 0x40000000 /* receiver intrupt enabled */ |
||||
#define PSC_MR1_ERR_MODE 0x20000000 /* block error mode */ |
||||
#define PSC_MR1_PAR_MODE_MULTI 0x18000000 /* multi_drop mode */ |
||||
#define PSC_MR1_NO_PARITY 0x10000000 /* no parity mode */ |
||||
#define PSC_MR1_ALWAYS_0 0x08000000 /* force parity mode */ |
||||
#define PSC_MR1_ALWAYS_1 0x0c000000 /* force parity mode */ |
||||
#define PSC_MR1_EVEN_PARITY 0x00000000 /* parity mode */ |
||||
#define PSC_MR1_ODD_PARITY 0x04000000 /* 0 = even, 1 = odd */ |
||||
#define PSC_MR1_BITS_CHAR_8 0x03000000 /* 8 bits */ |
||||
#define PSC_MR1_BITS_CHAR_7 0x02000000 /* 7 bits */ |
||||
#define PSC_MR1_BITS_CHAR_6 0x01000000 /* 6 bits */ |
||||
#define PSC_MR1_BITS_CHAR_5 0x00000000 /* 5 bits */ |
||||
|
||||
/* equates for mode reg. 2 for channel A or B */ |
||||
#define PSC_MR2_NORMAL_MODE 0x00000000 /* normal channel mode */ |
||||
#define PSC_MR2_AUTO_MODE 0x40000000 /* automatic channel mode */ |
||||
#define PSC_MR2_LOOPBACK_LOCL 0x80000000 /* local loopback channel mode */ |
||||
#define PSC_MR2_LOOPBACK_REMT 0xc0000000 /* remote loopback channel mode */ |
||||
#define PSC_MR2_TX_RTS 0x20000000 /* transmitter RTS enabled */ |
||||
#define PSC_MR2_TX_CTS 0x10000000 /* transmitter CTS enabled */ |
||||
#define PSC_MR2_STOP_BITS_2 0x0f000000 /* 2 stop bits */ |
||||
#define PSC_MR2_STOP_BITS_1 0x07000000 /* 1 stop bit */ |
||||
|
||||
/* equates for status reg. A or B */ |
||||
#define PSC_SR_BREAK 0x80000000 /* received break */ |
||||
#define PSC_SR_NEOF PSC_SR_BREAK /* Next byte is EOF - MIR/FIR */ |
||||
#define PSC_SR_FRAMING 0x40000000 /* framing error */ |
||||
#define PSC_SR_PHYERR PSC_SR_FRAMING/* Physical Layer error - MIR/FIR */ |
||||
#define PSC_SR_PARITY 0x20000000 /* parity error */ |
||||
#define PSC_SR_CRCERR PSC_SR_PARITY /* CRC error */ |
||||
#define PSC_SR_OVERRUN 0x10000000 /* overrun error */ |
||||
#define PSC_SR_TXEMT 0x08000000 /* transmitter empty */ |
||||
#define PSC_SR_TXRDY 0x04000000 /* transmitter ready*/ |
||||
#define PSC_SR_FFULL 0x02000000 /* fifo full */ |
||||
#define PSC_SR_RXRDY 0x01000000 /* receiver ready */ |
||||
#define PSC_SR_DEOF 0x00800000 /* Detect EOF or RX-FIFO contain EOF */ |
||||
#define PSC_SR_ERR 0x00400000 /* Error Status including FIFO */ |
||||
|
||||
/* equates for clock select reg. */ |
||||
#define PSC_CSRX16EXT_CLK 0x1110 /* x 16 ext_clock */ |
||||
#define PSC_CSRX1EXT_CLK 0x1111 /* x 1 ext_clock */ |
||||
|
||||
/* equates for command reg. A or B */ |
||||
#define PSC_CR_NO_COMMAND 0x00000000 /* no command */ |
||||
#define PSC_CR_RST_MR_PTR_CMD 0x10000000 /* reset mr pointer command */ |
||||
#define PSC_CR_RST_RX_CMD 0x20000000 /* reset receiver command */ |
||||
#define PSC_CR_RST_TX_CMD 0x30000000 /* reset transmitter command */ |
||||
#define PSC_CR_RST_ERR_STS_CMD 0x40000000 /* reset error status cmnd */ |
||||
#define PSC_CR_RST_BRK_INT_CMD 0x50000000 /* reset break int. command */ |
||||
#define PSC_CR_STR_BREAK_CMD 0x60000000 /* start break command */ |
||||
#define PSC_CR_STP_BREAK_CMD 0x70000000 /* stop break command */ |
||||
#define PSC_CR_RX_ENABLE 0x01000000 /* receiver enabled */ |
||||
#define PSC_CR_RX_DISABLE 0x02000000 /* receiver disabled */ |
||||
#define PSC_CR_TX_ENABLE 0x04000000 /* transmitter enabled */ |
||||
#define PSC_CR_TX_DISABLE 0x08000000 /* transmitter disabled */ |
||||
|
||||
/* equates for input port change reg. */ |
||||
#define PSC_IPCR_SYNC 0x80000000 /* Sync Detect */ |
||||
#define PSC_IPCR_D_CTS 0x10000000 /* Delta CTS */ |
||||
#define PSC_IPCR_CTS 0x01000000 /* CTS - current state of PSC_CTS */ |
||||
|
||||
/* equates for auxiliary control reg. (timer and counter clock selects) */ |
||||
#define PSC_ACR_BRG 0x80000000 /* for 68681 compatibility |
||||
baud rate gen select |
||||
0 = set 1; 1 = set 2 |
||||
equates are set 2 ONLY */ |
||||
#define PSC_ACR_TMR_EXT_CLK_16 0x70000000 /* xtnl clock divided by 16 */ |
||||
#define PSC_ACR_TMR_EXT_CLK 0x60000000 /* external clock */ |
||||
#define PSC_ACR_TMR_IP2_16 0x50000000 /* ip2 divided by 16 */ |
||||
#define PSC_ACR_TMR_IP2 0x40000000 /* ip2 */ |
||||
#define PSC_ACR_CTR_EXT_CLK_16 0x30000000 /* xtnl clock divided by 16 */ |
||||
#define PSC_ACR_CTR_TXCB 0x20000000 /* channel B xmitr clock */ |
||||
#define PSC_ACR_CTR_TXCA 0x10000000 /* channel A xmitr clock */ |
||||
#define PSC_ACR_CTR_IP2 0x00000000 /* ip2 */ |
||||
#define PSC_ACR_IEC0 0x01000000 /* interrupt enable ctrl for D_CTS */ |
||||
|
||||
/* equates for int. status reg. */ |
||||
#define PSC_ISR_IPC 0x80000000 /* input port change*/ |
||||
#define PSC_ISR_BREAK 0x04000000 /* delta break */ |
||||
#define PSC_ISR_RX_RDY 0x02000000 /* receiver rdy /fifo full */ |
||||
#define PSC_ISR_TX_RDY 0x01000000 /* transmitter ready */ |
||||
#define PSC_ISR_DEOF 0x00800000 /* Detect EOF / RX-FIFO contains EOF */ |
||||
#define PSC_ISR_ERR 0x00400000 /* Error Status including FIFO */ |
||||
|
||||
/* equates for int. mask reg. */ |
||||
#define PSC_IMR_CLEAR 0xff000000 /* Clear the imr */ |
||||
#define PSC_IMR_IPC 0x80000000 /* input port change*/ |
||||
#define PSC_IMR_BREAK 0x04000000 /* delta break */ |
||||
#define PSC_IMR_RX_RDY 0x02000000 /* rcvr ready / fifo full */ |
||||
#define PSC_IMR_TX_RDY 0x01000000 /* transmitter ready */ |
||||
#define PSC_IMR_DEOF 0x00800000 /* Detect EOF / RX-FIFO contains EOF */ |
||||
#define PSC_IMR_ERR 0x00400000 /* Error Status including FIFO */ |
||||
|
||||
/* equates for input port reg. */ |
||||
#define PSC_IP_LPWRB 0x80000000 /* Low power mode in Ac97 */ |
||||
#define PSC_IP_TGL 0x40000000 /* test usage */ |
||||
#define PSC_IP_CTS 0x01000000 /* CTS */ |
||||
|
||||
/* equates for output port bit set reg. */ |
||||
#define PSC_OPSET_RTS 0x01000000 /* Assert PSC_RTS output */ |
||||
|
||||
/* equates for output port bit reset reg. */ |
||||
#define PSC_OPRESET_RTS 0x01000000 /* Assert PSC_RTS output */ |
||||
|
||||
/* equates for rx FIFO number of data reg. */ |
||||
#define PSC_RFNUM(x) ((x&0xff)<<24)/* receive count */ |
||||
|
||||
/* equates for tx FIFO number of data reg. */ |
||||
#define PSC_TFNUM(x) ((x&0xff)<<24)/* receive count */ |
||||
|
||||
/* equates for rx FIFO status reg */ |
||||
#define PSC_RFSTAT_TAG(x) ((x&3)<<28) /* tag */ |
||||
#define PSC_RFSTAT_FRAME0 0x08 /* Frame Indicator 0 */ |
||||
#define PSC_RFSTAT_FRAME1 0x04 /* Frame Indicator 1 */ |
||||
#define PSC_RFSTAT_FRAME2 0x02 /* Frame Indicator 2 */ |
||||
#define PSC_RFSTAT_FRAME3 0x01 /* Frame Indicator 3 */ |
||||
#define PSC_RFSTAT_FRAME(x) ((x&0x0f)<<24)/* Frame indicator */ |
||||
#define PSC_RFSTAT_ERR 0x00400000 /* Fifo err */ |
||||
#define PSC_RFSTAT_UF 0x00200000 /* Underflow */ |
||||
#define PSC_RFSTAT_OF 0x00100000 /* overflow */ |
||||
#define PSC_RFSTAT_FR 0x00080000 /* frame ready */ |
||||
#define PSC_RFSTAT_FULL 0x00040000 /* full */ |
||||
#define PSC_RFSTAT_ALARM 0x00020000 /* alarm */ |
||||
#define PSC_RFSTAT_EMPTY 0x00010000 /* empty */ |
||||
|
||||
/* equates for tx FIFO status reg */ |
||||
#define PSC_TFSTAT_TAG(x) ((x&3)<<28) /* tag */ |
||||
#define PSC_TFSTAT_FRAME0 0x08 /* Frame Indicator 0 */ |
||||
#define PSC_TFSTAT_FRAME1 0x04 /* Frame Indicator 1 */ |
||||
#define PSC_TFSTAT_FRAME2 0x02 /* Frame Indicator 2 */ |
||||
#define PSC_TFSTAT_FRAME3 0x01 /* Frame Indicator 3 */ |
||||
#define PSC_TFSTAT_FRAME(x) ((x&0x0f)<<24)/* Frame indicator */ |
||||
#define PSC_TFSTAT_ERR 0x00400000 /* Fifo err */ |
||||
#define PSC_TFSTAT_UF 0x00200000 /* Underflow */ |
||||
#define PSC_TFSTAT_OF 0x00100000 /* overflow */ |
||||
#define PSC_TFSTAT_FR 0x00080000 /* frame ready */ |
||||
#define PSC_TFSTAT_FULL 0x00040000 /* full */ |
||||
#define PSC_TFSTAT_ALARM 0x00020000 /* alarm */ |
||||
#define PSC_TFSTAT_EMPTY 0x00010000 /* empty */ |
||||
|
||||
/* equates for rx FIFO control reg. */ |
||||
#define PSC_RFCNTL_WTAG(x) ((x&3)<<29) /* Write tag */ |
||||
#define PSC_RFCNTL_FRAME 0x08000000 /* Frame mode enable */ |
||||
#define PSC_RFCNTL_GR(x) ((x&7)<<24) /* Granularity */ |
||||
|
||||
/* equates for tx FIFO control reg. */ |
||||
#define PSC_TFCNTL_WTAG(x) ((x&3)<<29) /* Write tag */ |
||||
#define PSC_TFCNTL_FRAME 0x08000000 /* Frame mode enable */ |
||||
#define PSC_TFCNTL_GR(x) ((x&7)<<24) /* Granularity */ |
||||
|
||||
/* equates for rx FIFO alarm reg */ |
||||
#define PSC_RFALARM(x) (x&0x1ff) /* Alarm */ |
||||
|
||||
/* equates for tx FIFO alarm reg */ |
||||
#define PSC_TFALARM(x) (x&0x1ff) /* Alarm */ |
||||
|
||||
/* equates for rx FIFO read pointer */ |
||||
#define PSC_RFRPTR(x) (x&0x1ff) /* read pointer */ |
||||
|
||||
/* equates for tx FIFO read pointer */ |
||||
#define PSC_TFRPTR(x) (x&0x1ff) /* read pointer */ |
||||
|
||||
/* equates for rx FIFO write pointer */ |
||||
#define PSC_RFWPTR(x) (x&0x1ff) /* write pointer */ |
||||
|
||||
/* equates for rx FIFO write pointer */ |
||||
#define PSC_TFWPTR(x) (x&0x1ff) /* write pointer */ |
||||
|
||||
/* equates for rx FIFO last read frame pointer reg */ |
||||
#define PSC_RFLRFPTR(x) (x&0x1ff) /* last read frame pointer */ |
||||
|
||||
/* equates for tx FIFO last read frame pointer reg */ |
||||
#define PSC_TFLRFPTR(x) (x&0x1ff) /* last read frame pointer */ |
||||
|
||||
/* equates for rx FIFO last write frame pointer reg */ |
||||
#define PSC_RFLWFPTR(x) (x&0x1ff) /* last write frame pointer */ |
||||
|
||||
/* equates for tx FIFO last write frame pointer reg */ |
||||
#define PSC_TFLWFPTR(x) (x&0x1ff) /* last write frame pointer */ |
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */ |
||||
/*
|
||||
* Macro for General Purpose Timer |
||||
*/ |
||||
/* Enable and Mode Select */ |
||||
#define GPT_OCT(x) (x & 0x3)<<4/* Output Compare Type */ |
||||
#define GPT_ICT(x) (x & 0x3) /* Input Capture Type */ |
||||
#define GPT_CTRL_WDEN 0x80 /* Watchdog Enable */ |
||||
#define GPT_CTRL_CE 0x10 /* Counter Enable */ |
||||
#define GPT_CTRL_STPCNT 0x04 /* Stop continous */ |
||||
#define GPT_CTRL_ODRAIN 0x02 /* Open Drain */ |
||||
#define GPT_CTRL_INTEN 0x01 /* Interrupt Enable */ |
||||
#define GPT_MODE_GPIO(x) (x & 0x3)<<4/* Gpio Mode Type */ |
||||
#define GPT_TMS_ICT 0x01 /* Input Capture Enable */ |
||||
#define GPT_TMS_OCT 0x02 /* Output Capture Enable */ |
||||
#define GPT_TMS_PWM 0x03 /* PWM Capture Enable */ |
||||
#define GPT_TMS_SGPIO 0x04 /* PWM Capture Enable */ |
||||
|
||||
#define GPT_PWM_WIDTH(x) (x & 0xffff) |
||||
|
||||
/* Status */ |
||||
#define GPT_STA_CAPTURE(x) (x & 0xffff)/* Read of internal counter */ |
||||
|
||||
#define GPT_OVFPIN_OVF(x) (x & 0x70) /* Internal counter roll over */ |
||||
#define GPT_OVFPIN_PIN 0x01 /* Input pin - Timer 0 and 1 */ |
||||
|
||||
#define GPT_INT_TEXP 0x08 /* Timer Expired in Internal Timer mode */ |
||||
#define GPT_INT_PWMP 0x04 /* PWM end of period occurred */ |
||||
#define GPT_INT_COMP 0x02 /* OC reference event occurred */ |
||||
#define GPT_INT_CAPT 0x01 /* IC reference event occurred */ |
||||
|
||||
/* ------------------------------------------------------------------------ */ |
||||
/*
|
||||
* Port configuration |
||||
*/ |
||||
#define CFG_FEC1_PORT0_CONFIG 0x00000000 |
||||
#define CFG_FEC1_PORT1_CONFIG 0x00000000 |
||||
#define CFG_1284_PORT0_CONFIG 0x55555557 |
||||
#define CFG_1284_PORT1_CONFIG 0x80000000 |
||||
#define CFG_FEC2_PORT2_CONFIG 0x00000000 |
||||
#define CFG_PEV_PORT2_CONFIG 0x55555540 |
||||
#define CFG_GP0_PORT0_CONFIG 0xaaaaaaa0 |
||||
#define CFG_GP1_PORT2_CONFIG 0xaaaaa000 |
||||
#define CFG_PSC_PORT3_CONFIG 0x00000000 |
||||
#define CFG_CS2_PORT3_CONFIG 0x10000000 |
||||
#define CFG_CS3_PORT3_CONFIG 0x40000000 |
||||
#define CFG_CS4_PORT3_CONFIG 0x00000400 |
||||
#define CFG_CS5_PORT3_CONFIG 0x00000100 |
||||
#define CFG_I2C_PORT3_CONFIG 0x003c0000 |
||||
|
||||
/* ------------------------------------------------------------------------ */ |
||||
/*
|
||||
* DRAM configuration |
||||
*/ |
||||
|
||||
/* Field definitions for the control register */ |
||||
#define CTL_MODE_ENABLE_SHIFT 31 |
||||
#define CTL_CKE_SHIFT 30 |
||||
#define CTL_DDR_SHIFT 29 |
||||
#define CTL_REFRESH_SHIFT 28 |
||||
#define CTL_ADDRMUX_SHIFT 24 |
||||
#define CTL_PRECHARGE_SHIFT 23 |
||||
#define CTL_DRIVE_RULE_SHIFT 22 |
||||
#define CTL_REFRESH_INTERVAL_SHIFT 16 |
||||
#define CTL_DQSOEN_SHIFT 8 |
||||
#define CTL_BUFFERED_SHIFT 4 |
||||
#define CTL_REFRESH_CMD_SHIFT 2 |
||||
#define CTL_PRECHARGE_CMD_SHIFT 1 |
||||
|
||||
#define CTL_MODE_ENABLE (1<<CTL_MODE_ENABLE_SHIFT) |
||||
#define CTL_CKE_HIGH (1<<CTL_CKE_SHIFT) |
||||
#define CTL_DDR_MODE (1<<CTL_DDR_SHIFT) |
||||
#define CTL_REFRESH_ENABLE (1<<CTL_REFRESH_SHIFT) |
||||
#define CTL_ADDRMUX(value) ((value)<<CTL_ADDRMUX_SHIFT) |
||||
#define CTL_A8PRECHARGE (1<<CTL_PRECHARGE_SHIFT) |
||||
#define CTL_REFRESH_INTERVAL(value) ((value)<<CTL_REFRESH_INTERVAL_SHIFT) |
||||
#define CTL_DQSOEN(value) ((value)<<CTL_DQSOEN_SHIFT) |
||||
#define CTL_BUFFERED (1<<CTL_BUFFERED_SHIFT) |
||||
#define CTL_REFRESH_CMD (1<<CTL_REFRESH_CMD_SHIFT) |
||||
#define CTL_PRECHARGE_CMD (1<<CTL_PRECHARGE_CMD_SHIFT) |
||||
|
||||
/* Field definitions for config register 1 */ |
||||
|
||||
#define CFG1_SRD2RWP_SHIFT 28 |
||||
#define CFG1_SWT2RWP_SHIFT 24 |
||||
#define CFG1_RLATENCY_SHIFT 20 |
||||
#define CFG1_ACT2WR_SHIFT 16 |
||||
#define CFG1_PRE2ACT_SHIFT 12 |
||||
#define CFG1_REF2ACT_SHIFT 8 |
||||
#define CFG1_WLATENCY_SHIFT 4 |
||||
|
||||
#define CFG1_SRD2RWP(value) ((value)<<CFG1_SRD2RWP_SHIFT) |
||||
#define CFG1_SWT2RWP(value) ((value)<<CFG1_SWT2RWP_SHIFT) |
||||
#define CFG1_RLATENCY(value) ((value)<<CFG1_RLATENCY_SHIFT) |
||||
#define CFG1_ACT2WR(value) ((value)<<CFG1_ACT2WR_SHIFT) |
||||
#define CFG1_PRE2ACT(value) ((value)<<CFG1_PRE2ACT_SHIFT) |
||||
#define CFG1_REF2ACT(value) ((value)<<CFG1_REF2ACT_SHIFT) |
||||
#define CFG1_WLATENCY(value) ((value)<<CFG1_WLATENCY_SHIFT) |
||||
|
||||
/* Field definitions for config register 2 */ |
||||
#define CFG2_BRD2RP_SHIFT 28 |
||||
#define CFG2_BWT2RWP_SHIFT 24 |
||||
#define CFG2_BRD2WT_SHIFT 20 |
||||
#define CFG2_BURSTLEN_SHIFT 16 |
||||
|
||||
#define CFG2_BRD2RP(value) ((value)<<CFG2_BRD2RP_SHIFT) |
||||
#define CFG2_BWT2RWP(value) ((value)<<CFG2_BWT2RWP_SHIFT) |
||||
#define CFG2_BRD2WT(value) ((value)<<CFG2_BRD2WT_SHIFT) |
||||
#define CFG2_BURSTLEN(value) ((value)<<CFG2_BURSTLEN_SHIFT) |
||||
|
||||
/* Field definitions for the mode/extended mode register - mode
|
||||
* register access |
||||
*/ |
||||
#define MODE_REG_SHIFT 30 |
||||
#define MODE_OPMODE_SHIFT 25 |
||||
#define MODE_CL_SHIFT 22 |
||||
#define MODE_BT_SHIFT 21 |
||||
#define MODE_BURSTLEN_SHIFT 18 |
||||
#define MODE_CMD_SHIFT 16 |
||||
|
||||
#define MODE_MODE 0 |
||||
#define MODE_OPMODE(value) ((value)<<MODE_OPMODE_SHIFT) |
||||
#define MODE_CL(value) ((value)<<MODE_CL_SHIFT) |
||||
#define MODE_BT_INTERLEAVED (1<<MODE_BT_SHIFT) |
||||
#define MODE_BT_SEQUENTIAL (0<<MODE_BT_SHIFT) |
||||
#define MODE_BURSTLEN(value) ((value)<<MODE_BURSTLEN_SHIFT) |
||||
#define MODE_CMD (1<<MODE_CMD_SHIFT) |
||||
|
||||
#define MODE_BURSTLEN_8 3 |
||||
#define MODE_BURSTLEN_4 2 |
||||
#define MODE_BURSTLEN_2 1 |
||||
|
||||
#define MODE_CL_2 2 |
||||
#define MODE_CL_2p5 6 |
||||
#define MODE_OPMODE_NORMAL 0 |
||||
#define MODE_OPMODE_RESETDLL 2 |
||||
|
||||
|
||||
/* Field definitions for the mode/extended mode register - extended
|
||||
* mode register access |
||||
*/ |
||||
#define MODE_X_DLL_SHIFT 18 /* DLL enable/disable */ |
||||
#define MODE_X_DS_SHIFT 19 /* Drive strength normal/reduced */ |
||||
#define MODE_X_QFC_SHIFT 20 /* QFC function (whatever that is) */ |
||||
#define MODE_X_OPMODE_SHIFT 21 |
||||
|
||||
#define MODE_EXTENDED (1<<MODE_REG_SHIFT) |
||||
#define MODE_X_DLL_ENABLE 0 |
||||
#define MODE_X_DLL_DISABLE (1<<MODE_X_DLL_SHIFT) |
||||
#define MODE_X_DS_NORMAL 0 |
||||
#define MODE_X_DS_REDUCED (1<<MODE_X_DS_SHIFT) |
||||
#define MODE_X_QFC_DISABLED 0 |
||||
#define MODE_X_OPMODE(value) ((value)<<MODE_X_OPMODE_SHIFT) |
||||
|
||||
#ifndef __ASSEMBLY__ |
||||
/*
|
||||
* DMA control/status registers. |
||||
*/ |
||||
struct mpc8220_dma { |
||||
u32 taskBar; /* DMA + 0x00 */ |
||||
u32 currentPointer; /* DMA + 0x04 */ |
||||
u32 endPointer; /* DMA + 0x08 */ |
||||
u32 variablePointer;/* DMA + 0x0c */ |
||||
|
||||
u8 IntVect1; /* DMA + 0x10 */ |
||||
u8 IntVect2; /* DMA + 0x11 */ |
||||
u16 PtdCntrl; /* DMA + 0x12 */ |
||||
|
||||
u32 IntPend; /* DMA + 0x14 */ |
||||
u32 IntMask; /* DMA + 0x18 */ |
||||
|
||||
u16 tcr_0; /* DMA + 0x1c */ |
||||
u16 tcr_1; /* DMA + 0x1e */ |
||||
u16 tcr_2; /* DMA + 0x20 */ |
||||
u16 tcr_3; /* DMA + 0x22 */ |
||||
u16 tcr_4; /* DMA + 0x24 */ |
||||
u16 tcr_5; /* DMA + 0x26 */ |
||||
u16 tcr_6; /* DMA + 0x28 */ |
||||
u16 tcr_7; /* DMA + 0x2a */ |
||||
u16 tcr_8; /* DMA + 0x2c */ |
||||
u16 tcr_9; /* DMA + 0x2e */ |
||||
u16 tcr_a; /* DMA + 0x30 */ |
||||
u16 tcr_b; /* DMA + 0x32 */ |
||||
u16 tcr_c; /* DMA + 0x34 */ |
||||
u16 tcr_d; /* DMA + 0x36 */ |
||||
u16 tcr_e; /* DMA + 0x38 */ |
||||
u16 tcr_f; /* DMA + 0x3a */ |
||||
|
||||
u8 IPR0; /* DMA + 0x3c */ |
||||
u8 IPR1; /* DMA + 0x3d */ |
||||
u8 IPR2; /* DMA + 0x3e */ |
||||
u8 IPR3; /* DMA + 0x3f */ |
||||
u8 IPR4; /* DMA + 0x40 */ |
||||
u8 IPR5; /* DMA + 0x41 */ |
||||
u8 IPR6; /* DMA + 0x42 */ |
||||
u8 IPR7; /* DMA + 0x43 */ |
||||
u8 IPR8; /* DMA + 0x44 */ |
||||
u8 IPR9; /* DMA + 0x45 */ |
||||
u8 IPR10; /* DMA + 0x46 */ |
||||
u8 IPR11; /* DMA + 0x47 */ |
||||
u8 IPR12; /* DMA + 0x48 */ |
||||
u8 IPR13; /* DMA + 0x49 */ |
||||
u8 IPR14; /* DMA + 0x4a */ |
||||
u8 IPR15; /* DMA + 0x4b */ |
||||
u8 IPR16; /* DMA + 0x4c */ |
||||
u8 IPR17; /* DMA + 0x4d */ |
||||
u8 IPR18; /* DMA + 0x4e */ |
||||
u8 IPR19; /* DMA + 0x4f */ |
||||
u8 IPR20; /* DMA + 0x50 */ |
||||
u8 IPR21; /* DMA + 0x51 */ |
||||
u8 IPR22; /* DMA + 0x52 */ |
||||
u8 IPR23; /* DMA + 0x53 */ |
||||
u8 IPR24; /* DMA + 0x54 */ |
||||
u8 IPR25; /* DMA + 0x55 */ |
||||
u8 IPR26; /* DMA + 0x56 */ |
||||
u8 IPR27; /* DMA + 0x57 */ |
||||
u8 IPR28; /* DMA + 0x58 */ |
||||
u8 IPR29; /* DMA + 0x59 */ |
||||
u8 IPR30; /* DMA + 0x5a */ |
||||
u8 IPR31; /* DMA + 0x5b */ |
||||
|
||||
u32 res1; /* DMA + 0x5c */ |
||||
u32 res2; /* DMA + 0x60 */ |
||||
u32 res3; /* DMA + 0x64 */ |
||||
u32 MDEDebug; /* DMA + 0x68 */ |
||||
u32 ADSDebug; /* DMA + 0x6c */ |
||||
u32 Value1; /* DMA + 0x70 */ |
||||
u32 Value2; /* DMA + 0x74 */ |
||||
u32 Control; /* DMA + 0x78 */ |
||||
u32 Status; /* DMA + 0x7c */ |
||||
u32 EU00; /* DMA + 0x80 */ |
||||
u32 EU01; /* DMA + 0x84 */ |
||||
u32 EU02; /* DMA + 0x88 */ |
||||
u32 EU03; /* DMA + 0x8c */ |
||||
u32 EU04; /* DMA + 0x90 */ |
||||
u32 EU05; /* DMA + 0x94 */ |
||||
u32 EU06; /* DMA + 0x98 */ |
||||
u32 EU07; /* DMA + 0x9c */ |
||||
u32 EU10; /* DMA + 0xa0 */ |
||||
u32 EU11; /* DMA + 0xa4 */ |
||||
u32 EU12; /* DMA + 0xa8 */ |
||||
u32 EU13; /* DMA + 0xac */ |
||||
u32 EU14; /* DMA + 0xb0 */ |
||||
u32 EU15; /* DMA + 0xb4 */ |
||||
u32 EU16; /* DMA + 0xb8 */ |
||||
u32 EU17; /* DMA + 0xbc */ |
||||
u32 EU20; /* DMA + 0xc0 */ |
||||
u32 EU21; /* DMA + 0xc4 */ |
||||
u32 EU22; /* DMA + 0xc8 */ |
||||
u32 EU23; /* DMA + 0xcc */ |
||||
u32 EU24; /* DMA + 0xd0 */ |
||||
u32 EU25; /* DMA + 0xd4 */ |
||||
u32 EU26; /* DMA + 0xd8 */ |
||||
u32 EU27; /* DMA + 0xdc */ |
||||
u32 EU30; /* DMA + 0xe0 */ |
||||
u32 EU31; /* DMA + 0xe4 */ |
||||
u32 EU32; /* DMA + 0xe8 */ |
||||
u32 EU33; /* DMA + 0xec */ |
||||
u32 EU34; /* DMA + 0xf0 */ |
||||
u32 EU35; /* DMA + 0xf4 */ |
||||
u32 EU36; /* DMA + 0xf8 */ |
||||
u32 EU37; /* DMA + 0xfc */ |
||||
}; |
||||
|
||||
|
||||
/* function prototypes */ |
||||
void loadtask(int basetask, int tasks); |
||||
u32 dramSetup(void); |
||||
|
||||
#if defined(CONFIG_PSC_CONSOLE) |
||||
int psc_serial_init (void); |
||||
void psc_serial_putc(const char c); |
||||
void psc_serial_puts (const char *s); |
||||
int psc_serial_getc(void); |
||||
int psc_serial_tstc(void); |
||||
void psc_serial_setbrg(void); |
||||
#endif |
||||
|
||||
#if defined (CONFIG_EXTUART_CONSOLE) |
||||
int ext_serial_init (void); |
||||
void ext_serial_putc(const char c); |
||||
void ext_serial_puts (const char *s); |
||||
int ext_serial_getc(void); |
||||
int ext_serial_tstc(void); |
||||
void ext_serial_setbrg(void); |
||||
#endif |
||||
|
||||
#endif /* __ASSEMBLY__ */ |
||||
|
||||
#endif /* __MPC8220_H__ */ |
Loading…
Reference in new issue