mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add a directory by kernel instead of a common root, add qnap-301w and rpi4 kernel 6.1 suppport
This commit is contained in:
parent
e910436a7a
commit
46837ec4c0
9459 changed files with 362648 additions and 116345 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 nand.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(call cmd_link_o_target, $^)
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* (C) Copyright 2003
|
||||
* DAVE Srl
|
||||
* http://www.dave-tech.it
|
||||
* http://www.wawnet.biz
|
||||
* mailto:info@wawnet.biz
|
||||
*
|
||||
* 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 <asm/processor.h>
|
||||
#include <command.h>
|
||||
#include <malloc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int board_early_init_f (void)
|
||||
{
|
||||
out32(GPIO0_OR, CONFIG_SYS_NAND0_CE); /* set initial outputs */
|
||||
out32(GPIO0_OR, CONFIG_SYS_NAND1_CE); /* set initial outputs */
|
||||
|
||||
/*
|
||||
* IRQ 0-15 405GP internally generated; active high; level sensitive
|
||||
* IRQ 16 405GP internally generated; active low; level sensitive
|
||||
* IRQ 17-24 RESERVED
|
||||
* IRQ 25 (EXT IRQ 0)
|
||||
* IRQ 26 (EXT IRQ 1)
|
||||
* IRQ 27 (EXT IRQ 2)
|
||||
* IRQ 28 (EXT IRQ 3)
|
||||
* IRQ 29 (EXT IRQ 4)
|
||||
* IRQ 30 (EXT IRQ 5)
|
||||
* IRQ 31 (EXT IRQ 6)
|
||||
*/
|
||||
mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
|
||||
mtdcr(UIC0ER, 0x00000000); /* disable all ints */
|
||||
mtdcr(UIC0CR, 0x00000000); /* set all to be non-critical*/
|
||||
mtdcr(UIC0PR, 0xFFFFFF80); /* set int polarities */
|
||||
mtdcr(UIC0TR, 0x10000000); /* set int trigger levels */
|
||||
mtdcr(UIC0VCR, 0x00000001); /* set vect base=0,INT0 highest priority*/
|
||||
mtdcr(UIC0SR, 0xFFFFFFFF); /* clear all ints */
|
||||
|
||||
/*
|
||||
* EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
|
||||
*/
|
||||
#if 1 /* test-only */
|
||||
mtebc (EBC0_CFG, 0xa8400000); /* ebc always driven */
|
||||
#else
|
||||
mtebc (EBC0_CFG, 0x28400000); /* ebc in high-z */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int misc_init_f (void)
|
||||
{
|
||||
return 0; /* dummy implementation */
|
||||
}
|
||||
|
||||
extern flash_info_t flash_info[]; /* info for FLASH chips */
|
||||
|
||||
int misc_init_r (void)
|
||||
{
|
||||
/* adjust flash start and size as well as the offset */
|
||||
gd->bd->bi_flashstart = 0 - flash_info[0].size;
|
||||
gd->bd->bi_flashoffset= flash_info[0].size - CONFIG_SYS_MONITOR_LEN;
|
||||
#if 0
|
||||
volatile unsigned short *fpga_mode =
|
||||
(unsigned short *)((ulong)CONFIG_SYS_FPGA_BASE_ADDR + CONFIG_SYS_FPGA_CTRL);
|
||||
volatile unsigned char *duart0_mcr =
|
||||
(unsigned char *)((ulong)DUART0_BA + 4);
|
||||
volatile unsigned char *duart1_mcr =
|
||||
(unsigned char *)((ulong)DUART1_BA + 4);
|
||||
|
||||
bd_t *bd = gd->bd;
|
||||
char * tmp; /* Temporary char pointer */
|
||||
unsigned char *dst;
|
||||
ulong len = sizeof(fpgadata);
|
||||
int status;
|
||||
int index;
|
||||
int i;
|
||||
unsigned long CPC0_CR0Reg;
|
||||
|
||||
dst = malloc(CONFIG_SYS_FPGA_MAX_SIZE);
|
||||
if (gunzip (dst, CONFIG_SYS_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
|
||||
printf ("GUNZIP ERROR - must RESET board to recover\n");
|
||||
do_reset (NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
status = fpga_boot(dst, len);
|
||||
if (status != 0) {
|
||||
printf("\nFPGA: Booting failed ");
|
||||
switch (status) {
|
||||
case ERROR_FPGA_PRG_INIT_LOW:
|
||||
printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
|
||||
break;
|
||||
case ERROR_FPGA_PRG_INIT_HIGH:
|
||||
printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
|
||||
break;
|
||||
case ERROR_FPGA_PRG_DONE:
|
||||
printf("(Timeout: DONE not high after programming FPGA)\n ");
|
||||
break;
|
||||
}
|
||||
|
||||
/* display infos on fpgaimage */
|
||||
index = 15;
|
||||
for (i=0; i<4; i++) {
|
||||
len = dst[index];
|
||||
printf("FPGA: %s\n", &(dst[index+1]));
|
||||
index += len+3;
|
||||
}
|
||||
putc ('\n');
|
||||
/* delayed reboot */
|
||||
for (i=20; i>0; i--) {
|
||||
printf("Rebooting in %2d seconds \r",i);
|
||||
for (index=0;index<1000;index++)
|
||||
udelay(1000);
|
||||
}
|
||||
putc ('\n');
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
puts("FPGA: ");
|
||||
|
||||
/* display infos on fpgaimage */
|
||||
index = 15;
|
||||
for (i=0; i<4; i++) {
|
||||
len = dst[index];
|
||||
printf("%s ", &(dst[index+1]));
|
||||
index += len+3;
|
||||
}
|
||||
putc ('\n');
|
||||
|
||||
free(dst);
|
||||
|
||||
/*
|
||||
* Reset FPGA via FPGA_DATA pin
|
||||
*/
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK);
|
||||
udelay(1000); /* wait 1ms */
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
|
||||
udelay(1000); /* wait 1ms */
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Enable power on PS/2 interface
|
||||
*/
|
||||
*fpga_mode |= CONFIG_SYS_FPGA_CTRL_PS2_RESET;
|
||||
|
||||
/*
|
||||
* Enable interrupts in exar duart mcr[3]
|
||||
*/
|
||||
*duart0_mcr = 0x08;
|
||||
*duart1_mcr = 0x08;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Board Identity:
|
||||
*/
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
char str[64];
|
||||
int i = getenv_f("serial#", str, sizeof(str));
|
||||
|
||||
puts ("Board: ");
|
||||
|
||||
if (i == -1) {
|
||||
puts ("### No HW ID - assuming PPChameleonEVB");
|
||||
} else {
|
||||
puts(str);
|
||||
}
|
||||
|
||||
putc ('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
int testdram (void)
|
||||
{
|
||||
/* TODO: XXX XXX XXX */
|
||||
printf ("test: 16 MB - ok\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_CFB_CONSOLE
|
||||
# ifdef CONFIG_CONSOLE_EXTRA_INFO
|
||||
# include <video_fb.h>
|
||||
extern GraphicDevice smi;
|
||||
|
||||
void video_get_info_str (int line_number, char *info)
|
||||
{
|
||||
uint pvr = get_pvr ();
|
||||
|
||||
/* init video info strings for graphic console */
|
||||
switch (line_number) {
|
||||
case 1:
|
||||
switch (pvr) {
|
||||
case PVR_405EP_RB:
|
||||
sprintf (info, " AMCC PowerPC 405EP Rev. B");
|
||||
break;
|
||||
default:
|
||||
sprintf (info, " AMCC PowerPC 405EP Rev. <unknown>");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case 2:
|
||||
sprintf (info, " DAVE Srl PPChameleonEVB - www.dave-tech.it");
|
||||
return;
|
||||
case 3:
|
||||
sprintf (info, " %s", smi.modeIdent);
|
||||
return;
|
||||
}
|
||||
|
||||
/* no more info lines */
|
||||
*info = 0;
|
||||
return;
|
||||
}
|
||||
# endif /* CONFIG_CONSOLE_EXTRA_INFO */
|
||||
#endif /* CONFIG_CFB_CONSOLE */
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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 <asm/ppc4xx.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
/*
|
||||
* include common flash code (for esd boards)
|
||||
*/
|
||||
#include "../common/flash.c"
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (vu_long * addr, flash_info_t * info);
|
||||
static void flash_get_offsets (ulong base, flash_info_t * info);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
#ifdef __DEBUG_START_FROM_SRAM__
|
||||
return CONFIG_SYS_DUMMY_FLASH_SIZE;
|
||||
#else
|
||||
unsigned long size;
|
||||
int i;
|
||||
uint pbcr;
|
||||
unsigned long base;
|
||||
int size_val = 0;
|
||||
|
||||
debug("[%s, %d] Entering ...\n", __FUNCTION__, __LINE__);
|
||||
debug("[%s, %d] flash_info = 0x%p ...\n", __func__, __LINE__,
|
||||
flash_info);
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Static FLASH Bank configuration here - FIXME XXX */
|
||||
|
||||
debug("[%s, %d] Calling flash_get_size ...\n", __FUNCTION__, __LINE__);
|
||||
size = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
|
||||
|
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN) {
|
||||
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
|
||||
size, size<<20);
|
||||
}
|
||||
|
||||
debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* Setup offsets */
|
||||
flash_get_offsets (-size, &flash_info[0]);
|
||||
debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* Re-do sizing to get full correct info */
|
||||
mtdcr(EBC0_CFGADDR, PB0CR);
|
||||
pbcr = mfdcr(EBC0_CFGDATA);
|
||||
mtdcr(EBC0_CFGADDR, PB0CR);
|
||||
base = -size;
|
||||
switch (size) {
|
||||
case 1 << 20:
|
||||
size_val = 0;
|
||||
break;
|
||||
case 2 << 20:
|
||||
size_val = 1;
|
||||
break;
|
||||
case 4 << 20:
|
||||
size_val = 2;
|
||||
break;
|
||||
case 8 << 20:
|
||||
size_val = 3;
|
||||
break;
|
||||
case 16 << 20:
|
||||
size_val = 4;
|
||||
break;
|
||||
}
|
||||
pbcr = (pbcr & 0x0001ffff) | base | (size_val << 17);
|
||||
mtdcr(EBC0_CFGDATA, pbcr);
|
||||
debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* Monitor protection ON by default */
|
||||
(void)flash_protect(FLAG_PROTECT_SET,
|
||||
-CONFIG_SYS_MONITOR_LEN,
|
||||
0xffffffff,
|
||||
&flash_info[0]);
|
||||
|
||||
debug("[%s, %d] Test point ...\n", __FUNCTION__, __LINE__);
|
||||
flash_info[0].size = size;
|
||||
|
||||
return (size);
|
||||
#endif
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* (C) Copyright 2006 DENX Software Engineering
|
||||
*
|
||||
* 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 <asm/io.h>
|
||||
|
||||
#if defined(CONFIG_CMD_NAND)
|
||||
|
||||
#include <nand.h>
|
||||
|
||||
/*
|
||||
* hardware specific access to control-lines
|
||||
* function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c)
|
||||
*/
|
||||
static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
||||
{
|
||||
struct nand_chip *this = mtd->priv;
|
||||
ulong base = (ulong) this->IO_ADDR_W;
|
||||
|
||||
if (ctrl & NAND_CTRL_CHANGE) {
|
||||
if ( ctrl & NAND_CLE )
|
||||
MACRO_NAND_CTL_SETCLE((unsigned long)base);
|
||||
else
|
||||
MACRO_NAND_CTL_CLRCLE((unsigned long)base);
|
||||
if ( ctrl & NAND_ALE )
|
||||
MACRO_NAND_CTL_CLRCLE((unsigned long)base);
|
||||
else
|
||||
MACRO_NAND_CTL_CLRALE((unsigned long)base);
|
||||
if ( ctrl & NAND_NCE )
|
||||
MACRO_NAND_ENABLE_CE((unsigned long)base);
|
||||
else
|
||||
MACRO_NAND_DISABLE_CE((unsigned long)base);
|
||||
}
|
||||
|
||||
if (cmd != NAND_CMD_NONE)
|
||||
writeb(cmd, this->IO_ADDR_W);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* read device ready pin
|
||||
* function +/- borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c)
|
||||
*/
|
||||
static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo)
|
||||
{
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
ulong rb_gpio_pin;
|
||||
|
||||
/* use the base addr to find out which chip are we dealing with */
|
||||
switch((ulong) this->IO_ADDR_W) {
|
||||
case CONFIG_SYS_NAND0_BASE:
|
||||
rb_gpio_pin = CONFIG_SYS_NAND0_RDY;
|
||||
break;
|
||||
case CONFIG_SYS_NAND1_BASE:
|
||||
rb_gpio_pin = CONFIG_SYS_NAND1_RDY;
|
||||
break;
|
||||
default: /* this should never happen */
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (in32(GPIO0_IR) & rb_gpio_pin)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Board-specific NAND initialization. The following members of the
|
||||
* argument are board-specific (per include/linux/mtd/nand.h):
|
||||
* - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
|
||||
* - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
|
||||
* - cmd_ctrl: hardwarespecific function for accesing control-lines
|
||||
* - dev_ready: hardwarespecific function for accesing device ready/busy line
|
||||
* - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
|
||||
* only be provided if a hardware ECC is available
|
||||
* - ecc.mode: mode of ecc, see defines
|
||||
* - chip_delay: chip dependent delay for transfering data from array to
|
||||
* read regs (tR)
|
||||
* - options: various chip options. They can partly be set to inform
|
||||
* nand_scan about special functionality. See the defines for further
|
||||
* explanation
|
||||
* Members with a "?" were not set in the merged testing-NAND branch,
|
||||
* so they are not set here either.
|
||||
*/
|
||||
int board_nand_init(struct nand_chip *nand)
|
||||
{
|
||||
|
||||
nand->cmd_ctrl = ppchameleonevb_hwcontrol;
|
||||
nand->dev_ready = ppchameleonevb_device_ready;
|
||||
nand->ecc.mode = NAND_ECC_SOFT;
|
||||
nand->chip_delay = NAND_BIG_DELAY_US;
|
||||
nand->options = NAND_SAMSUNG_LP_OPTIONS;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2007-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h" /* CONFIG_BOARDDIR */
|
||||
|
||||
#ifndef RESET_VECTOR_ADDRESS
|
||||
#define RESET_VECTOR_ADDRESS 0xfffffffc
|
||||
#endif
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD;
|
||||
bss PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.text :
|
||||
{
|
||||
*(.text*)
|
||||
} :text
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.rodata :
|
||||
{
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
} :text
|
||||
|
||||
/* 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 = (_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 = .;
|
||||
|
||||
ppcenv_assert = ASSERT(. < 0xFFFF8000, ".bss section too big, overlaps .ppcenv section. Please update your confguration: CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN and CONFIG_SYS_TEXT_BASE may need to be modified.");
|
||||
. = 0xFFFF8000;
|
||||
.ppcenv :
|
||||
{
|
||||
common/env_embedded.o(.ppcenv);
|
||||
}
|
||||
|
||||
.resetvec RESET_VECTOR_ADDRESS :
|
||||
{
|
||||
KEEP(*(.resetvec))
|
||||
} :text = 0xffff
|
||||
|
||||
. = RESET_VECTOR_ADDRESS + 0x4;
|
||||
|
||||
/*
|
||||
* Make sure that the bss segment isn't linked at 0x0, otherwise its
|
||||
* address won't be updated during relocation fixups. Note that
|
||||
* this is a temporary fix. Code to dynamically the fixup the bss
|
||||
* location will be added in the future. When the bss relocation
|
||||
* fixup code is present this workaround should be removed.
|
||||
*/
|
||||
#if (RESET_VECTOR_ADDRESS == 0xfffffffc)
|
||||
. |= 0x10;
|
||||
#endif
|
||||
|
||||
__bss_start = .;
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
*(.bss*)
|
||||
*(.sbss*)
|
||||
*(COMMON)
|
||||
} :bss
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
|
|
@ -0,0 +1,707 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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 <asm/processor.h>
|
||||
|
||||
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
short n;
|
||||
|
||||
/* set up sector start address table */
|
||||
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * 0x00010000);
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
|
||||
info->start[i] = base;
|
||||
base += 8 << 10;
|
||||
}
|
||||
while (i < info->sector_count) { /* 64k regular sectors */
|
||||
info->start[i] = base;
|
||||
base += 64 << 10;
|
||||
++i;
|
||||
}
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
|
||||
/* set sector offsets for top boot block type */
|
||||
base += info->size;
|
||||
i = info->sector_count;
|
||||
for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
|
||||
base -= 8 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
while (i > 0) { /* 64k regular sectors */
|
||||
base -= 64 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
} else {
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
info->start[0] = base + 0x00000000;
|
||||
info->start[1] = base + 0x00004000;
|
||||
info->start[2] = base + 0x00006000;
|
||||
info->start[3] = base + 0x00008000;
|
||||
for (i = 4; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * 0x00010000) - 0x00030000;
|
||||
}
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - 0x00004000;
|
||||
info->start[i--] = base + info->size - 0x00006000;
|
||||
info->start[i--] = base + info->size - 0x00008000;
|
||||
for (; i >= 0; i--) {
|
||||
info->start[i] = base + i * 0x00010000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
int k;
|
||||
int size;
|
||||
int erased;
|
||||
volatile unsigned long *flash;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD: printf ("AMD "); break;
|
||||
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
|
||||
case FLASH_MAN_SST: printf ("SST "); break;
|
||||
case FLASH_MAN_STM: printf ("ST "); break;
|
||||
default: printf ("Unknown Vendor "); break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
|
||||
break;
|
||||
case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n");
|
||||
break;
|
||||
case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
|
||||
break;
|
||||
case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n");
|
||||
break;
|
||||
case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
|
||||
break;
|
||||
case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n");
|
||||
break;
|
||||
case FLASH_AM320T: printf ("AM29LV320T (32 M, top sector)\n");
|
||||
break;
|
||||
case FLASH_AM320B: printf ("AM29LV320B (32 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL322T: printf ("AM29DL322T (32 M, top sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL322B: printf ("AM29DL322B (32 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL323T: printf ("AM29DL323T (32 M, top sector)\n");
|
||||
break;
|
||||
case FLASH_AMDL323B: printf ("AM29DL323B (32 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_AM640U: printf ("AM29LV640D (64 M, uniform sector)\n");
|
||||
break;
|
||||
case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
|
||||
break;
|
||||
case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
|
||||
break;
|
||||
case FLASH_STMW320DT: printf ("M29W320DT (32 M, top sector)\n");
|
||||
break;
|
||||
default: printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i=0; i<info->sector_count; ++i) {
|
||||
#ifdef CONFIG_SYS_FLASH_EMPTY_INFO
|
||||
/*
|
||||
* Check if whole sector is erased
|
||||
*/
|
||||
if (i != (info->sector_count-1))
|
||||
size = info->start[i+1] - info->start[i];
|
||||
else
|
||||
size = info->start[0] + info->size - info->start[i];
|
||||
erased = 1;
|
||||
flash = (volatile unsigned long *)info->start[i];
|
||||
size = size >> 2; /* divide by 4 for longword access */
|
||||
for (k=0; k<size; k++)
|
||||
{
|
||||
if (*flash++ != 0xffffffff)
|
||||
{
|
||||
erased = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
/* print empty and read-only info */
|
||||
printf (" %08lX%s%s",
|
||||
info->start[i],
|
||||
erased ? " E" : " ",
|
||||
info->protect[i] ? "RO " : " ");
|
||||
#else
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
#endif
|
||||
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
{
|
||||
short i;
|
||||
short n;
|
||||
CONFIG_SYS_FLASH_WORD_SIZE value;
|
||||
ulong base = (ulong)addr;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)addr;
|
||||
|
||||
debug("[%s, %d] Entering ...\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00900090;
|
||||
|
||||
value = addr2[CONFIG_SYS_FLASH_READ0];
|
||||
|
||||
switch (value) {
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)FUJ_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_FUJ;
|
||||
break;
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)SST_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_SST;
|
||||
break;
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)STM_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_STM;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
value = addr2[CONFIG_SYS_FLASH_READ1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400T:
|
||||
info->flash_id += FLASH_AM400T;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00080000;
|
||||
break; /* => 0.5 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400B:
|
||||
info->flash_id += FLASH_AM400B;
|
||||
info->sector_count = 11;
|
||||
info->size = 0x00080000;
|
||||
break; /* => 0.5 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800T:
|
||||
info->flash_id += FLASH_AM800T;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800B:
|
||||
info->flash_id += FLASH_AM800B;
|
||||
info->sector_count = 19;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160T:
|
||||
info->flash_id += FLASH_AM160T;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160B:
|
||||
info->flash_id += FLASH_AM160B;
|
||||
info->sector_count = 35;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)STM_ID_29W320DT:
|
||||
info->flash_id += FLASH_STMW320DT;
|
||||
info->sector_count = 67;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
|
||||
info->flash_id += FLASH_AM320T;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
|
||||
info->flash_id += FLASH_AM320B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322T:
|
||||
info->flash_id += FLASH_AMDL322T;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322B:
|
||||
info->flash_id += FLASH_AMDL322B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323T:
|
||||
info->flash_id += FLASH_AMDL323T;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323B:
|
||||
info->flash_id += FLASH_AMDL323B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000; break; /* => 4 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV640U:
|
||||
info->flash_id += FLASH_AM640U;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x00800000; break; /* => 8 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF800A:
|
||||
info->flash_id += FLASH_SST800A;
|
||||
info->sector_count = 16;
|
||||
info->size = 0x00100000;
|
||||
break; /* => 1 MB */
|
||||
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF160A:
|
||||
info->flash_id += FLASH_SST160A;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00200000;
|
||||
break; /* => 2 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
|
||||
}
|
||||
|
||||
/* set up sector start address table */
|
||||
if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) {
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * 0x00010000);
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
for (i=0; i<8; ++i) { /* 8 x 8k boot sectors */
|
||||
info->start[i] = base;
|
||||
base += 8 << 10;
|
||||
}
|
||||
while (i < info->sector_count) { /* 64k regular sectors */
|
||||
info->start[i] = base;
|
||||
base += 64 << 10;
|
||||
++i;
|
||||
}
|
||||
} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) {
|
||||
/* set sector offsets for top boot block type */
|
||||
base += info->size;
|
||||
i = info->sector_count;
|
||||
for (n=0; n<8; ++n) { /* 8 x 8k boot sectors */
|
||||
base -= 8 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
while (i > 0) { /* 64k regular sectors */
|
||||
base -= 64 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
} else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT) {
|
||||
/* set sector offsets for top boot block type */
|
||||
base += info->size;
|
||||
i = info->sector_count;
|
||||
/* 1 x 16k boot sector */
|
||||
base -= 16 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
/* 2 x 8k boot sectors */
|
||||
for (n=0; n<2; ++n) {
|
||||
base -= 8 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
/* 1 x 32k boot sector */
|
||||
base -= 32 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
|
||||
while (i > 0) { /* 64k regular sectors */
|
||||
base -= 64 << 10;
|
||||
--i;
|
||||
info->start[i] = base;
|
||||
}
|
||||
} else {
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
info->start[0] = base + 0x00000000;
|
||||
info->start[1] = base + 0x00004000;
|
||||
info->start[2] = base + 0x00006000;
|
||||
info->start[3] = base + 0x00008000;
|
||||
for (i = 4; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * 0x00010000) - 0x00030000;
|
||||
}
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - 0x00004000;
|
||||
info->start[i--] = base + info->size - 0x00006000;
|
||||
info->start[i--] = base + info->size - 0x00008000;
|
||||
for (; i >= 0; i--) {
|
||||
info->start[i] = base + i * 0x00010000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check for protected sectors */
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
|
||||
/* D0 = 1 if protected */
|
||||
addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
|
||||
info->protect[i] = 0;
|
||||
else
|
||||
info->protect[i] = addr2[CONFIG_SYS_FLASH_READ2] & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevent writes to uninitialized FLASH.
|
||||
*/
|
||||
if (info->flash_id != FLASH_UNKNOWN) {
|
||||
addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
|
||||
*addr2 = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
|
||||
}
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
|
||||
int flag, prot, sect, l_sect;
|
||||
ulong start, now, last;
|
||||
int i;
|
||||
|
||||
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_UNKNOWN) {
|
||||
printf ("Can't erase unknown flash type - 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");
|
||||
}
|
||||
|
||||
l_sect = -1;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect<=s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[sect]);
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
|
||||
addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00500050; /* block erase */
|
||||
for (i=0; i<50; i++)
|
||||
udelay(1000); /* wait 1 ms */
|
||||
} else {
|
||||
if (sect == s_first) {
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
|
||||
}
|
||||
addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00300030; /* sector erase */
|
||||
}
|
||||
l_sect = sect;
|
||||
}
|
||||
}
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay (1000);
|
||||
|
||||
/*
|
||||
* We wait for the last triggered sector
|
||||
*/
|
||||
if (l_sect < 0)
|
||||
goto DONE;
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[l_sect]);
|
||||
while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) {
|
||||
if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
return 1;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
|
||||
DONE:
|
||||
/* reset to read mode */
|
||||
addr = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0];
|
||||
addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0; /* reset bank */
|
||||
|
||||
printf (" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp, data;
|
||||
int i, l, rc;
|
||||
|
||||
wp = (addr & ~3); /* get lower word aligned address */
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<l; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*(uchar *)cp)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
#endif
|
||||
}
|
||||
for (; i<4 && cnt>0; ++i) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*src++)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | *src++;
|
||||
#endif
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt==0 && i<4; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*(uchar *)cp)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= 4) {
|
||||
data = 0;
|
||||
#ifdef CONFIG_B2
|
||||
data = (*(ulong*)src);
|
||||
src += 4;
|
||||
#else
|
||||
for (i=0; i<4; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
#endif
|
||||
if ((rc = write_word(info, wp, data)) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += 4;
|
||||
cnt -= 4;
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*src++)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | *src++;
|
||||
#endif
|
||||
--cnt;
|
||||
}
|
||||
for (; i<4; ++i, ++cp) {
|
||||
#ifdef CONFIG_B2
|
||||
data = data | ((*(uchar *)cp)<<(8*i));
|
||||
#else
|
||||
data = (data << 8) | (*(uchar *)cp);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (write_word(info, wp, data));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_word (flash_info_t *info, ulong dest, ulong data)
|
||||
{
|
||||
ulong *data_ptr = &data;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]);
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *)dest;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *)data_ptr;
|
||||
ulong start;
|
||||
int flag;
|
||||
int i;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*((volatile ulong *)dest) & data) != data) {
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
for (i=0; i<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++)
|
||||
{
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00A000A0;
|
||||
|
||||
dest2[i] = data2[i];
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer (0);
|
||||
while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) !=
|
||||
(data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080)) {
|
||||
if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* (C) Copyright 2001-2003
|
||||
* Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
|
||||
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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 <asm/processor.h>
|
||||
#include <command.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef FPGA_DEBUG
|
||||
#define DBG(x...) printf(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif /* DEBUG */
|
||||
|
||||
#define MAX_ONES 226
|
||||
|
||||
#ifdef CONFIG_SYS_FPGA_PRG
|
||||
# define FPGA_PRG CONFIG_SYS_FPGA_PRG /* FPGA program pin (ppc output)*/
|
||||
# define FPGA_CLK CONFIG_SYS_FPGA_CLK /* FPGA clk pin (ppc output) */
|
||||
# define FPGA_DATA CONFIG_SYS_FPGA_DATA /* FPGA data pin (ppc output) */
|
||||
# define FPGA_DONE CONFIG_SYS_FPGA_DONE /* FPGA done pin (ppc input) */
|
||||
# define FPGA_INIT CONFIG_SYS_FPGA_INIT /* FPGA init pin (ppc input) */
|
||||
#else
|
||||
# define FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */
|
||||
# define FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */
|
||||
# define FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */
|
||||
# define FPGA_DONE 0x00800000 /* FPGA done pin (ppc input) */
|
||||
# define FPGA_INIT 0x00400000 /* FPGA init pin (ppc input) */
|
||||
#endif
|
||||
|
||||
#define ERROR_FPGA_PRG_INIT_LOW -1 /* Timeout after PRG* asserted */
|
||||
#define ERROR_FPGA_PRG_INIT_HIGH -2 /* Timeout after PRG* deasserted */
|
||||
#define ERROR_FPGA_PRG_DONE -3 /* Timeout after programming */
|
||||
|
||||
#define SET_FPGA(data) out32(GPIO0_OR, data)
|
||||
|
||||
#define FPGA_WRITE_1 { \
|
||||
SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \
|
||||
SET_FPGA(FPGA_PRG | FPGA_DATA); /* set data to 1 */ \
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set clock to 1 */ \
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
|
||||
|
||||
#define FPGA_WRITE_0 { \
|
||||
SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \
|
||||
SET_FPGA(FPGA_PRG); /* set data to 0 */ \
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK); /* set clock to 1 */ \
|
||||
SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */
|
||||
|
||||
#if 0
|
||||
static int fpga_boot (unsigned char *fpgadata, int size)
|
||||
{
|
||||
int i, index, len;
|
||||
int count;
|
||||
|
||||
#ifdef CONFIG_SYS_FPGA_SPARTAN2
|
||||
int j;
|
||||
#else
|
||||
unsigned char b;
|
||||
int bit;
|
||||
#endif
|
||||
|
||||
/* display infos on fpgaimage */
|
||||
index = 15;
|
||||
for (i = 0; i < 4; i++) {
|
||||
len = fpgadata[index];
|
||||
DBG ("FPGA: %s\n", &(fpgadata[index + 1]));
|
||||
index += len + 3;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_FPGA_SPARTAN2
|
||||
/* search for preamble 0xFFFFFFFF */
|
||||
while (1) {
|
||||
if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff)
|
||||
&& (fpgadata[index + 2] == 0xff)
|
||||
&& (fpgadata[index + 3] == 0xff))
|
||||
break; /* preamble found */
|
||||
else
|
||||
index++;
|
||||
}
|
||||
#else
|
||||
/* search for preamble 0xFF2X */
|
||||
for (index = 0; index < size - 1; index++) {
|
||||
if ((fpgadata[index] == 0xff)
|
||||
&& ((fpgadata[index + 1] & 0xf0) == 0x30))
|
||||
break;
|
||||
}
|
||||
index += 2;
|
||||
#endif
|
||||
|
||||
DBG ("FPGA: configdata starts at position 0x%x\n", index);
|
||||
DBG ("FPGA: length of fpga-data %d\n", size - index);
|
||||
|
||||
/*
|
||||
* Setup port pins for fpga programming
|
||||
*/
|
||||
out32 (GPIO0_ODR, 0x00000000); /* no open drain pins */
|
||||
out32 (GPIO0_TCR, in32 (GPIO0_TCR) | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* setup for output */
|
||||
out32 (GPIO0_OR, in32 (GPIO0_OR) | FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set pins to high */
|
||||
|
||||
DBG ("%s, ",
|
||||
((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
|
||||
|
||||
/*
|
||||
* Init fpga by asserting and deasserting PROGRAM*
|
||||
*/
|
||||
SET_FPGA (FPGA_CLK | FPGA_DATA);
|
||||
|
||||
/* Wait for FPGA init line low */
|
||||
count = 0;
|
||||
while (in32 (GPIO0_IR) & FPGA_INIT) {
|
||||
udelay (1000); /* wait 1ms */
|
||||
/* Check for timeout - 100us max, so use 3ms */
|
||||
if (count++ > 3) {
|
||||
DBG ("FPGA: Booting failed!\n");
|
||||
return ERROR_FPGA_PRG_INIT_LOW;
|
||||
}
|
||||
}
|
||||
|
||||
DBG ("%s, ",
|
||||
((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
|
||||
|
||||
/* deassert PROGRAM* */
|
||||
SET_FPGA (FPGA_PRG | FPGA_CLK | FPGA_DATA);
|
||||
|
||||
/* Wait for FPGA end of init period . */
|
||||
count = 0;
|
||||
while (!(in32 (GPIO0_IR) & FPGA_INIT)) {
|
||||
udelay (1000); /* wait 1ms */
|
||||
/* Check for timeout */
|
||||
if (count++ > 3) {
|
||||
DBG ("FPGA: Booting failed!\n");
|
||||
return ERROR_FPGA_PRG_INIT_HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
DBG ("%s, ",
|
||||
((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
|
||||
|
||||
DBG ("write configuration data into fpga\n");
|
||||
/* write configuration-data into fpga... */
|
||||
|
||||
#ifdef CONFIG_SYS_FPGA_SPARTAN2
|
||||
/*
|
||||
* Load uncompressed image into fpga
|
||||
*/
|
||||
for (i = index; i < size; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
if ((fpgadata[i] & 0x80) == 0x80) {
|
||||
FPGA_WRITE_1;
|
||||
} else {
|
||||
FPGA_WRITE_0;
|
||||
}
|
||||
fpgadata[i] <<= 1;
|
||||
}
|
||||
}
|
||||
#else /* ! CONFIG_SYS_FPGA_SPARTAN2 */
|
||||
/* send 0xff 0x20 */
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_0;
|
||||
FPGA_WRITE_0;
|
||||
FPGA_WRITE_1;
|
||||
FPGA_WRITE_0;
|
||||
FPGA_WRITE_0;
|
||||
FPGA_WRITE_0;
|
||||
FPGA_WRITE_0;
|
||||
FPGA_WRITE_0;
|
||||
|
||||
/*
|
||||
** Bit_DeCompression
|
||||
** Code 1 .. maxOnes : n '1's followed by '0'
|
||||
** maxOnes + 1 .. maxOnes + 1 : n - 1 '1's no '0'
|
||||
** maxOnes + 2 .. 254 : n - (maxOnes + 2) '0's followed by '1'
|
||||
** 255 : '1'
|
||||
*/
|
||||
|
||||
for (i = index; i < size; i++) {
|
||||
b = fpgadata[i];
|
||||
if ((b >= 1) && (b <= MAX_ONES)) {
|
||||
for (bit = 0; bit < b; bit++) {
|
||||
FPGA_WRITE_1;
|
||||
}
|
||||
FPGA_WRITE_0;
|
||||
} else if (b == (MAX_ONES + 1)) {
|
||||
for (bit = 1; bit < b; bit++) {
|
||||
FPGA_WRITE_1;
|
||||
}
|
||||
} else if ((b >= (MAX_ONES + 2)) && (b <= 254)) {
|
||||
for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) {
|
||||
FPGA_WRITE_0;
|
||||
}
|
||||
FPGA_WRITE_1;
|
||||
} else if (b == 255) {
|
||||
FPGA_WRITE_1;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_SYS_FPGA_SPARTAN2 */
|
||||
|
||||
DBG ("%s, ",
|
||||
((in32 (GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
|
||||
DBG ("%s\n",
|
||||
((in32 (GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
|
||||
|
||||
/*
|
||||
* Check if fpga's DONE signal - correctly booted ?
|
||||
*/
|
||||
|
||||
/* Wait for FPGA end of programming period . */
|
||||
count = 0;
|
||||
while (!(in32 (GPIO0_IR) & FPGA_DONE)) {
|
||||
udelay (1000); /* wait 1ms */
|
||||
/* Check for timeout */
|
||||
if (count++ > 3) {
|
||||
DBG ("FPGA: Booting failed!\n");
|
||||
return ERROR_FPGA_PRG_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
DBG ("FPGA: Booting successful!\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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 <asm/ppc4xx.h>
|
||||
#include <asm/processor.h>
|
||||
#include <pci.h>
|
||||
|
||||
|
||||
u_long pci9054_iobase;
|
||||
|
||||
|
||||
#define PCI_PRIMARY_CAR (0x500000dc) /* PCI config address reg */
|
||||
#define PCI_PRIMARY_CDR (0x80000000) /* PCI config data reg */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Subroutine: pci9054_read_config_dword
|
||||
| Description: Read a PCI configuration register
|
||||
| Inputs:
|
||||
| hose PCI Controller
|
||||
| dev PCI Bus+Device+Function number
|
||||
| offset Configuration register number
|
||||
| value Address of the configuration register value
|
||||
| Return value:
|
||||
| 0 Successful
|
||||
+-----------------------------------------------------------------------------*/
|
||||
int pci9054_read_config_dword(struct pci_controller *hose,
|
||||
pci_dev_t dev, int offset, u32* value)
|
||||
{
|
||||
unsigned long conAdrVal;
|
||||
unsigned long val;
|
||||
|
||||
/* generate coded value for CON_ADR register */
|
||||
conAdrVal = dev | (offset & 0xfc) | 0x80000000;
|
||||
|
||||
/* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
|
||||
*(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
|
||||
|
||||
/* Note: *pResult comes back as -1 if machine check happened */
|
||||
val = in32r(PCI_PRIMARY_CDR);
|
||||
|
||||
*value = (unsigned long) val;
|
||||
|
||||
out32r(PCI_PRIMARY_CAR, 0);
|
||||
|
||||
if ((*(unsigned long *)0x50000304) & 0x60000000)
|
||||
{
|
||||
/* clear pci master/target abort bits */
|
||||
*(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------+
|
||||
| Subroutine: pci9054_write_config_dword
|
||||
| Description: Write a PCI configuration register.
|
||||
| Inputs:
|
||||
| hose PCI Controller
|
||||
| dev PCI Bus+Device+Function number
|
||||
| offset Configuration register number
|
||||
| Value Configuration register value
|
||||
| Return value:
|
||||
| 0 Successful
|
||||
| Updated for pass2 errata #6. Need to disable interrupts and clear the
|
||||
| PCICFGADR reg after writing the PCICFGDATA reg.
|
||||
+-----------------------------------------------------------------------------*/
|
||||
int pci9054_write_config_dword(struct pci_controller *hose,
|
||||
pci_dev_t dev, int offset, u32 value)
|
||||
{
|
||||
unsigned long conAdrVal;
|
||||
|
||||
conAdrVal = dev | (offset & 0xfc) | 0x80000000;
|
||||
|
||||
*(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
|
||||
|
||||
out32r(PCI_PRIMARY_CDR, value);
|
||||
|
||||
out32r(PCI_PRIMARY_CAR, 0);
|
||||
|
||||
/* clear pci master/target abort bits */
|
||||
*(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DASA_SIM
|
||||
static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev,
|
||||
struct pci_config_table *_)
|
||||
{
|
||||
unsigned int iobase;
|
||||
unsigned short status = 0;
|
||||
unsigned char timer;
|
||||
|
||||
/*
|
||||
* Configure PLX PCI9054
|
||||
*/
|
||||
pci_read_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, &status);
|
||||
status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
|
||||
pci_write_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, status);
|
||||
|
||||
/* Check the latency timer for values >= 0x60.
|
||||
*/
|
||||
pci_read_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer);
|
||||
if (timer < 0x60)
|
||||
{
|
||||
pci_write_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60);
|
||||
}
|
||||
|
||||
/* Set I/O base register.
|
||||
*/
|
||||
pci_write_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CONFIG_SYS_PCI9054_IOBASE);
|
||||
pci_read_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase);
|
||||
|
||||
pci9054_iobase = pci_mem_to_phys(CONFIG_SYS_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK);
|
||||
|
||||
if (pci9054_iobase == 0xffffffff)
|
||||
{
|
||||
printf("Error: Can not set I/O base register.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pci_config_table pci9054_config_table[] = {
|
||||
#ifndef CONFIG_PCI_PNP
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_BUS(CONFIG_SYS_ETH_DEV_FN), PCI_DEV(CONFIG_SYS_ETH_DEV_FN), PCI_FUNC(CONFIG_SYS_ETH_DEV_FN),
|
||||
pci_cfgfunc_config_device, { CONFIG_SYS_ETH_IOBASE,
|
||||
CONFIG_SYS_ETH_IOBASE,
|
||||
PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
|
||||
#ifdef CONFIG_DASA_SIM
|
||||
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_BUS(CONFIG_SYS_PCI9054_DEV_FN), PCI_DEV(CONFIG_SYS_PCI9054_DEV_FN), PCI_FUNC(CONFIG_SYS_PCI9054_DEV_FN),
|
||||
pci_dasa_sim_config_pci9054 },
|
||||
#endif
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct pci_controller pci9054_hose = {
|
||||
config_table: pci9054_config_table,
|
||||
};
|
||||
|
||||
void pci_init(void)
|
||||
{
|
||||
struct pci_controller *hose = &pci9054_hose;
|
||||
|
||||
/*
|
||||
* Register the hose
|
||||
*/
|
||||
hose->first_busno = 0;
|
||||
hose->last_busno = 0xff;
|
||||
|
||||
/* System memory space */
|
||||
pci_set_region(hose->regions + 0,
|
||||
0x00000000, 0x00000000, 0x01000000,
|
||||
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
|
||||
|
||||
/* PCI Memory space */
|
||||
pci_set_region(hose->regions + 1,
|
||||
0x00000000, 0xc0000000, 0x10000000,
|
||||
PCI_REGION_MEM);
|
||||
|
||||
pci_set_ops(hose,
|
||||
pci_hose_read_config_byte_via_dword,
|
||||
pci_hose_read_config_word_via_dword,
|
||||
pci9054_read_config_dword,
|
||||
pci_hose_write_config_byte_via_dword,
|
||||
pci_hose_write_config_word_via_dword,
|
||||
pci9054_write_config_dword);
|
||||
|
||||
hose->region_count = 2;
|
||||
|
||||
pci_register_hose(hose);
|
||||
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue