* Add start-up delay to make sure power has stabilized before
attempting to switch on USB on SX1 board.
* Patch by Josef Wagner, 18 Mar 2004:
- Add support for MicroSys XM250 board (PXA255)
- Add support for MicroSys PM828 board (MPC8280)
- Add support for 32 MB Flash on PM825/826
- new SDRAM refresh rate for PM825/PM826
- added support for MicroSys PM520 (MPC5200)
- replaced Query by Identify command in CPU86/flash.c
to support 28F160F3B
* Fix wrap around problem with udelay() on ARM920T
* Add support for Macronix flash on TRAB board
This commit is contained in:
@@ -41,10 +41,10 @@ ulong flash_int_get_size (volatile unsigned long *baseaddr,
|
||||
info->sector_count = info->size = 0;
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
|
||||
/* Write query command sequence and test FLASH answer
|
||||
/* Write identify command sequence and test FLASH answer
|
||||
*/
|
||||
baseaddr[0] = 0x00980098;
|
||||
baseaddr[1] = 0x00980098;
|
||||
baseaddr[0] = 0x00900090;
|
||||
baseaddr[1] = 0x00900090;
|
||||
|
||||
flashtest_h = baseaddr[0]; /* manufacturer ID */
|
||||
flashtest_l = baseaddr[1];
|
||||
|
||||
47
board/pm520/Makefile
Normal file
47
board/pm520/Makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
#
|
||||
# (C) Copyright 2003-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := $(BOARD).o flash.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend
|
||||
|
||||
#########################################################################
|
||||
31
board/pm520/config.mk
Normal file
31
board/pm520/config.mk
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# (C) Copyright 2003-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# PM520 board
|
||||
#
|
||||
|
||||
TEXT_BASE = 0xfff00000
|
||||
# TEXT_BASE = 0x00100000
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
|
||||
545
board/pm520/flash.c
Normal file
545
board/pm520/flash.c
Normal file
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2001-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/byteorder/swab.h>
|
||||
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/* Board support for 1 or 2 flash devices */
|
||||
#define FLASH_PORT_WIDTH32
|
||||
#undef FLASH_PORT_WIDTH16
|
||||
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
#define FLASH_PORT_WIDTH ushort
|
||||
#define FLASH_PORT_WIDTHV vu_short
|
||||
#define SWAP(x) (x)
|
||||
#else
|
||||
#define FLASH_PORT_WIDTH ulong
|
||||
#define FLASH_PORT_WIDTHV vu_long
|
||||
#define SWAP(x) (x)
|
||||
#endif
|
||||
|
||||
/* Intel-compatible flash ID */
|
||||
#define INTEL_COMPAT 0x00890089
|
||||
#define INTEL_ALT 0x00B000B0
|
||||
|
||||
/* Intel-compatible flash commands */
|
||||
#define INTEL_PROGRAM 0x00100010
|
||||
#define INTEL_ERASE 0x00200020
|
||||
#define INTEL_CLEAR 0x00500050
|
||||
#define INTEL_LOCKBIT 0x00600060
|
||||
#define INTEL_PROTECT 0x00010001
|
||||
#define INTEL_STATUS 0x00700070
|
||||
#define INTEL_READID 0x00900090
|
||||
#define INTEL_CONFIRM 0x00D000D0
|
||||
#define INTEL_RESET 0xFFFFFFFF
|
||||
|
||||
/* Intel-compatible flash status bits */
|
||||
#define INTEL_FINISHED 0x00800080
|
||||
#define INTEL_OK 0x00800080
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define mb() __asm__ __volatile__ ("" : : : "memory")
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info);
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
void inline spin_wheel (void);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
int i;
|
||||
ulong size = 0;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
flash_get_size ((FPW *) CFG_FLASH_BASE, &flash_info[i]);
|
||||
flash_get_offsets (CFG_FLASH_BASE, &flash_info[i]);
|
||||
break;
|
||||
default:
|
||||
panic ("configured to many flash banks!\n");
|
||||
break;
|
||||
}
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
|
||||
/* Protect monitor and environment sectors
|
||||
*/
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE + monitor_flash_len - 1,
|
||||
&flash_info[0] );
|
||||
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
|
||||
info->protect[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_INTEL:
|
||||
printf ("INTEL ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F128J3A:
|
||||
printf ("28F128J3A\n");
|
||||
break;
|
||||
|
||||
case FLASH_28F640J3A:
|
||||
printf ("28F640J3A\n");
|
||||
break;
|
||||
|
||||
case FLASH_28F320J3A:
|
||||
printf ("28F320J3A\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||
{
|
||||
volatile FPW value;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr[0x5555] = (FPW) 0x00AA00AA;
|
||||
addr[0x2AAA] = (FPW) 0x00550055;
|
||||
addr[0x5555] = (FPW) 0x00900090;
|
||||
|
||||
mb ();
|
||||
value = addr[0];
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW) INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
mb ();
|
||||
value = addr[1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW) INTEL_ID_28F128J3A:
|
||||
info->flash_id += FLASH_28F128J3A;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x02000000;
|
||||
break; /* => 32 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F640J3A:
|
||||
info->flash_id += FLASH_28F640J3A;
|
||||
info->sector_count = 64;
|
||||
info->size = 0x01000000;
|
||||
break; /* => 16 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F320J3A:
|
||||
info->flash_id += FLASH_28F320J3A;
|
||||
info->sector_count = 32;
|
||||
info->size = 0x00800000;
|
||||
break; /* => 8 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info->sector_count > CFG_MAX_FLASH_SECT) {
|
||||
printf ("** ERROR: sector count %d > max (%d) **\n",
|
||||
info->sector_count, CFG_MAX_FLASH_SECT);
|
||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||
}
|
||||
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
ulong type, start, last;
|
||||
int rcode = 0;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
type = (info->flash_id & FLASH_VENDMASK);
|
||||
if ((type != FLASH_MAN_INTEL)) {
|
||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
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;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
FPWV *addr = (FPWV *) (info->start[sect]);
|
||||
FPW status;
|
||||
|
||||
printf ("Erasing sector %2d ... ", sect);
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
start = get_timer(0);
|
||||
|
||||
*addr = (FPW) 0x00500050; /* clear status register */
|
||||
*addr = (FPW) 0x00200020; /* erase setup */
|
||||
*addr = (FPW) 0x00D000D0; /* erase confirm */
|
||||
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer(start) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
*addr = (FPW) 0x00B000B0; /* suspend erase */
|
||||
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*addr = 0x00500050; /* clear status register cmd. */
|
||||
*addr = 0x00FF00FF; /* resest to read mode */
|
||||
|
||||
printf (" done\n");
|
||||
}
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 4 - Flash not identified
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp;
|
||||
FPW data;
|
||||
int count, i, l, rc, port_width;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return 4;
|
||||
}
|
||||
/* get lower word aligned address */
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
wp = (addr & ~1);
|
||||
port_width = 2;
|
||||
#else
|
||||
wp = (addr & ~3);
|
||||
port_width = 4;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
for (; i < port_width && cnt > 0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt == 0 && i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
count = 0;
|
||||
while (cnt >= port_width) {
|
||||
data = 0;
|
||||
for (i = 0; i < port_width; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
cnt -= port_width;
|
||||
if (count++ > 0x800) {
|
||||
spin_wheel ();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
return (write_data (info, wp, SWAP (data)));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word or halfword to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data)
|
||||
{
|
||||
FPWV *addr = (FPWV *) dest;
|
||||
ulong status;
|
||||
ulong start;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & data) != data) {
|
||||
printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*addr = (FPW) 0x00400040; /* write setup */
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
start = get_timer(0);
|
||||
|
||||
/* wait while polling the status register */
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void inline spin_wheel (void)
|
||||
{
|
||||
static int p = 0;
|
||||
static char w[] = "\\/-";
|
||||
|
||||
printf ("\010%c", w[p]);
|
||||
(++p == 3) ? (p = 0) : 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Set/Clear sector's lock bit, returns:
|
||||
* 0 - OK
|
||||
* 1 - Error (timeout, voltage problems, etc.)
|
||||
*/
|
||||
int flash_real_protect(flash_info_t *info, long sector, int prot)
|
||||
{
|
||||
ulong start;
|
||||
int i;
|
||||
int rc = 0;
|
||||
vu_long *addr = (vu_long *)(info->start[sector]);
|
||||
int flag = disable_interrupts();
|
||||
|
||||
*addr = INTEL_CLEAR; /* Clear status register */
|
||||
if (prot) { /* Set sector lock bit */
|
||||
*addr = INTEL_LOCKBIT; /* Sector lock bit */
|
||||
*addr = INTEL_PROTECT; /* set */
|
||||
}
|
||||
else { /* Clear sector lock bit */
|
||||
*addr = INTEL_LOCKBIT; /* All sectors lock bits */
|
||||
*addr = INTEL_CONFIRM; /* clear */
|
||||
}
|
||||
|
||||
start = get_timer(0);
|
||||
|
||||
while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
|
||||
if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT) {
|
||||
printf("Flash lock bit operation timed out\n");
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*addr != INTEL_OK) {
|
||||
printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
|
||||
(uint)addr, (uint)*addr);
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
info->protect[sector] = prot;
|
||||
|
||||
/*
|
||||
* Clear lock bit command clears all sectors lock bits, so
|
||||
* we have to restore lock bits of protected sectors.
|
||||
*/
|
||||
if (!prot)
|
||||
{
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
{
|
||||
if (info->protect[i])
|
||||
{
|
||||
start = get_timer(0);
|
||||
addr = (vu_long *)(info->start[i]);
|
||||
*addr = INTEL_LOCKBIT; /* Sector lock bit */
|
||||
*addr = INTEL_PROTECT; /* set */
|
||||
while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
|
||||
{
|
||||
if (get_timer(start) > CFG_FLASH_UNLOCK_TOUT)
|
||||
{
|
||||
printf("Flash lock bit operation timed out\n");
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
*addr = INTEL_RESET; /* Reset to read array mode */
|
||||
|
||||
return rc;
|
||||
}
|
||||
193
board/pm520/pm520.c
Normal file
193
board/pm520/pm520.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* (C) Copyright 2003-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc5xxx.h>
|
||||
#include <pci.h>
|
||||
|
||||
#ifndef CFG_RAMBOOT
|
||||
static long int dram_size(long int *base, long int maxsize)
|
||||
{
|
||||
volatile long int *addr;
|
||||
ulong cnt, val;
|
||||
ulong save[32]; /* to make test non-destructive */
|
||||
unsigned char i = 0;
|
||||
|
||||
for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
|
||||
addr = base + cnt; /* pointer arith! */
|
||||
|
||||
save[i++] = *addr;
|
||||
*addr = ~cnt;
|
||||
}
|
||||
|
||||
/* write 0 to base address */
|
||||
addr = base;
|
||||
save[i] = *addr;
|
||||
*addr = 0;
|
||||
|
||||
/* check at base address */
|
||||
if ((val = *addr) != 0) {
|
||||
*addr = save[i];
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
|
||||
addr = base + cnt; /* pointer arith! */
|
||||
|
||||
val = *addr;
|
||||
*addr = save[--i];
|
||||
|
||||
if (val != (~cnt)) {
|
||||
return (cnt * sizeof (long));
|
||||
}
|
||||
}
|
||||
return (maxsize);
|
||||
}
|
||||
|
||||
static void sdram_start (int hi_addr)
|
||||
{
|
||||
long hi_addr_bit = hi_addr ? 0x01000000 : 0;
|
||||
|
||||
/* unlock mode register */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0000 | hi_addr_bit;
|
||||
/* precharge all banks */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
|
||||
/* set mode register */
|
||||
#if defined(CONFIG_MPC5200)
|
||||
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x408d0000;
|
||||
#elif defined(CONFIG_MGT5100)
|
||||
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
|
||||
#endif
|
||||
/* precharge all banks */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0002 | hi_addr_bit;
|
||||
/* auto refresh */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0xd04f0004 | hi_addr_bit;
|
||||
/* set mode register */
|
||||
*(vu_long *)MPC5XXX_SDRAM_MODE = 0x008d0000;
|
||||
/* normal operation */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = 0x504f0000 | hi_addr_bit;
|
||||
}
|
||||
#endif
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
ulong dramsize = 0;
|
||||
#ifndef CFG_RAMBOOT
|
||||
ulong test1, test2;
|
||||
|
||||
/* configure SDRAM start/end */
|
||||
#if defined(CONFIG_MPC5200)
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */
|
||||
|
||||
/* setup config registers */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2233a00;
|
||||
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
|
||||
|
||||
#elif defined(CONFIG_MGT5100)
|
||||
*(vu_long *)MPC5XXX_SDRAM_START = 0x00000000;
|
||||
*(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */
|
||||
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
|
||||
|
||||
/* setup config registers */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = 0xc2222600;
|
||||
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = 0x88b70004;
|
||||
|
||||
/* address select register */
|
||||
*(vu_long *)MPC5XXX_SDRAM_XLBSEL = 0x03000000;
|
||||
#endif
|
||||
sdram_start(0);
|
||||
test1 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
|
||||
sdram_start(1);
|
||||
test2 = dram_size((ulong *)CFG_SDRAM_BASE, 0x80000000);
|
||||
if (test1 > test2) {
|
||||
sdram_start(0);
|
||||
dramsize = test1;
|
||||
} else {
|
||||
dramsize = test2;
|
||||
}
|
||||
#if defined(CONFIG_MPC5200)
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS0CFG =
|
||||
(0x13 + __builtin_ffs(dramsize >> 20) - 1);
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
|
||||
#elif defined(CONFIG_MGT5100)
|
||||
*(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15);
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifdef CONFIG_MGT5100
|
||||
*(vu_long *)MPC5XXX_ADDECR |= (1 << 22); /* Enable SDRAM */
|
||||
dramsize = ((*(vu_long *)MPC5XXX_SDRAM_STOP + 1) << 15);
|
||||
#else
|
||||
dramsize = ((1 << (*(vu_long *)MPC5XXX_SDRAM_CS0CFG - 0x13)) << 20);
|
||||
#endif
|
||||
#endif /* CFG_RAMBOOT */
|
||||
/* return total ram size */
|
||||
return dramsize;
|
||||
}
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
#if defined(CONFIG_MPC5200)
|
||||
puts ("Board: MicroSys PM520 \n");
|
||||
#elif defined(CONFIG_MGT5100)
|
||||
puts ("Board: MicroSys PM510 \n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flash_preinit(void)
|
||||
{
|
||||
/*
|
||||
* Now, when we are in RAM, enable flash write
|
||||
* access for detection process.
|
||||
* Note that CS_BOOT cannot be cleared when
|
||||
* executing in flash.
|
||||
*/
|
||||
#if defined(CONFIG_MGT5100)
|
||||
*(vu_long *)MPC5XXX_ADDECR &= ~(1 << 25); /* disable CS_BOOT */
|
||||
*(vu_long *)MPC5XXX_ADDECR |= (1 << 16); /* enable CS0 */
|
||||
#endif
|
||||
*(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
|
||||
}
|
||||
|
||||
void flash_afterinit(ulong size)
|
||||
{
|
||||
if (size == 0x800000) { /* adjust mapping */
|
||||
*(vu_long *)MPC5XXX_BOOTCS_START = *(vu_long *)MPC5XXX_CS0_START =
|
||||
START_REG(CFG_BOOTCS_START | size);
|
||||
*(vu_long *)MPC5XXX_BOOTCS_STOP = *(vu_long *)MPC5XXX_CS0_STOP =
|
||||
STOP_REG(CFG_BOOTCS_START | size, size);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static struct pci_controller hose;
|
||||
|
||||
extern void pci_mpc5xxx_init(struct pci_controller *);
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc5xxx_init(&hose);
|
||||
}
|
||||
#endif
|
||||
122
board/pm520/u-boot.lds
Normal file
122
board/pm520/u-boot.lds
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* (C) Copyright 2003-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
|
||||
/* Do we need any of these for elf?
|
||||
__DYNAMIC = 0; */
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.text : { *(.rel.text) }
|
||||
.rela.text : { *(.rela.text) }
|
||||
.rel.data : { *(.rel.data) }
|
||||
.rela.data : { *(.rela.data) }
|
||||
.rel.rodata : { *(.rel.rodata) }
|
||||
.rela.rodata : { *(.rela.rodata) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
cpu/mpc5xxx/start.o (.text)
|
||||
*(.text)
|
||||
*(.fixup)
|
||||
*(.got1)
|
||||
. = ALIGN(16);
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
*(.rodata.str1.4)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x0FFF) & 0xFFFFF000;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(4096);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# (C) Copyright 2001, 2002
|
||||
# (C) Copyright 2001-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
@@ -22,21 +22,16 @@
|
||||
#
|
||||
|
||||
#
|
||||
# PM826 boards
|
||||
# MicroSys PM826 board:
|
||||
#
|
||||
|
||||
# This should be equal to the CFG_FLASH_BASE or
|
||||
# CFG_BOOTROM_BASE define in config_PM826.h
|
||||
# for the "final" configuration, with U-Boot
|
||||
# in flash, or the address in RAM where
|
||||
# U-Boot is loaded at for debugging.
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_BOOT_ROM),y)
|
||||
TEXT_BASE := 0xFF800000
|
||||
PLATFORM_CPPFLAGS += -DCONFIG_BOOT_ROM
|
||||
else
|
||||
TEXT_BASE := 0xFF000000
|
||||
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
|
||||
|
||||
ifndef TEXT_BASE
|
||||
## Standard: boot 64-bit flash
|
||||
TEXT_BASE = 0xFF000000
|
||||
|
||||
endif
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)
|
||||
|
||||
@@ -69,6 +69,11 @@ ulong flash_get_size (volatile unsigned long *baseaddr,
|
||||
info->sector_count = 39;
|
||||
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
|
||||
break;
|
||||
case INTEL_ID_28F640C3B:
|
||||
info->flash_id = FLASH_28F640C3B;
|
||||
info->sector_count = 135;
|
||||
info->size = 0x02000000; /* 16 * 2 MB = 32 MB */
|
||||
break;
|
||||
default:
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
@@ -79,10 +84,11 @@ ulong flash_get_size (volatile unsigned long *baseaddr,
|
||||
volatile unsigned long *tmp = baseaddr;
|
||||
|
||||
/* set up sector start adress table (bottom sector type)
|
||||
* AND unlock the sectors (if our chip is 160C3)
|
||||
* AND unlock the sectors (if our chip is 160C3 or 640C3)
|
||||
*/
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) {
|
||||
if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
|
||||
tmp[0] = 0x00600060;
|
||||
tmp[1] = 0x00600060;
|
||||
tmp[0] = 0x00D000D0;
|
||||
@@ -177,6 +183,9 @@ void flash_print_info (flash_info_t * info)
|
||||
case FLASH_28F160F3B:
|
||||
printf ("28F160F3B (16 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_28F640C3B:
|
||||
printf ("28F640C3B (64 M, bottom sector)\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
|
||||
40
board/pm828/Makefile
Normal file
40
board/pm828/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# (C) Copyright 2001-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS = $(BOARD).o flash.o
|
||||
|
||||
$(LIB): .depend $(OBJS)
|
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend
|
||||
|
||||
#########################################################################
|
||||
37
board/pm828/config.mk
Normal file
37
board/pm828/config.mk
Normal file
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# (C) Copyright 2003-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# MicroSys PM828 board:
|
||||
#
|
||||
|
||||
|
||||
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp
|
||||
|
||||
ifndef TEXT_BASE
|
||||
## Standard: boot 64-bit flash
|
||||
TEXT_BASE = 0x40000000
|
||||
|
||||
endif
|
||||
|
||||
PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)
|
||||
386
board/pm828/flash.c
Normal file
386
board/pm828/flash.c
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* (C) Copyright 2001-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* Flash Routines for Intel devices
|
||||
*
|
||||
*--------------------------------------------------------------------
|
||||
* 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>
|
||||
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
ulong flash_get_size (volatile unsigned long *baseaddr,
|
||||
flash_info_t * info)
|
||||
{
|
||||
short i;
|
||||
unsigned long flashtest_h, flashtest_l;
|
||||
|
||||
info->sector_count = info->size = 0;
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
|
||||
/* Write query command sequence and test FLASH answer
|
||||
*/
|
||||
baseaddr[0] = 0x00980098;
|
||||
baseaddr[1] = 0x00980098;
|
||||
|
||||
flashtest_h = baseaddr[0]; /* manufacturer ID */
|
||||
flashtest_l = baseaddr[1];
|
||||
|
||||
if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
|
||||
return (0); /* no or unknown flash */
|
||||
|
||||
flashtest_h = baseaddr[2]; /* device ID */
|
||||
flashtest_l = baseaddr[3];
|
||||
|
||||
if (flashtest_h != flashtest_l)
|
||||
return (0);
|
||||
|
||||
switch (flashtest_h) {
|
||||
case INTEL_ID_28F160C3B:
|
||||
info->flash_id = FLASH_28F160C3B;
|
||||
info->sector_count = 39;
|
||||
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
|
||||
break;
|
||||
case INTEL_ID_28F160F3B:
|
||||
info->flash_id = FLASH_28F160F3B;
|
||||
info->sector_count = 39;
|
||||
info->size = 0x00800000; /* 4 * 2 MB = 8 MB */
|
||||
break;
|
||||
case INTEL_ID_28F640C3B:
|
||||
info->flash_id = FLASH_28F640C3B;
|
||||
info->sector_count = 135;
|
||||
info->size = 0x02000000; /* 16 * 2 MB = 32 MB */
|
||||
break;
|
||||
default:
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */
|
||||
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
volatile unsigned long *tmp = baseaddr;
|
||||
|
||||
/* set up sector start adress table (bottom sector type)
|
||||
* AND unlock the sectors (if our chip is 160C3 or 640c3)
|
||||
*/
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
|
||||
((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
|
||||
tmp[0] = 0x00600060;
|
||||
tmp[1] = 0x00600060;
|
||||
tmp[0] = 0x00D000D0;
|
||||
tmp[1] = 0x00D000D0;
|
||||
}
|
||||
info->start[i] = (uint) tmp;
|
||||
tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith */
|
||||
}
|
||||
}
|
||||
|
||||
memset (info->protect, 0, info->sector_count);
|
||||
|
||||
baseaddr[0] = 0x00FF00FF;
|
||||
baseaddr[1] = 0x00FF00FF;
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
unsigned long size_b0 = 0;
|
||||
int i;
|
||||
|
||||
/* Init: no FLASHes known
|
||||
*/
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Static FLASH Bank configuration here (only one bank) */
|
||||
|
||||
size_b0 = flash_get_size ((ulong *) CFG_FLASH0_BASE, &flash_info[0]);
|
||||
if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
|
||||
printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
|
||||
size_b0, size_b0 >> 20);
|
||||
}
|
||||
|
||||
/* protect monitor and environment sectors
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_BOOT_ROM
|
||||
/* If U-Boot is booted from ROM the CFG_MONITOR_BASE > CFG_FLASH0_BASE
|
||||
* but we shouldn't protect it.
|
||||
*/
|
||||
|
||||
# if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_MONITOR_BASE,
|
||||
CFG_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]
|
||||
);
|
||||
# endif
|
||||
#endif /* CONFIG_BOOT_ROM */
|
||||
|
||||
#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
|
||||
# ifndef CFG_ENV_SIZE
|
||||
# define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
|
||||
# endif
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
|
||||
#endif
|
||||
|
||||
return (size_b0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
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 >> 16) & 0xff) {
|
||||
case 0x89:
|
||||
printf ("INTEL ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F160C3B:
|
||||
printf ("28F160C3B (16 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_28F160F3B:
|
||||
printf ("28F160F3B (16 M, bottom sector)\n");
|
||||
break;
|
||||
case FLASH_28F640C3B:
|
||||
printf ("28F640C3B (64 M, bottom 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) {
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " "
|
||||
);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
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 erase on unprotected sectors
|
||||
*/
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
volatile ulong *addr =
|
||||
(volatile unsigned long *) info->start[sect];
|
||||
|
||||
start = get_timer (0);
|
||||
last = start;
|
||||
if (info->protect[sect] == 0) {
|
||||
/* Disable interrupts which might cause a timeout here
|
||||
*/
|
||||
flag = disable_interrupts ();
|
||||
|
||||
/* Erase the block
|
||||
*/
|
||||
addr[0] = 0x00200020;
|
||||
addr[1] = 0x00200020;
|
||||
addr[0] = 0x00D000D0;
|
||||
addr[1] = 0x00D000D0;
|
||||
|
||||
/* re-enable interrupts if necessary
|
||||
*/
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms
|
||||
*/
|
||||
udelay (1000);
|
||||
|
||||
last = start;
|
||||
while ((addr[0] & 0x00800080) != 0x00800080 ||
|
||||
(addr[1] & 0x00800080) != 0x00800080) {
|
||||
if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout (erase suspended!)\n");
|
||||
/* Suspend erase
|
||||
*/
|
||||
addr[0] = 0x00B000B0;
|
||||
addr[1] = 0x00B000B0;
|
||||
goto DONE;
|
||||
}
|
||||
/* show that we're waiting
|
||||
*/
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
serial_putc ('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
|
||||
printf ("*** ERROR: erase failed!\n");
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
/* Clear status register and reset to read mode
|
||||
*/
|
||||
addr[0] = 0x00500050;
|
||||
addr[1] = 0x00500050;
|
||||
addr[0] = 0x00FF00FF;
|
||||
addr[1] = 0x00FF00FF;
|
||||
}
|
||||
|
||||
printf (" done\n");
|
||||
|
||||
DONE:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_word (flash_info_t *, volatile unsigned long *, ulong);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* 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 v;
|
||||
int i, l, cc = cnt, res = 0;
|
||||
|
||||
|
||||
for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
|
||||
l = (addr & 3);
|
||||
addr &= ~3;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
v = (v << 8) + (i < l || i - l >= cc ?
|
||||
*((unsigned char *) addr + i) : *src++);
|
||||
}
|
||||
|
||||
if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_word (flash_info_t * info, volatile unsigned long *addr,
|
||||
ulong data)
|
||||
{
|
||||
int flag, res = 0;
|
||||
ulong start;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased
|
||||
*/
|
||||
if ((*addr & data) != data)
|
||||
return (2);
|
||||
|
||||
/* Disable interrupts which might cause a timeout here
|
||||
*/
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*addr = 0x00400040;
|
||||
*addr = data;
|
||||
|
||||
/* re-enable interrupts if necessary
|
||||
*/
|
||||
if (flag)
|
||||
enable_interrupts ();
|
||||
|
||||
start = get_timer (0);
|
||||
while ((*addr & 0x00800080) != 0x00800080) {
|
||||
if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
|
||||
/* Suspend program
|
||||
*/
|
||||
*addr = 0x00B000B0;
|
||||
res = 1;
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (*addr & 0x00220022) {
|
||||
printf ("*** ERROR: program failed!\n");
|
||||
res = 1;
|
||||
}
|
||||
|
||||
OUT:
|
||||
/* Clear status register and reset to read mode
|
||||
*/
|
||||
*addr = 0x00500050;
|
||||
*addr = 0x00FF00FF;
|
||||
|
||||
return (res);
|
||||
}
|
||||
363
board/pm828/pm828.c
Normal file
363
board/pm828/pm828.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* (C) Copyright 2001-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ioports.h>
|
||||
#include <mpc8260.h>
|
||||
#include <pci.h>
|
||||
|
||||
/*
|
||||
* I/O Port configuration table
|
||||
*
|
||||
* if conf is 1, then that port pin will be configured at boot time
|
||||
* according to the five values podr/pdir/ppar/psor/pdat for that entry
|
||||
*/
|
||||
|
||||
const iop_conf_t iop_conf_tab[4][32] = {
|
||||
|
||||
/* Port A configuration */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PA31 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 COL */
|
||||
/* PA30 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 CRS */
|
||||
/* PA29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC1 TXER */
|
||||
/* PA28 */ { 1, 1, 1, 1, 0, 0 }, /* FCC1 TXEN */
|
||||
/* PA27 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RXDV */
|
||||
/* PA26 */ { 1, 1, 1, 0, 0, 0 }, /* FCC1 RXER */
|
||||
/* PA25 */ { 0, 0, 0, 1, 0, 0 }, /* PA25 */
|
||||
/* PA24 */ { 0, 0, 0, 1, 0, 0 }, /* PA24 */
|
||||
/* PA23 */ { 0, 0, 0, 1, 0, 0 }, /* PA23 */
|
||||
/* PA22 */ { 0, 0, 0, 1, 0, 0 }, /* PA22 */
|
||||
/* PA21 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD3 */
|
||||
/* PA20 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD2 */
|
||||
/* PA19 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD1 */
|
||||
/* PA18 */ { 1, 1, 0, 1, 0, 0 }, /* FCC1 TXD0 */
|
||||
/* PA17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD0 */
|
||||
/* PA16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD1*/
|
||||
/* PA15 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD2 */
|
||||
/* PA14 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXD3 */
|
||||
/* PA13 */ { 0, 0, 0, 1, 0, 0 }, /* PA13 */
|
||||
/* PA12 */ { 0, 0, 0, 1, 0, 0 }, /* PA12 */
|
||||
/* PA11 */ { 0, 0, 0, 1, 0, 0 }, /* PA11 */
|
||||
/* PA10 */ { 0, 0, 0, 1, 0, 0 }, /* PA10 */
|
||||
/* PA9 */ { 0, 1, 0, 1, 0, 0 }, /* PA9 */
|
||||
/* PA8 */ { 0, 1, 0, 0, 0, 0 }, /* PA8 */
|
||||
/* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
|
||||
/* PA6 */ { 0, 0, 0, 1, 0, 0 }, /* PA6 */
|
||||
/* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
|
||||
/* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
|
||||
/* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
|
||||
/* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
|
||||
/* PA1 */ { 0, 0, 0, 1, 0, 0 }, /* PA1 */
|
||||
/* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
|
||||
},
|
||||
|
||||
/* Port B configuration */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TX_ER */
|
||||
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RX_DV */
|
||||
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 TX_EN */
|
||||
#if defined(CONFIG_ETHER_ON_SCC) && (CONFIG_ETHER_INDEX == 1)
|
||||
#ifdef CONFIG_ETHER_ON_FCC2
|
||||
#error "SCC1 conflicts with FCC2"
|
||||
#endif
|
||||
/* PB28 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 TXD */
|
||||
#else
|
||||
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RX_ER */
|
||||
#endif
|
||||
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 COL */
|
||||
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 CRS */
|
||||
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[3] */
|
||||
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[2] */
|
||||
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[1] */
|
||||
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 TxD[0] */
|
||||
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[0] */
|
||||
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[1] */
|
||||
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[2] */
|
||||
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RxD[3] */
|
||||
/* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
|
||||
/* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* PB16 */
|
||||
/* PB15 */ { 1, 1, 0, 0, 0, 0 }, /* SCC2 RXD */
|
||||
/* PB14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC3 RXD */
|
||||
/* PB13 */ { 0, 0, 0, 0, 0, 0 }, /* PB13 */
|
||||
/* PB12 */ { 0, 0, 0, 0, 0, 0 }, /* PB12 */
|
||||
/* PB11 */ { 0, 0, 0, 0, 0, 0 }, /* PB11 */
|
||||
/* PB10 */ { 0, 0, 0, 0, 0, 0 }, /* PB10 */
|
||||
/* PB9 */ { 0, 0, 0, 0, 0, 0 }, /* PB9 */
|
||||
/* PB8 */ { 1, 1, 1, 1, 0, 0 }, /* SCC3 TXD */
|
||||
/* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */
|
||||
/* PB6 */ { 0, 0, 0, 0, 0, 0 }, /* PB6 */
|
||||
/* PB5 */ { 0, 0, 0, 0, 0, 0 }, /* PB5 */
|
||||
/* PB4 */ { 0, 0, 0, 0, 0, 0 }, /* PB4 */
|
||||
/* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
|
||||
/* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
|
||||
/* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
|
||||
/* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
|
||||
},
|
||||
|
||||
/* Port C */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
|
||||
/* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */
|
||||
/* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* SCC1 CTS */
|
||||
/* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* SCC2 CTS */
|
||||
/* PC27 */ { 0, 0, 0, 1, 0, 0 }, /* PC27 */
|
||||
/* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
|
||||
/* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
|
||||
/* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
|
||||
/* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* PC23 */
|
||||
/* PC22 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 TXCK */
|
||||
/* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 RXCK */
|
||||
/* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC1 TXCK(2) */
|
||||
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 RXCK */
|
||||
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 TXCK */
|
||||
/* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
|
||||
/* PC16 */ { 0, 0, 0, 1, 0, 0 }, /* PC16 */
|
||||
/* PC15 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
|
||||
/* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* SCC1 DCD */
|
||||
/* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
|
||||
/* PC12 */ { 0, 0, 0, 1, 0, 0 }, /* SCC2 DCD */
|
||||
/* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* SCC3 CTS */
|
||||
/* PC10 */ { 0, 0, 0, 1, 0, 0 }, /* SCC3 DCD */
|
||||
/* PC9 */ { 0, 0, 0, 1, 0, 0 }, /* SCC4 CTS */
|
||||
/* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* SCC4 DCD */
|
||||
/* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
|
||||
/* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
|
||||
/* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */
|
||||
/* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */
|
||||
/* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
|
||||
/* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* PC2 */
|
||||
/* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* PC1 */
|
||||
/* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* PC0 */
|
||||
},
|
||||
|
||||
/* Port D */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 RXD */
|
||||
/* PD30 */ { 0, 1, 1, 1, 0, 0 }, /* PD30 */
|
||||
/* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* SCC1 RTS */
|
||||
/* PD28 */ { 0, 0, 0, 1, 0, 0 }, /* PD28 */
|
||||
/* PD27 */ { 0, 1, 0, 1, 0, 0 }, /* SCC2 RTS */
|
||||
/* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
|
||||
/* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */
|
||||
/* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */
|
||||
/* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* SCC3 RTS */
|
||||
/* PD22 */ { 1, 1, 0, 0, 0, 0 }, /* SCC4 RXD */
|
||||
/* PD21 */ { 1, 1, 0, 1, 0, 0 }, /* SCC4 TXD */
|
||||
/* PD20 */ { 0, 0, 1, 1, 0, 0 }, /* SCC4 RTS */
|
||||
/* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
|
||||
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD18 */
|
||||
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* PD17 */
|
||||
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* PD16 */
|
||||
#if defined(CONFIG_SOFT_I2C)
|
||||
/* PD15 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SDA */
|
||||
/* PD14 */ { 1, 0, 0, 1, 1, 1 }, /* I2C SCL */
|
||||
#else
|
||||
#if defined(CONFIG_HARD_I2C)
|
||||
/* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
|
||||
/* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
|
||||
#else /* normal I/O port pins */
|
||||
/* PD15 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SDA */
|
||||
/* PD14 */ { 0, 1, 1, 0, 1, 0 }, /* I2C SCL */
|
||||
#endif
|
||||
#endif
|
||||
/* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
|
||||
/* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
|
||||
/* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
|
||||
/* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
|
||||
/* PD9 */ { 0, 1, 0, 1, 0, 0 }, /* PD9 */
|
||||
/* PD8 */ { 0, 1, 0, 0, 0, 0 }, /* PD8 */
|
||||
/* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
|
||||
/* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
|
||||
/* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */
|
||||
/* PD4 */ { 1, 1, 1, 0, 0, 0 }, /* SMC2 RXD */
|
||||
/* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
|
||||
/* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
|
||||
/* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
|
||||
/* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Check Board Identity:
|
||||
*/
|
||||
int checkboard (void)
|
||||
{
|
||||
puts ("Board: PM828\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
|
||||
*
|
||||
* This routine performs standard 8260 initialization sequence
|
||||
* and calculates the available memory size. It may be called
|
||||
* several times to try different SDRAM configurations on both
|
||||
* 60x and local buses.
|
||||
*/
|
||||
static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
|
||||
ulong orx, volatile uchar * base)
|
||||
{
|
||||
volatile uchar c = 0xff;
|
||||
volatile ulong cnt, val;
|
||||
volatile ulong *addr;
|
||||
volatile uint *sdmr_ptr;
|
||||
volatile uint *orx_ptr;
|
||||
int i;
|
||||
ulong save[32]; /* to make test non-destructive */
|
||||
ulong maxsize;
|
||||
|
||||
/* We must be able to test a location outsize the maximum legal size
|
||||
* to find out THAT we are outside; but this address still has to be
|
||||
* mapped by the controller. That means, that the initial mapping has
|
||||
* to be (at least) twice as large as the maximum expected size.
|
||||
*/
|
||||
maxsize = (1 + (~orx | 0x7fff)) / 2;
|
||||
|
||||
sdmr_ptr = &memctl->memc_psdmr;
|
||||
orx_ptr = &memctl->memc_or2;
|
||||
|
||||
*orx_ptr = orx;
|
||||
|
||||
/*
|
||||
* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
|
||||
*
|
||||
* "At system reset, initialization software must set up the
|
||||
* programmable parameters in the memory controller banks registers
|
||||
* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
|
||||
* system software should execute the following initialization sequence
|
||||
* for each SDRAM device.
|
||||
*
|
||||
* 1. Issue a PRECHARGE-ALL-BANKS command
|
||||
* 2. Issue eight CBR REFRESH commands
|
||||
* 3. Issue a MODE-SET command to initialize the mode register
|
||||
*
|
||||
* The initial commands are executed by setting P/LSDMR[OP] and
|
||||
* accessing the SDRAM with a single-byte transaction."
|
||||
*
|
||||
* The appropriate BRx/ORx registers have already been set when we
|
||||
* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
|
||||
*/
|
||||
|
||||
*sdmr_ptr = sdmr | PSDMR_OP_PREA;
|
||||
*base = c;
|
||||
|
||||
*sdmr_ptr = sdmr | PSDMR_OP_CBRR;
|
||||
for (i = 0; i < 8; i++)
|
||||
*base = c;
|
||||
|
||||
*sdmr_ptr = sdmr | PSDMR_OP_MRW;
|
||||
*(base + CFG_MRS_OFFS) = c; /* setting MR on address lines */
|
||||
|
||||
*sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
|
||||
*base = c;
|
||||
|
||||
/*
|
||||
* Check memory range for valid RAM. A simple memory test determines
|
||||
* the actually available RAM size between addresses `base' and
|
||||
* `base + maxsize'. Some (not all) hardware errors are detected:
|
||||
* - short between address lines
|
||||
* - short between data lines
|
||||
*/
|
||||
i = 0;
|
||||
for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
|
||||
addr = (volatile ulong *) base + cnt; /* pointer arith! */
|
||||
save[i++] = *addr;
|
||||
*addr = ~cnt;
|
||||
}
|
||||
|
||||
addr = (volatile ulong *) base;
|
||||
save[i] = *addr;
|
||||
*addr = 0;
|
||||
|
||||
if ((val = *addr) != 0) {
|
||||
*addr = save[i];
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
|
||||
addr = (volatile ulong *) base + cnt; /* pointer arith! */
|
||||
val = *addr;
|
||||
*addr = save[--i];
|
||||
if (val != ~cnt) {
|
||||
/* Write the actual size to ORx
|
||||
*/
|
||||
*orx_ptr = orx | ~(cnt * sizeof (long) - 1);
|
||||
return (cnt * sizeof (long));
|
||||
}
|
||||
}
|
||||
return (maxsize);
|
||||
}
|
||||
|
||||
|
||||
long int initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CFG_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
|
||||
#ifndef CFG_RAMBOOT
|
||||
ulong size8, size9;
|
||||
#endif
|
||||
ulong psize = 32 * 1024 * 1024;
|
||||
|
||||
memctl->memc_psrt = CFG_PSRT;
|
||||
memctl->memc_mptpr = CFG_MPTPR;
|
||||
|
||||
#ifndef CFG_RAMBOOT
|
||||
size8 = try_init (memctl, CFG_PSDMR_8COL, CFG_OR2_8COL,
|
||||
(uchar *) CFG_SDRAM_BASE);
|
||||
size9 = try_init (memctl, CFG_PSDMR_9COL, CFG_OR2_9COL,
|
||||
(uchar *) CFG_SDRAM_BASE);
|
||||
|
||||
if (size8 < size9) {
|
||||
psize = size9;
|
||||
printf ("(60x:9COL) ");
|
||||
} else {
|
||||
psize = try_init (memctl, CFG_PSDMR_8COL, CFG_OR2_8COL,
|
||||
(uchar *) CFG_SDRAM_BASE);
|
||||
printf ("(60x:8COL) ");
|
||||
}
|
||||
#endif
|
||||
return (psize);
|
||||
}
|
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
|
||||
extern void doc_probe (ulong physadr);
|
||||
void doc_init (void)
|
||||
{
|
||||
doc_probe (CFG_DOC_BASE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_controller hose;
|
||||
|
||||
extern void pci_mpc8250_init(struct pci_controller *);
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc8250_init(&hose);
|
||||
}
|
||||
#endif
|
||||
123
board/pm828/u-boot.lds
Normal file
123
board/pm828/u-boot.lds
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* (C) Copyright 2001-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
|
||||
/* Do we need any of these for elf?
|
||||
__DYNAMIC = 0; */
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.rel.text : { *(.rel.text) }
|
||||
.rela.text : { *(.rela.text) }
|
||||
.rel.data : { *(.rel.data) }
|
||||
.rela.data : { *(.rela.data) }
|
||||
.rel.rodata : { *(.rel.rodata) }
|
||||
.rela.rodata : { *(.rela.rodata) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.init : { *(.init) }
|
||||
.plt : { *(.plt) }
|
||||
.text :
|
||||
{
|
||||
cpu/mpc8260/start.o (.text)
|
||||
*(.text)
|
||||
common/environment.o(.text)
|
||||
*(.fixup)
|
||||
*(.got1)
|
||||
. = ALIGN(16);
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
*(.rodata.str1.4)
|
||||
}
|
||||
.fini : { *(.fini) } =0
|
||||
.ctors : { *(.ctors) }
|
||||
.dtors : { *(.dtors) }
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x0FFF) & 0xFFFFF000;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
*(.got)
|
||||
_GOT2_TABLE_ = .;
|
||||
*(.got2)
|
||||
_FIXUP_TABLE_ = .;
|
||||
*(.fixup)
|
||||
}
|
||||
__got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_) >> 2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata2)
|
||||
*(.dynamic)
|
||||
CONSTRUCTORS
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(4096);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(4096);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.sbss) *(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
_end = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
@@ -118,30 +118,21 @@ platformsetup:
|
||||
str r1, [r0] /* EMIFS GlB Configuration. (value 0x12 most likely) */
|
||||
|
||||
ldr r0, _GPIO_PIN_CONTROL_REG
|
||||
ldrh r1,[r0]
|
||||
mov r1,#0
|
||||
orr r1, r1, #0x0001 /* M_PCM_SYNC */
|
||||
orr r1, r1, #0x4000 /* IPC_ACTIVE */
|
||||
orr r1, r1, #0x0002 /* A_IRDA_OFF */
|
||||
orr r1, r1, #0x0800 /* A_SWITCH */
|
||||
orr r1, r1, #0x8000 /* A_USB_ON */
|
||||
strh r1,[r0]
|
||||
|
||||
ldr r0, _GPIO_DIR_CONTROL_REG
|
||||
ldrh r1,[r0]
|
||||
mov r1,#0
|
||||
bic r1, r1, #0x0001 /* M_PCM_SYNC */
|
||||
bic r1, r1, #0x4000 /* IPC_ACTIVE */
|
||||
bic r1, r1, #0x0002 /* A_IRDA_OFF */
|
||||
bic r1, r1, #0x0800 /* A_SWITCH */
|
||||
bic r1, r1, #0x8000 /* A_USB_ON */
|
||||
strh r1,[r0]
|
||||
|
||||
ldr r0, _GPIO_DATA_OUTPUT_REG
|
||||
ldrh r1,[r0]
|
||||
mov r1,#0
|
||||
bic r1, r1, #0x0001 /* M_PCM_SYNC */
|
||||
orr r1, r1, #0x4000 /* IPC_ACTIVE */
|
||||
orr r1, r1, #0x0002 /* A_IRDA_OFF */
|
||||
bic r1, r1, #0x0800 /* A_SWITCH */
|
||||
bic r1, r1, #0x8000 /* A_USB_ON */
|
||||
strh r1,[r0]
|
||||
|
||||
/* Setup some clock domains */
|
||||
|
||||
@@ -83,6 +83,7 @@ ulong flash_init (void)
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case (FLASH_AM320B & FLASH_TYPEMASK):
|
||||
case (FLASH_MXLV320B & FLASH_TYPEMASK):
|
||||
/* Boot sector type: 8 x 8 + N x 128 kB */
|
||||
flashbase += (j < 8) ? 0x4000 : 0x20000;
|
||||
break;
|
||||
@@ -130,6 +131,8 @@ void flash_print_info (flash_info_t * info)
|
||||
printf ("AMD "); break;
|
||||
case (FLASH_MAN_FUJ & FLASH_VENDMASK):
|
||||
printf ("FUJITSU "); break;
|
||||
case (FLASH_MAN_MX & FLASH_VENDMASK):
|
||||
printf ("MACRONIX "); break;
|
||||
default: printf ("Unknown Vendor "); break;
|
||||
}
|
||||
|
||||
@@ -137,6 +140,9 @@ void flash_print_info (flash_info_t * info)
|
||||
case (FLASH_AM320B & FLASH_TYPEMASK):
|
||||
printf ("2x Am29LV320DB (32Mbit)\n");
|
||||
break;
|
||||
case (FLASH_MXLV320B & FLASH_TYPEMASK):
|
||||
printf ("2x MX29LV320DB (32Mbit)\n");
|
||||
break;
|
||||
case (FLASH_AM640U & FLASH_TYPEMASK):
|
||||
printf ("2x Am29LV640D (64Mbit)\n");
|
||||
break;
|
||||
@@ -191,6 +197,7 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case (FLASH_MAN_AMD & FLASH_VENDMASK): break; /* OK */
|
||||
case (FLASH_MAN_FUJ & FLASH_VENDMASK): break; /* OK */
|
||||
case (FLASH_MAN_MX & FLASH_VENDMASK): break; /* OK */
|
||||
default:
|
||||
debug ("## flash_erase: unknown manufacturer\n");
|
||||
return (ERR_UNKNOWN_FLASH_VENDOR);
|
||||
@@ -502,6 +509,9 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
case FUJ_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_FUJ;
|
||||
break;
|
||||
case MX_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_MX;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
@@ -532,6 +542,14 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
|
||||
addr[0] = 0x00F000F0; /* restore read mode */
|
||||
break; /* => 16 MB */
|
||||
|
||||
case MX_ID_LV320B:
|
||||
info->flash_id += FLASH_MXLV320B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00800000;
|
||||
|
||||
addr[0] = 0x00FF00FF; /* restore read mode */
|
||||
break; /* => 8 MB */
|
||||
|
||||
default:
|
||||
debug ("## flash_init: unknown flash chip\n");
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
|
||||
47
board/xm250/Makefile
Normal file
47
board/xm250/Makefile
Normal file
@@ -0,0 +1,47 @@
|
||||
#
|
||||
# (C) Copyright 2000-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = lib$(BOARD).a
|
||||
|
||||
OBJS := xm250.o flash.o
|
||||
SOBJS := memsetup.o
|
||||
|
||||
$(LIB): $(OBJS) $(SOBJS)
|
||||
$(AR) crv $@ $^
|
||||
|
||||
clean:
|
||||
rm -f $(SOBJS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f $(LIB) core *.bak .depend
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
|
||||
$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
|
||||
|
||||
-include .depend
|
||||
|
||||
#########################################################################
|
||||
35
board/xm250/config.mk
Normal file
35
board/xm250/config.mk
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# (C) Copyright 2003-2004
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
#
|
||||
# MicroSys XM250 board:
|
||||
#
|
||||
|
||||
|
||||
# This is the address where U-Boot lives in flash:
|
||||
#TEXT_BASE = 0
|
||||
|
||||
# FIXME: armboot does only work correctly when being compiled
|
||||
# for the addresses _after_ relocation to RAM!! Otherwhise the
|
||||
# .bss segment is assumed in flash...
|
||||
TEXT_BASE = 0xA3F80000
|
||||
536
board/xm250/flash.c
Normal file
536
board/xm250/flash.c
Normal file
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
* (C) Copyright 2001
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2001-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/byteorder/swab.h>
|
||||
|
||||
|
||||
flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/* Board support for 1 or 2 flash devices */
|
||||
#define FLASH_PORT_WIDTH32
|
||||
#undef FLASH_PORT_WIDTH16
|
||||
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
#define FLASH_PORT_WIDTH ushort
|
||||
#define FLASH_PORT_WIDTHV vu_short
|
||||
#define SWAP(x) __swab16(x)
|
||||
#else
|
||||
#define FLASH_PORT_WIDTH ulong
|
||||
#define FLASH_PORT_WIDTHV vu_long
|
||||
#define SWAP(x) __swab32(x)
|
||||
#endif
|
||||
|
||||
/* Intel-compatible flash ID */
|
||||
#define INTEL_COMPAT 0x00890089
|
||||
#define INTEL_ALT 0x00B000B0
|
||||
|
||||
/* Intel-compatible flash commands */
|
||||
#define INTEL_PROGRAM 0x00100010
|
||||
#define INTEL_ERASE 0x00200020
|
||||
#define INTEL_CLEAR 0x00500050
|
||||
#define INTEL_LOCKBIT 0x00600060
|
||||
#define INTEL_PROTECT 0x00010001
|
||||
#define INTEL_STATUS 0x00700070
|
||||
#define INTEL_READID 0x00900090
|
||||
#define INTEL_CONFIRM 0x00D000D0
|
||||
#define INTEL_RESET 0xFFFFFFFF
|
||||
|
||||
/* Intel-compatible flash status bits */
|
||||
#define INTEL_FINISHED 0x00800080
|
||||
#define INTEL_OK 0x00800080
|
||||
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define mb() __asm__ __volatile__ ("" : : : "memory")
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info);
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data);
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info);
|
||||
void inline spin_wheel (void);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init (void)
|
||||
{
|
||||
int i;
|
||||
ulong size = 0;
|
||||
|
||||
for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]);
|
||||
flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
|
||||
break;
|
||||
case 1:
|
||||
flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
|
||||
flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
|
||||
break;
|
||||
default:
|
||||
panic ("configured to many flash banks!\n");
|
||||
break;
|
||||
}
|
||||
size += flash_info[i].size;
|
||||
}
|
||||
|
||||
/* Protect monitor and environment sectors
|
||||
*/
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_FLASH_BASE,
|
||||
CFG_FLASH_BASE + monitor_flash_len - 1,
|
||||
&flash_info[0] );
|
||||
|
||||
flash_protect ( FLAG_PROTECT_SET,
|
||||
CFG_ENV_ADDR,
|
||||
CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0] );
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
static void flash_get_offsets (ulong base, flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
|
||||
info->protect[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
void flash_print_info (flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_INTEL:
|
||||
printf ("INTEL ");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_28F128J3A:
|
||||
printf ("28F128J3A\n");
|
||||
break;
|
||||
|
||||
case FLASH_28F640J3A:
|
||||
printf ("28F640J3A\n");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf (" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf (" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
if ((i % 5) == 0)
|
||||
printf ("\n ");
|
||||
printf (" %08lX%s",
|
||||
info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size (FPW *addr, flash_info_t *info)
|
||||
{
|
||||
volatile FPW value;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr[0x5555] = (FPW) 0x00AA00AA;
|
||||
addr[0x2AAA] = (FPW) 0x00550055;
|
||||
addr[0x5555] = (FPW) 0x00900090;
|
||||
|
||||
mb ();
|
||||
value = addr[0];
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW) INTEL_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_INTEL;
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
mb ();
|
||||
value = addr[1]; /* device ID */
|
||||
|
||||
switch (value) {
|
||||
|
||||
case (FPW) INTEL_ID_28F128J3A:
|
||||
info->flash_id += FLASH_28F128J3A;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x02000000;
|
||||
break; /* => 32 MB */
|
||||
|
||||
case (FPW) INTEL_ID_28F640J3A:
|
||||
info->flash_id += FLASH_28F640J3A;
|
||||
info->sector_count = 64;
|
||||
info->size = 0x01000000;
|
||||
break; /* => 16 MB */
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (info->sector_count > CFG_MAX_FLASH_SECT) {
|
||||
printf ("** ERROR: sector count %d > max (%d) **\n",
|
||||
info->sector_count, CFG_MAX_FLASH_SECT);
|
||||
info->sector_count = CFG_MAX_FLASH_SECT;
|
||||
}
|
||||
|
||||
addr[0] = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int flash_erase (flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
int flag, prot, sect;
|
||||
ulong type, start, last;
|
||||
int rcode = 0;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf ("- missing\n");
|
||||
} else {
|
||||
printf ("- no sectors to erase\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
type = (info->flash_id & FLASH_VENDMASK);
|
||||
if ((type != FLASH_MAN_INTEL)) {
|
||||
printf ("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
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;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
FPWV *addr = (FPWV *) (info->start[sect]);
|
||||
FPW status;
|
||||
|
||||
printf ("Erasing sector %2d ... ", sect);
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
*addr = (FPW) 0x00500050; /* clear status register */
|
||||
*addr = (FPW) 0x00200020; /* erase setup */
|
||||
*addr = (FPW) 0x00D000D0; /* erase confirm */
|
||||
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
|
||||
printf ("Timeout\n");
|
||||
*addr = (FPW) 0x00B000B0; /* suspend erase */
|
||||
*addr = (FPW) 0x00FF00FF; /* reset to read mode */
|
||||
rcode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*addr = 0x00500050; /* clear status register cmd. */
|
||||
*addr = 0x00FF00FF; /* resest to read mode */
|
||||
|
||||
printf (" done\n");
|
||||
}
|
||||
}
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
* 4 - Flash not identified
|
||||
*/
|
||||
|
||||
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp;
|
||||
FPW data;
|
||||
int count, i, l, rc, port_width;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
return 4;
|
||||
}
|
||||
/* get lower word aligned address */
|
||||
#ifdef FLASH_PORT_WIDTH16
|
||||
wp = (addr & ~1);
|
||||
port_width = 2;
|
||||
#else
|
||||
wp = (addr & ~3);
|
||||
port_width = 4;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
for (; i < port_width && cnt > 0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
for (; cnt == 0 && i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
count = 0;
|
||||
while (cnt >= port_width) {
|
||||
data = 0;
|
||||
for (i = 0; i < port_width; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
}
|
||||
if ((rc = write_data (info, wp, SWAP (data))) != 0) {
|
||||
return (rc);
|
||||
}
|
||||
wp += port_width;
|
||||
cnt -= port_width;
|
||||
if (count++ > 0x800) {
|
||||
spin_wheel ();
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i < port_width; ++i, ++cp) {
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
}
|
||||
|
||||
return (write_data (info, wp, SWAP (data)));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Write a word or halfword to Flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
static int write_data (flash_info_t *info, ulong dest, FPW data)
|
||||
{
|
||||
FPWV *addr = (FPWV *) dest;
|
||||
ulong status;
|
||||
int flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*addr & data) != data) {
|
||||
printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
|
||||
return (2);
|
||||
}
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts ();
|
||||
|
||||
*addr = (FPW) 0x00400040; /* write setup */
|
||||
*addr = data;
|
||||
|
||||
/* arm simple, non interrupt dependent timer */
|
||||
reset_timer_masked ();
|
||||
|
||||
/* wait while polling the status register */
|
||||
while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
|
||||
if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
*addr = (FPW) 0x00FF00FF; /* restore read mode */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void inline spin_wheel (void)
|
||||
{
|
||||
static int p = 0;
|
||||
static char w[] = "\\/-";
|
||||
|
||||
printf ("\010%c", w[p]);
|
||||
(++p == 3) ? (p = 0) : 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Set/Clear sector's lock bit, returns:
|
||||
* 0 - OK
|
||||
* 1 - Error (timeout, voltage problems, etc.)
|
||||
*/
|
||||
int flash_real_protect(flash_info_t *info, long sector, int prot)
|
||||
{
|
||||
int i;
|
||||
int rc = 0;
|
||||
vu_long *addr = (vu_long *)(info->start[sector]);
|
||||
int flag = disable_interrupts();
|
||||
|
||||
*addr = INTEL_CLEAR; /* Clear status register */
|
||||
if (prot) { /* Set sector lock bit */
|
||||
*addr = INTEL_LOCKBIT; /* Sector lock bit */
|
||||
*addr = INTEL_PROTECT; /* set */
|
||||
}
|
||||
else { /* Clear sector lock bit */
|
||||
*addr = INTEL_LOCKBIT; /* All sectors lock bits */
|
||||
*addr = INTEL_CONFIRM; /* clear */
|
||||
}
|
||||
|
||||
reset_timer_masked ();
|
||||
|
||||
while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
|
||||
if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT) {
|
||||
printf("Flash lock bit operation timed out\n");
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*addr != INTEL_OK) {
|
||||
printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
|
||||
(uint)addr, (uint)*addr);
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
info->protect[sector] = prot;
|
||||
|
||||
/*
|
||||
* Clear lock bit command clears all sectors lock bits, so
|
||||
* we have to restore lock bits of protected sectors.
|
||||
*/
|
||||
if (!prot)
|
||||
{
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
{
|
||||
if (info->protect[i])
|
||||
{
|
||||
reset_timer_masked ();
|
||||
addr = (vu_long *)(info->start[i]);
|
||||
*addr = INTEL_LOCKBIT; /* Sector lock bit */
|
||||
*addr = INTEL_PROTECT; /* set */
|
||||
while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
|
||||
{
|
||||
if (get_timer_masked () > CFG_FLASH_UNLOCK_TOUT)
|
||||
{
|
||||
printf("Flash lock bit operation timed out\n");
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
*addr = INTEL_RESET; /* Reset to read array mode */
|
||||
|
||||
return rc;
|
||||
}
|
||||
519
board/xm250/memsetup.S
Normal file
519
board/xm250/memsetup.S
Normal file
@@ -0,0 +1,519 @@
|
||||
/*
|
||||
* Most of this taken from Redboot hal_platform_setup.h with cleanup
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
|
||||
DRAM_SIZE: .long CFG_DRAM_SIZE
|
||||
|
||||
/* wait for coprocessor write complete */
|
||||
.macro CPWAIT reg
|
||||
mrc p15,0,\reg,c2,c0,0
|
||||
mov \reg,\reg
|
||||
sub pc,pc,#4
|
||||
.endm
|
||||
/*
|
||||
.macro SET_LED val
|
||||
ldr r6, =CRADLE_LED_CLR_REG
|
||||
ldr r7, =0
|
||||
str r7, [r6]
|
||||
ldr r6, =CRADLE_LED_SET_REG
|
||||
ldr r7, =\val
|
||||
str r7, [r6]
|
||||
.endm
|
||||
*/
|
||||
|
||||
.globl memsetup
|
||||
memsetup:
|
||||
|
||||
mov r10, lr
|
||||
|
||||
/* Set up GPIO pins first */
|
||||
|
||||
ldr r0, =GPSR0
|
||||
ldr r1, =CFG_GPSR0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPSR1
|
||||
ldr r1, =CFG_GPSR1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPSR2
|
||||
ldr r1, =CFG_GPSR2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPCR0
|
||||
ldr r1, =CFG_GPCR0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPCR1
|
||||
ldr r1, =CFG_GPCR1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPCR2
|
||||
ldr r1, =CFG_GPCR2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GRER0
|
||||
ldr r1, =CFG_GRER0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GRER1
|
||||
ldr r1, =CFG_GRER1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GRER2
|
||||
ldr r1, =CFG_GRER2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GFER0
|
||||
ldr r1, =CFG_GFER0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GFER1
|
||||
ldr r1, =CFG_GFER1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GFER2
|
||||
ldr r1, =CFG_GFER2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPDR0
|
||||
ldr r1, =CFG_GPDR0_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPDR1
|
||||
ldr r1, =CFG_GPDR1_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GPDR2
|
||||
ldr r1, =CFG_GPDR2_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR0_L
|
||||
ldr r1, =CFG_GAFR0_L_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR0_U
|
||||
ldr r1, =CFG_GAFR0_U_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR1_L
|
||||
ldr r1, =CFG_GAFR1_L_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR1_U
|
||||
ldr r1, =CFG_GAFR1_U_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR2_L
|
||||
ldr r1, =CFG_GAFR2_L_VAL
|
||||
str r1, [r0]
|
||||
|
||||
ldr r0, =GAFR2_U
|
||||
ldr r1, =CFG_GAFR2_U_VAL
|
||||
str r1, [r0]
|
||||
|
||||
/* enable GPIO pins */
|
||||
ldr r0, =PSSR
|
||||
ldr r1, =CFG_PSSR_VAL
|
||||
str r1, [r0]
|
||||
|
||||
/* SET_LED 1 */
|
||||
|
||||
ldr r3, =MSC1 /* low - bank 2 Lubbock Registers / SRAM */
|
||||
ldr r2, =CFG_MSC1_VAL /* high - bank 3 Ethernet Controller */
|
||||
str r2, [r3] /* need to set MSC1 before trying to write to the HEX LEDs */
|
||||
ldr r2, [r3] /* need to read it back to make sure the value latches (see MSC section of manual) */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* Initlialize Memory Controller
|
||||
*
|
||||
* See PXA250 Operating System Developer's Guide
|
||||
*
|
||||
* pause for 200 uSecs- allow internal clocks to settle
|
||||
* *Note: only need this if hard reset... doing it anyway for now
|
||||
*/
|
||||
|
||||
@ Step 1
|
||||
@ ---- Wait 200 usec
|
||||
ldr r3, =OSCR @ reset the OS Timer Count to zero
|
||||
mov r2, #0
|
||||
str r2, [r3]
|
||||
ldr r4, =0x300 @ really 0x2E1 is about 200usec, so 0x300 should be plenty
|
||||
1:
|
||||
ldr r2, [r3]
|
||||
cmp r4, r2
|
||||
bgt 1b
|
||||
|
||||
/* SET_LED 2 */
|
||||
|
||||
mem_init:
|
||||
@ get memory controller base address
|
||||
ldr r1, =MEMC_BASE
|
||||
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 2
|
||||
@
|
||||
|
||||
@ Step 2a
|
||||
@ write msc0, read back to ensure data latches
|
||||
@
|
||||
ldr r2, =CFG_MSC0_VAL
|
||||
str r2, [r1, #MSC0_OFFSET]
|
||||
ldr r2, [r1, #MSC0_OFFSET]
|
||||
|
||||
@ write msc1
|
||||
ldr r2, =CFG_MSC1_VAL
|
||||
str r2, [r1, #MSC1_OFFSET]
|
||||
ldr r2, [r1, #MSC1_OFFSET]
|
||||
|
||||
@ write msc2
|
||||
ldr r2, =CFG_MSC2_VAL
|
||||
str r2, [r1, #MSC2_OFFSET]
|
||||
ldr r2, [r1, #MSC2_OFFSET]
|
||||
|
||||
@ Step 2b
|
||||
@ write mecr
|
||||
ldr r2, =CFG_MECR_VAL
|
||||
str r2, [r1, #MECR_OFFSET]
|
||||
|
||||
@ write mcmem0
|
||||
ldr r2, =CFG_MCMEM0_VAL
|
||||
str r2, [r1, #MCMEM0_OFFSET]
|
||||
|
||||
@ write mcmem1
|
||||
ldr r2, =CFG_MCMEM1_VAL
|
||||
str r2, [r1, #MCMEM1_OFFSET]
|
||||
|
||||
@ write mcatt0
|
||||
ldr r2, =CFG_MCATT0_VAL
|
||||
str r2, [r1, #MCATT0_OFFSET]
|
||||
|
||||
@ write mcatt1
|
||||
ldr r2, =CFG_MCATT1_VAL
|
||||
str r2, [r1, #MCATT1_OFFSET]
|
||||
|
||||
@ write mcio0
|
||||
ldr r2, =CFG_MCIO0_VAL
|
||||
str r2, [r1, #MCIO0_OFFSET]
|
||||
|
||||
@ write mcio1
|
||||
ldr r2, =CFG_MCIO1_VAL
|
||||
str r2, [r1, #MCIO1_OFFSET]
|
||||
|
||||
/*SET_LED 3 */
|
||||
|
||||
@ Step 2c
|
||||
@ fly-by-dma is defeatured on this part
|
||||
@ write flycnfg
|
||||
@ldr r2, =CFG_FLYCNFG_VAL
|
||||
@str r2, [r1, #FLYCNFG_OFFSET]
|
||||
|
||||
/* FIXME Does this sequence really make sense */
|
||||
#ifdef REDBOOT_WAY
|
||||
@ Step 2d
|
||||
@ get the mdrefr settings
|
||||
ldr r3, =CFG_MDREFR_VAL
|
||||
|
||||
@ extract DRI field (we need a valid DRI field)
|
||||
@
|
||||
ldr r2, =0xFFF
|
||||
|
||||
@ valid DRI field in r3
|
||||
@
|
||||
and r3, r3, r2
|
||||
|
||||
@ get the reset state of MDREFR
|
||||
@
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ clear the DRI field
|
||||
@
|
||||
bic r4, r4, r2
|
||||
|
||||
@ insert the valid DRI field loaded above
|
||||
@
|
||||
orr r4, r4, r3
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ *Note: preserve the mdrefr value in r4 *
|
||||
|
||||
/*SET_LED 4 */
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 3
|
||||
@
|
||||
@ NO SRAM
|
||||
|
||||
mov pc, r10
|
||||
|
||||
|
||||
@****************************************************************************
|
||||
@ Step 4
|
||||
@
|
||||
|
||||
@ Assumes previous mdrefr value in r4, if not then read current mdrefr
|
||||
|
||||
@ clear the free-running clock bits
|
||||
@ (clear K0Free, K1Free, K2Free
|
||||
@
|
||||
bic r4, r4, #(0x00800000 | 0x01000000 | 0x02000000)
|
||||
|
||||
@ set K0RUN for CPLD clock
|
||||
@
|
||||
orr r4, r4, #0x00002000
|
||||
|
||||
@ set K1RUN if bank 0 installed
|
||||
@
|
||||
orr r4, r4, #0x00010000
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ deassert SLFRSH
|
||||
@
|
||||
bic r4, r4, #0x00400000
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ assert E1PIN
|
||||
@
|
||||
orr r4, r4, #0x00008000
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
nop
|
||||
nop
|
||||
#else
|
||||
@ Step 2d
|
||||
@ get the mdrefr settings
|
||||
ldr r4, =CFG_MDREFR_VAL
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ Step 4
|
||||
|
||||
@ set K0RUN for FLASH clock
|
||||
@
|
||||
orr r4, r4, #0x00002000
|
||||
|
||||
@ set K1RUN for bank DRAM 0
|
||||
@
|
||||
orr r4, r4, #0x00010000
|
||||
|
||||
@ set K2RUN for bank PLD
|
||||
@
|
||||
orr r4, r4, #0x00040000
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ deassert SLFRSH
|
||||
@
|
||||
bic r4, r4, #0x00400000
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
|
||||
@ assert E1PIN
|
||||
@
|
||||
orr r4, r4, #0x00008000
|
||||
|
||||
@ write back mdrefr
|
||||
@
|
||||
str r4, [r1, #MDREFR_OFFSET]
|
||||
ldr r4, [r1, #MDREFR_OFFSET]
|
||||
nop
|
||||
nop
|
||||
#endif
|
||||
|
||||
@ Step 4d
|
||||
@ fetch platform value of mdcnfg
|
||||
@
|
||||
ldr r2, =CFG_MDCNFG_VAL
|
||||
|
||||
@ disable all sdram banks
|
||||
@
|
||||
bic r2, r2, #(MDCNFG_DE0 | MDCNFG_DE1)
|
||||
bic r2, r2, #(MDCNFG_DE2 | MDCNFG_DE3)
|
||||
|
||||
@ program banks 0/1 for bus width
|
||||
@
|
||||
bic r2, r2, #MDCNFG_DWID0 @0=32-bit
|
||||
|
||||
@ write initial value of mdcnfg, w/o enabling sdram banks
|
||||
@
|
||||
str r2, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@ Step 4e
|
||||
@ pause for 200 uSecs
|
||||
@
|
||||
ldr r3, =OSCR @ reset the OS Timer Count to zero
|
||||
mov r2, #0
|
||||
str r2, [r3]
|
||||
ldr r4, =0x300 @ really 0x2E1 is about 200usec, so 0x300 should be plenty
|
||||
1:
|
||||
ldr r2, [r3]
|
||||
cmp r4, r2
|
||||
bgt 1b
|
||||
|
||||
/*SET_LED 5 */
|
||||
|
||||
/* Why is this here??? */
|
||||
mov r0, #0x78 @turn everything off
|
||||
mcr p15, 0, r0, c1, c0, 0 @(caches off, MMU off, etc.)
|
||||
|
||||
@ Step 4f
|
||||
@ Access memory *not yet enabled* for CBR refresh cycles (8)
|
||||
@ - CBR is generated for all banks
|
||||
|
||||
ldr r2, =CFG_DRAM_BASE
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
str r2, [r2]
|
||||
|
||||
@ Step 4g
|
||||
@get memory controller base address
|
||||
@
|
||||
ldr r1, =MEMC_BASE
|
||||
|
||||
@fetch current mdcnfg value
|
||||
@
|
||||
ldr r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@enable sdram bank 0 if installed (must do for any populated bank)
|
||||
@
|
||||
orr r3, r3, #MDCNFG_DE0
|
||||
|
||||
@write back mdcnfg, enabling the sdram bank(s)
|
||||
@
|
||||
str r3, [r1, #MDCNFG_OFFSET]
|
||||
|
||||
@ Step 4h
|
||||
@ write mdmrs
|
||||
@
|
||||
ldr r2, =CFG_MDMRS_VAL
|
||||
str r2, [r1, #MDMRS_OFFSET]
|
||||
|
||||
@ Done Memory Init
|
||||
|
||||
/*SET_LED 6 */
|
||||
|
||||
@********************************************************************
|
||||
@ Disable (mask) all interrupts at the interrupt controller
|
||||
@
|
||||
|
||||
@ clear the interrupt level register (use IRQ, not FIQ)
|
||||
@
|
||||
mov r1, #0
|
||||
ldr r2, =ICLR
|
||||
str r1, [r2]
|
||||
|
||||
@ Set interrupt mask register
|
||||
@
|
||||
ldr r1, =CFG_ICMR_VAL
|
||||
ldr r2, =ICMR
|
||||
str r1, [r2]
|
||||
|
||||
@ ********************************************************************
|
||||
@ Disable the peripheral clocks, and set the core clock
|
||||
@
|
||||
|
||||
@ Turn Off ALL on-chip peripheral clocks for re-configuration
|
||||
@
|
||||
ldr r1, =CKEN
|
||||
mov r2, #0
|
||||
str r2, [r1]
|
||||
|
||||
@ set core clocks
|
||||
@
|
||||
ldr r2, =CFG_CCCR_VAL
|
||||
ldr r1, =CCCR
|
||||
str r2, [r1]
|
||||
|
||||
#ifdef ENABLE32KHZ
|
||||
@ enable the 32Khz oscillator for RTC and PowerManager
|
||||
@
|
||||
ldr r1, =OSCC
|
||||
mov r2, #OSCC_OON
|
||||
str r2, [r1]
|
||||
|
||||
@ NOTE: spin here until OSCC.OOK get set,
|
||||
@ meaning the PLL has settled.
|
||||
@
|
||||
60:
|
||||
ldr r2, [r1]
|
||||
ands r2, r2, #1
|
||||
beq 60b
|
||||
#endif
|
||||
|
||||
@ Turn on needed clocks
|
||||
@
|
||||
ldr r1, =CKEN
|
||||
ldr r2, =CFG_CKEN_VAL
|
||||
str r2, [r1]
|
||||
|
||||
/*SET_LED 7 */
|
||||
|
||||
/* Is this needed???? */
|
||||
#define NODEBUG
|
||||
#ifdef NODEBUG
|
||||
/*Disable software and data breakpoints */
|
||||
mov r0,#0
|
||||
mcr p15,0,r0,c14,c8,0 /* ibcr0 */
|
||||
mcr p15,0,r0,c14,c9,0 /* ibcr1 */
|
||||
mcr p15,0,r0,c14,c4,0 /* dbcon */
|
||||
|
||||
/*Enable all debug functionality */
|
||||
mov r0,#0x80000000
|
||||
mcr p14,0,r0,c10,c0,0 /* dcsr */
|
||||
|
||||
#endif
|
||||
|
||||
/*SET_LED 8 */
|
||||
|
||||
mov pc, r10
|
||||
|
||||
@ End memsetup
|
||||
55
board/xm250/u-boot.lds
Normal file
55
board/xm250/u-boot.lds
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* (C) Copyright 2000-2004
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x00000000;
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
cpu/pxa/start.o (.text)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got : { *(.got) }
|
||||
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) }
|
||||
_end = .;
|
||||
}
|
||||
91
board/xm250/xm250.c
Normal file
91
board/xm250/xm250.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* (C) Copyright 2002
|
||||
* Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
|
||||
*
|
||||
* (C) Copyright 2002
|
||||
* Sysgo Real-Time Solutions, GmbH <www.elinos.com>
|
||||
* Marius Groeger <mgroeger@sysgo.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 <asm/arch/pxa-regs.h>
|
||||
#include <common.h>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* local prototypes */
|
||||
|
||||
inline void sleep (int i);
|
||||
|
||||
inline void
|
||||
/**********************************************************/
|
||||
sleep (int i)
|
||||
/**********************************************************/
|
||||
{
|
||||
while (i--) {
|
||||
udelay (1000000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Miscelaneous platform dependent initialisations
|
||||
*/
|
||||
|
||||
int
|
||||
/**********************************************************/
|
||||
board_post_init (void)
|
||||
/**********************************************************/
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
/**********************************************************/
|
||||
board_init (void)
|
||||
/**********************************************************/
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
/* arch number of MicroSys XM250 */
|
||||
gd->bd->bi_arch_number = 444;
|
||||
|
||||
/* adress of boot parameters */
|
||||
gd->bd->bi_boot_params = 0xa0000100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
/**********************************************************/
|
||||
dram_init (void)
|
||||
/**********************************************************/
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
|
||||
gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
|
||||
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
|
||||
gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
|
||||
gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
|
||||
gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
|
||||
gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
|
||||
gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
Reference in New Issue
Block a user