1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-03-09 15:40:20 +00:00

Fix for RUTX platform

This commit is contained in:
Ycarus (Yannick Chabanois) 2022-03-28 18:17:07 +02:00
parent ccdb64ad45
commit 59bc57d5d5
7254 changed files with 1810270 additions and 7 deletions

View file

@ -0,0 +1,44 @@
#
# (C) Copyright 2000-2006
# 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 = $(obj)lib$(BOARD).o
COBJS = $(BOARD).o flash.o beeper.o fpga.o ioport.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS)
$(call cmd_link_o_target, $(OBJS))
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################

View file

@ -0,0 +1,144 @@
This directory contains board specific code for a generic MPC860T based
embedded computer, called 'GEN860T'. The design is generic in the sense that
common, readily available components are used and that the architecture of the
system is relatively straightforward:
One eight bit wide boot (FLASH) memory
32 bit main memory using SDRAM
DOC 2000+
Ethernet PHY
Some I2C peripheral devices: Atmel AT24C256 EEPROM, Maxim DS1337 RTC.
Some other miscellaneous peripherals
NOTE: There are references to a XIlinx FPGA and Mil-Std 1553 databus in this
port. I guess the computer is not as generic as I first said 8) However,
these extras can be safely ignored.
Given the GEN860T files, it should be pretty easy to reverse engineer the
hardware configuration, if that's useful to you. Hopefully, this code will
be useful to someone as a basis for a port to a new system or as a head start
on a custom design. If you end up using any of this, I would appreciate
hearing from you, especially if you discover bugs or find ways to improve the
quality of this U-Boot port.
Here are the salient features of the system:
Clock : 33.3 Mhz oscillator
Processor core frequency : 66.6 Mhz if in 1:2:1 mode; can also run 1:1
Bus frequency : 33.3 Mhz
Main memory:
Type : SDRAM
Width : 32 bits
Size : 64 mibibytes
Chip : Two Micron MT48LC16M16A2TG-7E
CS : MPC860T CS1*/UPMA
UPMA CONNECTIONS:
SDRAM A10 : GPLA0*
SDRAM CAS* : GPLA2*
SDRAM WE* : GPLA3*
SDRAM RAS* : GPLA4*
Boot memory:
Type : FLASH
Width : 8 bits
Size : 16 mibibytes
Chip : One Intel 28F128J3A (StrataFlash)
CS : MPC860T CS0*/GPCM (this is the "boot" chip select)
EEPROM memory:
Type : Serial I2C EEPROM
Width : 8 bits
Size : 32 kibibytes
Chip : One Atmel AT25C256
CS : 0x50 (external I2C address pins on device are tied to GND)
Filesystem memory:
Type : NAND FLASH (Toshiba)
Width : 8 bits (i.e. interface to DOC is 8 bits)
Size : 32 mibibytes
Chip : One DiskOnCHip Millenium Plus (DOC 2000+)
CS : MPC860T CS2*/GPCM
Network support:
MAC : MPC86OT FEC (Fast Ethernet Controller)
PHY : Intel LXT971A
MII Addr: 0x0 (hardwired on the board)
MII IRQ :
Console:
RS-232 on SMC1 (Maxim MAX3232 LVCMOS-RS232 level shifter)
Real Time Clock:
Type : Low power, I2C interface
Chip : Maxim DS1337
CS : Address 0x68 on I2C bus
The MPC860T's internal RTC has a defect in Mask rev D that increases
the current drain on the KAPWR line to 10 mA. Since this is an
unreasonable amount of current draw for a RTC, and Motorola does not
plan to fix this in future mask revisions, a serial (I2C) RTC that
works has been included instead. NOTE that the DS1337 can be
configured to output a 32768 Hz clock while the main power is on.
This clock output has been routed to the MPC860T's EXTAL pin to allow
the internal RTC to be used. NOTE also that due to yet another
defect in the rev D mask, the RTC does not operate reliably when the
internal RTC divisor is set to use a 32768 Hz reference. So just use
the I2C RTC.
Miscellaneous:
Xilinx Virtex FPGA on CS3*/GPCM.
Virtex FPGA slave SelectMap interface on cs4*/UPMB.
Mil-Std 1553 databus interface on CS5*/GPCM.
Audio sounder (beeper) with digital volume control connected to SPKROUT.
SC variant:
A reduced-feature version of the GEN860T port is also supported: GEN860T_SC.
The 'SC' variant only provides support for the Virtex FPGA, SDRAM main
memory, EEPROM and flash memory. The system clock frequency is reduced
to 24 MHz.
Issues:
The DOC 2000+ returns 0x40 as its device ID when probed using the method
desxribed in the DOC datasheet. Unfortunately, the U-Boot DOC driver
does not recognize this device. As of this writing, it seems that MTD
does not support the DOC 2000+ either.
Status:
Everything appears to work except DOC support. As of this writing,
David Woodhouse has stated on the MTD mailing list that he has no
knowledge of the DOC Millineum Plus and therfore there is no support
in MTD for this device. I wish I had known this sooner :(
The GEN860T board specific files and configuration is based on the work
of others who have contributed to U-Boot. The copyright and license notices
of these authors have been retained wherever their code has been reused.
All new code to support the GEN860T board is:
(C) Copyright 2001-2003
Keith Outwater (keith_outwater@mvis.com)
and the following license applies:
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,
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
Thanks to Wolfgang Denk for a great software package and to everyone
who contributed to its development.
Keith Outwater
Sr. Staff Engineer
Microvision, Inc.
<keith_outwater@mvis.com>
<outwater@eskimo.com>

View file

@ -0,0 +1,199 @@
/*
* (C) Copyright 2002
* Keith Outwater, keith_outwater@mvis.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 <mpc8xx.h>
#include <asm/8xx_immap.h>
#include <linux/ctype.h>
/*
* Basic beeper support for the GEN860T board. The GEN860T includes
* an audio sounder driven by a Phillips TDA8551 amplifier. The
* TDA8551 features a digital volume control which uses a "trinary"
* input (high/high-Z/low) to set volume. The 860's SPKROUT pin
* drives the amplifier input.
*/
/*
* Initialize beeper-related hardware. Initialize timer 1 for use with
* the beeper. Use 66 MHz internal clock with prescale of 33 to get
* 1 uS period per count.
* FIXME: we should really compute the prescale based on the reported
* core clock frequency.
*/
void init_beeper (void)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_RST1 | TGCR_STP1;
immap->im_cpmtimer.cpmt_tmr1 = ((33 << TMR_PS_SHIFT) & TMR_PS_MSK)
| TMR_OM | TMR_FRR | TMR_ICLK_IN_GEN;
immap->im_cpmtimer.cpmt_tcn1 = 0;
immap->im_cpmtimer.cpmt_ter1 = 0xffff;
immap->im_cpmtimer.cpmt_tgcr |= TGCR_RST1;
}
/*
* Set beeper frequency. Max allowed frequency is 2.5 KHz. This limit
* is mostly arbitrary, but the beeper isn't really much good beyond this
* frequency.
*/
void set_beeper_frequency (uint frequency)
{
#define FREQ_LIMIT 2500
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
/*
* Compute timer ticks given desired frequency. The timer is set up
* to count 0.5 uS per tick and it takes two ticks per cycle (Hz).
*/
if (frequency > FREQ_LIMIT)
frequency = FREQ_LIMIT;
frequency = 1000000 / frequency;
immap->im_cpmtimer.cpmt_trr1 = (ushort) frequency;
}
/*
* Turn the beeper on
*/
void beeper_on (void)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
immap->im_cpmtimer.cpmt_tgcr &= ~TGCR_STP1;
}
/*
* Turn the beeper off
*/
void beeper_off (void)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
immap->im_cpmtimer.cpmt_tgcr |= TGCR_STP1;
}
/*
* Increase or decrease the beeper volume. Volume can be set
* from off to full in 64 steps. To increase volume, the output
* pin is actively driven high, then returned to tristate.
* To decrease volume, output a low on the port pin (no need to
* change pin mode to tristate) then output a high to go back to
* tristate.
*/
void set_beeper_volume (int steps)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
int i;
if (steps >= 0) {
for (i = 0; i < (steps >= 64 ? 64 : steps); i++) {
immap->im_cpm.cp_pbodr &= ~(0x80000000 >> 19);
udelay (1);
immap->im_cpm.cp_pbodr |= (0x80000000 >> 19);
udelay (1);
}
} else {
for (i = 0; i > (steps <= -64 ? -64 : steps); i--) {
immap->im_cpm.cp_pbdat &= ~(0x80000000 >> 19);
udelay (1);
immap->im_cpm.cp_pbdat |= (0x80000000 >> 19);
udelay (1);
}
}
}
/*
* Check the environment to see if the beeper needs beeping.
* Controlled by a sequence of the form:
* freq/delta volume/on time/off time;... where:
* freq = frequency in Hz (0 - 2500)
* delta volume = volume steps up or down (-64 <= vol <= 64)
* on time = time in mS
* off time = time in mS
*
* Return 1 on success, 0 on failure
*/
int do_beeper (char *sequence)
{
#define DELIMITER ';'
int args[4];
int i;
int val;
char *p = sequence;
char *tp;
/*
* Parse the control sequence. This is a really simple parser
* without any real error checking. You can probably blow it
* up really easily.
*/
if (*p == '\0' || !isdigit (*p)) {
printf ("%s:%d: null or invalid string (%s)\n",
__FILE__, __LINE__, p);
return 0;
}
i = 0;
while (*p != '\0') {
while (*p != DELIMITER) {
if (i > 3)
i = 0;
val = (int) simple_strtol (p, &tp, 0);
if (tp == p) {
printf ("%s:%d: no digits or bad format\n",
__FILE__, __LINE__);
return 0;
} else {
args[i] = val;
}
i++;
if (*tp == DELIMITER)
p = tp;
else
p = ++tp;
}
p++;
/*
* Well, we got something that has a chance of being correct
*/
#if 0
for (i = 0; i < 4; i++) {
printf ("%s:%d:arg %d = %d\n", __FILE__, __LINE__, i,
args[i]);
}
printf ("\n");
#endif
set_beeper_frequency (args[0]);
set_beeper_volume (args[1]);
beeper_on ();
udelay (1000 * args[2]);
beeper_off ();
udelay (1000 * args[3]);
}
return 1;
}

