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:
parent
ccdb64ad45
commit
59bc57d5d5
7254 changed files with 1810270 additions and 7 deletions
|
@ -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
|
||||
|
||||
#########################################################################
|
144
root/package/utils/sysupgrade-helper/src/board/gen860t/README
Normal file
144
root/package/utils/sysupgrade-helper/src/board/gen860t/README
Normal 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>
|
199
root/package/utils/sysupgrade-helper/src/board/gen860t/beeper.c
Normal file
199
root/package/utils/sysupgrade-helper/src/board/gen860t/beeper.c
Normal 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;
|
||||
}
|
|
@ -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);
|
644
root/package/utils/sysupgrade-helper/src/board/gen860t/flash.c
Normal file
644
root/package/utils/sysupgrade-helper/src/board/gen860t/flash.c
Normal 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: */
|
379
root/package/utils/sysupgrade-helper/src/board/gen860t/fpga.c
Normal file
379
root/package/utils/sysupgrade-helper/src/board/gen860t/fpga.c
Normal 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
|
|
@ -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 );
|
294
root/package/utils/sysupgrade-helper/src/board/gen860t/gen860t.c
Normal file
294
root/package/utils/sysupgrade-helper/src/board/gen860t/gen860t.c
Normal 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);
|
||||
}
|
347
root/package/utils/sysupgrade-helper/src/board/gen860t/ioport.c
Normal file
347
root/package/utils/sysupgrade-helper/src/board/gen860t/ioport.c
Normal 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);
|
||||
}
|
|
@ -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);
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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 = .);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue