Patch by TsiChung Liew, 23 Sep 2004:

- add support for MPC8220 CPU
- Add support for Alaska and Yukon boards
This commit is contained in:
wdenk 2004-10-28 00:09:35 +00:00
parent e3c9b9f928
commit 983fda8391
43 changed files with 8635 additions and 13 deletions

View file

@ -2,6 +2,10 @@
Changes since U-Boot 1.1.1:
======================================================================
* Patch by TsiChung Liew, 23 Sep 2004:
- add support for MPC8220 CPU
- Add support for Alaska and Yukon boards
* Fix configuration for ERIC board (needs more room)
* Adjust MIPS compiler options at run-time depending on tools version

10
MAKEALL
View file

@ -71,6 +71,14 @@ LIST_4xx=" \
WALNUT405 XPEDITE1K \
"
#########################################################################
## MPC8220 Systems
#########################################################################
LIST_8220=" \
Alaska8220 Yukon8220 \
"
#########################################################################
## MPC824x Systems
#########################################################################
@ -228,7 +236,7 @@ build_target() {
for arg in $@
do
case "$arg" in
ppc|5xx|5xxx|8xx|824x|8260|85xx|4xx|7xx|74xx| \
ppc|5xx|5xxx|8xx|8220|824x|8260|85xx|4xx|7xx|74xx| \
arm|SA|ARM7|ARM9|pxa|ixp| \
microblaze| \
mips| \

View file

@ -825,6 +825,15 @@ WALNUT405_config: unconfig
XPEDITE1K_config: unconfig
@./mkconfig $(@:_config=) ppc ppc4xx xpedite1k
#########################################################################
## MPC8220 Systems
#########################################################################
Alaska8220_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8220 alaska
Yukon8220_config: unconfig
@./mkconfig $(@:_config=) ppc mpc8220 yukon
#########################################################################
## MPC824x Systems
#########################################################################

22
README
View file

@ -123,24 +123,25 @@ Directory Hierarchy:
- board Board dependent files
- common Misc architecture independent functions
- cpu CPU specific files
- 74xx_7xx Files specific to Motorola MPC74xx and 7xx CPUs
- 74xx_7xx Files specific to Freescale MPC74xx and 7xx CPUs
- arm720t Files specific to ARM 720 CPUs
- arm920t Files specific to ARM 920 CPUs
- imx Files specific to Motorola MC9328 i.MX CPUs
- imx Files specific to Freescale MC9328 i.MX CPUs
- s3c24x0 Files specific to Samsung S3C24X0 CPUs
- arm925t Files specific to ARM 925 CPUs
- arm926ejs Files specific to ARM 926 CPUs
- at91rm9200 Files specific to Atmel AT91RM9200 CPUs
- i386 Files specific to i386 CPUs
- ixp Files specific to Intel XScale IXP CPUs
- mcf52x2 Files specific to Motorola ColdFire MCF52x2 CPUs
- mcf52x2 Files specific to Freescale ColdFire MCF52x2 CPUs
- mips Files specific to MIPS CPUs
- mpc5xx Files specific to Motorola MPC5xx CPUs
- mpc5xxx Files specific to Motorola MPC5xxx CPUs
- mpc8xx Files specific to Motorola MPC8xx CPUs
- mpc824x Files specific to Motorola MPC824x CPUs
- mpc8260 Files specific to Motorola MPC8260 CPUs
- mpc85xx Files specific to Motorola MPC85xx CPUs
- mpc5xx Files specific to Freescale MPC5xx CPUs
- mpc5xxx Files specific to Freescale MPC5xxx CPUs
- mpc8xx Files specific to Freescale MPC8xx CPUs
- mpc8220 Files specific to Freescale MPC8220 CPUs
- mpc824x Files specific to Freescale MPC824x CPUs
- mpc8260 Files specific to Freescale MPC8260 CPUs
- mpc85xx Files specific to Freescale MPC85xx CPUs
- nios Files specific to Altera NIOS CPUs
- nios2 Files specific to Altera Nios-II CPUs
- ppc4xx Files specific to IBM PowerPC 4xx CPUs
@ -229,6 +230,7 @@ The following options need to be configured:
-------------------
CONFIG_MPC823, CONFIG_MPC850, CONFIG_MPC855, CONFIG_MPC860
or CONFIG_MPC5xx
or CONFIG_MPC8220
or CONFIG_MPC824X, CONFIG_MPC8260
or CONFIG_MPC85xx
or CONFIG_IOP480
@ -2140,6 +2142,7 @@ configurations; the following names are supported:
ADCIOP_config FPS860L_config omap730p2_config
ADS860_config GEN860T_config pcu_e_config
Alaska8220_config
AR405_config GENIETV_config PIP405_config
at91rm9200dk_config GTH_config QS823_config
CANBT_config hermes_config QS850_config
@ -2161,6 +2164,7 @@ configurations; the following names are supported:
FADS860T_config omap1610inn_config TQM855L_config
FPS850L_config omap5912osk_config TQM860L_config
WALNUT405_config
Yukon8220_config
ZPC1900_config
Note: for some board special configuration names may exist; check if

45
board/alaska/Makefile Normal file
View file

@ -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
#########################################################################

153
board/alaska/alaska.c Normal file
View file

@ -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;
}

31
board/alaska/config.mk Normal file
View file

@ -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

110
board/alaska/extserial.c Normal file
View file

@ -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 */

807
board/alaska/flash.c Normal file
View file

@ -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;
}

131
board/alaska/serial.c Normal file
View file

@ -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
}
}

122
board/alaska/u-boot.lds Normal file
View file

@ -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 = .);
}

View file

@ -63,9 +63,9 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \
defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
print_str ("procfreq", strmhz(buf, bd->bi_procfreq));
print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq));
print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq));
#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq));
print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq));
#endif
#else /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
#if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
@ -79,6 +79,13 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#endif
print_str ("busfreq", strmhz(buf, bd->bi_busfreq));
#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
#if defined(CONFIG_MPC8220)
print_str ("inpfreq", strmhz(buf, bd->bi_inpfreq));
print_str ("flbfreq", strmhz(buf, bd->bi_flbfreq));
print_str ("pcifreq", strmhz(buf, bd->bi_pcifreq));
print_str ("vcofreq", strmhz(buf, bd->bi_vcofreq));
print_str ("pevfreq", strmhz(buf, bd->bi_pevfreq));
#endif
puts ("ethaddr =");
for (i=0; i<6; ++i) {

View file

@ -573,6 +573,13 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
/* convert all clock information to MHz */
kbd->bi_intfreq /= 1000000L;
kbd->bi_busfreq /= 1000000L;
#if defined(CONFIG_MPC8220)
kbd->bi_inpfreq /= 1000000L;
kbd->bi_pcifreq /= 1000000L;
kbd->bi_pevfreq /= 1000000L;
kbd->bi_flbfreq /= 1000000L;
kbd->bi_vcofreq /= 1000000L;
#endif
#if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
kbd->bi_cpmfreq /= 1000000L;
kbd->bi_brgfreq /= 1000000L;

45
cpu/mpc8220/Makefile Normal file
View file

@ -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
#########################################################################

27
cpu/mpc8220/config.mk Normal file
View file

@ -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

93
cpu/mpc8220/cpu.c Normal file
View file

@ -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);
}
/* ------------------------------------------------------------------------- */

130
cpu/mpc8220/cpu_init.c Normal file
View file

@ -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);
}

68
cpu/mpc8220/dma.h Normal file
View file

@ -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 */

755
cpu/mpc8220/dramSetup.c Normal file
View file

@ -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;
}

108
cpu/mpc8220/dramSetup.h Normal file
View file

@ -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 */

993
cpu/mpc8220/fec.c Normal file
View file

@ -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 */

283
cpu/mpc8220/fec.h Normal file
View file

@ -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 */

363
cpu/mpc8220/fec_dma_tasks.S Normal file
View file

@ -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

403
cpu/mpc8220/i2c.c Normal file
View file