View file

@ -0,0 +1,29 @@
/*
* (C) Copyright 2002
* Keith Outwater, keith_outwater@mvis.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
*/
void init_beeper(void);
void set_beeper_frequency(uint frequency);
void beeper_on(void);
void beeper_off(void);
void set_beeper_volume(int steps);
int do_beeper(char *sequence);

View file

@ -0,0 +1,644 @@
/*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* Keith Outwater, keith_outwater@mvsi.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 <mpc8xx.h>
#if defined(CONFIG_ENV_IS_IN_FLASH)
# ifndef CONFIG_ENV_ADDR
# define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
# endif
# ifndef CONFIG_ENV_SIZE
# define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
# endif
# ifndef CONFIG_ENV_SECT_SIZE
# define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE
# endif
#endif
/*
* Use buffered writes to flash by default - they are about 32x faster than
* single byte writes.
*/
#ifndef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
#define CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
#endif
/*
* Max time to wait (in mS) for flash device to allocate a write buffer.
*/
#ifndef CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT
#define CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT 100
#endif
/*
* These functions support a single Intel StrataFlash device (28F128J3A)
* in byte mode only!. The flash routines are very basic and simple
* since there isn't really any remapping necessary.
*/
/*
* Intel SCS (Scalable Command Set) command definitions
* (taken from 28F128J3A datasheet)
*/
#define SCS_READ_CMD 0xff
#define SCS_READ_ID_CMD 0x90
#define SCS_QUERY_CMD 0x98
#define SCS_READ_STATUS_CMD 0x70
#define SCS_CLEAR_STATUS_CMD 0x50
#define SCS_WRITE_BUF_CMD 0xe8
#define SCS_PROGRAM_CMD 0x40
#define SCS_BLOCK_ERASE_CMD 0x20
#define SCS_BLOCK_ERASE_RESUME_CMD 0xd0
#define SCS_PROGRAM_RESUME_CMD 0xd0
#define SCS_BLOCK_ERASE_SUSPEND_CMD 0xb0
#define SCS_SET_BLOCK_LOCK_CMD 0x60
#define SCS_CLR_BLOCK_LOCK_CMD 0x60
/*
* SCS status/extended status register bit definitions
*/
#define SCS_SR7 0x80
#define SCS_XSR7 0x80
/*---------------------------------------------------------------------*/
#if 0
#define DEBUG_FLASH
#endif
#ifdef DEBUG_FLASH
#define PRINTF(fmt,args...) printf(fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/*---------------------------------------------------------------------*/
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
/*-----------------------------------------------------------------------
* Functions
*/
static ulong flash_get_size (vu_char *addr, flash_info_t *info);
static int write_data8 (flash_info_t *info, ulong dest, uchar data);
static void flash_get_offsets (ulong base, flash_info_t *info);
/*-----------------------------------------------------------------------
* Initialize the flash memory.
*/
unsigned long
flash_init (void)
{
volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
unsigned long size_b0;
int i;
for (i= 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
flash_info[i].flash_id = FLASH_UNKNOWN;
}
/*
* The gen860t board only has one FLASH memory device, so the
* FLASH Bank configuration is done statically.
*/
PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM);
size_b0 = flash_get_size((vu_char *)FLASH_BASE0_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
printf ("## Unknown FLASH on Bank 0: "
"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
flash_info[0].flash_id,size_b0, size_b0 << 20);
}
PRINTF("## Before remap:\n"
" BR0: 0x%08x OR0: 0x%08x\n BR1: 0x%08x OR1: 0x%08x\n",
memctl->memc_br0, memctl->memc_or0,
memctl->memc_br1, memctl->memc_or1);
/*
* Remap FLASH according to real size
*/
memctl->memc_or0 |= (-size_b0 & 0xFFFF8000);
memctl->memc_br0 |= (CONFIG_SYS_FLASH_BASE & BR_BA_MSK);
PRINTF("## After remap:\n"
" BR0: 0x%08x OR0: 0x%08x\n", memctl->memc_br0, memctl->memc_or0);
/*
* Re-do sizing to get full correct info
*/
size_b0 = flash_get_size ((vu_char *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]);
flash_info[0].size = size_b0;
#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
/*
* Monitor protection is ON by default
*/
flash_protect(FLAG_PROTECT_SET,
CONFIG_SYS_MONITOR_BASE,
CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
&flash_info[0]);
#endif
#ifdef CONFIG_ENV_IS_IN_FLASH
/*
* Environment protection ON by default
*/
flash_protect(FLAG_PROTECT_SET,
CONFIG_ENV_ADDR,
CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
&flash_info[0]);
#endif
PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0);
return (size_b0);
}
/*-----------------------------------------------------------------------
* Fill in the FLASH offset table
*/
static void
flash_get_offsets (ulong base, flash_info_t *info)
{
int i;
if (info->flash_id == FLASH_UNKNOWN) {
return;
}
switch (info->flash_id & FLASH_VENDMASK) {
case FLASH_MAN_INTEL:
for (i = 0; i < info->sector_count; i++) {
info->start[i] = base;
base += 1024 * 128;
}
return;
default:
printf ("Don't know sector offsets for FLASH"
" type 0x%lx\n", info->flash_id);
return;
}
}
/*-----------------------------------------------------------------------
* Display FLASH device info
*/
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;
default:
printf ("Unknown Vendor ");
break;
}
switch (info->flash_id & FLASH_TYPEMASK) {
case FLASH_28F128J3A:
printf ("28F128J3A (128Mbit = 128K x 128)\n");
break;
default:
printf ("Unknown Chip Type\n");
break;
}
if (info->size >= (1024 * 1024)) {
i = 20;
} else {
i = 10;
}
printf (" Size: %ld %cB in %d Sectors\n",
info->size >> i,
(i == 20) ? 'M' : 'k',
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;
}
/*-----------------------------------------------------------------------
* Get size and other information for a FLASH device.
* NOTE: The following code cannot be run from FLASH!
*/
static
ulong flash_get_size (vu_char *addr, flash_info_t *info)
{
#define NO_FLASH 0
vu_char value[2];
/*
* Try to read the manufacturer ID
*/
addr[0] = SCS_READ_CMD;
addr[0] = SCS_READ_ID_CMD;
value[0] = addr[0];
value[1] = addr[2];
addr[0] = SCS_READ_CMD;
PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong)addr, value[0]);
switch (value[0]) {
case (INTEL_MANUFACT & 0xff):
info->flash_id = FLASH_MAN_INTEL;
break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->size = 0;
return (NO_FLASH);
}
/*
* Read the device ID
*/
PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong)(&addr[2]), value[1]);
switch (value[1]) {
case (INTEL_ID_28F128J3A & 0xff):
info->flash_id += FLASH_28F128J3A;
info->sector_count = 128;
info->size = 16 * 1024 * 1024;
break;
default:
info->flash_id = FLASH_UNKNOWN;
return (NO_FLASH);
}
if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
printf ("** ERROR: sector count %d > max (%d) **\n",
info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
}
return (info->size);
}
/*-----------------------------------------------------------------------
* Erase the specified sectors in the specified FLASH device
*/
int
flash_erase(flash_info_t *info, int s_first, int s_last)
{
int flag, prot, sect;
ulong start, now, last;
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;
}
if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
printf ("Can erase only Intel flash types - aborted\n");
return 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;
/*
* Start erase on unprotected sectors
*/
for (sect = s_first; sect<=s_last; sect++) {
if (info->protect[sect] == 0) { /* not protected */
vu_char *addr = (uchar *)(info->start[sect]);
vu_char status;
/*
* Disable interrupts which might cause a timeout
*/
flag = disable_interrupts();
*addr = SCS_CLEAR_STATUS_CMD;
*addr = SCS_BLOCK_ERASE_CMD;
*addr = SCS_BLOCK_ERASE_RESUME_CMD;
/*
* Re-enable interrupts if necessary
*/
if (flag)
enable_interrupts();
/*
* Wait at least 80us - let's wait 1 ms
*/
udelay (1000);
while (((status = *addr) & SCS_SR7) != SCS_SR7) {
if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
printf ("Timeout\n");
*addr = SCS_BLOCK_ERASE_SUSPEND_CMD;
*addr = SCS_READ_CMD;
return 1;
}
/*
* Show that we're waiting
*/
if ((now - last) > 1000) { /* 1 second */
putc ('.');
last = now;
}
}
*addr = SCS_READ_CMD;
}
}
printf (" done\n");
return 0;
}
#ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
/*
* Allocate a flash buffer, fill it with data and write it to the flash.
* 0 - OK
* 1 - Timeout on buffer request
*
* NOTE: After the last call to this function, WSM status needs to be checked!
*/
static int
write_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,
uint count)
{
vu_char *block_addr_p = NULL;
vu_char *start_addr_p = NULL;
ulong blocksize = info_p->size / (ulong)info_p->sector_count;
int i;
uint time = get_timer(0);
PRINTF("%s:%d: src: 0x%p dest: 0x%p count: %d\n",
__FUNCTION__, __LINE__, src_p, dest_p, count);
/*
* What block are we in? We already know that the source address is
* in the flash address range, but we also can't cross a block boundary.
* We assume that the block does not cross a boundary (we'll check before
* calling this function).
*/
for (i = 0; i < info_p->sector_count; ++i) {
if ( ((ulong)dest_p >= info_p->start[i]) &&
((ulong)dest_p < (info_p->start[i] + blocksize)) ) {
PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
__FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);
block_addr_p = (vu_char *)info_p->start[i];
break;
}
}
/*
* Request a buffer
*/
*block_addr_p = SCS_WRITE_BUF_CMD;
while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {
if (get_timer(time) > CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT) {
PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
__FUNCTION__, __LINE__, block_addr_p,
CONFIG_SYS_FLASH_ALLOC_BUFFER_TOUT);
return 1;
}
*block_addr_p = SCS_WRITE_BUF_CMD;
}
/*
* Fill the buffer with data
*/
start_addr_p = dest_p;
*block_addr_p = count - 1; /* flash device wants count - 1 */
PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
__FUNCTION__, __LINE__, block_addr_p);
for (i = 0; i < count; i++) {
*start_addr_p++ = *src_p++;
}
/*
* Flush buffer to flash
*/
*block_addr_p = SCS_PROGRAM_RESUME_CMD;
#if 1
time = get_timer(0);
while ((*block_addr_p & SCS_SR7) != SCS_SR7) {
if (get_timer(time) > CONFIG_SYS_FLASH_WRITE_TOUT) {
PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
__FUNCTION__, __LINE__, block_addr_p, CONFIG_SYS_FLASH_WRITE_TOUT);
return 1;
}
}
#endif
return 0;
}
#endif
/*-----------------------------------------------------------------------
* 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_p, uchar *src_p, ulong addr, ulong count)
{
int rc = 0;
#ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
#define FLASH_WRITE_BUF_SIZE 0x00000020 /* 32 bytes */
int i;
uint bufs;
ulong buf_count;
vu_char *sp;
vu_char *dp;
#else
ulong wp;
#endif
PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
__FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);
if (info_p->flash_id == FLASH_UNKNOWN) {
return 4;
}
#ifdef CONFIG_SYS_GEN860T_FLASH_USE_WRITE_BUFFER
sp = src_p;
dp = (uchar *)addr;
/*
* For maximum performance, we want to align the start address to
* the beginning of a write buffer boundary (i.e. A4-A0 of the
* start address = 0). See how many bytes are required to get to a
* write-buffer-aligned address. If that number is non-zero, do
* non buffered writes of the non-aligned data. By doing non-buffered
* writes, we avoid the problem of crossing a block (sector) boundary
* with buffered writes.
*/
buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));
if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */
buf_count = 0;
}
if (buf_count > count) { /* not a full buffers worth of data to write */
buf_count = count;
}
count -= buf_count;
PRINTF("%s:%d: Write buffer alignment count = %ld\n",
__FUNCTION__, __LINE__, buf_count);
while (buf_count-- >= 1) {
if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0) {
return (rc);
}
}
PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);
if (count == 0) { /* all done */
PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
__FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);
return (rc);
}
/*
* Now that we are write buffer aligned, write full or partial buffers.
* The fact that we are write buffer aligned automatically avoids
* crossing a block address during a write buffer operation.
*/
bufs = count / FLASH_WRITE_BUF_SIZE;
PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,
bufs, bufs);
while (bufs >= 1) {
rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);
if (rc != 0) {
PRINTF("%s:%d: ** Error writing buf %d\n",
__FUNCTION__, __LINE__, bufs);
return (rc);
}
bufs--;
sp += FLASH_WRITE_BUF_SIZE;
dp += FLASH_WRITE_BUF_SIZE;
}
/*
* Do the leftovers
*/
i = count % FLASH_WRITE_BUF_SIZE;
PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);
if (i > 0) {
rc = write_flash_buffer8(info_p, sp, dp, i);
}
sp = (vu_char*)info_p->start[0];
*sp = SCS_READ_CMD;
return (rc);
#else
wp = addr;
while (count-- >= 1) {
if((rc = write_data8(info_p, wp++, *src_p++)) != 0)
return (rc);
}
return 0;
#endif
}
/*-----------------------------------------------------------------------
* Write a byte to Flash, returns:
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
*/
static int
write_data8 (flash_info_t *info, ulong dest, uchar data)
{
vu_char *addr = (vu_char *)dest;
vu_char status;
ulong start;
int flag;
/* Check if Flash is (sufficiently) erased */
if ((*addr & data) != data) {
return (2);
}
/* Disable interrupts which might cause a timeout here */
flag = disable_interrupts();
*addr = SCS_PROGRAM_CMD;
*addr = data;
/* re-enable interrupts if necessary */
if (flag)
enable_interrupts();
start = get_timer (0);
while (((status = *addr) & SCS_SR7) != SCS_SR7) {
if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
*addr = SCS_READ_CMD;
return (1);
}
}
*addr = SCS_READ_CMD;
return (0);
}
/* vim: set ts=4 sw=4 tw=78: */

View file

@ -0,0 +1,379 @@
/*
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
* Keith Outwater, keith_outwater@mvis.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
*
*/
/*
* Virtex2 FPGA configuration support for the GEN860T computer
*/
#include <common.h>
#include <virtex2.h>
#include <command.h>
#include "fpga.h"
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_FPGA)
#if 0
#define GEN860T_FPGA_DEBUG
#endif
#ifdef GEN860T_FPGA_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/*
* Port bit numbers for the Selectmap controls
*/
#define FPGA_INIT_BIT_NUM 22 /* PB22 */
#define FPGA_RESET_BIT_NUM 11 /* PC11 */
#define FPGA_DONE_BIT_NUM 16 /* PB16 */
#define FPGA_PROGRAM_BIT_NUM 7 /* PA7 */
/* Note that these are pointers to code that is in Flash. They will be
* relocated at runtime.
*/
Xilinx_Virtex2_Slave_SelectMap_fns fpga_fns = {
fpga_pre_config_fn,
fpga_pgm_fn,
fpga_init_fn,
fpga_err_fn,
fpga_done_fn,
fpga_clk_fn,
fpga_cs_fn,
fpga_wr_fn,
fpga_read_data_fn,
fpga_write_data_fn,
fpga_busy_fn,
fpga_abort_fn,
fpga_post_config_fn
};
Xilinx_desc fpga[CONFIG_FPGA_COUNT] = {
{Xilinx_Virtex2,
slave_selectmap,
XILINX_XC2V3000_SIZE,
(void *) &fpga_fns,
0}
};
/*
* Display FPGA revision information
*/
void print_fpga_revision (void)
{
vu_long *rev_p = (vu_long *) 0x60000008;
printf ("FPGA Revision 0x%.8lx"
" (Date %.2lx/%.2lx/%.2lx, Status \"%.1lx\", Version %.3lu)\n",
*rev_p,
((*rev_p >> 28) & 0xf),
((*rev_p >> 20) & 0xff),
((*rev_p >> 12) & 0xff),
((*rev_p >> 8) & 0xf), (*rev_p & 0xff));
}
/*
* Perform a simple test of the FPGA to processor interface using the FPGA's
* inverting bus test register. The great thing about doing a read/write
* test on a register that inverts it's contents is that you avoid any
* problems with bus charging.
* Return 0 on failure, 1 on success.
*/
int test_fpga_ibtr (void)
{
vu_long *ibtr_p = (vu_long *) 0x60000010;
vu_long readback;
vu_long compare;
int i;
int j;
int k;
int pass = 1;
static const ulong bitpattern[] = {
0xdeadbeef, /* magic ID pattern for debug */
0x00000001, /* single bit */
0x00000003, /* two adjacent bits */
0x00000007, /* three adjacent bits */
0x0000000F, /* four adjacent bits */
0x00000005, /* two non-adjacent bits */
0x00000015, /* three non-adjacent bits */
0x00000055, /* four non-adjacent bits */
0xaaaaaaaa, /* alternating 1/0 */
};
for (i = 0; i < 1024; i++) {
for (j = 0; j < 31; j++) {
for (k = 0;
k < sizeof (bitpattern) / sizeof (bitpattern[0]);
k++) {
*ibtr_p = compare = (bitpattern[k] << j);
readback = *ibtr_p;
if (readback != ~compare) {
printf ("%s:%d: FPGA test fail: expected 0x%.8lx" " actual 0x%.8lx\n", __FUNCTION__, __LINE__, ~compare, readback);
pass = 0;
break;
}
}
if (!pass)
break;
}
if (!pass)
break;
}
if (pass) {
printf ("FPGA inverting bus test passed\n");
print_fpga_revision ();
} else {
printf ("** FPGA inverting bus test failed\n");
}
return pass;
}
/*
* Set the active-low FPGA reset signal.
*/
void fpga_reset (int assert)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
PRINTF ("%s:%d: RESET ", __FUNCTION__, __LINE__);
if (assert) {
immap->im_ioport.iop_pcdat &= ~(0x8000 >> FPGA_RESET_BIT_NUM);
PRINTF ("asserted\n");
} else {
immap->im_ioport.iop_pcdat |= (0x8000 >> FPGA_RESET_BIT_NUM);
PRINTF ("deasserted\n");
}
}
/*
* Initialize the SelectMap interface. We assume that the mode and the
* initial state of all of the port pins have already been set!
*/
void fpga_selectmap_init (void)
{
PRINTF ("%s:%d: Initialize SelectMap interface\n", __FUNCTION__,
__LINE__);
fpga_pgm_fn (FALSE, FALSE, 0); /* make sure program pin is inactive */
}
/*
* Initialize the fpga. Return 1 on success, 0 on failure.
*/
int gen860t_init_fpga (void)
{
int i;
PRINTF ("%s:%d: Initialize FPGA interface\n",
__FUNCTION__, __LINE__);
fpga_init ();
fpga_selectmap_init ();
for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
PRINTF ("%s:%d: Adding fpga %d\n", __FUNCTION__, __LINE__, i);
fpga_add (fpga_xilinx, &fpga[i]);
}
return 1;
}
/*
* Set the FPGA's active-low SelectMap program line to the specified level
*/
int fpga_pgm_fn (int assert, int flush, int cookie)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
PRINTF ("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__);
if (assert) {
immap->im_ioport.iop_padat &=
~(0x8000 >> FPGA_PROGRAM_BIT_NUM);
PRINTF ("asserted\n");
} else {
immap->im_ioport.iop_padat |=
(0x8000 >> FPGA_PROGRAM_BIT_NUM);
PRINTF ("deasserted\n");
}
return assert;
}
/*
* Test the state of the active-low FPGA INIT line. Return 1 on INIT
* asserted (low).
*/
int fpga_init_fn (int cookie)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
PRINTF ("%s:%d: INIT check... ", __FUNCTION__, __LINE__);
if (immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_INIT_BIT_NUM)) {
PRINTF ("high\n");
return 0;
} else {
PRINTF ("low\n");
return 1;
}
}
/*
* Test the state of the active-high FPGA DONE pin
*/
int fpga_done_fn (int cookie)
{
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
PRINTF ("%s:%d: DONE check... ", __FUNCTION__, __LINE__);
if (immap->im_cpm.cp_pbdat & (0x80000000 >> FPGA_DONE_BIT_NUM)) {
PRINTF ("high\n");
return FPGA_SUCCESS;
} else {
PRINTF ("low\n");
return FPGA_FAIL;
}
}
/*
* Read FPGA SelectMap data.
*/
int fpga_read_data_fn (unsigned char *data, int cookie)
{
vu_char *p = (vu_char *) SELECTMAP_BASE;
*data = *p;
#if 0
PRINTF ("%s: Read 0x%x into 0x%p\n", __FUNCTION__, (int) data, data);
#endif
return (int) data;
}
/*
* Write data to the FPGA SelectMap port
*/
int fpga_write_data_fn (unsigned char data, int flush, int cookie)
{
vu_char *p = (vu_char *) SELECTMAP_BASE;
#if 0
PRINTF ("%s: Write Data 0x%x\n", __FUNCTION__, (int) data);
#endif
*p = data;
return (int) data;
}
/*
* Abort and FPGA operation
*/
int fpga_abort_fn (int cookie)
{
PRINTF ("%s:%d: FPGA program sequence aborted\n",
__FUNCTION__, __LINE__);
return FPGA_FAIL;
}
/*
* FPGA pre-configuration function. Just make sure that
* FPGA reset is asserted to keep the FPGA from starting up after
* configuration.
*/
int fpga_pre_config_fn (int cookie)
{
PRINTF ("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__);
fpga_reset (TRUE);
return 0;
}
/*
* FPGA post configuration function. Blip the FPGA reset line and then see if
* the FPGA appears to be running.
*/
int fpga_post_config_fn (int cookie)
{
int rc;
PRINTF ("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__);
fpga_reset (TRUE);
udelay (1000);
fpga_reset (FALSE);
udelay (1000);
/*
* Use the FPGA,s inverting bus test register to do a simple test of the
* processor interface.
*/
rc = test_fpga_ibtr ();
return rc;
}
/*
* Clock, chip select and write signal assert functions and error check
* and busy functions. These are only stubs because the GEN860T selectmap
* interface handles sequencing of control signals automatically (it uses
* a memory-mapped interface to the FPGA SelectMap port). The design of
* the interface guarantees that the SelectMap port cannot be overrun so
* no busy check is needed. A configuration error is signalled by INIT
* going low during configuration, so there is no need for a separate error
* function.
*/
int fpga_clk_fn (int assert_clk, int flush, int cookie)
{
return assert_clk;
}
int fpga_cs_fn (int assert_cs, int flush, int cookie)
{
return assert_cs;
}
int fpga_wr_fn (int assert_write, int flush, int cookie)
{
return assert_write;
}
int fpga_err_fn (int cookie)
{
return 0;
}
int fpga_busy_fn (int cookie)
{
return 0;
}
#endif

View file

@ -0,0 +1,43 @@
/*
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
* Keith Outwater, keith_outwater@mvis.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
*
*/
/*
* Virtex2 FPGA configuration support for the GEN860T computer
*/
extern int gen860t_init_fpga(void);
extern int fpga_pgm_fn(int assert_pgm, int flush, int cookie);
extern int fpga_init_fn(int cookie);
extern int fpga_err_fn(int cookie);
extern int fpga_done_fn(int cookie);
extern int fpga_clk_fn(int assert_clk, int flush, int cookie);
extern int fpga_cs_fn(int assert_cs, int flush, int cookie);
extern int fpga_wr_fn(int assert_write, int flush, int cookie);
extern int fpga_read_data_fn(unsigned char *data, int cookie);
extern int fpga_write_data_fn(unsigned char data, int flush, int cookie);
extern int fpga_busy_fn(int cookie);
extern int fpga_abort_fn(int cookie );
extern int fpga_pre_config_fn(int cookie );
extern int fpga_post_config_fn(int cookie );

View file

@ -0,0 +1,294 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* Keith Outwater, keith_outwater@mvis.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 <virtex2.h>
#include <common.h>
#include <mpc8xx.h>
#include <asm/8xx_immap.h>
#include "beeper.h"
#include "fpga.h"
#include "ioport.h"
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
#if defined(CONFIG_CMD_MII) && defined(CONFIG_MII)
#include <net.h>
#endif
#if 0
#define GEN860T_DEBUG
#endif
#ifdef GEN860T_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/*
* The following UPM init tables were generated automatically by
* Motorola's MCUINIT program. See the README file for UPM to
* SDRAM pin assignments if you want to type this data into
* MCUINIT in order to reverse engineer the waveforms.
*/
/*
* UPM initialization tables for MICRON MT48LC16M16A2TG SDRAM devices
* (UPMA) and Virtex FPGA SelectMap interface (UPMB).
* NOTE that unused areas of the table are used to hold NOP, precharge
* and mode register set sequences.
*
*/
#define UPMA_NOP_ADDR 0x5
#define UPMA_PRECHARGE_ADDR 0x6
#define UPMA_MRS_ADDR 0x12
#define UPM_SINGLE_READ_ADDR 0x00
#define UPM_BURST_READ_ADDR 0x08
#define UPM_SINGLE_WRITE_ADDR 0x18
#define UPM_BURST_WRITE_ADDR 0x20
#define UPM_REFRESH_ADDR 0x30
const uint sdram_upm_table[] = {
/* single read (offset 0x00 in upm ram) */
0x0e0fdc04, 0x01adfc04, 0x0fbffc00, 0x1fff5c05,
0xffffffff, 0x0fffffcd, 0x0fff0fce, 0xefcfffff,
/* burst read (offset 0x08 in upm ram) */
0x0f0fdc04, 0x00fdfc04, 0xf0fffc00, 0xf0fffc00,
0xf1fffc00, 0xfffffc00, 0xfffffc05, 0xffffffff,
0xffffffff, 0xffffffff, 0x0ffffff4, 0x1f3d5ff4,
0xfffffff4, 0xfffffff5, 0xffffffff, 0xffffffff,
/* single write (offset 0x18 in upm ram) */
0x0f0fdc04, 0x00ad3c00, 0x1fff5c05, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/* burst write (offset 0x20 in upm ram) */
0x0f0fdc00, 0x10fd7c00, 0xf0fffc00, 0xf0fffc00,
0xf1fffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xfffff7ff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/* refresh (offset 0x30 in upm ram) */
0x1ffddc84, 0xfffffc04, 0xfffffc04, 0xfffffc84,
0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/* exception (offset 0x3C in upm ram) */
};
const uint selectmap_upm_table[] = {
/* single read (offset 0x00 in upm ram) */
0x88fffc06, 0x00fff404, 0x00fffc04, 0x33fffc00,
0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff,
/* burst read (offset 0x08 in upm ram) */
0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/* single write (offset 0x18 in upm ram) */
0x88fffc04, 0x00fff400, 0x77fffc05, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/* burst write (offset 0x20 in upm ram) */
0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/* refresh (offset 0x30 in upm ram) */
0xfffffc04, 0xfffffc05, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
/* exception (offset 0x3C in upm ram) */
0xfffffc05, 0xffffffff, 0xffffffff, 0xffffffff
};
/*
* Check board identity. Always successful (gives information only)
*/
int checkboard (void)
{
char *s;
char buf[64];
int i;
i = getenv_f("board_id", buf, sizeof (buf));
s = (i > 0) ? buf : NULL;
if (s) {
printf ("%s ", s);
} else {
printf ("<unknown> ");
}
i = getenv_f("serial#", buf, sizeof (buf));
s = (i > 0) ? buf : NULL;
if (s) {
printf ("S/N %s\n", s);
} else {
printf ("S/N <unknown>\n");
}
printf ("CPU at %s MHz, ", strmhz (buf, gd->cpu_clk));
printf ("local bus at %s MHz\n", strmhz (buf, gd->bus_clk));
return (0);
}
/*
* Initialize SDRAM
*/
phys_size_t initdram (int board_type)
{
volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
volatile memctl8xx_t *memctl = &immr->im_memctl;
upmconfig (UPMA,
(uint *) sdram_upm_table,
sizeof (sdram_upm_table) / sizeof (uint)
);
/*
* Setup MAMR register
*/
memctl->memc_mptpr = CONFIG_SYS_MPTPR_1BK_8K;
memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
/*
* Map CS1* to SDRAM bank
*/
memctl->memc_or1 = CONFIG_SYS_OR1;
memctl->memc_br1 = CONFIG_SYS_BR1;
/*
* Perform SDRAM initialization sequence:
* 1. Apply at least one NOP command
* 2. 100 uS delay (JEDEC standard says 200 uS)
* 3. Issue 4 precharge commands
* 4. Perform two refresh cycles
* 5. Program mode register
*
* Program SDRAM for standard operation, sequential burst, burst length
* of 4, CAS latency of 2.
*/
memctl->memc_mar = 0x00000000;
memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
MCR_MLCF (0) | UPMA_NOP_ADDR;
udelay (200);
memctl->memc_mar = 0x00000000;
memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
MCR_MLCF (4) | UPMA_PRECHARGE_ADDR;
memctl->memc_mar = 0x00000000;
memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
MCR_MLCF (2) | UPM_REFRESH_ADDR;
memctl->memc_mar = 0x00000088;
memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
MCR_MLCF (1) | UPMA_MRS_ADDR;
memctl->memc_mar = 0x00000000;
memctl->memc_mcr = MCR_UPM_A | MCR_OP_RUN | MCR_MB_CS1 |
MCR_MLCF (0) | UPMA_NOP_ADDR;
/*
* Enable refresh
*/
memctl->memc_mamr |= MAMR_PTAE;
return (SDRAM_SIZE);
}
/*
* Disk On Chip (DOC) Millenium initialization.
* The DOC lives in the CS2* space
*/
#if defined(CONFIG_CMD_DOC)
void doc_init (void)
{
printf ("Probing at 0x%.8x: ", DOC_BASE);
doc_probe (DOC_BASE);
}
#endif
/*
* Miscellaneous intialization
*/
int misc_init_r (void)
{
volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
volatile memctl8xx_t *memctl = &immr->im_memctl;
/*
* Set up UPMB to handle the Virtex FPGA SelectMap interface
*/
upmconfig (UPMB, (uint *) selectmap_upm_table,
sizeof (selectmap_upm_table) / sizeof (uint));
memctl->memc_mbmr = 0x0;
config_mpc8xx_ioports (immr);
#if defined(CONFIG_CMD_MII)
mii_init ();
#endif
#if defined(CONFIG_FPGA)
gen860t_init_fpga ();
#endif
return 0;
}
/*
* Final init hook before entering command loop.
*/
int last_stage_init (void)
{
#if !defined(CONFIG_SC)
char buf[256];
int i;
/*
* Turn the beeper volume all the way down in case this is a warm boot.
*/
set_beeper_volume (-64);
init_beeper ();
/*
* Read the environment to see what to do with the beeper
*/
i = getenv_f("beeper", buf, sizeof (buf));
if (i > 0) {
do_beeper (buf);
}
#endif
return 0;
}
/*
* Stub to make POST code happy. Can't self-poweroff, so just hang.
*/
void board_poweroff (void)
{
puts ("### Please power off the board ###\n");
while (1);
}

View file

@ -0,0 +1,347 @@
/*
* (C) Copyright 2000
* 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 <mpc8xx.h>
#include <asm/8xx_immap.h>
#include "ioport.h"
#if 0
#define IOPORT_DEBUG
#endif
#ifdef IOPORT_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/*
* The ioport configuration table.
*/
const mpc8xx_iop_conf_t iop_conf_tab[NUM_PORTS][PORT_BITS] = {
/*
* Port A configuration
* Pin Signal Type Active Initial state
* PA7 fpgaProgramLowOut Out Low High
* PA1 fpgaCoreVoltageFailLow In Low N/A
*/
{ /* conf ppar psor pdir podr pdat pint function */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* No pin */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* No pin */
/* PA15 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA12 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA11 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA10 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA9 */ { 1, 0, 0, 1, 0, 0, 0 }, /* grn bicolor LED 1*/
/* PA8 */ { 1, 0, 0, 1, 0, 0, 0 }, /* red bicolor LED 1*/
/* PA7 */ { 1, 0, 0, 1, 0, 1, 0 }, /* fpgaProgramLow */
/* PA6 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA5 */ { 1, 0, 0, 1, 0, 0, 0 }, /* grn bicolor LED 0*/
/* PA4 */ { 1, 0, 0, 1, 0, 0, 0 }, /* red bicolor LED 0*/
/* PA3 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PA2 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#if !defined(CONFIG_SC)
/* PA1 */ { 1, 0, 0, 0, 0, 0, 0 }, /* fpgaCoreVoltageFail*/
#else
/* PA1 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#endif
/* PA0 */ { 0, 0, 0, 0, 0, 0, 0 } /* */
},
/*
* Port B configuration
* Pin Signal Type Active Initial state
* PB14 docBusyLowIn In Low X
* PB15 gpio1Sig Out High Low
* PB16 fpgaDoneBi In High X
* PB17 swBitOkLowOut Out Low High
* PB19 speakerVolSig Out/Hi-Z High/Low High (Hi-Z)
* PB22 fpgaInitLowBi In Low X
* PB23 batteryOkSig In High X
* PB31 pulseCatcherClr Out High 0
*/
{ /* conf ppar psor pdir podr pdat pint function */
#if !defined(CONFIG_SC)
/* PB31 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#else
/* PB31 */ { 1, 0, 0, 1, 0, 0, 0 }, /* pulseCatcherClr */
#endif
/* PB30 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB29 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB28 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB27 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB26 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB25 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB24 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#if !defined(CONFIG_SC)
/* PB23 */ { 1, 0, 0, 0, 0, 0, 0 }, /* batteryOk */
#else
/* PB23 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#endif
/* PB22 */ { 1, 0, 0, 0, 0, 0, 0 }, /* fpgaInitLowBi */
/* PB21 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB20 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#if !defined(CONFIG_SC)
/* PB19 */ { 1, 0, 0, 1, 1, 1, 0 }, /* speakerVol */
#else
/* PB19 */ { 0, 0, 0, 1, 1, 1, 0 }, /* */
#endif
/* PB18 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PB17 */ { 1, 0, 0, 1, 0, 1, 0 }, /* swBitOkLow */
/* PB16 */ { 1, 0, 0, 0, 0, 0, 0 }, /* fpgaDone */
/* PB15 */ { 1, 0, 0, 1, 0, 0, 0 }, /* gpio1 */
#if !defined(CONFIG_SC)
/* PB14 */ { 1, 0, 0, 0, 0, 0, 0 } /* docBusyLow */
#else
/* PB14 */ { 0, 0, 0, 0, 0, 0, 0 } /* */
#endif
},
/*
* Port C configuration
* Pin Signal Type Active Initial state
* PC4 i2cBus1EnSig Out High High
* PC5 i2cBus2EnSig Out High High
* PC6 gpio0Sig Out High Low
* PC8 i2cBus3EnSig Out High High
* PC10 i2cBus4EnSig Out High High
* PC11 fpgaResetLowOut Out Low High
* PC12 systemBitOkIn In High X
* PC15 selfDreqLow In Low X
*/
{ /* conf ppar psor pdir podr pdat pint function */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PC15 */ { 1, 0, 0, 0, 0, 0, 0 }, /* selfDreqLowIn */
/* PC14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PC13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#if !defined(CONFIG_SC)
/* PC12 */ { 1, 0, 0, 0, 0, 0, 0 }, /* systemBitOkIn */
#else
/* PC12 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#endif
/* PC11 */ { 1, 0, 0, 1, 0, 1, 0 }, /* fpgaResetLowOut */
#if !defined(CONFIG_SC)
/* PC10 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus4EnSig */
#else
/* PC10 */ { 0, 0, 0, 1, 0, 1, 0 }, /* */
#endif
/* PC9 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
#if !defined(CONFIG_SC)
/* PC8 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus3EnSig */
#else
/* PC8 */ { 0, 0, 0, 1, 0, 1, 0 }, /* */
#endif
/* PC7 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PC6 */ { 1, 0, 0, 1, 0, 1, 0 }, /* gpio0 */
#if !defined(CONFIG_SC)
/* PC5 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus2EnSig */
/* PC4 */ { 1, 0, 0, 1, 0, 1, 0 }, /* i2cBus1EnSig */
#else
/* PC5 */ { 0, 0, 0, 1, 0, 1, 0 }, /* */
/* PC4 */ { 0, 0, 0, 1, 0, 1, 0 }, /* */
#endif
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 } /* */
},
/*
* Port D configuration
*/
{ /* conf ppar psor pdir podr pdat pint function */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD15 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD14 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD13 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD12 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD11 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD10 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD9 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD8 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD7 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD6 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD5 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD4 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* PD3 */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 }, /* */
/* N/A */ { 0, 0, 0, 0, 0, 0, 0 } /* */
}
};
/*
* Configure the MPC8XX I/O ports per the ioport configuration table
* (taken from ./arch/powerpc/cpu/mpc8260/cpu_init.c)
*/
void config_mpc8xx_ioports (volatile immap_t * immr)
{
int portnum;
for (portnum = 0; portnum < NUM_PORTS; portnum++) {
uint pmsk = 0, ppar = 0, psor = 0, pdir = 0;
uint podr = 0, pdat = 0, pint = 0;
uint msk = 1;
mpc8xx_iop_conf_t *iopc =
(mpc8xx_iop_conf_t *) & iop_conf_tab[portnum][0];
mpc8xx_iop_conf_t *eiopc = iopc + PORT_BITS;
/*
* For all ports except port B, ignore the two don't care entries
* in the configuration tables.
*/
if (portnum != 1) {
iopc = (mpc8xx_iop_conf_t *) &
iop_conf_tab[portnum][2];
}
/*
* NOTE: index 0 refers to pin 17, index 17 refers to pin 0
*/
while (iopc < eiopc) {
if (iopc->conf) {
pmsk |= msk;
if (iopc->ppar)
ppar |= msk;
if (iopc->psor)
psor |= msk;
if (iopc->pdir)
pdir |= msk;
if (iopc->podr)
podr |= msk;
if (iopc->pdat)
pdat |= msk;
if (iopc->pint)
pint |= msk;
}
msk <<= 1;
iopc++;
}
PRINTF ("%s:%d:\n portnum=%d ", __FUNCTION__, __LINE__,
portnum);
#ifdef IOPORT_DEBUG
switch (portnum) {
case 0:
printf ("(A)\n");
break;
case 1:
printf ("(B)\n");
break;
case 2:
printf ("(C)\n");
break;
case 3:
printf ("(D)\n");
break;
default:
printf ("(?)\n");
break;
}
#endif
PRINTF (" ppar=0x%.8x pdir=0x%.8x podr=0x%.8x\n"
" pdat=0x%.8x psor=0x%.8x pint=0x%.8x pmsk=0x%.8x\n",
ppar, pdir, podr, pdat, psor, pint, pmsk);
/*
* Have to handle the ioports on a port-by-port basis since there
* are three different flavors.
*/
if (pmsk != 0) {
uint tpmsk = ~pmsk;
if (0 == portnum) { /* port A */
immr->im_ioport.iop_papar &= tpmsk;
immr->im_ioport.iop_padat =
(immr->im_ioport.
iop_padat & tpmsk) | pdat;
immr->im_ioport.iop_padir =
(immr->im_ioport.
iop_padir & tpmsk) | pdir;
immr->im_ioport.iop_paodr =
(immr->im_ioport.
iop_paodr & tpmsk) | podr;
immr->im_ioport.iop_papar |= ppar;
} else if (1 == portnum) { /* port B */
immr->im_cpm.cp_pbpar &= tpmsk;
immr->im_cpm.cp_pbdat =
(immr->im_cpm.
cp_pbdat & tpmsk) | pdat;
immr->im_cpm.cp_pbdir =
(immr->im_cpm.
cp_pbdir & tpmsk) | pdir;
immr->im_cpm.cp_pbodr =
(immr->im_cpm.
cp_pbodr & tpmsk) | podr;
immr->im_cpm.cp_pbpar |= ppar;
} else if (2 == portnum) { /* port C */
immr->im_ioport.iop_pcpar &= tpmsk;
immr->im_ioport.iop_pcdat =
(immr->im_ioport.
iop_pcdat & tpmsk) | pdat;
immr->im_ioport.iop_pcdir =
(immr->im_ioport.
iop_pcdir & tpmsk) | pdir;
immr->im_ioport.iop_pcint =
(immr->im_ioport.
iop_pcint & tpmsk) | pint;
immr->im_ioport.iop_pcso =
(immr->im_ioport.
iop_pcso & tpmsk) | psor;
immr->im_ioport.iop_pcpar |= ppar;
} else if (3 == portnum) { /* port D */
immr->im_ioport.iop_pdpar &= tpmsk;
immr->im_ioport.iop_pddat =
(immr->im_ioport.
iop_pddat & tpmsk) | pdat;
immr->im_ioport.iop_pddir =
(immr->im_ioport.
iop_pddir & tpmsk) | pdir;
immr->im_ioport.iop_pdpar |= ppar;
}
}
}
PRINTF ("%s:%d: Port A:\n papar=0x%.4x padir=0x%.4x"
" paodr=0x%.4x\n padat=0x%.4x\n", __FUNCTION__, __LINE__,
immr->im_ioport.iop_papar, immr->im_ioport.iop_padir,
immr->im_ioport.iop_paodr, immr->im_ioport.iop_padat);
PRINTF ("%s:%d: Port B:\n pbpar=0x%.8x pbdir=0x%.8x"
" pbodr=0x%.8x\n pbdat=0x%.8x\n", __FUNCTION__, __LINE__,
immr->im_cpm.cp_pbpar, immr->im_cpm.cp_pbdir,
immr->im_cpm.cp_pbodr, immr->im_cpm.cp_pbdat);
PRINTF ("%s:%d: Port C:\n pcpar=0x%.4x pcdir=0x%.4x"
" pcdat=0x%.4x\n pcso=0x%.4x pcint=0x%.4x\n ",
__FUNCTION__, __LINE__, immr->im_ioport.iop_pcpar,
immr->im_ioport.iop_pcdir, immr->im_ioport.iop_pcdat,
immr->im_ioport.iop_pcso, immr->im_ioport.iop_pcint);
PRINTF ("%s:%d: Port D:\n pdpar=0x%.4x pddir=0x%.4x"
" pddat=0x%.4x\n", __FUNCTION__, __LINE__,
immr->im_ioport.iop_pdpar, immr->im_ioport.iop_pddir,
immr->im_ioport.iop_pddat);
}