@ -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 (&regs->sr);
while (timeout-- && (status & I2C_BB)) {
#if 1
volatile int temp;
mpc_reg_out (&regs->cr, I2C_STA, I2C_STA);
temp = mpc_reg_in (&regs->dr);
mpc_reg_out (&regs->cr, 0, I2C_STA);
mpc_reg_out (&regs->cr, 0, 0);
mpc_reg_out (&regs->cr, I2C_EN, 0);
#endif
udelay (1000);
status = mpc_reg_in (&regs->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 (&regs->sr);
while (timeout-- && !(*status & I2C_IF)) {
udelay (1000);
*status = mpc_reg_in (&regs->sr);
}
if (!(*status & I2C_IF)) {
return -1;
}
mpc_reg_out (&regs->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 (&regs->cr, I2C_TX, I2C_TX);
mpc_reg_out (&regs->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 (&regs->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 (&regs->cr, 0, I2C_TX);
for (i = 0; i < len; ++i) {
buf[rdcount] = mpc_reg_in (&regs->dr);
if (dummy)
dummy = 0;
else
rdcount++;
if (wait_for_pin (&status))
return -4;
}
mpc_reg_out (&regs->cr, I2C_TXAK, I2C_TXAK);
buf[rdcount++] = mpc_reg_in (&regs->dr);
if (wait_for_pin (&status))
return -5;
mpc_reg_out (&regs->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 (&regs->cr, 0, 0);
mpc_reg_out (&regs->adr, saddr << 1, 0);
/* Set clock
*/
mpc_reg_out (&regs->fdr, mpc_get_fdr (speed), 0);
/* Enable module
*/
mpc_reg_out (&regs->cr, I2C_EN, I2C_INIT_MASK);
mpc_reg_out (&regs->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 (&regs->cr, I2C_STA, I2C_STA);
if (!do_address (chip, 0)) {
mpc_reg_out (&regs->cr, 0, I2C_STA);
break;
}
mpc_reg_out (&regs->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 (&regs->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 (&regs->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 (&regs->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 (&regs->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 (&regs->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 */

627
cpu/mpc8220/i2cCore.c Normal file
View file

@ -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;
}

103
cpu/mpc8220/i2cCore.h Normal file
View file

@ -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 */

80
cpu/mpc8220/interrupts.c Normal file
View file

@ -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");
}

128
cpu/mpc8220/io.S Normal file
View file

@ -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

78
cpu/mpc8220/loadtask.c Normal file
View file

@ -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");
}

119
cpu/mpc8220/speed.c Normal file
View file

@ -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);
}
/* ------------------------------------------------------------------------- */

774
cpu/mpc8220/start.S Normal file
View file

@ -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

239
cpu/mpc8220/traps.c Normal file
View file

@ -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;
}

128
cpu/mpc8220/uart.c Normal file
View file

@ -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 */

482
doc/README.alaska8220 Normal file
View file

@ -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

View file

@ -49,6 +49,14 @@ typedef struct global_data {
#if defined(CONFIG_MPC5xxx)
unsigned long ipb_clk;
unsigned long pci_clk;
#endif
#if defined(CONFIG_MPC8220)
unsigned long bExtUart;
unsigned long inp_clk;
unsigned long pci_clk;
unsigned long vco_clk;
unsigned long pev_clk;
unsigned long flb_clk;
#endif
unsigned long ram_size; /* RAM size */
unsigned long reloc_off; /* Relocation Offset */

View file

@ -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__ */

View file

@ -44,6 +44,14 @@ typedef struct bd_info {
#endif
#if defined(CONFIG_MPC5xxx)
unsigned long bi_mbar_base; /* base of internal registers */
#endif
#if defined(CONFIG_MPC8220)
unsigned long bi_mbar_base; /* base of internal registers */
unsigned long bi_inpfreq; /* Input Freq, In MHz */
unsigned long bi_pcifreq; /* PCI Freq, in MHz */
unsigned long bi_pevfreq; /* PEV Freq, in MHz */
unsigned long bi_flbfreq; /* Flexbus Freq, in MHz */
unsigned long bi_vcofreq; /* VCO Freq, in MHz */
#endif
unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
unsigned long bi_ip_addr; /* IP Address */

View file

@ -63,6 +63,8 @@ typedef volatile unsigned char vu_char;
#endif
#elif defined(CONFIG_5xx)
#include <asm/5xx_immap.h>
#elif defined(CONFIG_MPC8220)
#include <asm/immap_8220.h>
#elif defined(CONFIG_8260)
#if defined(CONFIG_MPC8247) \
|| defined(CONFIG_MPC8248) \
@ -355,6 +357,7 @@ void trap_init (ulong);
defined (CONFIG_74x) || \
defined (CONFIG_75x) || \
defined (CONFIG_74xx) || \
defined (CONFIG_MPC8220) || \
defined(CONFIG_MPC85xx)
unsigned char in8(unsigned int);
void out8(unsigned int, unsigned char);
@ -399,6 +402,9 @@ int prt_8260_clks (void);
#if defined(CONFIG_MPC5xxx)
int prt_mpc5xxx_clks (void);
#endif
#if defined(CONFIG_MPC8220)
int prt_mpc8220_clks (void);
#endif
#ifdef CONFIG_4xx
ulong get_OPB_freq (void);
ulong get_PCI_freq (void);

View file

@ -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 */

551
include/mpc8220.h Normal file
View file

@ -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__ */

View file

@ -175,7 +175,7 @@
#define IM_IMMR (IM_REGBASE+0x01a8)
#define IM_SCCR (IM_REGBASE+0x0c80)
#elif defined(CONFIG_MPC5xxx)
#elif defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8220)
#define HID0_ICE_BITPOS 16
#define HID0_DCE_BITPOS 17

View file

@ -297,6 +297,9 @@ init_fnc_t *init_sequence[] = {
#if defined(CONFIG_MPC5xxx)
prt_mpc5xxx_clks,
#endif /* CONFIG_MPC5xxx */
#if defined(CONFIG_MPC8220)
prt_mpc8220_clks,
#endif
checkboard,
INIT_FUNC_WATCHDOG_INIT
#if defined(CONFIG_MISC_INIT_F)
@ -477,6 +480,9 @@ void board_init_f (ulong bootflag)
#ifdef CONFIG_IP860
bd->bi_sramstart = SRAM_BASE; /* start of SRAM memory */
bd->bi_sramsize = SRAM_SIZE; /* size of SRAM memory */
#elif defined CONFIG_MPC8220
bd->bi_sramstart = CFG_SRAM_BASE; /* start of SRAM memory */
bd->bi_sramsize = CFG_SRAM_SIZE; /* size of SRAM memory */
#else
bd->bi_sramstart = 0; /* FIXME */ /* start of SRAM memory */
bd->bi_sramsize = 0; /* FIXME */ /* size of SRAM memory */
@ -489,6 +495,26 @@ void board_init_f (ulong bootflag)
#if defined(CONFIG_MPC5xxx)
bd->bi_mbar_base = CFG_MBAR; /* base of internal registers */
#endif
#if defined(CONFIG_MPC8220)
bd->bi_mbar_base = CFG_MBAR; /* base of internal registers */
bd->bi_inpfreq = gd->inp_clk;
bd->bi_pcifreq = gd->pci_clk;
bd->bi_vcofreq = gd->vco_clk;
bd->bi_pevfreq = gd->pev_clk;
bd->bi_flbfreq = gd->flb_clk;
/* store bootparam to sram (backward compatible), here? */
{
u32 *sram = (u32 *)CFG_SRAM_BASE;
*sram++ = gd->ram_size;
*sram++ = gd->bus_clk;
*sram++ = gd->inp_clk;
*sram++ = gd->cpu_clk;
*sram++ = gd->vco_clk;
*sram++ = gd->flb_clk;
*sram++ = 0xb8c3ba11; /* boot signature */
}
#endif
bd->bi_bootflags = bootflag; /* boot / reboot flag (for LynxOS) */

View file

@ -39,6 +39,7 @@ extern int eth_3com_initialize(bd_t*);
extern int fec_initialize(bd_t*);
extern int inca_switch_initialize(bd_t*);
extern int mpc5xxx_fec_initialize(bd_t*);
extern int mpc8220_fec_initialize(bd_t*);
extern int mv6436x_eth_initialize(bd_t *);
extern int mv6446x_eth_initialize(bd_t *);
extern int natsemi_initialize(bd_t*);
@ -144,6 +145,9 @@ int eth_initialize(bd_t *bis)
#if defined(CONFIG_MPC5xxx_FEC)
mpc5xxx_fec_initialize(bis);
#endif
#if defined(CONFIG_MPC8220)
mpc8220_fec_initialize(bis);
#endif
#if defined(CONFIG_SK98)
skge_initialize(bis);
#endif