View file

@ -0,0 +1,42 @@
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
* Keith Outwater, keith_outwater@mvis.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
*/
#define NUM_PORTS 4
#define PORT_BITS 18
/*
* This structure provides configuration information for one port pin.
* We include all fields needed to initialize any of the ioports.
*/
typedef struct {
unsigned char conf:1; /* If 1, configure this port */
unsigned char ppar:1; /* Port Pin Assignment Register */
unsigned char psor:1; /* Port Special Options Register */
unsigned char pdir:1; /* Port Data Direction Register */
unsigned char podr:1; /* Port Open Drain Register */
unsigned char pdat:1; /* Port Data Register */
unsigned char pint:1; /* Port Interrupt Register */
} mpc8xx_iop_conf_t;
extern void config_mpc8xx_ioports(volatile immap_t *immr);

View file

@ -0,0 +1,107 @@
/*
* Linker command file for the GEN860T board when the environment is
* stored in flash memory.
*
* (C) Copyright 2000-2010
* 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)
SECTIONS
{
/*
* Read-only sections, merged into text segment:
*/
. = + SIZEOF_HEADERS;
.text :
{
arch/powerpc/cpu/mpc8xx/start.o (.text*)
arch/powerpc/cpu/mpc8xx/traps.o (.text*)
*(.text*)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
}
/*
* Read-write section, merged into data segment:
*/
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
KEEP(*(.got))
_GOT2_TABLE_ = .;
KEEP(*(.got2))
_FIXUP_TABLE_ = .;
KEEP(*(.fixup))
}
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data:
{
*(.data*)
*(.sdata*)
}
_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(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss (NOLOAD) :
{
*(.bss*)
*(.sbss*)
*(COMMON)
. = ALIGN(4);
}
__bss_end__ = . ;
PROVIDE (end = .);
.ppcenv:
{
. = env_offset;
common/env_embedded.o
}
}

View file

@ -0,0 +1,101 @@
/*
* Linker command file for the GEN860T board.
*
* (C) Copyright 2000-2010
* 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)
SECTIONS
{
/*
* Read-only sections, merged into text segment:
*/
. = + SIZEOF_HEADERS;
.text :
{
arch/powerpc/cpu/mpc8xx/start.o (.text*)
arch/powerpc/cpu/mpc8xx/traps.o (.text*)
*(.text*)
}
_etext = .;
PROVIDE (etext = .);
.rodata :
{
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
}
/*
* Read-write section, merged into data segment:
*/
. = (. + 0x00FF) & 0xFFFFFF00;
_erotext = .;
PROVIDE (erotext = .);
.reloc :
{
_GOT2_TABLE_ = .;
KEEP(*(.got2))
KEEP(*(.got))
PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
_FIXUP_TABLE_ = .;
KEEP(*(.fixup))
}
__got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
.data :
{
*(.data*)
*(.sdata*)
}
_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(256);
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(256);
__init_end = .;
__bss_start = .;
.bss (NOLOAD) :
{
*(.bss*)
*(.sbss*)
*(COMMON)
. = ALIGN(4);
}
__bss_end__ = . ;
PROVIDE (end = .);
}