mirror of
https://github.com/Ysurac/openmptcprouter.git
synced 2025-03-09 15:40:20 +00:00
Add a directory by kernel instead of a common root, add qnap-301w and rpi4 kernel 6.1 suppport
This commit is contained in:
parent
e910436a7a
commit
46837ec4c0
9459 changed files with 362648 additions and 116345 deletions
|
|
@ -0,0 +1,47 @@
|
|||
#
|
||||
# (C) Copyright 2003-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(BOARD).o
|
||||
|
||||
COBJS := $(BOARD).o cmd_stk52xx.o cmd_tb5200.o cam5200_flash.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
cam5200_flash.o: cam5200_flash.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,784 @@
|
|||
/*
|
||||
* (C) Copyright 2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc5xxx.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH)
|
||||
|
||||
#if 0
|
||||
#define DEBUGF(x...) printf(x)
|
||||
#else
|
||||
#define DEBUGF(x...)
|
||||
#endif
|
||||
|
||||
#define swap16(x) __swab16(x)
|
||||
|
||||
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
||||
|
||||
/*
|
||||
* CAM5200 is a TQM5200B based board. Additionally it also features
|
||||
* a NIOS cpu. The NIOS CPU peripherals are accessible through MPC5xxx
|
||||
* Local Bus on CS5. This includes 32 bit wide RAM and SRAM as well as
|
||||
* 16 bit wide flash device. Big Endian order on a 32 bit CS5 makes
|
||||
* access to flash chip slightly more complicated as additional byte
|
||||
* swapping is necessary within each 16 bit wide flash 'word'.
|
||||
*
|
||||
* This driver's task is to handle both flash devices: 32 bit TQM5200B
|
||||
* flash chip and 16 bit NIOS cpu flash chip. In the below
|
||||
* flash_addr_table table we use least significant address bit to mark
|
||||
* 16 bit flash bank and two sets of routines *_32 and *_16 to handle
|
||||
* specifics of both flashes.
|
||||
*/
|
||||
static unsigned long flash_addr_table[][CONFIG_SYS_MAX_FLASH_BANKS] = {
|
||||
{CONFIG_SYS_BOOTCS_START, CONFIG_SYS_CS5_START | 1}
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static int write_word(flash_info_t * info, ulong dest, ulong data);
|
||||
#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
|
||||
static int write_word_32(flash_info_t * info, ulong dest, ulong data);
|
||||
static int write_word_16(flash_info_t * info, ulong dest, ulong data);
|
||||
static int flash_erase_32(flash_info_t * info, int s_first, int s_last);
|
||||
static int flash_erase_16(flash_info_t * info, int s_first, int s_last);
|
||||
static ulong flash_get_size_32(vu_long * addr, flash_info_t * info);
|
||||
static ulong flash_get_size_16(vu_long * addr, flash_info_t * info);
|
||||
#endif
|
||||
|
||||
void flash_print_info(flash_info_t * info)
|
||||
{
|
||||
int i, k;
|
||||
int size, erased;
|
||||
volatile unsigned long *flash;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_AMD:
|
||||
printf("AMD ");
|
||||
break;
|
||||
case FLASH_MAN_FUJ:
|
||||
printf("FUJITSU ");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_S29GL128N:
|
||||
printf ("S29GL128N (256 Mbit, uniform sector size)\n");
|
||||
break;
|
||||
case FLASH_AM320B:
|
||||
printf ("29LV320B (32 Mbit, bottom boot sect)\n");
|
||||
break;
|
||||
case FLASH_AM320T:
|
||||
printf ("29LV320T (32 Mbit, top boot sect)\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Size: %ld KB in %d Sectors\n",
|
||||
info->size >> 10, info->sector_count);
|
||||
|
||||
printf(" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
/*
|
||||
* Check if whole sector is erased
|
||||
*/
|
||||
if (i != (info->sector_count - 1))
|
||||
size = info->start[i + 1] - info->start[i];
|
||||
else
|
||||
size = info->start[0] + info->size - info->start[i];
|
||||
|
||||
erased = 1;
|
||||
flash = (volatile unsigned long *)info->start[i];
|
||||
size = size >> 2; /* divide by 4 for longword access */
|
||||
|
||||
for (k = 0; k < size; k++) {
|
||||
if (*flash++ != 0xffffffff) {
|
||||
erased = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((i % 5) == 0)
|
||||
printf("\n ");
|
||||
|
||||
printf(" %08lX%s%s", info->start[i],
|
||||
erased ? " E" : " ",
|
||||
info->protect[i] ? "RO " : " ");
|
||||
}
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
|
||||
static ulong flash_get_size(vu_long * addr, flash_info_t * info)
|
||||
{
|
||||
|
||||
DEBUGF("get_size: FLASH ADDR %08lx\n", addr);
|
||||
|
||||
/* bit 0 used for big flash marking */
|
||||
if ((ulong)addr & 0x1)
|
||||
return flash_get_size_16((vu_long *)((ulong)addr & 0xfffffffe), info);
|
||||
else
|
||||
return flash_get_size_32(addr, info);
|
||||
}
|
||||
|
||||
static ulong flash_get_size_32(vu_long * addr, flash_info_t * info)
|
||||
#else
|
||||
static ulong flash_get_size(vu_long * addr, flash_info_t * info)
|
||||
#endif
|
||||
{
|
||||
short i;
|
||||
CONFIG_SYS_FLASH_WORD_SIZE value;
|
||||
ulong base = (ulong) addr;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
|
||||
|
||||
DEBUGF("get_size32: FLASH ADDR: %08x\n", (unsigned)addr);
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00900090;
|
||||
udelay(1000);
|
||||
|
||||
value = addr2[0];
|
||||
DEBUGF("FLASH MANUFACT: %x\n", value);
|
||||
|
||||
switch (value) {
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
value = addr2[1]; /* device ID */
|
||||
DEBUGF("\nFLASH DEVICEID: %x\n", value);
|
||||
|
||||
switch (value) {
|
||||
case AMD_ID_MIRROR:
|
||||
DEBUGF("Mirror Bit flash: addr[14] = %08lX addr[15] = %08lX\n",
|
||||
addr[14], addr[15]);
|
||||
switch(addr[14]) {
|
||||
case AMD_ID_GL128N_2:
|
||||
if (addr[15] != AMD_ID_GL128N_3) {
|
||||
DEBUGF("Chip: S29GL128N -> unknown\n");
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
} else {
|
||||
DEBUGF("Chip: S29GL128N\n");
|
||||
info->flash_id += FLASH_S29GL128N;
|
||||
info->sector_count = 128;
|
||||
info->size = 0x02000000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
}
|
||||
|
||||
/* set up sector start address table */
|
||||
for (i = 0; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * 0x00040000);
|
||||
|
||||
/* check for protected sectors */
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
|
||||
/* D0 = 1 if protected */
|
||||
addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
|
||||
|
||||
info->protect[i] = addr2[2] & 1;
|
||||
}
|
||||
|
||||
/* issue bank reset to return to read mode */
|
||||
addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
static int wait_for_DQ7_32(flash_info_t * info, int sect)
|
||||
{
|
||||
ulong start, now, last;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
|
||||
(CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
|
||||
|
||||
start = get_timer(0);
|
||||
last = start;
|
||||
while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
|
||||
(CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) {
|
||||
if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
|
||||
printf("Timeout\n");
|
||||
return -1;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
|
||||
int flash_erase(flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
|
||||
return flash_erase_16(info, s_first, s_last);
|
||||
} else {
|
||||
return flash_erase_32(info, s_first, s_last);
|
||||
}
|
||||
}
|
||||
|
||||
static int flash_erase_32(flash_info_t * info, int s_first, int s_last)
|
||||
#else
|
||||
int flash_erase(flash_info_t * info, int s_first, int s_last)
|
||||
#endif
|
||||
{
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
|
||||
int flag, prot, sect;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN)
|
||||
printf("- missing\n");
|
||||
else
|
||||
printf("- no sectors to erase\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf("Can't erase unknown flash type - aborted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect])
|
||||
prot++;
|
||||
}
|
||||
|
||||
if (prot)
|
||||
printf("- Warning: %d protected sectors will not be erased!", prot);
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
|
||||
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
|
||||
addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00300030; /* sector erase */
|
||||
|
||||
/*
|
||||
* Wait for each sector to complete, it's more
|
||||
* reliable. According to AMD Spec, you must
|
||||
* issue all erase commands within a specified
|
||||
* timeout. This has been seen to fail, especially
|
||||
* if printf()s are included (for debug)!!
|
||||
*/
|
||||
wait_for_DQ7_32(info, sect);
|
||||
}
|
||||
}
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay(1000);
|
||||
|
||||
/* reset to read mode */
|
||||
addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
|
||||
addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0; /* reset bank */
|
||||
|
||||
printf(" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong cp, wp, data;
|
||||
int i, l, rc;
|
||||
|
||||
wp = (addr & ~3); /* get lower word aligned address */
|
||||
|
||||
/*
|
||||
* handle unaligned start bytes
|
||||
*/
|
||||
if ((l = addr - wp) != 0) {
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < l; ++i, ++cp)
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
|
||||
for (; i < 4 && cnt > 0; ++i) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
++cp;
|
||||
}
|
||||
|
||||
for (; cnt == 0 && i < 4; ++i, ++cp)
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0)
|
||||
return (rc);
|
||||
|
||||
wp += 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle word aligned part
|
||||
*/
|
||||
while (cnt >= 4) {
|
||||
data = 0;
|
||||
for (i = 0; i < 4; ++i)
|
||||
data = (data << 8) | *src++;
|
||||
|
||||
if ((rc = write_word(info, wp, data)) != 0)
|
||||
return (rc);
|
||||
|
||||
wp += 4;
|
||||
cnt -= 4;
|
||||
}
|
||||
|
||||
if (cnt == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* handle unaligned tail bytes
|
||||
*/
|
||||
data = 0;
|
||||
for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
|
||||
data = (data << 8) | *src++;
|
||||
--cnt;
|
||||
}
|
||||
for (; i < 4; ++i, ++cp)
|
||||
data = (data << 8) | (*(uchar *) cp);
|
||||
|
||||
return (write_word(info, wp, data));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Copy memory to flash, returns:
|
||||
* 0 - OK
|
||||
* 1 - write timeout
|
||||
* 2 - Flash not erased
|
||||
*/
|
||||
#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
|
||||
static int write_word(flash_info_t * info, ulong dest, ulong data)
|
||||
{
|
||||
if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
|
||||
return write_word_16(info, dest, data);
|
||||
} else {
|
||||
return write_word_32(info, dest, data);
|
||||
}
|
||||
}
|
||||
|
||||
static int write_word_32(flash_info_t * info, ulong dest, ulong data)
|
||||
#else
|
||||
static int write_word(flash_info_t * info, ulong dest, ulong data)
|
||||
#endif
|
||||
{
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
|
||||
ulong *datap = &data;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 =
|
||||
(volatile CONFIG_SYS_FLASH_WORD_SIZE *)datap;
|
||||
ulong start;
|
||||
int i, flag;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
if ((*((vu_long *)dest) & data) != data)
|
||||
return (2);
|
||||
|
||||
for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00A000A0;
|
||||
|
||||
dest2[i] = data2[i];
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer(0);
|
||||
while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
|
||||
(data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080)) {
|
||||
|
||||
if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
|
||||
|
||||
#undef CONFIG_SYS_FLASH_WORD_SIZE
|
||||
#define CONFIG_SYS_FLASH_WORD_SIZE unsigned short
|
||||
|
||||
/*
|
||||
* The following code cannot be run from FLASH!
|
||||
*/
|
||||
static ulong flash_get_size_16(vu_long * addr, flash_info_t * info)
|
||||
{
|
||||
short i;
|
||||
CONFIG_SYS_FLASH_WORD_SIZE value;
|
||||
ulong base = (ulong) addr;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
|
||||
|
||||
DEBUGF("get_size16: FLASH ADDR: %08x\n", (unsigned)addr);
|
||||
|
||||
/* issue bank reset to return to read mode */
|
||||
addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
|
||||
|
||||
/* Write auto select command: read Manufacturer ID */
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x90009000;
|
||||
udelay(1000);
|
||||
|
||||
value = swap16(addr2[0]);
|
||||
DEBUGF("FLASH MANUFACT: %x\n", value);
|
||||
|
||||
switch (value) {
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_AMD;
|
||||
break;
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE) FUJ_MANUFACT:
|
||||
info->flash_id = FLASH_MAN_FUJ;
|
||||
break;
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
info->sector_count = 0;
|
||||
info->size = 0;
|
||||
return (0); /* no or unknown flash */
|
||||
}
|
||||
|
||||
value = swap16(addr2[1]); /* device ID */
|
||||
DEBUGF("\nFLASH DEVICEID: %x\n", value);
|
||||
|
||||
switch (value) {
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
|
||||
info->flash_id += FLASH_AM320B;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
|
||||
info->flash_id += FLASH_AM320T;
|
||||
info->sector_count = 71;
|
||||
info->size = 0x00400000;
|
||||
break; /* => 4 MB */
|
||||
default:
|
||||
info->flash_id = FLASH_UNKNOWN;
|
||||
return (0); /* => no or unknown flash */
|
||||
}
|
||||
|
||||
if (info->flash_id & FLASH_BTYPE) {
|
||||
/* set sector offsets for bottom boot block type */
|
||||
info->start[0] = base + 0x00000000;
|
||||
info->start[1] = base + 0x00002000;
|
||||
info->start[2] = base + 0x00004000;
|
||||
info->start[3] = base + 0x00006000;
|
||||
info->start[4] = base + 0x00008000;
|
||||
info->start[5] = base + 0x0000a000;
|
||||
info->start[6] = base + 0x0000c000;
|
||||
info->start[7] = base + 0x0000e000;
|
||||
|
||||
for (i = 8; i < info->sector_count; i++)
|
||||
info->start[i] = base + (i * 0x00010000) - 0x00070000;
|
||||
} else {
|
||||
/* set sector offsets for top boot block type */
|
||||
i = info->sector_count - 1;
|
||||
info->start[i--] = base + info->size - 0x00002000;
|
||||
info->start[i--] = base + info->size - 0x00004000;
|
||||
info->start[i--] = base + info->size - 0x00006000;
|
||||
info->start[i--] = base + info->size - 0x00008000;
|
||||
info->start[i--] = base + info->size - 0x0000a000;
|
||||
info->start[i--] = base + info->size - 0x0000c000;
|
||||
info->start[i--] = base + info->size - 0x0000e000;
|
||||
|
||||
for (; i >= 0; i--)
|
||||
info->start[i] = base + i * 0x00010000;
|
||||
}
|
||||
|
||||
/* check for protected sectors */
|
||||
for (i = 0; i < info->sector_count; i++) {
|
||||
/* read sector protection at sector address, (A7 .. A0) = 0x02 */
|
||||
/* D0 = 1 if protected */
|
||||
addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
|
||||
|
||||
info->protect[i] = addr2[2] & 1;
|
||||
}
|
||||
|
||||
/* issue bank reset to return to read mode */
|
||||
addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
|
||||
|
||||
return (info->size);
|
||||
}
|
||||
|
||||
static int wait_for_DQ7_16(flash_info_t * info, int sect)
|
||||
{
|
||||
ulong start, now, last;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
|
||||
(CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
|
||||
|
||||
start = get_timer(0);
|
||||
last = start;
|
||||
while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
|
||||
(CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) {
|
||||
if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
|
||||
printf("Timeout\n");
|
||||
return -1;
|
||||
}
|
||||
/* show that we're waiting */
|
||||
if ((now - last) > 1000) { /* every second */
|
||||
putc('.');
|
||||
last = now;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flash_erase_16(flash_info_t * info, int s_first, int s_last)
|
||||
{
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
|
||||
int flag, prot, sect;
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
if (info->flash_id == FLASH_UNKNOWN)
|
||||
printf("- missing\n");
|
||||
else
|
||||
printf("- no sectors to erase\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf("Can't erase unknown flash type - aborted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect])
|
||||
prot++;
|
||||
}
|
||||
|
||||
if (prot)
|
||||
printf("- Warning: %d protected sectors will not be erased!", prot);
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
/* Start erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect] == 0) { /* not protected */
|
||||
addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
|
||||
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000;
|
||||
addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
|
||||
addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
|
||||
addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x30003000; /* sector erase */
|
||||
|
||||
/*
|
||||
* Wait for each sector to complete, it's more
|
||||
* reliable. According to AMD Spec, you must
|
||||
* issue all erase commands within a specified
|
||||
* timeout. This has been seen to fail, especially
|
||||
* if printf()s are included (for debug)!!
|
||||
*/
|
||||
wait_for_DQ7_16(info, sect);
|
||||
}
|
||||
}
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* wait at least 80us - let's wait 1 ms */
|
||||
udelay(1000);
|
||||
|
||||
/* reset to read mode */
|
||||
addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
|
||||
addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000; /* reset bank */
|
||||
|
||||
printf(" done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_word_16(flash_info_t * info, ulong dest, ulong data)
|
||||
{
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
|
||||
ulong *datap = &data;
|
||||
volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 =
|
||||
(volatile CONFIG_SYS_FLASH_WORD_SIZE *)datap;
|
||||
ulong start;
|
||||
int i;
|
||||
|
||||
/* Check if Flash is (sufficiently) erased */
|
||||
for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
|
||||
if ((dest2[i] & swap16(data2[i])) != swap16(data2[i]))
|
||||
return (2);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
|
||||
int flag;
|
||||
|
||||
/* Disable interrupts which might cause a timeout here */
|
||||
flag = disable_interrupts();
|
||||
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
|
||||
addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xA000A000;
|
||||
|
||||
dest2[i] = swap16(data2[i]);
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flag)
|
||||
enable_interrupts();
|
||||
|
||||
/* data polling for D7 */
|
||||
start = get_timer(0);
|
||||
while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
|
||||
(swap16(data2[i]) & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000)) {
|
||||
|
||||
if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* CONFIG_SYS_FLASH_2ND_16BIT_DEV */
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Functions
|
||||
*/
|
||||
static ulong flash_get_size(vu_long * addr, flash_info_t * info);
|
||||
static int write_word(flash_info_t * info, ulong dest, ulong data);
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
unsigned long flash_init(void)
|
||||
{
|
||||
unsigned long total_b = 0;
|
||||
unsigned long size_b[CONFIG_SYS_MAX_FLASH_BANKS];
|
||||
unsigned short index = 0;
|
||||
int i;
|
||||
|
||||
DEBUGF("\n");
|
||||
DEBUGF("FLASH: Index: %d\n", index);
|
||||
|
||||
/* Init: no FLASHes known */
|
||||
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
|
||||
flash_info[i].flash_id = FLASH_UNKNOWN;
|
||||
flash_info[i].sector_count = -1;
|
||||
flash_info[i].size = 0;
|
||||
|
||||
/* check whether the address is 0 */
|
||||
if (flash_addr_table[index][i] == 0)
|
||||
continue;
|
||||
|
||||
/* call flash_get_size() to initialize sector address */
|
||||
size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i],
|
||||
&flash_info[i]);
|
||||
|
||||
flash_info[i].size = size_b[i];
|
||||
|
||||
if (flash_info[i].flash_id == FLASH_UNKNOWN) {
|
||||
printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
|
||||
i+1, size_b[i], size_b[i] << 20);
|
||||
flash_info[i].sector_count = -1;
|
||||
flash_info[i].size = 0;
|
||||
}
|
||||
|
||||
/* Monitor protection ON by default */
|
||||
(void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
|
||||
CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
|
||||
&flash_info[i]);
|
||||
#if defined(CONFIG_ENV_IS_IN_FLASH)
|
||||
(void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
|
||||
CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
|
||||
&flash_info[i]);
|
||||
#if defined(CONFIG_ENV_ADDR_REDUND)
|
||||
(void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
|
||||
CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
|
||||
&flash_info[i]);
|
||||
#endif
|
||||
#endif
|
||||
total_b += flash_info[i].size;
|
||||
}
|
||||
|
||||
return total_b;
|
||||
}
|
||||
#endif /* if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH) */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* (C) Copyright 2005 - 2006
|
||||
* Martin Krause, TQ-Systems GmbH, martin.krause@tqs.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
|
||||
*/
|
||||
|
||||
/*
|
||||
* TB5200 specific functions
|
||||
*/
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
|
||||
#if defined(CONFIG_CMD_BSP)
|
||||
#if defined (CONFIG_TB5200)
|
||||
|
||||
#define SM501_PANEL_DISPLAY_CONTROL 0x00080000UL
|
||||
|
||||
static void led_init(void)
|
||||
{
|
||||
struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5XXX_GPT;
|
||||
|
||||
/* configure timer 4 for simple GPIO output */
|
||||
gpt->gpt4.emsr |= 0x00000024;
|
||||
}
|
||||
|
||||
int cmd_led(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5XXX_GPT;
|
||||
|
||||
led_init();
|
||||
|
||||
if (strcmp (argv[1], "on") == 0) {
|
||||
debug ("switch status LED on\n");
|
||||
gpt->gpt4.emsr |= (1 << 4);
|
||||
} else if (strcmp (argv[1], "off") == 0) {
|
||||
debug ("switch status LED off\n");
|
||||
gpt->gpt4.emsr &= ~(1 << 4);
|
||||
} else {
|
||||
printf ("Usage:\nled on/off\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sm501_backlight (unsigned int state)
|
||||
{
|
||||
if (state == 1) {
|
||||
*(vu_long *)(SM501_MMIO_BASE+SM501_PANEL_DISPLAY_CONTROL) |=
|
||||
(1 << 26) | (1 << 27);
|
||||
} else if (state == 0)
|
||||
*(vu_long *)(SM501_MMIO_BASE+SM501_PANEL_DISPLAY_CONTROL) &=
|
||||
~((1 << 26) | (1 << 27));
|
||||
}
|
||||
|
||||
int cmd_backlight(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
if (strcmp (argv[1], "on") == 0) {
|
||||
debug ("switch backlight on\n");
|
||||
sm501_backlight (1);
|
||||
} else if (strcmp (argv[1], "off") == 0) {
|
||||
debug ("switch backlight off\n");
|
||||
sm501_backlight (0);
|
||||
} else {
|
||||
printf ("Usage:\nbacklight on/off\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
led , 2, 1, cmd_led,
|
||||
"switch status LED on or off",
|
||||
"on/off"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
backlight , 2, 1, cmd_backlight,
|
||||
"switch backlight on or off",
|
||||
"on/off"
|
||||
);
|
||||
|
||||
#endif /* CONFIG_STK52XX */
|
||||
#endif
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* (C) Copyright 2004
|
||||
* Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define SDRAM_DDR 0 /* is SDR */
|
||||
|
||||
/* Settings for XLB = 132 MHz */
|
||||
#define SDRAM_MODE 0x00CD0000
|
||||
/* #define SDRAM_MODE 0x008D0000 */ /* CAS latency 2 */
|
||||
#define SDRAM_CONTROL 0x504F0000
|
||||
#define SDRAM_CONFIG1 0xD2322800
|
||||
/* #define SDRAM_CONFIG1 0xD2222800 */ /* CAS latency 2 */
|
||||
/*#define SDRAM_CONFIG1 0xD7322800 */ /* SDRAM controller bug workaround */
|
||||
#define SDRAM_CONFIG2 0x8AD70000
|
||||
/*#define SDRAM_CONFIG2 0xDDD70000 */ /* SDRAM controller bug workaround */
|
||||
|
|
@ -0,0 +1,905 @@
|
|||
/*
|
||||
* (C) Copyright 2003-2006
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* (C) Copyright 2004
|
||||
* Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
|
||||
*
|
||||
* (C) Copyright 2004-2006
|
||||
* Martin Krause, TQ-Systems GmbH, martin.krause@tqs.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>
|
||||
#include <asm/processor.h>
|
||||
#include <libfdt.h>
|
||||
#include <netdev.h>
|
||||
|
||||
#ifdef CONFIG_VIDEO_SM501
|
||||
#include <sm501.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MPC5200_DDR)
|
||||
#include "mt46v16m16-75.h"
|
||||
#else
|
||||
#include "mt48lc16m16a2-75.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF_LIBFDT
|
||||
#include <fdt_support.h>
|
||||
#endif /* CONFIG_OF_LIBFDT */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifdef CONFIG_PS2MULT
|
||||
void ps2mult_early_init(void);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) && \
|
||||
defined(CONFIG_VIDEO)
|
||||
/*
|
||||
* EDID block has been generated using Phoenix EDID Designer 1.3.
|
||||
* This tool creates a text file containing:
|
||||
*
|
||||
* EDID BYTES:
|
||||
*
|
||||
* 0x 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
||||
* ------------------------------------------------
|
||||
* 00 | 00 FF FF FF FF FF FF 00 04 21 00 00 00 00 00 00
|
||||
* 10 | 01 00 01 03 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
* 20 | 00 00 00 21 00 00 01 01 01 01 01 01 01 01 01 01
|
||||
* 30 | 01 01 01 01 01 01 64 00 00 00 00 00 00 00 00 00
|
||||
* 40 | 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00
|
||||
* 50 | 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00
|
||||
* 60 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10
|
||||
* 70 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17
|
||||
*
|
||||
* Then this data has been manually converted to the char
|
||||
* array below.
|
||||
*/
|
||||
static unsigned char edid_buf[128] = {
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_RAMBOOT
|
||||
static void sdram_start (int hi_addr)
|
||||
{
|
||||
long hi_addr_bit = hi_addr ? 0x01000000 : 0;
|
||||
|
||||
/* unlock mode register */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 |
|
||||
hi_addr_bit;
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
/* precharge all banks */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
|
||||
hi_addr_bit;
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
#if SDRAM_DDR
|
||||
/* set mode register: extended mode */
|
||||
*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_EMODE;
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
/* set mode register: reset DLL */
|
||||
*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE | 0x04000000;
|
||||
__asm__ volatile ("sync");
|
||||
#endif
|
||||
|
||||
/* precharge all banks */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 |
|
||||
hi_addr_bit;
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
/* auto refresh */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000004 |
|
||||
hi_addr_bit;
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
/* set mode register */
|
||||
*(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE;
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
/* normal operation */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit;
|
||||
__asm__ volatile ("sync");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ATTENTION: Although partially referenced initdram does NOT make real use
|
||||
* use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
|
||||
* is something else than 0x00000000.
|
||||
*/
|
||||
|
||||
phys_size_t initdram (int board_type)
|
||||
{
|
||||
ulong dramsize = 0;
|
||||
ulong dramsize2 = 0;
|
||||
uint svr, pvr;
|
||||
|
||||
#ifndef CONFIG_SYS_RAMBOOT
|
||||
ulong test1, test2;
|
||||
|
||||
/* setup SDRAM chip selects */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001c; /* 512MB at 0x0 */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x40000000; /* disabled */
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
/* setup config registers */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CONFIG1 = SDRAM_CONFIG1;
|
||||
*(vu_long *)MPC5XXX_SDRAM_CONFIG2 = SDRAM_CONFIG2;
|
||||
__asm__ volatile ("sync");
|
||||
|
||||
#if SDRAM_DDR
|
||||
/* set tap delay */
|
||||
*(vu_long *)MPC5XXX_CDM_PORCFG = SDRAM_TAPDELAY;
|
||||
__asm__ volatile ("sync");
|
||||
#endif
|
||||
|
||||
/* find RAM size using SDRAM CS0 only */
|
||||
sdram_start(0);
|
||||
test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
|
||||
sdram_start(1);
|
||||
test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
|
||||
if (test1 > test2) {
|
||||
sdram_start(0);
|
||||
dramsize = test1;
|
||||
} else {
|
||||
dramsize = test2;
|
||||
}
|
||||
|
||||
/* memory smaller than 1MB is impossible */
|
||||
if (dramsize < (1 << 20)) {
|
||||
dramsize = 0;
|
||||
}
|
||||
|
||||
/* set SDRAM CS0 size according to the amount of RAM found */
|
||||
if (dramsize > 0) {
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 +
|
||||
__builtin_ffs(dramsize >> 20) - 1;
|
||||
} else {
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */
|
||||
}
|
||||
|
||||
/* let SDRAM CS1 start right after CS0 */
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001c; /* 512MB */
|
||||
|
||||
/* find RAM size using SDRAM CS1 only */
|
||||
if (!dramsize)
|
||||
sdram_start(0);
|
||||
test2 = test1 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
|
||||
if (!dramsize) {
|
||||
sdram_start(1);
|
||||
test2 = get_ram_size((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
|
||||
}
|
||||
if (test1 > test2) {
|
||||
sdram_start(0);
|
||||
dramsize2 = test1;
|
||||
} else {
|
||||
dramsize2 = test2;
|
||||
}
|
||||
|
||||
/* memory smaller than 1MB is impossible */
|
||||
if (dramsize2 < (1 << 20)) {
|
||||
dramsize2 = 0;
|
||||
}
|
||||
|
||||
/* set SDRAM CS1 size according to the amount of RAM found */
|
||||
if (dramsize2 > 0) {
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize
|
||||
| (0x13 + __builtin_ffs(dramsize2 >> 20) - 1);
|
||||
} else {
|
||||
*(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize; /* disabled */
|
||||
}
|
||||
|
||||
#else /* CONFIG_SYS_RAMBOOT */
|
||||
|
||||
/* retrieve size of memory connected to SDRAM CS0 */
|
||||
dramsize = *(vu_long *)MPC5XXX_SDRAM_CS0CFG & 0xFF;
|
||||
if (dramsize >= 0x13) {
|
||||
dramsize = (1 << (dramsize - 0x13)) << 20;
|
||||
} else {
|
||||
dramsize = 0;
|
||||
}
|
||||
|
||||
/* retrieve size of memory connected to SDRAM CS1 */
|
||||
dramsize2 = *(vu_long *)MPC5XXX_SDRAM_CS1CFG & 0xFF;
|
||||
if (dramsize2 >= 0x13) {
|
||||
dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
|
||||
} else {
|
||||
dramsize2 = 0;
|
||||
}
|
||||
#endif /* CONFIG_SYS_RAMBOOT */
|
||||
|
||||
/*
|
||||
* On MPC5200B we need to set the special configuration delay in the
|
||||
* DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
|
||||
* Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
|
||||
*
|
||||
* "The SDelay should be written to a value of 0x00000004. It is
|
||||
* required to account for changes caused by normal wafer processing
|
||||
* parameters."
|
||||
*/
|
||||
svr = get_svr();
|
||||
pvr = get_pvr();
|
||||
if ((SVR_MJREV(svr) >= 2) &&
|
||||
(PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
|
||||
|
||||
*(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
|
||||
__asm__ volatile ("sync");
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TQM5200_B)
|
||||
return dramsize + dramsize2;
|
||||
#else
|
||||
return dramsize;
|
||||
#endif /* CONFIG_TQM5200_B */
|
||||
}
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
#if defined(CONFIG_AEVFIFO)
|
||||
puts ("Board: AEVFIFO\n");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TQM5200S)
|
||||
# define MODULE_NAME "TQM5200S"
|
||||
#else
|
||||
# define MODULE_NAME "TQM5200"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STK52XX)
|
||||
# define CARRIER_NAME "STK52xx"
|
||||
#elif defined(CONFIG_TB5200)
|
||||
# define CARRIER_NAME "TB5200"
|
||||
#elif defined(CONFIG_CAM5200)
|
||||
# define CARRIER_NAME "CAM5200"
|
||||
#elif defined(CONFIG_FO300)
|
||||
# define CARRIER_NAME "FO300"
|
||||
#elif defined(CONFIG_CHARON)
|
||||
# define CARRIER_NAME "CHARON"
|
||||
#else
|
||||
# error "UNKNOWN"
|
||||
#endif
|
||||
|
||||
puts ( "Board: " MODULE_NAME " (TQ-Components GmbH)\n"
|
||||
" on a " CARRIER_NAME " carrier board\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef MODULE_NAME
|
||||
#undef CARRIER_NAME
|
||||
|
||||
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.
|
||||
*/
|
||||
*(vu_long *)MPC5XXX_BOOTCS_CFG &= ~0x1; /* clear RO */
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_RESET)
|
||||
|
||||
#if defined (CONFIG_MINIFAP)
|
||||
#define SM501_POWER_MODE0_GATE 0x00000040UL
|
||||
#define SM501_POWER_MODE1_GATE 0x00000048UL
|
||||
#define POWER_MODE_GATE_GPIO_PWM_I2C 0x00000040UL
|
||||
#define SM501_GPIO_DATA_DIR_HIGH 0x0001000CUL
|
||||
#define SM501_GPIO_DATA_HIGH 0x00010004UL
|
||||
#define SM501_GPIO_51 0x00080000UL
|
||||
#endif /* CONFIG MINIFAP */
|
||||
|
||||
void init_ide_reset (void)
|
||||
{
|
||||
debug ("init_ide_reset\n");
|
||||
|
||||
#if defined (CONFIG_MINIFAP)
|
||||
/* Configure GPIO_51 of the SM501 grafic controller as ATA reset */
|
||||
|
||||
/* enable GPIO control (in both power modes) */
|
||||
*(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE0_GATE) |=
|
||||
POWER_MODE_GATE_GPIO_PWM_I2C;
|
||||
*(vu_long *) (SM501_MMIO_BASE+SM501_POWER_MODE1_GATE) |=
|
||||
POWER_MODE_GATE_GPIO_PWM_I2C;
|
||||
/* configure GPIO51 as output */
|
||||
*(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_DIR_HIGH) |=
|
||||
SM501_GPIO_51;
|
||||
#else
|
||||
/* Configure PSC1_4 as GPIO output for ATA reset */
|
||||
*(vu_long *) MPC5XXX_WU_GPIO_ENABLE |= GPIO_PSC1_4;
|
||||
*(vu_long *) MPC5XXX_WU_GPIO_DIR |= GPIO_PSC1_4;
|
||||
|
||||
/* by default the ATA reset is de-asserted */
|
||||
*(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ide_set_reset (int idereset)
|
||||
{
|
||||
debug ("ide_reset(%d)\n", idereset);
|
||||
|
||||
#if defined (CONFIG_MINIFAP)
|
||||
if (idereset) {
|
||||
*(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) &=
|
||||
~SM501_GPIO_51;
|
||||
} else {
|
||||
*(vu_long *) (SM501_MMIO_BASE+SM501_GPIO_DATA_HIGH) |=
|
||||
SM501_GPIO_51;
|
||||
}
|
||||
#else
|
||||
if (idereset) {
|
||||
*(vu_long *) MPC5XXX_WU_GPIO_DATA_O &= ~GPIO_PSC1_4;
|
||||
} else {
|
||||
*(vu_long *) MPC5XXX_WU_GPIO_DATA_O |= GPIO_PSC1_4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_POST
|
||||
/*
|
||||
* Reads GPIO pin PSC6_3. A keypress is reported, if PSC6_3 is low. If PSC6_3
|
||||
* is left open, no keypress is detected.
|
||||
*/
|
||||
int post_hotkeys_pressed(void)
|
||||
{
|
||||
#ifdef CONFIG_STK52XX
|
||||
struct mpc5xxx_gpio *gpio;
|
||||
|
||||
gpio = (struct mpc5xxx_gpio*) MPC5XXX_GPIO;
|
||||
|
||||
/*
|
||||
* Configure PSC6_0 through PSC6_3 as GPIO.
|
||||
*/
|
||||
gpio->port_config &= ~(0x00700000);
|
||||
|
||||
/* Enable GPIO for GPIO_IRDA_1 (IR_USB_CLK pin) = PSC6_3 */
|
||||
gpio->simple_gpioe |= 0x20000000;
|
||||
|
||||
/* Configure GPIO_IRDA_1 as input */
|
||||
gpio->simple_ddr &= ~(0x20000000);
|
||||
|
||||
return ((gpio->simple_ival & 0x20000000) ? 0 : 1);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOARD_EARLY_INIT_R
|
||||
int board_early_init_r (void)
|
||||
{
|
||||
|
||||
extern int usb_cpu_init(void);
|
||||
|
||||
#ifdef CONFIG_PS2MULT
|
||||
ps2mult_early_init();
|
||||
#endif /* CONFIG_PS2MULT */
|
||||
|
||||
#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
|
||||
/* Low level USB init, required for proper kernel operation */
|
||||
usb_cpu_init();
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FO300
|
||||
int silent_boot (void)
|
||||
{
|
||||
vu_long timer3_status;
|
||||
|
||||
/* Configure GPT3 as GPIO input */
|
||||
*(vu_long *)MPC5XXX_GPT3_ENABLE = 0x00000004;
|
||||
|
||||
/* Read in TIMER_3 pin status */
|
||||
timer3_status = *(vu_long *)MPC5XXX_GPT3_STATUS;
|
||||
|
||||
#ifdef FO300_SILENT_CONSOLE_WHEN_S1_CLOSED
|
||||
/* Force silent console mode if S1 switch
|
||||
* is in closed position (TIMER_3 pin status is LOW). */
|
||||
if (MPC5XXX_GPT_GPIO_PIN(timer3_status) == 0)
|
||||
return 1;
|
||||
#else
|
||||
/* Force silent console mode if S1 switch
|
||||
* is in open position (TIMER_3 pin status is HIGH). */
|
||||
if (MPC5XXX_GPT_GPIO_PIN(timer3_status) == 1)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_f (void)
|
||||
{
|
||||
if (silent_boot())
|
||||
gd->flags |= GD_FLG_SILENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_FO300 */
|
||||
|
||||
#if defined(CONFIG_CHARON)
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* The TFP410 registers */
|
||||
#define TFP410_REG_VEN_ID_L 0x00
|
||||
#define TFP410_REG_VEN_ID_H 0x01
|
||||
#define TFP410_REG_DEV_ID_L 0x02
|
||||
#define TFP410_REG_DEV_ID_H 0x03
|
||||
#define TFP410_REG_REV_ID 0x04
|
||||
|
||||
#define TFP410_REG_CTL_1_MODE 0x08
|
||||
#define TFP410_REG_CTL_2_MODE 0x09
|
||||
#define TFP410_REG_CTL_3_MODE 0x0A
|
||||
|
||||
#define TFP410_REG_CFG 0x0B
|
||||
|
||||
#define TFP410_REG_DE_DLY 0x32
|
||||
#define TFP410_REG_DE_CTL 0x33
|
||||
#define TFP410_REG_DE_TOP 0x34
|
||||
#define TFP410_REG_DE_CNT_L 0x36
|
||||
#define TFP410_REG_DE_CNT_H 0x37
|
||||
#define TFP410_REG_DE_LIN_L 0x38
|
||||
#define TFP410_REG_DE_LIN_H 0x39
|
||||
|
||||
#define TFP410_REG_H_RES_L 0x3A
|
||||
#define TFP410_REG_H_RES_H 0x3B
|
||||
#define TFP410_REG_V_RES_L 0x3C
|
||||
#define TFP410_REG_V_RES_H 0x3D
|
||||
|
||||
static int tfp410_read_reg(int reg, uchar *buf)
|
||||
{
|
||||
if (i2c_read(CONFIG_SYS_TFP410_ADDR, reg, 1, buf, 1) != 0) {
|
||||
puts ("Error reading the chip.\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tfp410_write_reg(int reg, uchar buf)
|
||||
{
|
||||
if (i2c_write(CONFIG_SYS_TFP410_ADDR, reg, 1, &buf, 1) != 0) {
|
||||
puts ("Error writing the chip.\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _tfp410_config {
|
||||
int reg;
|
||||
uchar val;
|
||||
}TFP410_CONFIG;
|
||||
|
||||
static TFP410_CONFIG tfp410_configtbl[] = {
|
||||
{TFP410_REG_CTL_1_MODE, 0x37},
|
||||
{TFP410_REG_CTL_2_MODE, 0x20},
|
||||
{TFP410_REG_CTL_3_MODE, 0x80},
|
||||
{TFP410_REG_DE_DLY, 0x90},
|
||||
{TFP410_REG_DE_CTL, 0x00},
|
||||
{TFP410_REG_DE_TOP, 0x23},
|
||||
{TFP410_REG_DE_CNT_H, 0x02},
|
||||
{TFP410_REG_DE_CNT_L, 0x80},
|
||||
{TFP410_REG_DE_LIN_H, 0x01},
|
||||
{TFP410_REG_DE_LIN_L, 0xe0},
|
||||
{-1, 0},
|
||||
};
|
||||
|
||||
static int charon_last_stage_init(void)
|
||||
{
|
||||
volatile struct mpc5xxx_lpb *lpb =
|
||||
(struct mpc5xxx_lpb *) MPC5XXX_LPB;
|
||||
int oldbus = i2c_get_bus_num();
|
||||
uchar buf;
|
||||
int i = 0;
|
||||
|
||||
i2c_set_bus_num(CONFIG_SYS_TFP410_BUS);
|
||||
|
||||
/* check version */
|
||||
if (tfp410_read_reg(TFP410_REG_DEV_ID_H, &buf) != 0)
|
||||
return -1;
|
||||
if (!(buf & 0x04))
|
||||
return -1;
|
||||
if (tfp410_read_reg(TFP410_REG_DEV_ID_L, &buf) != 0)
|
||||
return -1;
|
||||
if (!(buf & 0x10))
|
||||
return -1;
|
||||
/* OK, now init the chip */
|
||||
while (tfp410_configtbl[i].reg != -1) {
|
||||
int ret;
|
||||
|
||||
ret = tfp410_write_reg(tfp410_configtbl[i].reg,
|
||||
tfp410_configtbl[i].val);
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
i++;
|
||||
}
|
||||
printf("TFP410 initialized.\n");
|
||||
i2c_set_bus_num(oldbus);
|
||||
|
||||
/* set deadcycle for cs3 to 0 */
|
||||
setbits_be32(&lpb->cs_deadcycle, 0xffffcfff);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int last_stage_init (void)
|
||||
{
|
||||
/*
|
||||
* auto scan for really existing devices and re-set chip select
|
||||
* configuration.
|
||||
*/
|
||||
u16 save, tmp;
|
||||
int restore;
|
||||
|
||||
/*
|
||||
* Check for SRAM and SRAM size
|
||||
*/
|
||||
|
||||
/* save original SRAM content */
|
||||
save = *(volatile u16 *)CONFIG_SYS_CS2_START;
|
||||
restore = 1;
|
||||
|
||||
/* write test pattern to SRAM */
|
||||
*(volatile u16 *)CONFIG_SYS_CS2_START = 0xA5A5;
|
||||
__asm__ volatile ("sync");
|
||||
/*
|
||||
* Put a different pattern on the data lines: otherwise they may float
|
||||
* long enough to read back what we wrote.
|
||||
*/
|
||||
tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE;
|
||||
if (tmp == 0xA5A5)
|
||||
puts ("!! possible error in SRAM detection\n");
|
||||
|
||||
if (*(volatile u16 *)CONFIG_SYS_CS2_START != 0xA5A5) {
|
||||
/* no SRAM at all, disable cs */
|
||||
*(vu_long *)MPC5XXX_ADDECR &= ~(1 << 18);
|
||||
*(vu_long *)MPC5XXX_CS2_START = 0x0000FFFF;
|
||||
*(vu_long *)MPC5XXX_CS2_STOP = 0x0000FFFF;
|
||||
restore = 0;
|
||||
__asm__ volatile ("sync");
|
||||
} else if (*(volatile u16 *)(CONFIG_SYS_CS2_START + (1<<19)) == 0xA5A5) {
|
||||
/* make sure that we access a mirrored address */
|
||||
*(volatile u16 *)CONFIG_SYS_CS2_START = 0x1111;
|
||||
__asm__ volatile ("sync");
|
||||
if (*(volatile u16 *)(CONFIG_SYS_CS2_START + (1<<19)) == 0x1111) {
|
||||
/* SRAM size = 512 kByte */
|
||||
*(vu_long *)MPC5XXX_CS2_STOP = STOP_REG(CONFIG_SYS_CS2_START,
|
||||
0x80000);
|
||||
__asm__ volatile ("sync");
|
||||
puts ("SRAM: 512 kB\n");
|
||||
}
|
||||
else
|
||||
puts ("!! possible error in SRAM detection\n");
|
||||
} else {
|
||||
puts ("SRAM: 1 MB\n");
|
||||
}
|
||||
/* restore origianl SRAM content */
|
||||
if (restore) {
|
||||
*(volatile u16 *)CONFIG_SYS_CS2_START = save;
|
||||
__asm__ volatile ("sync");
|
||||
}
|
||||
|
||||
#ifndef CONFIG_TQM5200S /* The TQM5200S has no SM501 grafic controller */
|
||||
/*
|
||||
* Check for Grafic Controller
|
||||
*/
|
||||
|
||||
/* save origianl FB content */
|
||||
save = *(volatile u16 *)CONFIG_SYS_CS1_START;
|
||||
restore = 1;
|
||||
|
||||
/* write test pattern to FB memory */
|
||||
*(volatile u16 *)CONFIG_SYS_CS1_START = 0xA5A5;
|
||||
__asm__ volatile ("sync");
|
||||
/*
|
||||
* Put a different pattern on the data lines: otherwise they may float
|
||||
* long enough to read back what we wrote.
|
||||
*/
|
||||
tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE;
|
||||
if (tmp == 0xA5A5)
|
||||
puts ("!! possible error in grafic controller detection\n");
|
||||
|
||||
if (*(volatile u16 *)CONFIG_SYS_CS1_START != 0xA5A5) {
|
||||
/* no grafic controller at all, disable cs */
|
||||
*(vu_long *)MPC5XXX_ADDECR &= ~(1 << 17);
|
||||
*(vu_long *)MPC5XXX_CS1_START = 0x0000FFFF;
|
||||
*(vu_long *)MPC5XXX_CS1_STOP = 0x0000FFFF;
|
||||
restore = 0;
|
||||
__asm__ volatile ("sync");
|
||||
} else {
|
||||
puts ("VGA: SMI501 (Voyager) with 8 MB\n");
|
||||
}
|
||||
/* restore origianl FB content */
|
||||
if (restore) {
|
||||
*(volatile u16 *)CONFIG_SYS_CS1_START = save;
|
||||
__asm__ volatile ("sync");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FO300
|
||||
if (silent_boot()) {
|
||||
setenv("bootdelay", "0");
|
||||
disable_ctrlc(1);
|
||||
}
|
||||
#endif
|
||||
#endif /* !CONFIG_TQM5200S */
|
||||
|
||||
#if defined(CONFIG_CHARON)
|
||||
charon_last_stage_init();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_SM501
|
||||
|
||||
#ifdef CONFIG_FO300
|
||||
#define DISPLAY_WIDTH 800
|
||||
#else
|
||||
#define DISPLAY_WIDTH 640
|
||||
#endif
|
||||
#define DISPLAY_HEIGHT 480
|
||||
|
||||
#ifdef CONFIG_VIDEO_SM501_8BPP
|
||||
#error CONFIG_VIDEO_SM501_8BPP not supported.
|
||||
#endif /* CONFIG_VIDEO_SM501_8BPP */
|
||||
|
||||
#ifdef CONFIG_VIDEO_SM501_16BPP
|
||||
#error CONFIG_VIDEO_SM501_16BPP not supported.
|
||||
#endif /* CONFIG_VIDEO_SM501_16BPP */
|
||||
#ifdef CONFIG_VIDEO_SM501_32BPP
|
||||
static const SMI_REGS init_regs [] =
|
||||
{
|
||||
#if 0 /* CRT only */
|
||||
{0x00004, 0x0},
|
||||
{0x00048, 0x00021807},
|
||||
{0x0004C, 0x10090a01},
|
||||
{0x00054, 0x1},
|
||||
{0x00040, 0x00021807},
|
||||
{0x00044, 0x10090a01},
|
||||
{0x00054, 0x0},
|
||||
{0x80200, 0x00010000},
|
||||
{0x80204, 0x0},
|
||||
{0x80208, 0x0A000A00},
|
||||
{0x8020C, 0x02fa027f},
|
||||
{0x80210, 0x004a028b},
|
||||
{0x80214, 0x020c01df},
|
||||
{0x80218, 0x000201e9},
|
||||
{0x80200, 0x00013306},
|
||||
#else /* panel + CRT */
|
||||
#ifdef CONFIG_FO300
|
||||
{0x00004, 0x0},
|
||||
{0x00048, 0x00021807},
|
||||
{0x0004C, 0x301a0a01},
|
||||
{0x00054, 0x1},
|
||||
{0x00040, 0x00021807},
|
||||
{0x00044, 0x091a0a01},
|
||||
{0x00054, 0x0},
|
||||
{0x80000, 0x0f013106},
|
||||
{0x80004, 0xc428bb17},
|
||||
{0x8000C, 0x00000000},
|
||||
{0x80010, 0x0C800C80},
|
||||
{0x80014, 0x03200000},
|
||||
{0x80018, 0x01e00000},
|
||||
{0x8001C, 0x00000000},
|
||||
{0x80020, 0x01e00320},
|
||||
{0x80024, 0x042a031f},
|
||||
{0x80028, 0x0086034a},
|
||||
{0x8002C, 0x020c01df},
|
||||
{0x80030, 0x000201ea},
|
||||
{0x80200, 0x00010000},
|
||||
#else
|
||||
{0x00004, 0x0},
|
||||
{0x00048, 0x00021807},
|
||||
{0x0004C, 0x091a0a01},
|
||||
{0x00054, 0x1},
|
||||
{0x00040, 0x00021807},
|
||||
{0x00044, 0x091a0a01},
|
||||
{0x00054, 0x0},
|
||||
{0x80000, 0x0f013106},
|
||||
{0x80004, 0xc428bb17},
|
||||
{0x8000C, 0x00000000},
|
||||
{0x80010, 0x0a000a00},
|
||||
{0x80014, 0x02800000},
|
||||
{0x80018, 0x01e00000},
|
||||
{0x8001C, 0x00000000},
|
||||
{0x80020, 0x01e00280},
|
||||
{0x80024, 0x02fa027f},
|
||||
{0x80028, 0x004a028b},
|
||||
{0x8002C, 0x020c01df},
|
||||
{0x80030, 0x000201e9},
|
||||
{0x80200, 0x00010000},
|
||||
#endif /* #ifdef CONFIG_FO300 */
|
||||
#endif
|
||||
{0, 0}
|
||||
};
|
||||
#endif /* CONFIG_VIDEO_SM501_32BPP */
|
||||
|
||||
#ifdef CONFIG_CONSOLE_EXTRA_INFO
|
||||
/*
|
||||
* Return text to be printed besides the logo.
|
||||
*/
|
||||
void video_get_info_str (int line_number, char *info)
|
||||
{
|
||||
if (line_number == 1) {
|
||||
strcpy (info, " Board: TQM5200 (TQ-Components GmbH)");
|
||||
#if defined (CONFIG_CHARON) || defined (CONFIG_FO300) || \
|
||||
defined(CONFIG_STK52XX) || defined(CONFIG_TB5200)
|
||||
} else if (line_number == 2) {
|
||||
#if defined (CONFIG_CHARON)
|
||||
strcpy (info, " on a CHARON carrier board");
|
||||
#endif
|
||||
#if defined (CONFIG_STK52XX)
|
||||
strcpy (info, " on a STK52xx carrier board");
|
||||
#endif
|
||||
#if defined (CONFIG_TB5200)
|
||||
strcpy (info, " on a TB5200 carrier board");
|
||||
#endif
|
||||
#if defined (CONFIG_FO300)
|
||||
strcpy (info, " on a FO300 carrier board");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
info [0] = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns SM501 register base address. First thing called in the
|
||||
* driver. Checks if SM501 is physically present.
|
||||
*/
|
||||
unsigned int board_video_init (void)
|
||||
{
|
||||
u16 save, tmp;
|
||||
int restore, ret;
|
||||
|
||||
/*
|
||||
* Check for Grafic Controller
|
||||
*/
|
||||
|
||||
/* save origianl FB content */
|
||||
save = *(volatile u16 *)CONFIG_SYS_CS1_START;
|
||||
restore = 1;
|
||||
|
||||
/* write test pattern to FB memory */
|
||||
*(volatile u16 *)CONFIG_SYS_CS1_START = 0xA5A5;
|
||||
__asm__ volatile ("sync");
|
||||
/*
|
||||
* Put a different pattern on the data lines: otherwise they may float
|
||||
* long enough to read back what we wrote.
|
||||
*/
|
||||
tmp = *(volatile u16 *)CONFIG_SYS_FLASH_BASE;
|
||||
if (tmp == 0xA5A5)
|
||||
puts ("!! possible error in grafic controller detection\n");
|
||||
|
||||
if (*(volatile u16 *)CONFIG_SYS_CS1_START != 0xA5A5) {
|
||||
/* no grafic controller found */
|
||||
restore = 0;
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = SM501_MMIO_BASE;
|
||||
}
|
||||
|
||||
if (restore) {
|
||||
*(volatile u16 *)CONFIG_SYS_CS1_START = save;
|
||||
__asm__ volatile ("sync");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns SM501 framebuffer address
|
||||
*/
|
||||
unsigned int board_video_get_fb (void)
|
||||
{
|
||||
return SM501_FB_BASE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after initializing the SM501 and before clearing the screen.
|
||||
*/
|
||||
void board_validate_screen (unsigned int base)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to the initialization sequence.
|
||||
*/
|
||||
const SMI_REGS *board_get_regs (void)
|
||||
{
|
||||
return init_regs;
|
||||
}
|
||||
|
||||
int board_get_width (void)
|
||||
{
|
||||
return DISPLAY_WIDTH;
|
||||
}
|
||||
|
||||
int board_get_height (void)
|
||||
{
|
||||
return DISPLAY_HEIGHT;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_VIDEO_SM501 */
|
||||
|
||||
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
|
||||
void ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
ft_cpu_setup(blob, bd);
|
||||
#if defined(CONFIG_VIDEO)
|
||||
fdt_add_edid(blob, "smi,sm501", edid_buf);
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */
|
||||
|
||||
#if defined(CONFIG_RESET_PHY_R)
|
||||
#include <miiphy.h>
|
||||
|
||||
void reset_phy(void)
|
||||
{
|
||||
/* init Micrel KSZ8993 PHY */
|
||||
miiphy_write("FEC", CONFIG_PHY_ADDR, 0x01, 0x09);
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
cpu_eth_init(bis); /* Built in FEC comes first */
|
||||
return pci_eth_init(bis);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#
|
||||
# (C) Copyright 2001-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
ifneq ($(OBJTREE),$(SRCTREE))
|
||||
$(shell mkdir -p $(obj)../tqm8xx/)
|
||||
endif
|
||||
|
||||
LIB = $(obj)lib$(BOARD).o
|
||||
|
||||
COBJS = $(BOARD).o ../tqm8xx/load_sernum_ethaddr.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* (C) Copyright 2001
|
||||
* 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>
|
||||
|
||||
/*
|
||||
* 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 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 *ATMTXEN */
|
||||
/* PA30 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTCA */
|
||||
/* PA29 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTSOC */
|
||||
/* PA28 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 *ATMRXEN */
|
||||
/* PA27 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRSOC */
|
||||
/* PA26 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRCA */
|
||||
/* PA25 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
|
||||
/* PA24 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
|
||||
/* PA23 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
|
||||
/* PA22 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
|
||||
/* PA21 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
|
||||
/* PA20 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
|
||||
/* PA19 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
|
||||
/* PA18 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
|
||||
/* PA17 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[7] */
|
||||
/* PA16 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[6] */
|
||||
/* PA15 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[5] */
|
||||
/* PA14 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[4] */
|
||||
/* PA13 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[3] */
|
||||
/* PA12 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[2] */
|
||||
/* PA11 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[1] */
|
||||
/* PA10 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[0] */
|
||||
/* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
|
||||
/* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */
|
||||
/* 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 MII TX_ER */
|
||||
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
|
||||
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
|
||||
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
|
||||
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
|
||||
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
|
||||
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
|
||||
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
|
||||
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
|
||||
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
|
||||
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
|
||||
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
|
||||
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
|
||||
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
|
||||
/* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
|
||||
/* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* PB16 */
|
||||
/* PB15 */ { 0, 0, 0, 0, 0, 0 }, /* PB15 */
|
||||
/* PB14 */ { 0, 0, 0, 0, 0, 0 }, /* PB14 */
|
||||
/* 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 */ { 0, 0, 0, 0, 0, 0 }, /* PB8 */
|
||||
/* 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 */ { 1, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
|
||||
/* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
|
||||
/* 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 }, /* ATMTFCLK */
|
||||
/* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
|
||||
/* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
|
||||
/* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
|
||||
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */
|
||||
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */
|
||||
/* PC17 */ { 0, 0, 0, 1, 0, 0 }, /* PC17 */
|
||||
/* PC16 */ { 0, 0, 0, 1, 0, 0 }, /* PC16 */
|
||||
/* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */
|
||||
/* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
|
||||
/* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
|
||||
/* PC12 */ { 0, 0, 0, 1, 0, 0 }, /* PC12 */
|
||||
/* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* PC11 */
|
||||
/* PC10 */ { 0, 0, 0, 1, 0, 0 }, /* FCC2 MDC */
|
||||
/* PC9 */ { 0, 0, 0, 1, 0, 0 }, /* FCC2 MDIO */
|
||||
/* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
|
||||
/* 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 }, /* ENET FDE */
|
||||
/* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */
|
||||
/* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */
|
||||
},
|
||||
|
||||
/* Port D */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */
|
||||
/* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */
|
||||
/* PD29 */ { 1, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
|
||||
/* PD28 */ { 0, 0, 0, 1, 0, 0 }, /* PD28 */
|
||||
/* PD27 */ { 0, 0, 0, 1, 0, 0 }, /* PD27 */
|
||||
/* 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 }, /* PD23 */
|
||||
/* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */
|
||||
/* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */
|
||||
/* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */
|
||||
/* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
|
||||
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
|
||||
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
|
||||
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
|
||||
#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 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
|
||||
/* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
|
||||
/* 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 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */
|
||||
/* 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)
|
||||
{
|
||||
char buf[64];
|
||||
int i = getenv_f("serial#", buf, sizeof(buf));
|
||||
|
||||
puts ("Board: ");
|
||||
|
||||
if (i < 0 || strncmp(buf, "TQM82", 5)) {
|
||||
puts ("### No HW ID - assuming TQM8260\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
puts (buf);
|
||||
putc ('\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 uint *sdmr_ptr;
|
||||
volatile uint *orx_ptr;
|
||||
ulong maxsize, size;
|
||||
int i;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Since CONFIG_SYS_SDRAM_BASE is always 0 (??), we assume that
|
||||
* we are configuring CS1 if base != 0
|
||||
*/
|
||||
sdmr_ptr = base ? &memctl->memc_lsdmr : &memctl->memc_psdmr;
|
||||
orx_ptr = base ? &memctl->memc_or2 : &memctl->memc_or1;
|
||||
|
||||
*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 CONFIG_SYS_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 + CONFIG_SYS_MRS_OFFS) = c; /* setting MR on address lines */
|
||||
|
||||
*sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
|
||||
*base = c;
|
||||
|
||||
size = get_ram_size((long *)base, maxsize);
|
||||
*orx_ptr = orx | ~(size - 1);
|
||||
|
||||
return (size);
|
||||
}
|
||||
|
||||
phys_size_t initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
|
||||
#ifndef CONFIG_SYS_RAMBOOT
|
||||
long size8, size9;
|
||||
#endif
|
||||
long psize, lsize;
|
||||
|
||||
psize = 16 * 1024 * 1024;
|
||||
lsize = 0;
|
||||
|
||||
memctl->memc_psrt = CONFIG_SYS_PSRT;
|
||||
memctl->memc_mptpr = CONFIG_SYS_MPTPR;
|
||||
|
||||
#if 0 /* Just for debugging */
|
||||
#define prt_br_or(brX,orX) do { \
|
||||
ulong start = memctl->memc_ ## brX & 0xFFFF8000; \
|
||||
ulong sizem = ~memctl->memc_ ## orX | 0x00007FFF; \
|
||||
printf ("\n" \
|
||||
#brX " 0x%08x " #orX " 0x%08x " \
|
||||
"==> 0x%08lx ... 0x%08lx = %ld MB\n", \
|
||||
memctl->memc_ ## brX, memctl->memc_ ## orX, \
|
||||
start, start+sizem, (sizem+1)>>20); \
|
||||
} while (0)
|
||||
prt_br_or (br0, or0);
|
||||
prt_br_or (br1, or1);
|
||||
prt_br_or (br2, or2);
|
||||
prt_br_or (br3, or3);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_RAMBOOT
|
||||
/* 60x SDRAM setup:
|
||||
*/
|
||||
size8 = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
|
||||
(uchar *) CONFIG_SYS_SDRAM_BASE);
|
||||
size9 = try_init (memctl, CONFIG_SYS_PSDMR_9COL, CONFIG_SYS_OR1_9COL,
|
||||
(uchar *) CONFIG_SYS_SDRAM_BASE);
|
||||
|
||||
if (size8 < size9) {
|
||||
psize = size9;
|
||||
printf ("(60x:9COL - %ld MB, ", psize >> 20);
|
||||
} else {
|
||||
psize = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
|
||||
(uchar *) CONFIG_SYS_SDRAM_BASE);
|
||||
printf ("(60x:8COL - %ld MB, ", psize >> 20);
|
||||
}
|
||||
|
||||
/* Local SDRAM setup:
|
||||
*/
|
||||
#ifdef CONFIG_SYS_INIT_LOCAL_SDRAM
|
||||
memctl->memc_lsrt = CONFIG_SYS_LSRT;
|
||||
size8 = try_init (memctl, CONFIG_SYS_LSDMR_8COL, CONFIG_SYS_OR2_8COL,
|
||||
(uchar *) SDRAM_BASE2_PRELIM);
|
||||
size9 = try_init (memctl, CONFIG_SYS_LSDMR_9COL, CONFIG_SYS_OR2_9COL,
|
||||
(uchar *) SDRAM_BASE2_PRELIM);
|
||||
|
||||
if (size8 < size9) {
|
||||
lsize = size9;
|
||||
printf ("Local:9COL - %ld MB) using ", lsize >> 20);
|
||||
} else {
|
||||
lsize = try_init (memctl, CONFIG_SYS_LSDMR_8COL, CONFIG_SYS_OR2_8COL,
|
||||
(uchar *) SDRAM_BASE2_PRELIM);
|
||||
printf ("Local:8COL - %ld MB) using ", lsize >> 20);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Set up BR2 so that the local SDRAM goes
|
||||
* right after the 60x SDRAM
|
||||
*/
|
||||
memctl->memc_br2 = (CONFIG_SYS_BR2_PRELIM & ~BRx_BA_MSK) |
|
||||
(CONFIG_SYS_SDRAM_BASE + psize);
|
||||
#endif
|
||||
#endif /* CONFIG_SYS_INIT_LOCAL_SDRAM */
|
||||
#endif /* CONFIG_SYS_RAMBOOT */
|
||||
|
||||
icache_enable ();
|
||||
|
||||
return (psize);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#
|
||||
# (C) Copyright 2001-2008
|
||||
# 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
|
||||
ifneq ($(OBJTREE),$(SRCTREE))
|
||||
$(shell mkdir -p $(obj)../tqm8xx/)
|
||||
endif
|
||||
|
||||
LIB = $(obj)lib$(BOARD).o
|
||||
|
||||
COBJS = $(BOARD).o ../tqm8xx/load_sernum_ethaddr.o nand.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* (C) Copyright 2008
|
||||
* Heiko Schocher, DENX Software Engineering, hs@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 "tqm8272.h"
|
||||
|
||||
/* UPM pattern for bus clock = 66.7 MHz */
|
||||
static const uint upmTable67[] =
|
||||
{
|
||||
/* Offset UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0fa3f100, 0x0fa3b000, 0x0fa33100, 0x0fa33000,
|
||||
/* 0x04 */ 0x0fa33000, 0x0fa33004, 0xfffffc01, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */
|
||||
/* 0x18 */ 0x00a3fc00, 0x00a3fc00, 0x00a3fc00, 0x00a3fc00,
|
||||
/* 0x1C */ 0x0fa3fc00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 100 MHz */
|
||||
static const uint upmTable100[] =
|
||||
{
|
||||
/* Offset UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0fa3f200, 0x0fa3b000, 0x0fa33300, 0x0fa33000,
|
||||
/* 0x04 */ 0x0fa33000, 0x0fa33004, 0xfffffc01, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */
|
||||
/* 0x18 */ 0x00a3ff00, 0x00a3fc00, 0x00a3fc00, 0x0fa3fc00,
|
||||
/* 0x1C */ 0x0fa3fc00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 133.3 MHz */
|
||||
static const uint upmTable133[] =
|
||||
{
|
||||
/* Offset UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0fa3f300, 0x0fa3b000, 0x0fa33300, 0x0fa33000,
|
||||
/* 0x04 */ 0x0fa33200, 0x0fa33004, 0xfffffc01, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */
|
||||
/* 0x18 */ 0x00a3ff00, 0x00a3fc00, 0x00a3fd00, 0x0fa3fc00,
|
||||
/* 0x1C */ 0x0fa3fd00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
static int chipsel = 0;
|
||||
|
||||
#if defined(CONFIG_CMD_NAND)
|
||||
|
||||
#include <nand.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
|
||||
static u8 hwctl = 0;
|
||||
|
||||
static void upmnand_write_byte(struct mtd_info *mtdinfo, u_char byte)
|
||||
{
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
ulong base = (ulong) (this->IO_ADDR_W + chipsel * CONFIG_SYS_NAND_CS_DIST);
|
||||
|
||||
if (hwctl & 0x1) {
|
||||
WRITE_NAND_UPM(byte, base, CONFIG_SYS_NAND_UPM_WRITE_CMD_OFS);
|
||||
} else if (hwctl & 0x2) {
|
||||
WRITE_NAND_UPM(byte, base, CONFIG_SYS_NAND_UPM_WRITE_ADDR_OFS);
|
||||
} else {
|
||||
WRITE_NAND(byte, base);
|
||||
}
|
||||
}
|
||||
|
||||
static void upmnand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
||||
{
|
||||
if (ctrl & NAND_CTRL_CHANGE) {
|
||||
if ( ctrl & NAND_CLE )
|
||||
hwctl |= 0x1;
|
||||
else
|
||||
hwctl &= ~0x1;
|
||||
if ( ctrl & NAND_ALE )
|
||||
hwctl |= 0x2;
|
||||
else
|
||||
hwctl &= ~0x2;
|
||||
}
|
||||
if (cmd != NAND_CMD_NONE)
|
||||
upmnand_write_byte (mtd, cmd);
|
||||
}
|
||||
|
||||
static u_char upmnand_read_byte(struct mtd_info *mtdinfo)
|
||||
{
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
ulong base = (ulong) (this->IO_ADDR_W + chipsel * CONFIG_SYS_NAND_CS_DIST);
|
||||
|
||||
return READ_NAND(base);
|
||||
}
|
||||
|
||||
static int tqm8272_dev_ready(struct mtd_info *mtdinfo)
|
||||
{
|
||||
/* constant delay (see also tR in the datasheet) */
|
||||
udelay(12); \
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_NAND_SPL
|
||||
static void tqm8272_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
|
||||
{
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CONFIG_SYS_NAND_CS_DIST);
|
||||
int i;
|
||||
|
||||
for (i = 0; i< len; i++)
|
||||
buf[i] = *base;
|
||||
}
|
||||
|
||||
static void tqm8272_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
|
||||
{
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CONFIG_SYS_NAND_CS_DIST);
|
||||
int i;
|
||||
|
||||
for (i = 0; i< len; i++)
|
||||
*base = buf[i];
|
||||
}
|
||||
|
||||
static int tqm8272_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
|
||||
{
|
||||
struct nand_chip *this = mtdinfo->priv;
|
||||
unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CONFIG_SYS_NAND_CS_DIST);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (buf[i] != *base)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* #ifndef CONFIG_NAND_SPL */
|
||||
|
||||
void board_nand_select_device(struct nand_chip *nand, int chip)
|
||||
{
|
||||
chipsel = chip;
|
||||
}
|
||||
|
||||
int board_nand_init(struct nand_chip *nand)
|
||||
{
|
||||
static int UpmInit = 0;
|
||||
volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||
volatile memctl8260_t *memctl = &immr->im_memctl;
|
||||
|
||||
if (hwinf.nand == 0) return -1;
|
||||
|
||||
/* Setup the UPM */
|
||||
if (UpmInit == 0) {
|
||||
switch (hwinf.busclk_real) {
|
||||
case 100000000:
|
||||
upmconfig (UPMB, (uint *) upmTable100,
|
||||
sizeof (upmTable100) / sizeof (uint));
|
||||
break;
|
||||
case 133333333:
|
||||
upmconfig (UPMB, (uint *) upmTable133,
|
||||
sizeof (upmTable133) / sizeof (uint));
|
||||
break;
|
||||
default:
|
||||
upmconfig (UPMB, (uint *) upmTable67,
|
||||
sizeof (upmTable67) / sizeof (uint));
|
||||
break;
|
||||
}
|
||||
UpmInit = 1;
|
||||
}
|
||||
|
||||
/* Setup the memctrl */
|
||||
memctl->memc_or3 = CONFIG_SYS_NAND_OR;
|
||||
memctl->memc_br3 = CONFIG_SYS_NAND_BR;
|
||||
memctl->memc_mbmr = (MxMR_OP_NORM);
|
||||
|
||||
nand->ecc.mode = NAND_ECC_SOFT;
|
||||
|
||||
nand->cmd_ctrl = upmnand_hwcontrol;
|
||||
nand->read_byte = upmnand_read_byte;
|
||||
nand->dev_ready = tqm8272_dev_ready;
|
||||
|
||||
#ifndef CONFIG_NAND_SPL
|
||||
nand->write_buf = tqm8272_write_buf;
|
||||
nand->read_buf = tqm8272_read_buf;
|
||||
nand->verify_buf = tqm8272_verify_buf;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Select required NAND chip
|
||||
*/
|
||||
board_nand_select_device(nand, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,960 @@
|
|||
/*
|
||||
* (C) Copyright 2006
|
||||
* Heiko Schocher, DENX Software Engineering, hs@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 <command.h>
|
||||
#include <netdev.h>
|
||||
#ifdef CONFIG_PCI
|
||||
#include <pci.h>
|
||||
#include <asm/m8260_pci.h>
|
||||
#endif
|
||||
#include "tqm8272.h"
|
||||
|
||||
#if 0
|
||||
#define deb_printf(fmt,arg...) \
|
||||
printf ("TQM8272 %s %s: " fmt,__FILE__, __FUNCTION__, ##arg)
|
||||
#else
|
||||
#define deb_printf(fmt,arg...) \
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
|
||||
unsigned long board_get_cpu_clk_f (void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 *ATMTXEN */
|
||||
/* PA30 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTCA */
|
||||
/* PA29 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTSOC */
|
||||
/* PA28 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 *ATMRXEN */
|
||||
/* PA27 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRSOC */
|
||||
/* PA26 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRCA */
|
||||
/* PA25 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[0] */
|
||||
/* PA24 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[1] */
|
||||
/* PA23 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[2] */
|
||||
/* PA22 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[3] */
|
||||
/* PA21 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[4] */
|
||||
/* PA20 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[5] */
|
||||
/* PA19 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[6] */
|
||||
/* PA18 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMTXD[7] */
|
||||
/* PA17 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[7] */
|
||||
/* PA16 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[6] */
|
||||
/* PA15 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[5] */
|
||||
/* PA14 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[4] */
|
||||
/* PA13 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[3] */
|
||||
/* PA12 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[2] */
|
||||
/* PA11 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[1] */
|
||||
/* PA10 */ { 0, 0, 0, 1, 0, 0 }, /* FCC1 ATMRXD[0] */
|
||||
/* PA9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC2 TXD */
|
||||
/* PA8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC2 RXD */
|
||||
/* 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 MII TX_ER */
|
||||
/* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_DV */
|
||||
/* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FCC2 MII TX_EN */
|
||||
/* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_ER */
|
||||
/* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII COL */
|
||||
/* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII CRS */
|
||||
/* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[3] */
|
||||
/* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[2] */
|
||||
/* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[1] */
|
||||
/* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FCC2 MII TxD[0] */
|
||||
/* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[0] */
|
||||
/* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[1] */
|
||||
/* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[2] */
|
||||
/* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RxD[3] */
|
||||
/* PB17 */ { 0, 0, 0, 0, 0, 0 }, /* PB17 */
|
||||
/* PB16 */ { 0, 0, 0, 0, 0, 0 }, /* PB16 */
|
||||
/* PB15 */ { 0, 0, 0, 0, 0, 0 }, /* PB15 */
|
||||
/* PB14 */ { 0, 0, 0, 0, 0, 0 }, /* PB14 */
|
||||
/* 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 */ { 0, 0, 0, 0, 0, 0 }, /* PB8 */
|
||||
/* 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, 0, 0, 0 }, /* PC30 */
|
||||
/* PC29 */ { 1, 1, 1, 0, 0, 0 }, /* SCC1 EN *CLSN */
|
||||
/* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
|
||||
/* 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 }, /* ATMTFCLK */
|
||||
/* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* ATMRFCLK */
|
||||
/* PC21 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RXCLK */
|
||||
/* PC20 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN TXCLK */
|
||||
/* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII RX_CLK */
|
||||
/* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FCC2 MII TX_CLK */
|
||||
/* PC17 */ { 1, 0, 0, 1, 0, 0 }, /* PC17 MDC */
|
||||
/* PC16 */ { 1, 0, 0, 0, 0, 0 }, /* PC16 MDIO*/
|
||||
/* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */
|
||||
/* PC14 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN *CD */
|
||||
/* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
|
||||
/* PC12 */ { 0, 0, 0, 1, 0, 0 }, /* PC12 */
|
||||
/* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* PC11 */
|
||||
/* PC10 */ { 0, 0, 0, 1, 0, 0 }, /* PC10 */
|
||||
/* PC9 */ { 0, 0, 0, 1, 0, 0 }, /* PC9 */
|
||||
/* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
|
||||
/* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
|
||||
/* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
|
||||
/* PC5 */ { 1, 1, 0, 1, 0, 0 }, /* PC5 SMC1 TXD */
|
||||
/* PC4 */ { 1, 1, 0, 0, 0, 0 }, /* PC4 SMC1 RXD */
|
||||
/* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
|
||||
/* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* ENET FDE */
|
||||
/* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* ENET DSQE */
|
||||
/* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* ENET LBK */
|
||||
},
|
||||
|
||||
/* Port D */
|
||||
{ /* conf ppar psor pdir podr pdat */
|
||||
/* PD31 */ { 1, 1, 0, 0, 0, 0 }, /* SCC1 EN RxD */
|
||||
/* PD30 */ { 1, 1, 1, 1, 0, 0 }, /* SCC1 EN TxD */
|
||||
/* PD29 */ { 1, 1, 0, 1, 0, 0 }, /* SCC1 EN TENA */
|
||||
/* PD28 */ { 0, 0, 0, 1, 0, 0 }, /* PD28 */
|
||||
/* PD27 */ { 0, 0, 0, 1, 0, 0 }, /* PD27 */
|
||||
/* 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 }, /* PD23 */
|
||||
/* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */
|
||||
/* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */
|
||||
/* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */
|
||||
/* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
|
||||
/* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
|
||||
/* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* FCC1 ATMRXPRTY */
|
||||
/* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* FCC1 ATMTXPRTY */
|
||||
#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 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
|
||||
/* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
|
||||
/* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
|
||||
/* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
|
||||
/* PD5 */ { 0, 0, 0, 1, 0, 0 }, /* PD5 */
|
||||
/* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */
|
||||
/* 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 */
|
||||
}
|
||||
};
|
||||
|
||||
/* UPM pattern for slow init */
|
||||
static const uint upmTableSlow[] =
|
||||
{
|
||||
/* Offset UPM Read Single RAM array entry */
|
||||
/* 0x00 */ 0xffffee00, 0x00ffcc80, 0x00ffcf00, 0x00ffdc00,
|
||||
/* 0x04 */ 0x00ffce80, 0x00ffcc00, 0x00ffee00, 0x3fffcc07,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry */
|
||||
/* 0x18 */ 0xffffee00, 0x00ffec80, 0x00ffef00, 0x00fffc80,
|
||||
/* 0x1C */ 0x00fffe00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for fast init */
|
||||
static const uint upmTableFast[] =
|
||||
{
|
||||
/* Offset UPM Read Single RAM array entry */
|
||||
/* 0x00 */ 0xffffee00, 0x00ffcc80, 0x00ffcd80, 0x00ffdc00,
|
||||
/* 0x04 */ 0x00ffdc00, 0x00ffcf00, 0x00ffec00, 0x3fffcc07,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x08 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> unused */
|
||||
/* 0x10 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry */
|
||||
/* 0x18 */ 0xffffee00, 0x00ffec80, 0x00ffee80, 0x00fffc00,
|
||||
/* 0x1C */ 0x00fffc00, 0x00ffec00, 0x0fffef00, 0x3fffec05,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Check Board Identity:
|
||||
*/
|
||||
int checkboard (void)
|
||||
{
|
||||
char *p = (char *) HWIB_INFO_START_ADDR;
|
||||
|
||||
puts ("Board: ");
|
||||
if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
|
||||
puts (p);
|
||||
} else {
|
||||
puts ("No HWIB assuming TQM8272");
|
||||
}
|
||||
putc ('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
|
||||
static int get_cas_latency (void)
|
||||
{
|
||||
/* get it from the option -ts in CIB */
|
||||
/* default is 3 */
|
||||
int ret = 3;
|
||||
int pos = 0;
|
||||
char *p = (char *) CIB_INFO_START_ADDR;
|
||||
|
||||
while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
|
||||
if (*p < ' ' || *p > '~') { /* ASCII strings! */
|
||||
return ret;
|
||||
}
|
||||
if (*p == '-') {
|
||||
if ((p[1] == 't') && (p[2] == 's')) {
|
||||
return (p[4] - '0');
|
||||
}
|
||||
}
|
||||
p++;
|
||||
pos++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static ulong set_sdram_timing (volatile uint *sdmr_ptr, ulong sdmr, int col)
|
||||
{
|
||||
#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
|
||||
int clk = board_get_cpu_clk_f ();
|
||||
volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||
int busmode = (immr->im_siu_conf.sc_bcr & BCR_EBM ? 1 : 0);
|
||||
int cas;
|
||||
|
||||
sdmr = sdmr & ~(PSDMR_RFRC_MSK | PSDMR_PRETOACT_MSK | PSDMR_WRC_MSK | \
|
||||
PSDMR_BUFCMD);
|
||||
if (busmode) {
|
||||
switch (clk) {
|
||||
case 66666666:
|
||||
sdmr |= (PSDMR_RFRC_66MHZ_60X | \
|
||||
PSDMR_PRETOACT_66MHZ_60X | \
|
||||
PSDMR_WRC_66MHZ_60X | \
|
||||
PSDMR_BUFCMD_66MHZ_60X);
|
||||
break;
|
||||
case 100000000:
|
||||
sdmr |= (PSDMR_RFRC_100MHZ_60X | \
|
||||
PSDMR_PRETOACT_100MHZ_60X | \
|
||||
PSDMR_WRC_100MHZ_60X | \
|
||||
PSDMR_BUFCMD_100MHZ_60X);
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
switch (clk) {
|
||||
case 66666666:
|
||||
sdmr |= (PSDMR_RFRC_66MHZ_SINGLE | \
|
||||
PSDMR_PRETOACT_66MHZ_SINGLE | \
|
||||
PSDMR_WRC_66MHZ_SINGLE | \
|
||||
PSDMR_BUFCMD_66MHZ_SINGLE);
|
||||
break;
|
||||
case 100000000:
|
||||
sdmr |= (PSDMR_RFRC_100MHZ_SINGLE | \
|
||||
PSDMR_PRETOACT_100MHZ_SINGLE | \
|
||||
PSDMR_WRC_100MHZ_SINGLE | \
|
||||
PSDMR_BUFCMD_100MHZ_SINGLE);
|
||||
break;
|
||||
case 133333333:
|
||||
sdmr |= (PSDMR_RFRC_133MHZ_SINGLE | \
|
||||
PSDMR_PRETOACT_133MHZ_SINGLE | \
|
||||
PSDMR_WRC_133MHZ_SINGLE | \
|
||||
PSDMR_BUFCMD_133MHZ_SINGLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cas = get_cas_latency();
|
||||
sdmr &=~ (PSDMR_CL_MSK | PSDMR_LDOTOPRE_MSK);
|
||||
sdmr |= cas;
|
||||
sdmr |= ((cas - 1) << 6);
|
||||
return sdmr;
|
||||
#else
|
||||
return sdmr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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, int col)
|
||||
{
|
||||
volatile uchar c = 0xff;
|
||||
volatile uint *sdmr_ptr;
|
||||
volatile uint *orx_ptr;
|
||||
ulong maxsize, size;
|
||||
int i;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Since CONFIG_SYS_SDRAM_BASE is always 0 (??), we assume that
|
||||
* we are configuring CS1 if base != 0
|
||||
*/
|
||||
sdmr_ptr = base ? &memctl->memc_lsdmr : &memctl->memc_psdmr;
|
||||
orx_ptr = base ? &memctl->memc_or2 : &memctl->memc_or1;
|
||||
|
||||
*orx_ptr = orx;
|
||||
sdmr = set_sdram_timing (sdmr_ptr, sdmr, col);
|
||||
/*
|
||||
* 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 CONFIG_SYS_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 + CONFIG_SYS_MRS_OFFS) = c; /* setting MR on address lines */
|
||||
|
||||
*sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
|
||||
*base = c;
|
||||
|
||||
size = get_ram_size((long *)base, maxsize);
|
||||
*orx_ptr = orx | ~(size - 1);
|
||||
|
||||
return (size);
|
||||
}
|
||||
|
||||
phys_size_t initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile memctl8260_t *memctl = &immap->im_memctl;
|
||||
|
||||
#ifndef CONFIG_SYS_RAMBOOT
|
||||
long size8, size9;
|
||||
#endif
|
||||
long psize;
|
||||
|
||||
psize = 16 * 1024 * 1024;
|
||||
|
||||
memctl->memc_psrt = CONFIG_SYS_PSRT;
|
||||
memctl->memc_mptpr = CONFIG_SYS_MPTPR;
|
||||
|
||||
#ifndef CONFIG_SYS_RAMBOOT
|
||||
/* 60x SDRAM setup:
|
||||
*/
|
||||
size8 = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
|
||||
(uchar *) CONFIG_SYS_SDRAM_BASE, 8);
|
||||
size9 = try_init (memctl, CONFIG_SYS_PSDMR_9COL, CONFIG_SYS_OR1_9COL,
|
||||
(uchar *) CONFIG_SYS_SDRAM_BASE, 9);
|
||||
|
||||
if (size8 < size9) {
|
||||
psize = size9;
|
||||
printf ("(60x:9COL - %ld MB, ", psize >> 20);
|
||||
} else {
|
||||
psize = try_init (memctl, CONFIG_SYS_PSDMR_8COL, CONFIG_SYS_OR1_8COL,
|
||||
(uchar *) CONFIG_SYS_SDRAM_BASE, 8);
|
||||
printf ("(60x:8COL - %ld MB, ", psize >> 20);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SYS_RAMBOOT */
|
||||
|
||||
icache_enable ();
|
||||
|
||||
return (psize);
|
||||
}
|
||||
|
||||
|
||||
static inline int scanChar (char *p, int len, unsigned long *number)
|
||||
{
|
||||
int akt = 0;
|
||||
|
||||
*number = 0;
|
||||
while (akt < len) {
|
||||
if ((*p >= '0') && (*p <= '9')) {
|
||||
*number *= 10;
|
||||
*number += *p - '0';
|
||||
p += 1;
|
||||
} else {
|
||||
if (*p == '-') return akt;
|
||||
return -1;
|
||||
}
|
||||
akt ++;
|
||||
}
|
||||
return akt;
|
||||
}
|
||||
|
||||
static int dump_hwib(void)
|
||||
{
|
||||
HWIB_INFO *hw = &hwinf;
|
||||
char buf[64];
|
||||
int i = getenv_f("serial#", buf, sizeof(buf));
|
||||
volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||
|
||||
if (i < 0)
|
||||
buf[0] = '\0';
|
||||
|
||||
if (hw->OK) {
|
||||
printf ("HWIB on %x\n", HWIB_INFO_START_ADDR);
|
||||
printf ("serial : %s\n", buf);
|
||||
printf ("ethaddr: %s\n", hw->ethaddr);
|
||||
printf ("FLASH : %x nr:%d\n", hw->flash, hw->flash_nr);
|
||||
printf ("RAM : %x cs:%d\n", hw->ram, hw->ram_cs);
|
||||
printf ("CPU : %lu\n", hw->cpunr);
|
||||
printf ("CAN : %d\n", hw->can);
|
||||
if (hw->eeprom) printf ("EEprom : %x\n", hw->eeprom);
|
||||
else printf ("No EEprom\n");
|
||||
if (hw->nand) {
|
||||
printf ("NAND : %x\n", hw->nand);
|
||||
printf ("NAND CS: %d\n", hw->nand_cs);
|
||||
} else { printf ("No NAND\n");}
|
||||
printf ("Bus %s mode.\n", (hw->Bus ? "60x" : "Single PQII"));
|
||||
printf (" real : %s\n", (immr->im_siu_conf.sc_bcr & BCR_EBM ? \
|
||||
"60x" : "Single PQII"));
|
||||
printf ("Option : %lx\n", hw->option);
|
||||
printf ("%s Security Engine\n", (hw->SecEng ? "with" : "no"));
|
||||
printf ("CPM Clk: %d\n", hw->cpmcl);
|
||||
printf ("CPU Clk: %d\n", hw->cpucl);
|
||||
printf ("Bus Clk: %d\n", hw->buscl);
|
||||
if (hw->busclk_real_ok) {
|
||||
printf (" real Clk: %d\n", hw->busclk_real);
|
||||
}
|
||||
printf ("CAS : %d\n", get_cas_latency());
|
||||
} else {
|
||||
printf("HWIB @%x not OK\n", HWIB_INFO_START_ADDR);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int search_real_busclk (int *clk)
|
||||
{
|
||||
int part = 0, pos = 0;
|
||||
char *p = (char *) CIB_INFO_START_ADDR;
|
||||
int ok = 0;
|
||||
|
||||
while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
|
||||
if (*p < ' ' || *p > '~') { /* ASCII strings! */
|
||||
return 0;
|
||||
}
|
||||
switch (part) {
|
||||
default:
|
||||
if (*p == '-') {
|
||||
++part;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (*p == '-') {
|
||||
++part;
|
||||
break;
|
||||
}
|
||||
if (*p == 'b') {
|
||||
ok = 1;
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
if (ok) {
|
||||
switch (*p) {
|
||||
case '6':
|
||||
*clk = 66666666;
|
||||
return 1;
|
||||
break;
|
||||
case '1':
|
||||
if (p[1] == '3') {
|
||||
*clk = 133333333;
|
||||
} else {
|
||||
*clk = 100000000;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int analyse_hwib (void)
|
||||
{
|
||||
char *p = (char *) HWIB_INFO_START_ADDR;
|
||||
int anz;
|
||||
int part = 1, i = 0, pos = 0;
|
||||
HWIB_INFO *hw = &hwinf;
|
||||
|
||||
deb_printf(" %s pointer: %p\n", __FUNCTION__, p);
|
||||
/* Head = TQM */
|
||||
if (*((unsigned long *)p) != (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
|
||||
deb_printf("No HWIB\n");
|
||||
return -1;
|
||||
}
|
||||
p += 3;
|
||||
if (scanChar (p, 4, &hw->cpunr) < 0) {
|
||||
deb_printf("No CPU\n");
|
||||
return -2;
|
||||
}
|
||||
p +=4;
|
||||
|
||||
hw->flash = 0x200000 << (*p - 'A');
|
||||
p++;
|
||||
hw->flash_nr = *p - '0';
|
||||
p++;
|
||||
|
||||
hw->ram = 0x2000000 << (*p - 'A');
|
||||
p++;
|
||||
if (*p == '2') {
|
||||
hw->ram_cs = 2;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p == 'A') hw->can = 1;
|
||||
if (*p == 'B') hw->can = 2;
|
||||
p +=1;
|
||||
p +=1; /* connector */
|
||||
if (*p != '0') {
|
||||
hw->eeprom = 0x1000 << (*p - 'A');
|
||||
}
|
||||
p++;
|
||||
|
||||
if ((*p < '0') || (*p > '9')) {
|
||||
/* NAND before z-option */
|
||||
hw->nand = 0x8000000 << (*p - 'A');
|
||||
p++;
|
||||
hw->nand_cs = *p - '0';
|
||||
p += 2;
|
||||
}
|
||||
/* z-option */
|
||||
anz = scanChar (p, 4, &hw->option);
|
||||
if (anz < 0) {
|
||||
deb_printf("No option\n");
|
||||
return -3;
|
||||
}
|
||||
if (hw->option & 0x8) hw->Bus = 1;
|
||||
p += anz;
|
||||
if (*p != '-') {
|
||||
deb_printf("No -\n");
|
||||
return -4;
|
||||
}
|
||||
p++;
|
||||
/* C option */
|
||||
if (*p == 'E') {
|
||||
hw->SecEng = 1;
|
||||
p++;
|
||||
}
|
||||
switch (*p) {
|
||||
case 'M': hw->cpucl = 266666666;
|
||||
break;
|
||||
case 'P': hw->cpucl = 300000000;
|
||||
break;
|
||||
case 'T': hw->cpucl = 400000000;
|
||||
break;
|
||||
default:
|
||||
deb_printf("No CPU Clk: %c\n", *p);
|
||||
return -5;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
switch (*p) {
|
||||
case 'I': hw->cpmcl = 200000000;
|
||||
break;
|
||||
case 'M': hw->cpmcl = 300000000;
|
||||
break;
|
||||
default:
|
||||
deb_printf("No CPM Clk\n");
|
||||
return -6;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
switch (*p) {
|
||||
case 'B': hw->buscl = 66666666;
|
||||
break;
|
||||
case 'E': hw->buscl = 100000000;
|
||||
break;
|
||||
case 'F': hw->buscl = 133333333;
|
||||
break;
|
||||
default:
|
||||
deb_printf("No BUS Clk\n");
|
||||
return -7;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
|
||||
hw->OK = 1;
|
||||
/* search MAC Address */
|
||||
while ((*p != '\0') && (pos < CONFIG_SYS_HWINFO_SIZE)) {
|
||||
if (*p < ' ' || *p > '~') { /* ASCII strings! */
|
||||
return 0;
|
||||
}
|
||||
switch (part) {
|
||||
default:
|
||||
if (*p == ' ') {
|
||||
++part;
|
||||
i = 0;
|
||||
}
|
||||
break;
|
||||
case 3: /* Copy MAC address */
|
||||
if (*p == ' ') {
|
||||
++part;
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
hw->ethaddr[i++] = *p;
|
||||
if ((i % 3) == 2)
|
||||
hw->ethaddr[i++] = ':';
|
||||
break;
|
||||
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
hw->busclk_real_ok = search_real_busclk (&hw->busclk_real);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_GET_CPU_STR_F)
|
||||
/* !! This routine runs from Flash */
|
||||
char get_cpu_str_f (char *buf)
|
||||
{
|
||||
char *p = (char *) HWIB_INFO_START_ADDR;
|
||||
int i = 0;
|
||||
|
||||
buf[i++] = 'M';
|
||||
buf[i++] = 'P';
|
||||
buf[i++] = 'C';
|
||||
if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
|
||||
buf[i++] = *&p[3];
|
||||
buf[i++] = *&p[4];
|
||||
buf[i++] = *&p[5];
|
||||
buf[i++] = *&p[6];
|
||||
} else {
|
||||
buf[i++] = '8';
|
||||
buf[i++] = '2';
|
||||
buf[i++] = '7';
|
||||
buf[i++] = 'x';
|
||||
}
|
||||
buf[i++] = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BOARD_GET_CPU_CLK_F)
|
||||
/* !! This routine runs from Flash */
|
||||
unsigned long board_get_cpu_clk_f (void)
|
||||
{
|
||||
char *p = (char *) HWIB_INFO_START_ADDR;
|
||||
int i = 0;
|
||||
|
||||
if (*((unsigned long *)p) == (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
|
||||
if (search_real_busclk (&i))
|
||||
return i;
|
||||
}
|
||||
return CONFIG_8260_CLKIN;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_BOARD_EARLY_INIT_R
|
||||
|
||||
static int can_test (unsigned long off)
|
||||
{
|
||||
volatile unsigned char *base = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
|
||||
|
||||
*(base + 0x17) = 'T';
|
||||
*(base + 0x18) = 'Q';
|
||||
*(base + 0x19) = 'M';
|
||||
if ((*(base + 0x17) != 'T') ||
|
||||
(*(base + 0x18) != 'Q') ||
|
||||
(*(base + 0x19) != 'M')) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int can_config_one (unsigned long off)
|
||||
{
|
||||
volatile unsigned char *ctrl = (unsigned char *) (CONFIG_SYS_CAN_BASE + off);
|
||||
volatile unsigned char *cpu_if = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x02);
|
||||
volatile unsigned char *clkout = (unsigned char *) (CONFIG_SYS_CAN_BASE + off + 0x1f);
|
||||
unsigned char temp;
|
||||
|
||||
*cpu_if = 0x45;
|
||||
temp = *ctrl;
|
||||
temp |= 0x40;
|
||||
*ctrl = temp;
|
||||
*clkout = 0x20;
|
||||
temp = *ctrl;
|
||||
temp &= ~0x40;
|
||||
*ctrl = temp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int can_config (void)
|
||||
{
|
||||
int ret = 0;
|
||||
can_config_one (0);
|
||||
if (hwinf.can == 2) {
|
||||
can_config_one (0x100);
|
||||
}
|
||||
/* make Test if they really there */
|
||||
ret += can_test (0);
|
||||
ret += can_test (0x100);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int init_can (void)
|
||||
{
|
||||
volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||
volatile memctl8260_t *memctl = &immr->im_memctl;
|
||||
int count = 0;
|
||||
|
||||
if ((hwinf.OK) && (hwinf.can)) {
|
||||
memctl->memc_or4 = CONFIG_SYS_CAN_OR;
|
||||
memctl->memc_br4 = CONFIG_SYS_CAN_BR;
|
||||
/* upm Init */
|
||||
upmconfig (UPMC, (uint *) upmTableFast,
|
||||
sizeof (upmTableFast) / sizeof (uint));
|
||||
memctl->memc_mcmr = (MxMR_DSx_3_CYCL |
|
||||
MxMR_GPL_x4DIS |
|
||||
MxMR_RLFx_2X |
|
||||
MxMR_WLFx_2X |
|
||||
MxMR_OP_NORM);
|
||||
/* can configure */
|
||||
count = can_config ();
|
||||
printf ("CAN: %d @ %x\n", count, CONFIG_SYS_CAN_BASE);
|
||||
if (hwinf.can != count) printf("!!! difference to HWIB\n");
|
||||
} else {
|
||||
printf ("CAN: No\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
analyse_hwib ();
|
||||
init_can ();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int do_hwib_dump (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
dump_hwib ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
hwib, 1, 1, do_hwib_dump,
|
||||
"dump HWIB'",
|
||||
""
|
||||
);
|
||||
|
||||
#ifdef CONFIG_SYS_UPDATE_FLASH_SIZE
|
||||
static int get_flash_timing (void)
|
||||
{
|
||||
/* get it from the option -tf in CIB */
|
||||
/* default is 0x00000c84 */
|
||||
int ret = 0x00000c84;
|
||||
int pos = 0;
|
||||
int nr = 0;
|
||||
char *p = (char *) CIB_INFO_START_ADDR;
|
||||
|
||||
while ((*p != '\0') && (pos < CIB_INFO_LEN)) {
|
||||
if (*p < ' ' || *p > '~') { /* ASCII strings! */
|
||||
return ret;
|
||||
}
|
||||
if (*p == '-') {
|
||||
if ((p[1] == 't') && (p[2] == 'f')) {
|
||||
p += 6;
|
||||
ret = 0;
|
||||
while (nr < 8) {
|
||||
if ((*p >= '0') && (*p <= '9')) {
|
||||
ret *= 0x10;
|
||||
ret += *p - '0';
|
||||
p += 1;
|
||||
nr ++;
|
||||
} else if ((*p >= 'A') && (*p <= 'F')) {
|
||||
ret *= 10;
|
||||
ret += *p - '7';
|
||||
p += 1;
|
||||
nr ++;
|
||||
} else {
|
||||
if (nr < 8) return 0x00000c84;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
p++;
|
||||
pos++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Update the Flash_Size and the Flash Timing */
|
||||
int update_flash_size (int flash_size)
|
||||
{
|
||||
volatile immap_t * immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||
volatile memctl8260_t *memctl = &immr->im_memctl;
|
||||
unsigned long reg;
|
||||
unsigned long tim;
|
||||
|
||||
/* I must use reg, otherwise the board hang */
|
||||
reg = memctl->memc_or0;
|
||||
reg &= ~ORxU_AM_MSK;
|
||||
reg |= MEG_TO_AM(flash_size >> 20);
|
||||
tim = get_flash_timing ();
|
||||
reg &= ~0xfff;
|
||||
reg |= (tim & 0xfff);
|
||||
memctl->memc_or0 = reg;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
struct pci_controller hose;
|
||||
|
||||
int board_early_init_f (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
|
||||
immap->im_clkrst.car_sccr |= M826X_SCCR_PCI_MODE_EN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void pci_mpc8250_init(struct pci_controller *);
|
||||
|
||||
void pci_init_board(void)
|
||||
{
|
||||
pci_mpc8250_init(&hose);
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
return pci_eth_init(bis);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* (C) Copyright 2008
|
||||
* Heiko Schocher, DENX Software Engineering, hs@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
|
||||
*/
|
||||
|
||||
#ifndef _TQM8272_HEADER_H
|
||||
#define _TQM8272_HEADER_H
|
||||
|
||||
#define _NOT_USED_ 0xFFFFFFFF
|
||||
|
||||
typedef struct{
|
||||
int Bus;
|
||||
int flash;
|
||||
int flash_nr;
|
||||
int ram;
|
||||
int ram_cs;
|
||||
int nand;
|
||||
int nand_cs;
|
||||
int eeprom;
|
||||
int can;
|
||||
unsigned long cpunr;
|
||||
unsigned long option;
|
||||
int SecEng;
|
||||
int cpucl;
|
||||
int cpmcl;
|
||||
int buscl;
|
||||
int busclk_real_ok;
|
||||
int busclk_real;
|
||||
unsigned char OK;
|
||||
unsigned char ethaddr[20];
|
||||
} HWIB_INFO;
|
||||
|
||||
static HWIB_INFO hwinf = {0, 0, 1, 0, 1, 0, 0, 0, 0, 8272, 0 ,0,
|
||||
0, 0, 0, 0, 0, 0};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# (C) Copyright 2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# Copyright 2004 Freescale Semiconductor, Inc.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(BOARD).o
|
||||
|
||||
COBJS-y += $(BOARD).o
|
||||
COBJS-$(CONFIG_PCI) += pci.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* (C) Copyright 2005
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
* Copyright (C) 2006-2009 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/io.h>
|
||||
#include <common.h>
|
||||
#include <mpc83xx.h>
|
||||
#include <pci.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/fsl_i2c.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static struct pci_region pci1_regions[] = {
|
||||
{
|
||||
bus_start: CONFIG_SYS_PCI1_MEM_BASE,
|
||||
phys_start: CONFIG_SYS_PCI1_MEM_PHYS,
|
||||
size: CONFIG_SYS_PCI1_MEM_SIZE,
|
||||
flags: PCI_REGION_MEM | PCI_REGION_PREFETCH
|
||||
},
|
||||
{
|
||||
bus_start: CONFIG_SYS_PCI1_IO_BASE,
|
||||
phys_start: CONFIG_SYS_PCI1_IO_PHYS,
|
||||
size: CONFIG_SYS_PCI1_IO_SIZE,
|
||||
flags: PCI_REGION_IO
|
||||
},
|
||||
{
|
||||
bus_start: CONFIG_SYS_PCI1_MMIO_BASE,
|
||||
phys_start: CONFIG_SYS_PCI1_MMIO_PHYS,
|
||||
size: CONFIG_SYS_PCI1_MMIO_SIZE,
|
||||
flags: PCI_REGION_MEM
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* pci_init_board()
|
||||
*
|
||||
* NOTICE: MPC8349 internally has two PCI controllers (PCI1 and PCI2) but since
|
||||
* per TQM834x design physical connections to external devices (PCI sockets)
|
||||
* are routed only to the PCI1 we do not account for the second one - this code
|
||||
* supports PCI1 module only. Should support for the PCI2 be required in the
|
||||
* future it needs a separate pci_controller structure (above) and handling -
|
||||
* please refer to other boards' implementation for dual PCI host controllers,
|
||||
* for example board/Marvell/db64360/pci.c, pci_init_board()
|
||||
*
|
||||
*/
|
||||
void
|
||||
pci_init_board(void)
|
||||
{
|
||||
volatile immap_t *immr = (volatile immap_t *)CONFIG_SYS_IMMR;
|
||||
volatile clk83xx_t *clk = (volatile clk83xx_t *)&immr->clk;
|
||||
volatile law83xx_t *pci_law = immr->sysconf.pcilaw;
|
||||
struct pci_region *reg[] = { pci1_regions };
|
||||
u32 reg32;
|
||||
|
||||
/*
|
||||
* Configure PCI controller and PCI_CLK_OUTPUT
|
||||
*
|
||||
* WARNING! only PCI_CLK_OUTPUT1 is enabled here as this is the one
|
||||
* line actually used for clocking all external PCI devices in TQM83xx.
|
||||
* Enabling other PCI_CLK_OUTPUT lines may lead to board's hang for
|
||||
* unknown reasons - particularly PCI_CLK_OUTPUT6 and PCI_CLK_OUTPUT7
|
||||
* are known to hang the board; this issue is under investigation
|
||||
* (13 oct 05)
|
||||
*/
|
||||
reg32 = OCCR_PCICOE1;
|
||||
#if 0
|
||||
/* enabling all PCI_CLK_OUTPUT lines HANGS the board... */
|
||||
reg32 = 0xff000000;
|
||||
#endif
|
||||
if (clk->spmr & SPMR_CKID) {
|
||||
/* PCI Clock is half CONFIG_83XX_CLKIN so need to set up OCCR
|
||||
* fields accordingly */
|
||||
reg32 |= (OCCR_PCI1CR | OCCR_PCI2CR);
|
||||
|
||||
reg32 |= (OCCR_PCICD0 | OCCR_PCICD1 | OCCR_PCICD2 \
|
||||
| OCCR_PCICD3 | OCCR_PCICD4 | OCCR_PCICD5 \
|
||||
| OCCR_PCICD6 | OCCR_PCICD7);
|
||||
}
|
||||
|
||||
clk->occr = reg32;
|
||||
udelay(2000);
|
||||
|
||||
/* Configure PCI Local Access Windows */
|
||||
pci_law[0].bar = CONFIG_SYS_PCI1_MEM_PHYS & LAWBAR_BAR;
|
||||
pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_512M;
|
||||
|
||||
pci_law[1].bar = CONFIG_SYS_PCI1_IO_PHYS & LAWBAR_BAR;
|
||||
pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_16M;
|
||||
|
||||
udelay(2000);
|
||||
|
||||
mpc83xx_pci_init(1, reg);
|
||||
}
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
/*
|
||||
* (C) Copyright 2005
|
||||
* 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 <mpc83xx.h>
|
||||
#include <asm/mpc8349_pci.h>
|
||||
#include <i2c.h>
|
||||
#include <miiphy.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <pci.h>
|
||||
#include <flash.h>
|
||||
#include <mtd/cfi_flash.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define IOSYNC asm("eieio")
|
||||
#define ISYNC asm("isync")
|
||||
#define SYNC asm("sync")
|
||||
#define FPW FLASH_PORT_WIDTH
|
||||
#define FPWV FLASH_PORT_WIDTHV
|
||||
|
||||
#define DDR_MAX_SIZE_PER_CS 0x20000000
|
||||
|
||||
#if defined(DDR_CASLAT_20)
|
||||
#define TIMING_CASLAT TIMING_CFG1_CASLAT_20
|
||||
#define MODE_CASLAT DDR_MODE_CASLAT_20
|
||||
#else
|
||||
#define TIMING_CASLAT TIMING_CFG1_CASLAT_25
|
||||
#define MODE_CASLAT DDR_MODE_CASLAT_25
|
||||
#endif
|
||||
|
||||
#define INITIAL_CS_CONFIG (CSCONFIG_EN | CSCONFIG_ROW_BIT_12 | \
|
||||
CSCONFIG_COL_BIT_9)
|
||||
|
||||
/* External definitions */
|
||||
ulong flash_get_size (ulong base, int banknum);
|
||||
|
||||
/* Local functions */
|
||||
static int detect_num_flash_banks(void);
|
||||
static long int get_ddr_bank_size(short cs, long *base);
|
||||
static void set_cs_bounds(short cs, long base, long size);
|
||||
static void set_cs_config(short cs, long config);
|
||||
static void set_ddr_config(void);
|
||||
|
||||
/* Local variable */
|
||||
static volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
|
||||
|
||||
/**************************************************************************
|
||||
* Board initialzation after relocation to RAM. Used to detect the number
|
||||
* of Flash banks on TQM834x.
|
||||
*/
|
||||
int board_early_init_r (void) {
|
||||
/* sanity check, IMMARBAR should be mirrored at offset zero of IMMR */
|
||||
if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
|
||||
return 0;
|
||||
|
||||
/* detect the number of Flash banks */
|
||||
return detect_num_flash_banks();
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* DRAM initalization and size detection
|
||||
*/
|
||||
phys_size_t initdram (int board_type)
|
||||
{
|
||||
long bank_size;
|
||||
long size;
|
||||
int cs;
|
||||
|
||||
/* during size detection, set up the max DDRLAW size */
|
||||
im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_BASE;
|
||||
im->sysconf.ddrlaw[0].ar = (LAWAR_EN | LAWAR_SIZE_2G);
|
||||
|
||||
/* set CS bounds to maximum size */
|
||||
for(cs = 0; cs < 4; ++cs) {
|
||||
set_cs_bounds(cs,
|
||||
CONFIG_SYS_DDR_BASE + (cs * DDR_MAX_SIZE_PER_CS),
|
||||
DDR_MAX_SIZE_PER_CS);
|
||||
|
||||
set_cs_config(cs, INITIAL_CS_CONFIG);
|
||||
}
|
||||
|
||||
/* configure ddr controller */
|
||||
set_ddr_config();
|
||||
|
||||
udelay(200);
|
||||
|
||||
/* enable DDR controller */
|
||||
im->ddr.sdram_cfg = (SDRAM_CFG_MEM_EN |
|
||||
SDRAM_CFG_SREN |
|
||||
SDRAM_CFG_SDRAM_TYPE_DDR1);
|
||||
SYNC;
|
||||
|
||||
/* size detection */
|
||||
debug("\n");
|
||||
size = 0;
|
||||
for(cs = 0; cs < 4; ++cs) {
|
||||
debug("\nDetecting Bank%d\n", cs);
|
||||
|
||||
bank_size = get_ddr_bank_size(cs,
|
||||
(long *)(CONFIG_SYS_DDR_BASE + size));
|
||||
size += bank_size;
|
||||
|
||||
debug("DDR Bank%d size: %ld MiB\n\n", cs, bank_size >> 20);
|
||||
|
||||
/* exit if less than one bank */
|
||||
if(size < DDR_MAX_SIZE_PER_CS) break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* checkboard()
|
||||
*/
|
||||
int checkboard (void)
|
||||
{
|
||||
puts("Board: TQM834x\n");
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
volatile immap_t * immr;
|
||||
u32 w, f;
|
||||
|
||||
immr = (immap_t *)CONFIG_SYS_IMMR;
|
||||
if (!(immr->reset.rcwh & HRCWH_PCI_HOST)) {
|
||||
printf("PCI: NOT in host mode..?!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get bus width */
|
||||
w = 32;
|
||||
if (immr->reset.rcwh & HRCWH_64_BIT_PCI)
|
||||
w = 64;
|
||||
|
||||
/* get clock */
|
||||
f = gd->pci_clk;
|
||||
|
||||
printf("PCI1: %d bit, %d MHz\n", w, f / 1000000);
|
||||
#else
|
||||
printf("PCI: disabled\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Local functions
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Detect the number of flash banks (1 or 2). Store it in
|
||||
* a global variable tqm834x_num_flash_banks.
|
||||
* Bank detection code based on the Monitor code.
|
||||
*/
|
||||
static int detect_num_flash_banks(void)
|
||||
{
|
||||
typedef unsigned long FLASH_PORT_WIDTH;
|
||||
typedef volatile unsigned long FLASH_PORT_WIDTHV;
|
||||
FPWV *bank1_base;
|
||||
FPWV *bank2_base;
|
||||
FPW bank1_read;
|
||||
FPW bank2_read;
|
||||
ulong bank1_size;
|
||||
ulong bank2_size;
|
||||
ulong total_size;
|
||||
|
||||
cfi_flash_num_flash_banks = 2; /* assume two banks */
|
||||
|
||||
/* Get bank 1 and 2 information */
|
||||
bank1_size = flash_get_size(CONFIG_SYS_FLASH_BASE, 0);
|
||||
debug("Bank1 size: %lu\n", bank1_size);
|
||||
bank2_size = flash_get_size(CONFIG_SYS_FLASH_BASE + bank1_size, 1);
|
||||
debug("Bank2 size: %lu\n", bank2_size);
|
||||
total_size = bank1_size + bank2_size;
|
||||
|
||||
if (bank2_size > 0) {
|
||||
/* Seems like we've got bank 2, but maybe it's mirrored 1 */
|
||||
|
||||
/* Set the base addresses */
|
||||
bank1_base = (FPWV *) (CONFIG_SYS_FLASH_BASE);
|
||||
bank2_base = (FPWV *) (CONFIG_SYS_FLASH_BASE + bank1_size);
|
||||
|
||||
/* Put bank 2 into CFI command mode and read */
|
||||
bank2_base[0x55] = 0x00980098;
|
||||
IOSYNC;
|
||||
ISYNC;
|
||||
bank2_read = bank2_base[0x10];
|
||||
|
||||
/* Read from bank 1 (it's in read mode) */
|
||||
bank1_read = bank1_base[0x10];
|
||||
|
||||
/* Reset Flash */
|
||||
bank1_base[0] = 0x00F000F0;
|
||||
bank2_base[0] = 0x00F000F0;
|
||||
|
||||
if (bank2_read == bank1_read) {
|
||||
/*
|
||||
* Looks like just one bank, but not sure yet. Let's
|
||||
* read from bank 2 in autosoelect mode.
|
||||
*/
|
||||
bank2_base[0x0555] = 0x00AA00AA;
|
||||
bank2_base[0x02AA] = 0x00550055;
|
||||
bank2_base[0x0555] = 0x00900090;
|
||||
IOSYNC;
|
||||
ISYNC;
|
||||
bank2_read = bank2_base[0x10];
|
||||
|
||||
/* Read from bank 1 (it's in read mode) */
|
||||
bank1_read = bank1_base[0x10];
|
||||
|
||||
/* Reset Flash */
|
||||
bank1_base[0] = 0x00F000F0;
|
||||
bank2_base[0] = 0x00F000F0;
|
||||
|
||||
if (bank2_read == bank1_read) {
|
||||
/*
|
||||
* In both CFI command and autoselect modes,
|
||||
* we got the some data reading from Flash.
|
||||
* There is only one mirrored bank.
|
||||
*/
|
||||
cfi_flash_num_flash_banks = 1;
|
||||
total_size = bank1_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug("Number of flash banks detected: %d\n", cfi_flash_num_flash_banks);
|
||||
|
||||
/* set OR0 and BR0 */
|
||||
set_lbc_or(0, CONFIG_SYS_OR_TIMING_FLASH |
|
||||
(-(total_size) & OR_GPCM_AM));
|
||||
set_lbc_br(0, (CONFIG_SYS_FLASH_BASE & BR_BA) |
|
||||
(BR_MS_GPCM | BR_PS_32 | BR_V));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Detect the size of a ddr bank. Sets CS bounds and CS config accordingly.
|
||||
*/
|
||||
static long int get_ddr_bank_size(short cs, long *base)
|
||||
{
|
||||
/* This array lists all valid DDR SDRAM configurations, with
|
||||
* Bank sizes in bytes. (Refer to Table 9-27 in the MPC8349E RM).
|
||||
* The last entry has to to have size equal 0 and is igonred during
|
||||
* autodection. Bank sizes must be in increasing order of size
|
||||
*/
|
||||
struct {
|
||||
long row;
|
||||
long col;
|
||||
long size;
|
||||
} conf[] = {
|
||||
{CSCONFIG_ROW_BIT_12, CSCONFIG_COL_BIT_8, 32 << 20},
|
||||
{CSCONFIG_ROW_BIT_12, CSCONFIG_COL_BIT_9, 64 << 20},
|
||||
{CSCONFIG_ROW_BIT_12, CSCONFIG_COL_BIT_10, 128 << 20},
|
||||
{CSCONFIG_ROW_BIT_13, CSCONFIG_COL_BIT_9, 128 << 20},
|
||||
{CSCONFIG_ROW_BIT_13, CSCONFIG_COL_BIT_10, 256 << 20},
|
||||
{CSCONFIG_ROW_BIT_13, CSCONFIG_COL_BIT_11, 512 << 20},
|
||||
{CSCONFIG_ROW_BIT_14, CSCONFIG_COL_BIT_10, 512 << 20},
|
||||
{CSCONFIG_ROW_BIT_14, CSCONFIG_COL_BIT_11, 1024 << 20},
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
int i;
|
||||
int detected;
|
||||
long size;
|
||||
|
||||
detected = -1;
|
||||
for(i = 0; conf[i].size != 0; ++i) {
|
||||
|
||||
/* set sdram bank configuration */
|
||||
set_cs_config(cs, CSCONFIG_EN | conf[i].col | conf[i].row);
|
||||
|
||||
debug("Getting RAM size...\n");
|
||||
size = get_ram_size(base, DDR_MAX_SIZE_PER_CS);
|
||||
|
||||
if((size == conf[i].size) && (i == detected + 1))
|
||||
detected = i;
|
||||
|
||||
debug("Trying %ld x %ld (%ld MiB) at addr %p, detected: %ld MiB\n",
|
||||
conf[i].row,
|
||||
conf[i].col,
|
||||
conf[i].size >> 20,
|
||||
base,
|
||||
size >> 20);
|
||||
}
|
||||
|
||||
if(detected == -1){
|
||||
/* disable empty cs */
|
||||
debug("\nNo valid configurations for CS%d, disabling...\n", cs);
|
||||
set_cs_config(cs, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("\nDetected configuration %ld x %ld (%ld MiB) at addr %p\n",
|
||||
conf[detected].row, conf[detected].col, conf[detected].size >> 20, base);
|
||||
|
||||
/* configure cs ro detected params */
|
||||
set_cs_config(cs, CSCONFIG_EN | conf[detected].row |
|
||||
conf[detected].col);
|
||||
|
||||
set_cs_bounds(cs, (long)base, conf[detected].size);
|
||||
|
||||
return(conf[detected].size);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Sets DDR bank CS bounds.
|
||||
*/
|
||||
static void set_cs_bounds(short cs, long base, long size)
|
||||
{
|
||||
debug("Setting bounds %08lx, %08lx for cs %d\n", base, size, cs);
|
||||
if(size == 0){
|
||||
im->ddr.csbnds[cs].csbnds = 0x00000000;
|
||||
} else {
|
||||
im->ddr.csbnds[cs].csbnds =
|
||||
((base >> CSBNDS_SA_SHIFT) & CSBNDS_SA) |
|
||||
(((base + size - 1) >> CSBNDS_EA_SHIFT) &
|
||||
CSBNDS_EA);
|
||||
}
|
||||
SYNC;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Sets DDR banks CS configuration.
|
||||
* config == 0x00000000 disables the CS.
|
||||
*/
|
||||
static void set_cs_config(short cs, long config)
|
||||
{
|
||||
debug("Setting config %08lx for cs %d\n", config, cs);
|
||||
im->ddr.cs_config[cs] = config;
|
||||
SYNC;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Sets DDR clocks, timings and configuration.
|
||||
*/
|
||||
static void set_ddr_config(void) {
|
||||
/* clock control */
|
||||
im->ddr.sdram_clk_cntl = DDR_SDRAM_CLK_CNTL_SS_EN |
|
||||
DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05;
|
||||
SYNC;
|
||||
|
||||
/* timing configuration */
|
||||
im->ddr.timing_cfg_1 =
|
||||
(4 << TIMING_CFG1_PRETOACT_SHIFT) |
|
||||
(7 << TIMING_CFG1_ACTTOPRE_SHIFT) |
|
||||
(4 << TIMING_CFG1_ACTTORW_SHIFT) |
|
||||
(5 << TIMING_CFG1_REFREC_SHIFT) |
|
||||
(3 << TIMING_CFG1_WRREC_SHIFT) |
|
||||
(3 << TIMING_CFG1_ACTTOACT_SHIFT) |
|
||||
(1 << TIMING_CFG1_WRTORD_SHIFT) |
|
||||
(TIMING_CFG1_CASLAT & TIMING_CASLAT);
|
||||
|
||||
im->ddr.timing_cfg_2 =
|
||||
TIMING_CFG2_CPO_DEF |
|
||||
(2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT);
|
||||
SYNC;
|
||||
|
||||
/* don't enable DDR controller yet */
|
||||
im->ddr.sdram_cfg =
|
||||
SDRAM_CFG_SREN |
|
||||
SDRAM_CFG_SDRAM_TYPE_DDR1;
|
||||
SYNC;
|
||||
|
||||
/* Set SDRAM mode */
|
||||
im->ddr.sdram_mode =
|
||||
((DDR_MODE_EXT_MODEREG | DDR_MODE_WEAK) <<
|
||||
SDRAM_MODE_ESD_SHIFT) |
|
||||
((DDR_MODE_MODEREG | DDR_MODE_BLEN_4) <<
|
||||
SDRAM_MODE_SD_SHIFT) |
|
||||
((DDR_MODE_CASLAT << SDRAM_MODE_SD_SHIFT) &
|
||||
MODE_CASLAT);
|
||||
SYNC;
|
||||
|
||||
/* Set fast SDRAM refresh rate */
|
||||
im->ddr.sdram_interval =
|
||||
(DDR_REFINT_166MHZ_7US << SDRAM_INTERVAL_REFINT_SHIFT) |
|
||||
(DDR_BSTOPRE << SDRAM_INTERVAL_BSTOPRE_SHIFT);
|
||||
SYNC;
|
||||
|
||||
/* Workaround for DDR6 Erratum
|
||||
* see MPC8349E Device Errata Rev.8, 2/2006
|
||||
* This workaround influences the MPC internal "input enables"
|
||||
* dependent on CAS latency and MPC revision. According to errata
|
||||
* sheet the internal reserved registers for this workaround are
|
||||
* not available from revision 2.0 and up.
|
||||
*/
|
||||
|
||||
/* Get REVID from register SPRIDR. Skip workaround if rev >= 2.0
|
||||
* (0x200)
|
||||
*/
|
||||
if ((im->sysconf.spridr & SPRIDR_REVID) < 0x200) {
|
||||
|
||||
/* There is a internal reserved register at IMMRBAR+0x2F00
|
||||
* which has to be written with a certain value defined by
|
||||
* errata sheet.
|
||||
*/
|
||||
u32 *reserved_p = (u32 *)((u8 *)im + 0x2f00);
|
||||
|
||||
#if defined(DDR_CASLAT_20)
|
||||
*reserved_p = 0x201c0000;
|
||||
#else
|
||||
*reserved_p = 0x202c0000;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
void ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
ft_pci_setup(blob, bd);
|
||||
#endif /* CONFIG_PCI */
|
||||
}
|
||||
#endif /* CONFIG_OF_BOARD_SETUP */
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#
|
||||
# (C) Copyright 2001-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(BOARD).o
|
||||
|
||||
COBJS-y += $(BOARD).o
|
||||
COBJS-y += sdram.o
|
||||
COBJS-y += law.o
|
||||
COBJS-y += tlb.o
|
||||
|
||||
COBJS-$(CONFIG_NAND) += nand.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/fsl_law.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
/*
|
||||
* LAW(Local Access Window) configuration:
|
||||
*
|
||||
* Standard mapping:
|
||||
*
|
||||
* 0x0000_0000 0x7fff_ffff DDR 2G
|
||||
* 0x8000_0000 0x9fff_ffff PCI1 MEM 512M
|
||||
* 0xc000_0000 0xdfff_ffff RapidIO or PCI express 512M
|
||||
* 0xe000_0000 0xe000_ffff CCSR 1M
|
||||
* 0xe200_0000 0xe2ff_ffff PCI1 IO 16M
|
||||
* 0xe300_0000 0xe3ff_ffff CAN and NAND Flash 16M
|
||||
* 0xef00_0000 0xefff_ffff PCI express IO 16M
|
||||
* 0xfc00_0000 0xffff_ffff FLASH (boot bank) 128M
|
||||
*
|
||||
* Big FLASH mapping:
|
||||
*
|
||||
* 0x0000_0000 0x7fff_ffff DDR 2G
|
||||
* 0x8000_0000 0x9fff_ffff PCI1 MEM 512M
|
||||
* 0xa000_0000 0xa000_ffff CCSR 1M
|
||||
* 0xa200_0000 0xa2ff_ffff PCI1 IO 16M
|
||||
* 0xa300_0000 0xa3ff_ffff CAN and NAND Flash 16M
|
||||
* 0xaf00_0000 0xafff_ffff PCI express IO 16M
|
||||
* 0xb000_0000 0xbfff_ffff RapidIO or PCI express 256M
|
||||
* 0xc000_0000 0xffff_ffff FLASH (boot bank) 1G
|
||||
*
|
||||
* Notes:
|
||||
* CCSRBAR and L2-as-SRAM don't need a configured Local Access Window.
|
||||
* If flash is 8M at default position (last 8M), no LAW needed.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_TQM_BIGFLASH
|
||||
#define LAW_3_SIZE LAW_SIZE_1G
|
||||
#define LAW_5_SIZE LAW_SIZE_256M
|
||||
#else
|
||||
#define LAW_3_SIZE LAW_SIZE_128M
|
||||
#define LAW_5_SIZE LAW_SIZE_512M
|
||||
#endif
|
||||
|
||||
struct law_entry law_table[] = {
|
||||
SET_LAW(CONFIG_SYS_DDR_SDRAM_BASE, LAW_SIZE_2G, LAW_TRGT_IF_DDR),
|
||||
SET_LAW(CONFIG_SYS_LBC_FLASH_BASE, LAW_3_SIZE, LAW_TRGT_IF_LBC),
|
||||
#ifndef CONFIG_PCIE1
|
||||
SET_LAW(CONFIG_SYS_RIO_MEM_BASE, LAW_5_SIZE, LAW_TRGT_IF_RIO),
|
||||
#endif /* CONFIG_PCIE1 */
|
||||
#if defined(CONFIG_CAN_DRIVER) || defined(CONFIG_NAND)
|
||||
SET_LAW(CONFIG_SYS_CAN_BASE, LAW_SIZE_16M, LAW_TRGT_IF_LBC),
|
||||
#endif /* CONFIG_CAN_DRIVER || CONFIG_NAND */
|
||||
};
|
||||
|
||||
int num_law_entries = ARRAY_SIZE (law_table);
|
||||
|
|
@ -0,0 +1,472 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Wolfgang Grandegger <wg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2006
|
||||
* Thomas Waehner, TQ-System GmbH, thomas.waehner@tqs.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 <asm/processor.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/fsl_upm.h>
|
||||
#include <ioports.h>
|
||||
|
||||
#include <nand.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
extern uint get_lbc_clock (void);
|
||||
|
||||
/* index of UPM RAM array run pattern for NAND command cycle */
|
||||
#define CONFIG_SYS_NAN_UPM_WRITE_CMD_OFS 0x08
|
||||
|
||||
/* index of UPM RAM array run pattern for NAND address cycle */
|
||||
#define CONFIG_SYS_NAND_UPM_WRITE_ADDR_OFS 0x10
|
||||
|
||||
/* Structure for table with supported UPM timings */
|
||||
struct upm_freq {
|
||||
ulong freq;
|
||||
const u32 *upm_patt;
|
||||
uchar gpl4_disable;
|
||||
uchar ehtr;
|
||||
uchar ead;
|
||||
};
|
||||
|
||||
/* NAND-FLASH UPM tables for TQM85XX according to TQM8548.pq.timing.101.doc */
|
||||
|
||||
/* UPM pattern for bus clock = 25 MHz */
|
||||
static const u32 upm_patt_25[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff32000, 0x0fa32000, 0x3fb32005, 0xfffffc00,
|
||||
/* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 33.3 MHz */
|
||||
static const u32 upm_patt_33[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff32000, 0x0fa32100, 0x3fb32005, 0xfffffc00,
|
||||
/* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 41.7 MHz */
|
||||
static const u32 upm_patt_42[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff32000, 0x0fa32100, 0x3fb32005, 0xfffffc00,
|
||||
/* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff2c30, 0x00ff2c30, 0x0fff2c35, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3ec30, 0x00f3ec30, 0x0ff3ec35, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f32c00, 0x00f32c00, 0x0ff32c05, 0xfffffc00,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 50 MHz */
|
||||
static const u32 upm_patt_50[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff33000, 0x0fa33100, 0x0fa33005, 0xfffffc00,
|
||||
/* 0x04 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff3d30, 0x00ff3c30, 0x0fff3c35, 0xfffffc00,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3fd30, 0x00f3fc30, 0x0ff3fc35, 0xfffffc00,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f33d00, 0x00f33c00, 0x0ff33c05, 0xfffffc00,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 66.7 MHz */
|
||||
static const u32 upm_patt_67[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff33000, 0x0fe33000, 0x0fa33100, 0x0fa33000,
|
||||
/* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff3d30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3fd30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f33d00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 83.3 MHz */
|
||||
static const u32 upm_patt_83[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff33000, 0x0fe33000, 0x0fa33100, 0x0fa33000,
|
||||
/* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff3e30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3fe30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f33e00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 100 MHz */
|
||||
static const u32 upm_patt_100[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff33100, 0x0fe33000, 0x0fa33200, 0x0fa33000,
|
||||
/* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff3f30, 0x00ff3c30, 0x0fff3c30, 0x0fff3c35,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3ff30, 0x00f3fc30, 0x0ff3fc30, 0x0ff3fc35,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f33f00, 0x00f33c00, 0x0ff33c00, 0x0ff33c05,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 133.3 MHz */
|
||||
static const u32 upm_patt_133[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff33100, 0x0fe33000, 0x0fa33300, 0x0fa33000,
|
||||
/* 0x04 */ 0x0fa33000, 0x0fa33005, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff3f30, 0x00ff3d30, 0x0fff3d30, 0x0fff3c35,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3ff30, 0x00f3fd30, 0x0ff3fd30, 0x0ff3fc35,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f33f00, 0x00f33d00, 0x0ff33d00, 0x0ff33c05,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* UPM pattern for bus clock = 166.7 MHz */
|
||||
static const u32 upm_patt_167[] = {
|
||||
/* Offset */ /* UPM Read Single RAM array entry -> NAND Read Data */
|
||||
/* 0x00 */ 0x0ff33200, 0x0fe33000, 0x0fa33300, 0x0fa33300,
|
||||
/* 0x04 */ 0x0fa33005, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write CMD */
|
||||
/* 0x08 */ 0x00ff3f30, 0x00ff3f30, 0x0fff3e30, 0xffff3c35,
|
||||
/* 0x0C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Read Burst RAM array entry -> NAND Write ADDR */
|
||||
/* 0x10 */ 0x00f3ff30, 0x00f3ff30, 0x0ff3fe30, 0x0ff3fc35,
|
||||
/* 0x14 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Single RAM array entry -> NAND Write Data */
|
||||
/* 0x18 */ 0x00f33f00, 0x00f33f00, 0x0ff33e00, 0x0ff33c05,
|
||||
/* 0x1C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
|
||||
/* UPM Write Burst RAM array entry -> unused */
|
||||
/* 0x20 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x24 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x28 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x2C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Refresh Timer RAM array entry -> unused */
|
||||
/* 0x30 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x34 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
|
||||
/* 0x38 */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
|
||||
/* UPM Exception RAM array entry -> unsused */
|
||||
/* 0x3C */ 0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
|
||||
};
|
||||
|
||||
/* Supported UPM timings */
|
||||
struct upm_freq upm_freq_table[] = {
|
||||
/* nominal freq. | ptr to table | GPL4 dis. | EHTR | EAD */
|
||||
{25000000, upm_patt_25, 1, 0, 0},
|
||||
{33333333, upm_patt_33, 1, 0, 0},
|
||||
{41666666, upm_patt_42, 1, 0, 0},
|
||||
{50000000, upm_patt_50, 0, 0, 0},
|
||||
{66666666, upm_patt_67, 0, 0, 0},
|
||||
{83333333, upm_patt_83, 0, 0, 0},
|
||||
{100000000, upm_patt_100, 0, 1, 1},
|
||||
{133333333, upm_patt_133, 0, 1, 1},
|
||||
{166666666, upm_patt_167, 0, 1, 1},
|
||||
};
|
||||
|
||||
#define UPM_FREQS (sizeof(upm_freq_table) / sizeof(struct upm_freq))
|
||||
|
||||
volatile const u32 *nand_upm_patt;
|
||||
|
||||
/*
|
||||
* write into UPMB ram
|
||||
*/
|
||||
static void upmb_write (u_char addr, ulong val)
|
||||
{
|
||||
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
|
||||
|
||||
out_be32 (&lbc->mdr, val);
|
||||
|
||||
clrsetbits_be32(&lbc->mbmr, MxMR_MAD_MSK,
|
||||
MxMR_OP_WARR | (addr & MxMR_MAD_MSK));
|
||||
|
||||
/* dummy access to perform write */
|
||||
out_8 ((void __iomem *)CONFIG_SYS_NAND_BASE, 0);
|
||||
|
||||
clrbits_be32(&lbc->mbmr, MxMR_OP_WARR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize UPM for NAND flash access.
|
||||
*/
|
||||
static void nand_upm_setup (volatile fsl_lbc_t *lbc)
|
||||
{
|
||||
uint i, j;
|
||||
uint or3 = CONFIG_SYS_OR3_PRELIM;
|
||||
uint clock = get_lbc_clock ();
|
||||
|
||||
set_lbc_br(3, 0); /* disable bank and reset all bits */
|
||||
set_lbc_br(3, CONFIG_SYS_BR3_PRELIM);
|
||||
|
||||
/*
|
||||
* Search appropriate UPM table for bus clock.
|
||||
* If the bus clock exceeds a tolerated value, take the UPM timing for
|
||||
* the next higher supported frequency to ensure that access works
|
||||
* (even the access may be slower then).
|
||||
*/
|
||||
for (i = 0; (i < UPM_FREQS) && (clock > upm_freq_table[i].freq); i++)
|
||||
;
|
||||
|
||||
if (i >= UPM_FREQS)
|
||||
/* no valid entry found */
|
||||
/* take last entry with configuration for max. bus clock */
|
||||
i--;
|
||||
|
||||
if (upm_freq_table[i].ehtr) {
|
||||
/* EHTR must be set due to TQM8548 timing specification */
|
||||
or3 |= OR_UPM_EHTR;
|
||||
}
|
||||
if (upm_freq_table[i].ead)
|
||||
/* EAD must be set due to TQM8548 timing specification */
|
||||
or3 |= OR_UPM_EAD;
|
||||
|
||||
set_lbc_or(3, or3);
|
||||
|
||||
/* Assign address of table */
|
||||
nand_upm_patt = upm_freq_table[i].upm_patt;
|
||||
|
||||
for (j = 0; j < 64; j++) {
|
||||
upmb_write (j, *nand_upm_patt);
|
||||
nand_upm_patt++;
|
||||
}
|
||||
|
||||
/* Put UPM back to normal operation mode */
|
||||
if (upm_freq_table[i].gpl4_disable)
|
||||
/* GPL4 must be disabled according to timing specification */
|
||||
out_be32 (&lbc->mbmr, MxMR_OP_NORM | MxMR_GPL_x4DIS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct fsl_upm_nand fun = {
|
||||
.width = 8,
|
||||
.upm_cmd_offset = 0x08,
|
||||
.upm_addr_offset = 0x10,
|
||||
.upm_mar_chip_offset = CONFIG_SYS_NAND_CS_DIST,
|
||||
.chip_offset = CONFIG_SYS_NAND_CS_DIST,
|
||||
.chip_delay = NAND_BIG_DELAY_US,
|
||||
.wait_flags = FSL_UPM_WAIT_RUN_PATTERN | FSL_UPM_WAIT_WRITE_BUFFER,
|
||||
};
|
||||
|
||||
void board_nand_select_device (struct nand_chip *nand, int chip)
|
||||
{
|
||||
}
|
||||
|
||||
int board_nand_init (struct nand_chip *nand)
|
||||
{
|
||||
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
|
||||
|
||||
if (!nand_upm_patt)
|
||||
nand_upm_setup (lbc);
|
||||
|
||||
fun.upm.io_addr = nand->IO_ADDR_R;
|
||||
fun.upm.mxmr = (void __iomem *)&lbc->mbmr;
|
||||
fun.upm.mdr = (void __iomem *)&lbc->mdr;
|
||||
fun.upm.mar = (void __iomem *)&lbc->mar;
|
||||
|
||||
return fsl_upm_nand_init (nand, &fun);
|
||||
}
|
||||
|
|
@ -0,0 +1,436 @@
|
|||
|
||||
/*
|
||||
* (C) Copyright 2005
|
||||
* Stefan Roese, DENX Software Engineering, sr@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 <asm/processor.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
struct sdram_conf_s {
|
||||
unsigned long size;
|
||||
unsigned long reg;
|
||||
#ifdef CONFIG_TQM8548
|
||||
unsigned long refresh;
|
||||
#endif /* CONFIG_TQM8548 */
|
||||
};
|
||||
|
||||
typedef struct sdram_conf_s sdram_conf_t;
|
||||
|
||||
#ifdef CONFIG_TQM8548
|
||||
#ifdef CONFIG_TQM8548_AG
|
||||
sdram_conf_t ddr_cs_conf[] = {
|
||||
{(1024 << 20), 0x80044202, 0x0002D000}, /* 1024MB, 14x10(4) */
|
||||
{ (512 << 20), 0x80044102, 0x0001A000}, /* 512MB, 13x10(4) */
|
||||
{ (256 << 20), 0x80040102, 0x00014000}, /* 256MB, 13x10(4) */
|
||||
{ (128 << 20), 0x80040101, 0x0000C000}, /* 128MB, 13x9(4) */
|
||||
};
|
||||
#else /* !CONFIG_TQM8548_AG */
|
||||
sdram_conf_t ddr_cs_conf[] = {
|
||||
{(512 << 20), 0x80044102, 0x0001A000}, /* 512MB, 13x10(4) */
|
||||
{(256 << 20), 0x80040102, 0x00014000}, /* 256MB, 13x10(4) */
|
||||
{(128 << 20), 0x80040101, 0x0000C000}, /* 128MB, 13x9(4) */
|
||||
};
|
||||
#endif /* CONFIG_TQM8548_AG */
|
||||
#else /* !CONFIG_TQM8548 */
|
||||
sdram_conf_t ddr_cs_conf[] = {
|
||||
{(512 << 20), 0x80000202}, /* 512MB, 14x10(4) */
|
||||
{(256 << 20), 0x80000102}, /* 256MB, 13x10(4) */
|
||||
{(128 << 20), 0x80000101}, /* 128MB, 13x9(4) */
|
||||
{( 64 << 20), 0x80000001}, /* 64MB, 12x9(4) */
|
||||
};
|
||||
#endif /* CONFIG_TQM8548 */
|
||||
|
||||
#define N_DDR_CS_CONF (sizeof(ddr_cs_conf) / sizeof(ddr_cs_conf[0]))
|
||||
|
||||
int cas_latency (void);
|
||||
static phys_size_t sdram_setup(int);
|
||||
|
||||
/*
|
||||
* Autodetect onboard DDR SDRAM on 85xx platforms
|
||||
*
|
||||
* NOTE: Some of the hardcoded values are hardware dependant,
|
||||
* so this should be extended for other future boards
|
||||
* using this routine!
|
||||
*/
|
||||
phys_size_t fixed_sdram(void)
|
||||
{
|
||||
int casl = 0;
|
||||
phys_size_t dram_size = 0;
|
||||
|
||||
casl = cas_latency();
|
||||
dram_size = sdram_setup(casl);
|
||||
if ((dram_size == 0) && (casl != CONFIG_DDR_DEFAULT_CL)) {
|
||||
/*
|
||||
* Try again with default CAS latency
|
||||
*/
|
||||
printf("Problem with CAS lantency, using default CL %d/10!\n",
|
||||
CONFIG_DDR_DEFAULT_CL);
|
||||
dram_size = sdram_setup(CONFIG_DDR_DEFAULT_CL);
|
||||
puts(" ");
|
||||
}
|
||||
return dram_size;
|
||||
}
|
||||
|
||||
static phys_size_t sdram_setup(int casl)
|
||||
{
|
||||
int i;
|
||||
volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
|
||||
#ifdef CONFIG_TQM8548
|
||||
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE)
|
||||
volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
|
||||
#endif
|
||||
#else /* !CONFIG_TQM8548 */
|
||||
unsigned long cfg_ddr_timing1;
|
||||
unsigned long cfg_ddr_mode;
|
||||
#endif /* CONFIG_TQM8548 */
|
||||
|
||||
/*
|
||||
* Disable memory controller.
|
||||
*/
|
||||
ddr->cs0_config = 0;
|
||||
ddr->sdram_cfg = 0;
|
||||
|
||||
#ifdef CONFIG_TQM8548
|
||||
/* Timing and refresh settings for DDR2-533 and below */
|
||||
|
||||
ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
|
||||
ddr->cs0_config = ddr_cs_conf[0].reg;
|
||||
ddr->timing_cfg_3 = 0x00020000;
|
||||
|
||||
/* TIMING CFG 1, 533MHz
|
||||
* PRETOACT: 4 Clocks
|
||||
* ACTTOPRE: 12 Clocks
|
||||
* ACTTORW: 4 Clocks
|
||||
* CASLAT: 4 Clocks
|
||||
* REFREC: EXT_REFREC:REFREC 53 Clocks
|
||||
* WRREC: 4 Clocks
|
||||
* ACTTOACT: 3 Clocks
|
||||
* WRTORD: 2 Clocks
|
||||
*/
|
||||
ddr->timing_cfg_1 = 0x4C47D432;
|
||||
|
||||
/* TIMING CFG 2, 533MHz
|
||||
* ADD_LAT: 3 Clocks
|
||||
* CPO: READLAT + 1
|
||||
* WR_LAT: 3 Clocks
|
||||
* RD_TO_PRE: 2 Clocks
|
||||
* WR_DATA_DELAY: 1/2 Clock
|
||||
* CKE_PLS: 3 Clock
|
||||
* FOUR_ACT: 14 Clocks
|
||||
*/
|
||||
ddr->timing_cfg_2 = 0x331848CE;
|
||||
|
||||
/* DDR SDRAM Mode, 533MHz
|
||||
* MRS: Extended Mode Register
|
||||
* OUT: Outputs enabled
|
||||
* RDQS: no
|
||||
* DQS: enabled
|
||||
* OCD: default state
|
||||
* RTT: 75 Ohms
|
||||
* Posted CAS: 3 Clocks
|
||||
* ODS: reduced strength
|
||||
* DLL: enabled
|
||||
* MR: Mode Register
|
||||
* PD: fast exit
|
||||
* WR: 4 Clocks
|
||||
* DLL: no DLL reset
|
||||
* TM: normal
|
||||
* CAS latency: 4 Clocks
|
||||
* BT: sequential
|
||||
* Burst length: 4
|
||||
*/
|
||||
ddr->sdram_mode = 0x439E0642;
|
||||
|
||||
/* DDR SDRAM Interval, 533MHz
|
||||
* REFINT: 1040 Clocks
|
||||
* BSTOPRE: 256
|
||||
*/
|
||||
ddr->sdram_interval = (1040 << 16) | 0x100;
|
||||
|
||||
/*
|
||||
* Workaround for erratum DDR19 according to MPC8548 Device Errata
|
||||
* document, Rev. 1: DDR IO receiver must be set to an acceptable
|
||||
* bias point by modifying a hidden register.
|
||||
*/
|
||||
if (SVR_REV (get_svr ()) < 0x21)
|
||||
gur->ddrioovcr = 0x90000000; /* enable, VSEL 1.8V */
|
||||
|
||||
/* DDR SDRAM CFG 2
|
||||
* FRC_SR: normal mode
|
||||
* SR_IE: no self-refresh interrupt
|
||||
* DLL_RST_DIS: don't care, leave at reset value
|
||||
* DQS_CFG: differential DQS signals
|
||||
* ODT_CFG: assert ODT to internal IOs only during reads to DRAM
|
||||
* LVWx_CFG: don't care, leave at reset value
|
||||
* NUM_PR: 1 refresh will be issued at a time
|
||||
* DM_CFG: don't care, leave at reset value
|
||||
* D_INIT: no data initialization
|
||||
*/
|
||||
ddr->sdram_cfg_2 = 0x04401000;
|
||||
|
||||
/* DDR SDRAM MODE 2
|
||||
* MRS: Extended Mode Register 2
|
||||
*/
|
||||
ddr->sdram_mode_2 = 0x8000C000;
|
||||
|
||||
/* DDR SDRAM CLK CNTL
|
||||
* CLK_ADJUST: 1/2 Clock 0x02000000
|
||||
* CLK_ADJUST: 5/8 Clock 0x02800000
|
||||
*/
|
||||
ddr->sdram_clk_cntl = 0x02800000;
|
||||
|
||||
/* wait for clock stabilization */
|
||||
asm ("sync;isync;msync");
|
||||
udelay (1000);
|
||||
|
||||
#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE)
|
||||
/*
|
||||
* Workaround for erratum DDR20 according to MPC8548 Device Errata
|
||||
* document, Rev. 1: "CKE signal may not function correctly after
|
||||
* assertion of HRESET"
|
||||
*/
|
||||
|
||||
/* 1. Configure DDR register as is done in normal DDR configuration.
|
||||
* Do not set DDR_SDRAM_CFG[MEM_EN].
|
||||
*
|
||||
* 2. Set reserved bit EEBACR[3] at offset 0x1000
|
||||
*/
|
||||
ecm->eebacr |= 0x10000000;
|
||||
|
||||
/*
|
||||
* 3. Before DDR_SDRAM_CFG[MEM_EN] is set, write DDR_SDRAM_CFG_2[D_INIT]
|
||||
*
|
||||
* DDR_SDRAM_CFG_2:
|
||||
* FRC_SR: normal mode
|
||||
* SR_IE: no self-refresh interrupt
|
||||
* DLL_RST_DIS: don't care, leave at reset value
|
||||
* DQS_CFG: differential DQS signals
|
||||
* ODT_CFG: assert ODT to internal IOs only during reads to DRAM
|
||||
* LVWx_CFG: don't care, leave at reset value
|
||||
* NUM_PR: 1 refresh will be issued at a time
|
||||
* DM_CFG: don't care, leave at reset value
|
||||
* D_INIT: enable data initialization
|
||||
*/
|
||||
ddr->sdram_cfg_2 |= 0x00000010;
|
||||
|
||||
/*
|
||||
* 4. Before DDR_SDRAM_CFG[MEM_EN] set, write D3[21] to disable data
|
||||
* training
|
||||
*/
|
||||
ddr->debug[2] |= 0x00000400;
|
||||
|
||||
/*
|
||||
* 5. Wait 200 micro-seconds
|
||||
*/
|
||||
udelay (200);
|
||||
|
||||
/*
|
||||
* 6. Set DDR_SDRAM_CFG[MEM_EN]
|
||||
*
|
||||
* BTW, initialize DDR_SDRAM_CFG:
|
||||
* MEM_EN: enabled
|
||||
* SREN: don't care, leave at reset value
|
||||
* ECC_EN: no error report
|
||||
* RD_EN: no registered DIMMs
|
||||
* SDRAM_TYPE: DDR2
|
||||
* DYN_PWR: no power management
|
||||
* 32_BE: don't care, leave at reset value
|
||||
* 8_BE: 4 beat burst
|
||||
* NCAP: don't care, leave at reset value
|
||||
* 2T_EN: 1T Timing
|
||||
* BA_INTLV_CTL: no interleaving
|
||||
* x32_EN: x16 organization
|
||||
* PCHB8: MA[10] for auto-precharge
|
||||
* HSE: half strength for single and 2-layer stacks
|
||||
* (full strength for 3- and 4-layer stacks not
|
||||
* yet considered)
|
||||
* MEM_HALT: no halt
|
||||
* BI: automatic initialization
|
||||
*/
|
||||
ddr->sdram_cfg = 0x83000008;
|
||||
|
||||
/*
|
||||
* 7. Poll DDR_SDRAM_CFG_2[D_INIT] until it is cleared by hardware
|
||||
*/
|
||||
asm ("sync;isync;msync");
|
||||
while (ddr->sdram_cfg_2 & 0x00000010)
|
||||
asm ("eieio");
|
||||
|
||||
/*
|
||||
* 8. Clear D3[21] to re-enable data training
|
||||
*/
|
||||
ddr->debug[2] &= ~0x00000400;
|
||||
|
||||
/*
|
||||
* 9. Set D2(21) to force data training to run
|
||||
*/
|
||||
ddr->debug[1] |= 0x00000400;
|
||||
|
||||
/*
|
||||
* 10. Poll on D2[21] until it is cleared by hardware
|
||||
*/
|
||||
asm ("sync;isync;msync");
|
||||
while (ddr->debug[1] & 0x00000400)
|
||||
asm ("eieio");
|
||||
|
||||
/*
|
||||
* 11. Clear reserved bit EEBACR[3] at offset 0x1000
|
||||
*/
|
||||
ecm->eebacr &= ~0x10000000;
|
||||
|
||||
#else /* !(CONFIG_TQM8548_AG || CONFIG_TQM8548_BE) */
|
||||
|
||||
/* DDR SDRAM CLK CNTL
|
||||
* MEM_EN: enabled
|
||||
* SREN: don't care, leave at reset value
|
||||
* ECC_EN: no error report
|
||||
* RD_EN: no register DIMMs
|
||||
* SDRAM_TYPE: DDR2
|
||||
* DYN_PWR: no power management
|
||||
* 32_BE: don't care, leave at reset value
|
||||
* 8_BE: 4 beat burst
|
||||
* NCAP: don't care, leave at reset value
|
||||
* 2T_EN: 1T Timing
|
||||
* BA_INTLV_CTL: no interleaving
|
||||
* x32_EN: x16 organization
|
||||
* PCHB8: MA[10] for auto-precharge
|
||||
* HSE: half strength for single and 2-layer stacks
|
||||
* (full strength for 3- and 4-layer stacks no yet considered)
|
||||
* MEM_HALT: no halt
|
||||
* BI: automatic initialization
|
||||
*/
|
||||
ddr->sdram_cfg = 0x83000008;
|
||||
|
||||
#endif /* CONFIG_TQM8548_AG || CONFIG_TQM8548_BE */
|
||||
|
||||
asm ("sync; isync; msync");
|
||||
udelay (1000);
|
||||
#else /* !CONFIG_TQM8548 */
|
||||
switch (casl) {
|
||||
case 20:
|
||||
cfg_ddr_timing1 = 0x47405331 | (3 << 16);
|
||||
cfg_ddr_mode = 0x40020002 | (2 << 4);
|
||||
break;
|
||||
|
||||
case 25:
|
||||
cfg_ddr_timing1 = 0x47405331 | (4 << 16);
|
||||
cfg_ddr_mode = 0x40020002 | (6 << 4);
|
||||
break;
|
||||
|
||||
case 30:
|
||||
default:
|
||||
cfg_ddr_timing1 = 0x47405331 | (5 << 16);
|
||||
cfg_ddr_mode = 0x40020002 | (3 << 4);
|
||||
break;
|
||||
}
|
||||
|
||||
ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
|
||||
ddr->cs0_config = ddr_cs_conf[0].reg;
|
||||
ddr->timing_cfg_1 = cfg_ddr_timing1;
|
||||
ddr->timing_cfg_2 = 0x00000800; /* P9-45,may need tuning */
|
||||
ddr->sdram_mode = cfg_ddr_mode;
|
||||
ddr->sdram_interval = 0x05160100; /* autocharge,no open page */
|
||||
ddr->err_disable = 0x0000000D;
|
||||
|
||||
asm ("sync; isync; msync");
|
||||
udelay (1000);
|
||||
|
||||
ddr->sdram_cfg = 0xc2000000; /* unbuffered,no DYN_PWR */
|
||||
asm ("sync; isync; msync");
|
||||
udelay (1000);
|
||||
#endif /* CONFIG_TQM8548 */
|
||||
|
||||
/*
|
||||
* get_ram_size() depends on having tlbs for the DDR, but they are
|
||||
* not yet setup because we don't know the size. Set up a temp
|
||||
* mapping and delete it when done.
|
||||
*/
|
||||
setup_ddr_tlbs(CONFIG_SYS_DDR_EARLY_SIZE_MB);
|
||||
for (i = 0; i < N_DDR_CS_CONF; i++) {
|
||||
ddr->cs0_config = ddr_cs_conf[i].reg;
|
||||
|
||||
if (get_ram_size (0, ddr_cs_conf[i].size) ==
|
||||
ddr_cs_conf[i].size) {
|
||||
/*
|
||||
* size detected -> set Chip Select Bounds Register
|
||||
*/
|
||||
ddr->cs0_bnds = (ddr_cs_conf[i].size - 1) >> 24;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
clear_ddr_tlbs(CONFIG_SYS_DDR_EARLY_SIZE_MB);
|
||||
|
||||
#ifdef CONFIG_TQM8548
|
||||
if (i < N_DDR_CS_CONF) {
|
||||
/* Adjust refresh rate for DDR2 */
|
||||
|
||||
ddr->timing_cfg_3 = ddr_cs_conf[i].refresh & 0x00070000;
|
||||
|
||||
ddr->timing_cfg_1 = (ddr->timing_cfg_1 & 0xFFFF0FFF) |
|
||||
(ddr_cs_conf[i].refresh & 0x0000F000);
|
||||
|
||||
return ddr_cs_conf[i].size;
|
||||
}
|
||||
#endif /* CONFIG_TQM8548 */
|
||||
|
||||
/* return size if detected, else return 0 */
|
||||
return (i < N_DDR_CS_CONF) ? ddr_cs_conf[i].size : 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SYS_DRAM_TEST)
|
||||
int testdram (void)
|
||||
{
|
||||
uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START;
|
||||
uint *pend = (uint *) CONFIG_SYS_MEMTEST_END;
|
||||
uint *p;
|
||||
|
||||
printf ("SDRAM test phase 1:\n");
|
||||
for (p = pstart; p < pend; p++)
|
||||
*p = 0xaaaaaaaa;
|
||||
|
||||
for (p = pstart; p < pend; p++) {
|
||||
if (*p != 0xaaaaaaaa) {
|
||||
printf ("SDRAM test fails at: %08x\n", (uint) p);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("SDRAM test phase 2:\n");
|
||||
for (p = pstart; p < pend; p++)
|
||||
*p = 0x55555555;
|
||||
|
||||
for (p = pstart; p < pend; p++) {
|
||||
if (*p != 0x55555555) {
|
||||
printf ("SDRAM test fails at: %08x\n", (uint) p);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("SDRAM test passed.\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright 2008 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/mmu.h>
|
||||
|
||||
struct fsl_e_tlb_entry tlb_table[] = {
|
||||
/* TLB 0 - for temp stack in cache */
|
||||
SET_TLB_ENTRY (0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
SET_TLB_ENTRY (0, CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024,
|
||||
CONFIG_SYS_INIT_RAM_ADDR + 4 * 1024,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
SET_TLB_ENTRY (0, CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024,
|
||||
CONFIG_SYS_INIT_RAM_ADDR + 8 * 1024,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
SET_TLB_ENTRY (0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024,
|
||||
CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, 0,
|
||||
0, 0, BOOKE_PAGESZ_4K, 0),
|
||||
|
||||
#ifndef CONFIG_TQM_BIGFLASH
|
||||
/*
|
||||
* TLB 0, 1: 128M Non-cacheable, guarded
|
||||
* 0xf8000000 128M FLASH
|
||||
* Out of reset this entry is only 4K.
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 1, BOOKE_PAGESZ_64M, 1),
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_FLASH_BASE + 0x4000000,
|
||||
CONFIG_SYS_FLASH_BASE + 0x4000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_64M, 1),
|
||||
|
||||
/*
|
||||
* TLB 2: 256M Non-cacheable, guarded
|
||||
* 0x80000000 256M PCI1 MEM First half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCI1_MEM_PHYS, CONFIG_SYS_PCI1_MEM_PHYS,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 2, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
/*
|
||||
* TLB 3: 256M Non-cacheable, guarded
|
||||
* 0x90000000 256M PCI1 MEM Second half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCI1_MEM_PHYS + 0x10000000,
|
||||
CONFIG_SYS_PCI1_MEM_PHYS + 0x10000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 3, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
#ifdef CONFIG_PCIE1
|
||||
/*
|
||||
* TLB 4: 256M Non-cacheable, guarded
|
||||
* 0xc0000000 256M PCI express MEM First half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCIE1_MEM_BUS, CONFIG_SYS_PCIE1_MEM_BUS,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 4, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
/*
|
||||
* TLB 5: 256M Non-cacheable, guarded
|
||||
* 0xd0000000 256M PCI express MEM Second half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCIE1_MEM_BUS + 0x10000000,
|
||||
CONFIG_SYS_PCIE1_MEM_BUS + 0x10000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 5, BOOKE_PAGESZ_256M, 1),
|
||||
#else /* !CONFIG_PCIE */
|
||||
/*
|
||||
* TLB 4: 256M Non-cacheable, guarded
|
||||
* 0xc0000000 256M Rapid IO MEM First half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_RIO_MEM_BASE, CONFIG_SYS_RIO_MEM_BASE,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 4, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
/*
|
||||
* TLB 5: 256M Non-cacheable, guarded
|
||||
* 0xd0000000 256M Rapid IO MEM Second half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_RIO_MEM_BASE + 0x10000000,
|
||||
CONFIG_SYS_RIO_MEM_BASE + 0x10000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 5, BOOKE_PAGESZ_256M, 1),
|
||||
#endif /* CONFIG_PCIE */
|
||||
|
||||
/*
|
||||
* TLB 6: 64M Non-cacheable, guarded
|
||||
* 0xe0000000 1M CCSRBAR
|
||||
* 0xe2000000 16M PCI1 IO
|
||||
* 0xe3000000 16M CAN and NAND Flash
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 6, BOOKE_PAGESZ_64M, 1),
|
||||
#ifdef CONFIG_PCIE1
|
||||
/*
|
||||
* TLB 9: 16M Non-cacheable, guarded
|
||||
* 0xef000000 16M PCI express IO
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCIE1_IO_BUS, CONFIG_SYS_PCIE1_IO_BUS,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 9, BOOKE_PAGESZ_16M, 1),
|
||||
#endif /* CONFIG_PCIE */
|
||||
|
||||
#else /* CONFIG_TQM_BIGFLASH */
|
||||
|
||||
/*
|
||||
* TLB 0,1,2,3: 1G Non-cacheable, guarded
|
||||
* 0xc0000000 1G FLASH
|
||||
* Out of reset this entry is only 4K.
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 3, BOOKE_PAGESZ_256M, 1),
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_FLASH_BASE + 0x10000000,
|
||||
CONFIG_SYS_FLASH_BASE + 0x10000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 2, BOOKE_PAGESZ_256M, 1),
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_FLASH_BASE + 0x20000000,
|
||||
CONFIG_SYS_FLASH_BASE + 0x20000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 1, BOOKE_PAGESZ_256M, 1),
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_FLASH_BASE + 0x30000000,
|
||||
CONFIG_SYS_FLASH_BASE + 0x30000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 0, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
/*
|
||||
* TLB 4: 256M Non-cacheable, guarded
|
||||
* 0x80000000 256M PCI1 MEM First half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCI1_MEM_PHYS, CONFIG_SYS_PCI1_MEM_PHYS,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 4, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
/*
|
||||
* TLB 5: 256M Non-cacheable, guarded
|
||||
* 0x90000000 256M PCI1 MEM Second half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCI1_MEM_PHYS + 0x10000000,
|
||||
CONFIG_SYS_PCI1_MEM_PHYS + 0x10000000,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 5, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
#ifdef CONFIG_PCIE1
|
||||
/*
|
||||
* TLB 6: 256M Non-cacheable, guarded
|
||||
* 0xc0000000 256M PCI express MEM First half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCIE1_MEM_BUS, CONFIG_SYS_PCIE1_MEM_BUS,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 6, BOOKE_PAGESZ_256M, 1),
|
||||
#else /* !CONFIG_PCIE */
|
||||
/*
|
||||
* TLB 6: 256M Non-cacheable, guarded
|
||||
* 0xb0000000 256M Rapid IO MEM First half
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_RIO_MEM_BASE, CONFIG_SYS_RIO_MEM_BASE,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 6, BOOKE_PAGESZ_256M, 1),
|
||||
|
||||
#endif /* CONFIG_PCIE */
|
||||
|
||||
/*
|
||||
* TLB 7: 64M Non-cacheable, guarded
|
||||
* 0xa0000000 1M CCSRBAR
|
||||
* 0xa2000000 16M PCI1 IO
|
||||
* 0xa3000000 16M CAN and NAND Flash
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 7, BOOKE_PAGESZ_64M, 1),
|
||||
#ifdef CONFIG_PCIE1
|
||||
/*
|
||||
* TLB 10: 16M Non-cacheable, guarded
|
||||
* 0xaf000000 16M PCI express IO
|
||||
*/
|
||||
SET_TLB_ENTRY (1, CONFIG_SYS_PCIE1_IO_BASE, CONFIG_SYS_PCIE1_IO_BASE,
|
||||
MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G,
|
||||
0, 10, BOOKE_PAGESZ_16M, 1),
|
||||
#endif /* CONFIG_PCIE */
|
||||
|
||||
#endif /* CONFIG_TQM_BIGFLASH */
|
||||
};
|
||||
|
||||
int num_tlb_entries = ARRAY_SIZE (tlb_table);
|
||||
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* (C) Copyright 2008 Wolfgang Grandegger <wg@denx.de>
|
||||
*
|
||||
* (C) Copyright 2006
|
||||
* Thomas Waehner, TQ-Systems GmbH, thomas.waehner@tqs.de.
|
||||
*
|
||||
* (C) Copyright 2005
|
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
*
|
||||
* Copyright 2004 Freescale Semiconductor.
|
||||
* (C) Copyright 2002,2003, Motorola Inc.
|
||||
* Xianghua Xiao, (X.Xiao@motorola.com)
|
||||
*
|
||||
* (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <pci.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/immap_85xx.h>
|
||||
#include <asm/fsl_pci.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/fsl_serdes.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <ioports.h>
|
||||
#include <flash.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <netdev.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
extern flash_info_t flash_info[]; /* FLASH chips info */
|
||||
|
||||
void local_bus_init (void);
|
||||
ulong flash_get_size (ulong base, int banknum);
|
||||
|
||||
#ifdef CONFIG_PS2MULT
|
||||
void ps2mult_early_init (void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPM2
|
||||
/*
|
||||
* 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: conf, ppar, psor, pdir, podr, pdat */
|
||||
{
|
||||
{1, 1, 1, 0, 0, 0}, /* PA31: FCC1 MII COL */
|
||||
{1, 1, 1, 0, 0, 0}, /* PA30: FCC1 MII CRS */
|
||||
{1, 1, 1, 1, 0, 0}, /* PA29: FCC1 MII TX_ER */
|
||||
{1, 1, 1, 1, 0, 0}, /* PA28: FCC1 MII TX_EN */
|
||||
{1, 1, 1, 0, 0, 0}, /* PA27: FCC1 MII RX_DV */
|
||||
{1, 1, 1, 0, 0, 0}, /* PA26: FCC1 MII RX_ER */
|
||||
{0, 1, 0, 1, 0, 0}, /* PA25: FCC1 ATMTXD[0] */
|
||||
{0, 1, 0, 1, 0, 0}, /* PA24: FCC1 ATMTXD[1] */
|
||||
{0, 1, 0, 1, 0, 0}, /* PA23: FCC1 ATMTXD[2] */
|
||||
{0, 1, 0, 1, 0, 0}, /* PA22: FCC1 ATMTXD[3] */
|
||||
{1, 1, 0, 1, 0, 0}, /* PA21: FCC1 MII TxD[3] */
|
||||
{1, 1, 0, 1, 0, 0}, /* PA20: FCC1 MII TxD[2] */
|
||||
{1, 1, 0, 1, 0, 0}, /* PA19: FCC1 MII TxD[1] */
|
||||
{1, 1, 0, 1, 0, 0}, /* PA18: FCC1 MII TxD[0] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PA17: FCC1 MII RxD[0] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PA16: FCC1 MII RxD[1] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PA15: FCC1 MII RxD[2] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PA14: FCC1 MII RxD[3] */
|
||||
{0, 1, 0, 0, 0, 0}, /* PA13: FCC1 ATMRXD[3] */
|
||||
{0, 1, 0, 0, 0, 0}, /* PA12: FCC1 ATMRXD[2] */
|
||||
{0, 1, 0, 0, 0, 0}, /* PA11: FCC1 ATMRXD[1] */
|
||||
{0, 1, 0, 0, 0, 0}, /* PA10: FCC1 ATMRXD[0] */
|
||||
{0, 1, 1, 1, 0, 0}, /* PA9 : FCC1 L1TXD */
|
||||
{0, 1, 1, 0, 0, 0}, /* PA8 : FCC1 L1RXD */
|
||||
{0, 0, 0, 1, 0, 0}, /* PA7 : PA7 */
|
||||
{0, 1, 1, 1, 0, 0}, /* PA6 : TDM A1 L1RSYNC */
|
||||
{0, 0, 0, 1, 0, 0}, /* PA5 : PA5 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PA4 : PA4 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PA3 : PA3 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PA2 : PA2 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PA1 : FREERUN */
|
||||
{0, 0, 0, 1, 0, 0} /* PA0 : PA0 */
|
||||
},
|
||||
|
||||
/* Port B: conf, ppar, psor, pdir, podr, pdat */
|
||||
{
|
||||
{1, 1, 0, 1, 0, 0}, /* PB31: FCC2 MII TX_ER */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB30: FCC2 MII RX_DV */
|
||||
{1, 1, 1, 1, 0, 0}, /* PB29: FCC2 MII TX_EN */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB28: FCC2 MII RX_ER */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB27: FCC2 MII COL */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB26: FCC2 MII CRS */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB25: FCC2 MII TxD[3] */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB24: FCC2 MII TxD[2] */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB23: FCC2 MII TxD[1] */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB22: FCC2 MII TxD[0] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB21: FCC2 MII RxD[0] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB20: FCC2 MII RxD[1] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB19: FCC2 MII RxD[2] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB18: FCC2 MII RxD[3] */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB17: FCC3:RX_DIV */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB16: FCC3:RX_ERR */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB15: FCC3:TX_ERR */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB14: FCC3:TX_EN */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB13: FCC3:COL */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB12: FCC3:CRS */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB11: FCC3:RXD */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB10: FCC3:RXD */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB9 : FCC3:RXD */
|
||||
{1, 1, 0, 0, 0, 0}, /* PB8 : FCC3:RXD */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB7 : FCC3:TXD */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB6 : FCC3:TXD */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB5 : FCC3:TXD */
|
||||
{1, 1, 0, 1, 0, 0}, /* PB4 : FCC3:TXD */
|
||||
{0, 0, 0, 0, 0, 0}, /* PB3 : pin doesn't exist */
|
||||
{0, 0, 0, 0, 0, 0}, /* PB2 : pin doesn't exist */
|
||||
{0, 0, 0, 0, 0, 0}, /* PB1 : pin doesn't exist */
|
||||
{0, 0, 0, 0, 0, 0} /* PB0 : pin doesn't exist */
|
||||
},
|
||||
|
||||
/* Port C: conf, ppar, psor, pdir, podr, pdat */
|
||||
{
|
||||
{0, 0, 0, 1, 0, 0}, /* PC31: PC31 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC30: PC30 */
|
||||
{0, 1, 1, 0, 0, 0}, /* PC29: SCC1 EN *CLSN */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC28: PC28 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC27: UART Clock in */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC26: PC26 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC25: PC25 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC24: PC24 */
|
||||
{0, 1, 0, 1, 0, 0}, /* PC23: ATMTFCLK */
|
||||
{0, 1, 0, 0, 0, 0}, /* PC22: ATMRFCLK */
|
||||
{1, 1, 0, 0, 0, 0}, /* PC21: SCC1 EN RXCLK */
|
||||
{1, 1, 0, 0, 0, 0}, /* PC20: SCC1 EN TXCLK */
|
||||
{1, 1, 0, 0, 0, 0}, /* PC19: FCC2 MII RX_CLK CLK13 */
|
||||
{1, 1, 0, 0, 0, 0}, /* PC18: FCC Tx Clock (CLK14) */
|
||||
{1, 1, 0, 0, 0, 0}, /* PC17: PC17 */
|
||||
{1, 1, 0, 0, 0, 0}, /* PC16: FCC Tx Clock (CLK16) */
|
||||
{0, 1, 0, 0, 0, 0}, /* PC15: PC15 */
|
||||
{0, 1, 0, 0, 0, 0}, /* PC14: SCC1 EN *CD */
|
||||
{0, 1, 0, 0, 0, 0}, /* PC13: PC13 */
|
||||
{0, 1, 0, 1, 0, 0}, /* PC12: PC12 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC11: LXT971 transmit control */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC10: FETHMDC */
|
||||
{0, 0, 0, 0, 0, 0}, /* PC9 : FETHMDIO */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC8 : PC8 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC7 : PC7 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC6 : PC6 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC5 : PC5 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC4 : PC4 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC3 : PC3 */
|
||||
{0, 0, 0, 1, 0, 1}, /* PC2 : ENET FDE */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC1 : ENET DSQE */
|
||||
{0, 0, 0, 1, 0, 0}, /* PC0 : ENET LBK */
|
||||
},
|
||||
|
||||
/* Port D: conf, ppar, psor, pdir, podr, pdat */
|
||||
{
|
||||
#ifdef CONFIG_TQM8560
|
||||
{1, 1, 0, 0, 0, 0}, /* PD31: SCC1 EN RxD */
|
||||
{1, 1, 1, 1, 0, 0}, /* PD30: SCC1 EN TxD */
|
||||
{1, 1, 0, 1, 0, 0}, /* PD29: SCC1 EN TENA */
|
||||
#else /* !CONFIG_TQM8560 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD31: PD31 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD30: PD30 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD29: PD29 */
|
||||
#endif /* CONFIG_TQM8560 */
|
||||
{1, 1, 0, 0, 0, 0}, /* PD28: PD28 */
|
||||
{1, 1, 0, 1, 0, 0}, /* PD27: PD27 */
|
||||
{1, 1, 0, 1, 0, 0}, /* PD26: PD26 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD25: PD25 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD24: PD24 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD23: PD23 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD22: PD22 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD21: PD21 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD20: PD20 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD19: PD19 */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD18: PD18 */
|
||||
{0, 1, 0, 0, 0, 0}, /* PD17: FCC1 ATMRXPRTY */
|
||||
{0, 1, 0, 1, 0, 0}, /* PD16: FCC1 ATMTXPRTY */
|
||||
{0, 1, 1, 0, 1, 0}, /* PD15: I2C SDA */
|
||||
{0, 0, 0, 1, 0, 0}, /* PD14: LED */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD13: PD13 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD12: PD12 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD11: PD11 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD10: PD10 */
|
||||
{0, 1, 0, 1, 0, 0}, /* PD9 : SMC1 TXD */
|
||||
{0, 1, 0, 0, 0, 0}, /* PD8 : SMC1 RXD */
|
||||
{0, 0, 0, 1, 0, 1}, /* PD7 : PD7 */
|
||||
{0, 0, 0, 1, 0, 1}, /* PD6 : PD6 */
|
||||
{0, 0, 0, 1, 0, 1}, /* PD5 : PD5 */
|
||||
{0, 0, 0, 1, 0, 1}, /* PD4 : PD4 */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD3 : pin doesn't exist */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD2 : pin doesn't exist */
|
||||
{0, 0, 0, 0, 0, 0}, /* PD1 : pin doesn't exist */
|
||||
{0, 0, 0, 0, 0, 0} /* PD0 : pin doesn't exist */
|
||||
}
|
||||
};
|
||||
#endif /* CONFIG_CPM2 */
|
||||
|
||||
#define CASL_STRING1 "casl=xx"
|
||||
#define CASL_STRING2 "casl="
|
||||
|
||||
static const int casl_table[] = { 20, 25, 30 };
|
||||
#define N_CASL (sizeof(casl_table) / sizeof(casl_table[0]))
|
||||
|
||||
int cas_latency (void)
|
||||
{
|
||||
char buf[128];
|
||||
int casl;
|
||||
int val;
|
||||
int i;
|
||||
|
||||
casl = CONFIG_DDR_DEFAULT_CL;
|
||||
|
||||
i = getenv_f("serial#", buf, sizeof(buf));
|
||||
|
||||
if (i >0) {
|
||||
if (strncmp(buf + strlen (buf) - strlen (CASL_STRING1),
|
||||
CASL_STRING2, strlen (CASL_STRING2)) == 0) {
|
||||
val = simple_strtoul (buf + strlen (buf) - 2, NULL, 10);
|
||||
|
||||
for (i = 0; i < N_CASL; ++i) {
|
||||
if (val == casl_table[i]) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return casl;
|
||||
}
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
char buf[64];
|
||||
int i = getenv_f("serial#", buf, sizeof(buf));
|
||||
|
||||
printf ("Board: %s", CONFIG_BOARDNAME);
|
||||
if (i > 0) {
|
||||
puts(", serial# ");
|
||||
puts(buf);
|
||||
}
|
||||
putc ('\n');
|
||||
|
||||
/*
|
||||
* Initialize local bus.
|
||||
*/
|
||||
local_bus_init ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int misc_init_r (void)
|
||||
{
|
||||
/*
|
||||
* Adjust flash start and offset to detected values
|
||||
*/
|
||||
gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
|
||||
gd->bd->bi_flashoffset = 0;
|
||||
|
||||
/*
|
||||
* Recalculate CS configuration if second FLASH bank is available
|
||||
*/
|
||||
if (flash_info[0].size > 0) {
|
||||
set_lbc_or(1, ((-flash_info[0].size) & 0xffff8000) |
|
||||
(CONFIG_SYS_OR1_PRELIM & 0x00007fff));
|
||||
set_lbc_br(1, gd->bd->bi_flashstart |
|
||||
(CONFIG_SYS_BR1_PRELIM & 0x00007fff));
|
||||
/*
|
||||
* Re-check to get correct base address for bank 1
|
||||
*/
|
||||
flash_get_size (gd->bd->bi_flashstart, 0);
|
||||
} else {
|
||||
set_lbc_or(1, 0);
|
||||
set_lbc_br(1, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If bank 1 is equipped, bank 0 is mapped after bank 1
|
||||
*/
|
||||
set_lbc_or(0, ((-flash_info[1].size) & 0xffff8000) |
|
||||
(CONFIG_SYS_OR0_PRELIM & 0x00007fff));
|
||||
set_lbc_br(0, (gd->bd->bi_flashstart + flash_info[0].size) |
|
||||
(CONFIG_SYS_BR0_PRELIM & 0x00007fff));
|
||||
|
||||
/*
|
||||
* Re-check to get correct base address for bank 0
|
||||
*/
|
||||
flash_get_size (gd->bd->bi_flashstart + flash_info[0].size, 1);
|
||||
|
||||
/*
|
||||
* Re-do flash protection upon new addresses
|
||||
*/
|
||||
flash_protect (FLAG_PROTECT_CLEAR,
|
||||
gd->bd->bi_flashstart, 0xffffffff,
|
||||
&flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);
|
||||
|
||||
/* Monitor protection ON by default */
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CONFIG_SYS_MONITOR_BASE, 0xffffffff,
|
||||
&flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);
|
||||
|
||||
/* Environment protection ON by default */
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CONFIG_ENV_ADDR,
|
||||
CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
|
||||
&flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);
|
||||
|
||||
#ifdef CONFIG_ENV_ADDR_REDUND
|
||||
/* Redundant environment protection ON by default */
|
||||
flash_protect (FLAG_PROTECT_SET,
|
||||
CONFIG_ENV_ADDR_REDUND,
|
||||
CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
|
||||
&flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAN_DRIVER
|
||||
/*
|
||||
* Initialize UPMC RAM
|
||||
*/
|
||||
static void upmc_write (u_char addr, uint val)
|
||||
{
|
||||
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
|
||||
|
||||
out_be32 (&lbc->mdr, val);
|
||||
|
||||
clrsetbits_be32(&lbc->mcmr, MxMR_MAD_MSK,
|
||||
MxMR_OP_WARR | (addr & MxMR_MAD_MSK));
|
||||
|
||||
/* dummy access to perform write */
|
||||
out_8 ((void __iomem *)CONFIG_SYS_CAN_BASE, 0);
|
||||
|
||||
/* normal operation */
|
||||
clrbits_be32(&lbc->mcmr, MxMR_OP_WARR);
|
||||
}
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
|
||||
uint get_lbc_clock (void)
|
||||
{
|
||||
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
|
||||
sys_info_t sys_info;
|
||||
ulong clkdiv = lbc->lcrr & LCRR_CLKDIV;
|
||||
|
||||
get_sys_info (&sys_info);
|
||||
|
||||
if (clkdiv == 2 || clkdiv == 4 || clkdiv == 8) {
|
||||
#ifdef CONFIG_MPC8548
|
||||
/*
|
||||
* Yes, the entire PQ38 family use the same
|
||||
* bit-representation for twice the clock divider value.
|
||||
*/
|
||||
clkdiv *= 2;
|
||||
#endif
|
||||
return sys_info.freqSystemBus / clkdiv;
|
||||
}
|
||||
|
||||
puts("Invalid clock divider value in CONFIG_SYS_LBC_LCRR\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize Local Bus
|
||||
*/
|
||||
void local_bus_init (void)
|
||||
{
|
||||
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
|
||||
uint lbc_mhz = get_lbc_clock () / 1000000;
|
||||
|
||||
#ifdef CONFIG_MPC8548
|
||||
uint svr = get_svr ();
|
||||
uint lcrr;
|
||||
|
||||
/*
|
||||
* MPC revision < 2.0
|
||||
* According to MPC8548E_Device_Errata Rev. L, Erratum LBIU1:
|
||||
* Modify engineering use only register at address 0xE_0F20.
|
||||
* "1. Read register at offset 0xE_0F20
|
||||
* 2. And value with 0x0000_FFFF
|
||||
* 3. OR result with 0x0000_0004
|
||||
* 4. Write result back to offset 0xE_0F20."
|
||||
*
|
||||
* According to MPC8548E_Device_Errata Rev. L, Erratum LBIU2:
|
||||
* Modify engineering use only register at address 0xE_0F20.
|
||||
* "1. Read register at offset 0xE_0F20
|
||||
* 2. And value with 0xFFFF_FFDF
|
||||
* 3. Write result back to offset 0xE_0F20."
|
||||
*
|
||||
* Since it is the same register, we do the modification in one step.
|
||||
*/
|
||||
if (SVR_MAJ (svr) < 2) {
|
||||
uint dummy = gur->lbiuiplldcr1;
|
||||
dummy &= 0x0000FFDF;
|
||||
dummy |= 0x00000004;
|
||||
gur->lbiuiplldcr1 = dummy;
|
||||
}
|
||||
|
||||
lcrr = CONFIG_SYS_LBC_LCRR;
|
||||
|
||||
/*
|
||||
* Local Bus Clock > 83.3 MHz. According to timing
|
||||
* specifications set LCRR[EADC] to 2 delay cycles.
|
||||
*/
|
||||
if (lbc_mhz > 83) {
|
||||
lcrr &= ~LCRR_EADC;
|
||||
lcrr |= LCRR_EADC_2;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to MPC8548ERMAD Rev. 1.3, 13.3.1.16, 13-30
|
||||
* disable PLL bypass for Local Bus Clock > 83 MHz.
|
||||
*/
|
||||
if (lbc_mhz >= 66)
|
||||
lcrr &= (~LCRR_DBYP); /* DLL Enabled */
|
||||
|
||||
else
|
||||
lcrr |= LCRR_DBYP; /* DLL Bypass */
|
||||
|
||||
lbc->lcrr = lcrr;
|
||||
asm ("sync;isync;msync");
|
||||
|
||||
/*
|
||||
* According to MPC8548ERMAD Rev.1.3 read back LCRR
|
||||
* and terminate with isync
|
||||
*/
|
||||
lcrr = lbc->lcrr;
|
||||
asm ("isync;");
|
||||
|
||||
/* let DLL stabilize */
|
||||
udelay (500);
|
||||
|
||||
#else /* !CONFIG_MPC8548 */
|
||||
|
||||
/*
|
||||
* Errata LBC11.
|
||||
* Fix Local Bus clock glitch when DLL is enabled.
|
||||
*
|
||||
* If localbus freq is < 66MHz, DLL bypass mode must be used.
|
||||
* If localbus freq is > 133MHz, DLL can be safely enabled.
|
||||
* Between 66 and 133, the DLL is enabled with an override workaround.
|
||||
*/
|
||||
|
||||
if (lbc_mhz < 66) {
|
||||
lbc->lcrr = CONFIG_SYS_LBC_LCRR | LCRR_DBYP; /* DLL Bypass */
|
||||
lbc->ltedr = LTEDR_BMD | LTEDR_PARD | LTEDR_WPD | LTEDR_WARA |
|
||||
LTEDR_RAWA | LTEDR_CSD; /* Disable all error checking */
|
||||
|
||||
} else if (lbc_mhz >= 133) {
|
||||
lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* On REV1 boards, need to change CLKDIV before enable DLL.
|
||||
* Default CLKDIV is 8, change it to 4 temporarily.
|
||||
*/
|
||||
uint pvr = get_pvr ();
|
||||
uint temp_lbcdll = 0;
|
||||
|
||||
if (pvr == PVR_85xx_REV1) {
|
||||
/* FIXME: Justify the high bit here. */
|
||||
lbc->lcrr = 0x10000004;
|
||||
}
|
||||
|
||||
lbc->lcrr = CONFIG_SYS_LBC_LCRR & (~LCRR_DBYP); /* DLL Enabled */
|
||||
udelay (200);
|
||||
|
||||
/*
|
||||
* Sample LBC DLL ctrl reg, upshift it to set the
|
||||
* override bits.
|
||||
*/
|
||||
temp_lbcdll = gur->lbcdllcr;
|
||||
gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000);
|
||||
asm ("sync;isync;msync");
|
||||
}
|
||||
#endif /* !CONFIG_MPC8548 */
|
||||
|
||||
#ifdef CONFIG_CAN_DRIVER
|
||||
/*
|
||||
* According to timing specifications EAD must be
|
||||
* set if Local Bus Clock is > 83 MHz.
|
||||
*/
|
||||
if (lbc_mhz > 83)
|
||||
set_lbc_or(2, CONFIG_SYS_OR2_CAN | OR_UPM_EAD);
|
||||
else
|
||||
set_lbc_or(2, CONFIG_SYS_OR2_CAN);
|
||||
set_lbc_br(2, CONFIG_SYS_BR2_CAN);
|
||||
|
||||
/* LGPL4 is UPWAIT */
|
||||
out_be32(&lbc->mcmr, MxMR_DSx_3_CYCL | MxMR_GPL_x4DIS | MxMR_WLFx_3X);
|
||||
|
||||
/* Initialize UPMC for CAN: single read */
|
||||
upmc_write (0x00, 0xFFFFED00);
|
||||
upmc_write (0x01, 0xCCFFCC00);
|
||||
upmc_write (0x02, 0x00FFCF00);
|
||||
upmc_write (0x03, 0x00FFCF00);
|
||||
upmc_write (0x04, 0x00FFDC00);
|
||||
upmc_write (0x05, 0x00FFCF00);
|
||||
upmc_write (0x06, 0x00FFED00);
|
||||
upmc_write (0x07, 0x3FFFCC07);
|
||||
|
||||
/* Initialize UPMC for CAN: single write */
|
||||
upmc_write (0x18, 0xFFFFED00);
|
||||
upmc_write (0x19, 0xCCFFEC00);
|
||||
upmc_write (0x1A, 0x00FFED80);
|
||||
upmc_write (0x1B, 0x00FFED80);
|
||||
upmc_write (0x1C, 0x00FFFC00);
|
||||
upmc_write (0x1D, 0x0FFFEC00);
|
||||
upmc_write (0x1E, 0x0FFFEF00);
|
||||
upmc_write (0x1F, 0x3FFFEC05);
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize PCI Devices, report devices found.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PCI1
|
||||
static struct pci_controller pci1_hose;
|
||||
#endif /* CONFIG_PCI1 */
|
||||
|
||||
void pci_init_board (void)
|
||||
{
|
||||
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
|
||||
int first_free_busno = 0;
|
||||
#ifdef CONFIG_PCI1
|
||||
struct fsl_pci_info pci_info;
|
||||
int pcie_ep;
|
||||
|
||||
u32 devdisr = in_be32(&gur->devdisr);
|
||||
|
||||
uint pci_32 = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_PCI32;
|
||||
uint pci_arb = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_ARB;
|
||||
uint pci_speed = CONFIG_SYS_CLK_FREQ; /* PCI PSPEED in [4:5] */
|
||||
uint pci_clk_sel = in_be32(&gur->porpllsr) & MPC85xx_PORDEVSR_PCI1_SPD;
|
||||
|
||||
if (!(devdisr & MPC85xx_DEVDISR_PCI1)) {
|
||||
SET_STD_PCI_INFO(pci_info, 1);
|
||||
set_next_law(pci_info.mem_phys,
|
||||
law_size_bits(pci_info.mem_size), pci_info.law);
|
||||
set_next_law(pci_info.io_phys,
|
||||
law_size_bits(pci_info.io_size), pci_info.law);
|
||||
|
||||
pcie_ep = fsl_setup_hose(&pci1_hose, pci_info.regs);
|
||||
printf("PCI1: %d bit, %s MHz, %s, %s, %s\n",
|
||||
(pci_32) ? 32 : 64,
|
||||
(pci_speed == 33333333) ? "33" :
|
||||
(pci_speed == 66666666) ? "66" : "unknown",
|
||||
pci_clk_sel ? "sync" : "async",
|
||||
pcie_ep ? "agent" : "host",
|
||||
pci_arb ? "arbiter" : "external-arbiter");
|
||||
first_free_busno = fsl_pci_init_port(&pci_info,
|
||||
&pci1_hose, first_free_busno);
|
||||
#ifdef CONFIG_PCIX_CHECK
|
||||
if (!(in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1)) {
|
||||
ushort reg16 =
|
||||
PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ |
|
||||
PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
|
||||
uint dev = PCI_BDF(0, 0, 0);
|
||||
|
||||
/* PCI-X init */
|
||||
if (CONFIG_SYS_CLK_FREQ < 66000000)
|
||||
puts ("PCI-X will only work at 66 MHz\n");
|
||||
|
||||
pci_write_config_word(dev, PCIX_COMMAND, reg16);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
printf("PCI1: disabled\n");
|
||||
}
|
||||
#else
|
||||
setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1);
|
||||
#endif
|
||||
|
||||
fsl_pcie_init_board(first_free_busno);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_BOARD_SETUP
|
||||
void ft_board_setup (void *blob, bd_t *bd)
|
||||
{
|
||||
ft_cpu_setup (blob, bd);
|
||||
|
||||
FT_FSL_PCI_SETUP;
|
||||
}
|
||||
#endif /* CONFIG_OF_BOARD_SETUP */
|
||||
|
||||
#ifdef CONFIG_BOARD_EARLY_INIT_R
|
||||
int board_early_init_r (void)
|
||||
{
|
||||
#ifdef CONFIG_PS2MULT
|
||||
ps2mult_early_init ();
|
||||
#endif /* CONFIG_PS2MULT */
|
||||
return (0);
|
||||
}
|
||||
#endif /* CONFIG_BOARD_EARLY_INIT_R */
|
||||
|
||||
int board_eth_init(bd_t *bis)
|
||||
{
|
||||
cpu_eth_init(bis); /* Intialize TSECs first */
|
||||
return pci_eth_init(bis);
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# See file CREDITS for list of people who contributed to this
|
||||
# project.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
# MA 02111-1307 USA
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)lib$(BOARD).o
|
||||
|
||||
COBJS = $(BOARD).o load_sernum_ethaddr.o
|
||||
|
||||
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
SOBJS := $(addprefix $(obj),$(SOBJS))
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* (C) Copyright 2000, 2001, 2002
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mpc8xx.h>
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Process Hardware Information Block:
|
||||
*
|
||||
* If we boot on a system fresh from factory, check if the Hardware
|
||||
* Information Block exists and save the information it contains.
|
||||
*
|
||||
* The TQM8xxL / TQM82xx Hardware Information Block is defined as
|
||||
* follows:
|
||||
* - located in first flash bank
|
||||
* - starts at offset 0x0003FFC0
|
||||
* - size 0x00000040
|
||||
*
|
||||
* Internal structure:
|
||||
* - sequence of ASCII character strings
|
||||
* - fields separated by a single space character (0x20)
|
||||
* - last field terminated by NUL character (0x00)
|
||||
* - remaining space filled with NUL characters (0x00)
|
||||
*
|
||||
* Fields in Hardware Information Block:
|
||||
* 1) Module Type
|
||||
* 2) Serial Number
|
||||
* 3) First MAC Address
|
||||
* 4) Number of additional MAC addresses
|
||||
*/
|
||||
|
||||
void load_sernum_ethaddr (void)
|
||||
{
|
||||
unsigned char *hwi;
|
||||
unsigned char serial [CONFIG_SYS_HWINFO_SIZE];
|
||||
unsigned char ethaddr[CONFIG_SYS_HWINFO_SIZE];
|
||||
unsigned short ih, is, ie, part;
|
||||
|
||||
hwi = (unsigned char *)(CONFIG_SYS_FLASH_BASE + CONFIG_SYS_HWINFO_OFFSET);
|
||||
ih = is = ie = 0;
|
||||
|
||||
if (*((unsigned long *)hwi) != (unsigned long)CONFIG_SYS_HWINFO_MAGIC) {
|
||||
return;
|
||||
}
|
||||
|
||||
part = 1;
|
||||
|
||||
/* copy serial # / MAC address */
|
||||
while ((hwi[ih] != '\0') && (ih < CONFIG_SYS_HWINFO_SIZE)) {
|
||||
if (hwi[ih] < ' ' || hwi[ih] > '~') { /* ASCII strings! */
|
||||
return;
|
||||
}
|
||||
switch (part) {
|
||||
default: /* Copy serial # */
|
||||
if (hwi[ih] == ' ') {
|
||||
++part;
|
||||
}
|
||||
serial[is++] = hwi[ih];
|
||||
break;
|
||||
case 3: /* Copy MAC address */
|
||||
if (hwi[ih] == ' ') {
|
||||
++part;
|
||||
break;
|
||||
}
|
||||
ethaddr[ie++] = hwi[ih];
|
||||
if ((ie % 3) == 2)
|
||||
ethaddr[ie++] = ':';
|
||||
break;
|
||||
}
|
||||
++ih;
|
||||
}
|
||||
serial[is] = '\0';
|
||||
if (ie && ethaddr[ie-1] == ':')
|
||||
--ie;
|
||||
ethaddr[ie] = '\0';
|
||||
|
||||
/* set serial# and ethaddr if not yet defined */
|
||||
if (getenv("serial#") == NULL) {
|
||||
setenv ((char *)"serial#", (char *)serial);
|
||||
}
|
||||
|
||||
if (getenv("ethaddr") == NULL) {
|
||||
setenv ((char *)"ethaddr", (char *)ethaddr);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,744 @@
|
|||
/*
|
||||
* (C) Copyright 2000-2008
|
||||
* 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 <hwconfig.h>
|
||||
#include <mpc8xx.h>
|
||||
#ifdef CONFIG_PS2MULT
|
||||
#include <ps2mult.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
|
||||
#include <libfdt.h>
|
||||
#endif
|
||||
|
||||
extern flash_info_t flash_info[]; /* FLASH chips info */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static long int dram_size (long int, long int *, long int);
|
||||
|
||||
#define _NOT_USED_ 0xFFFFFFFF
|
||||
|
||||
/* UPM initialization table for SDRAM: 40, 50, 66 MHz CLKOUT @ CAS latency 2, tWR=2 */
|
||||
const uint sdram_table[] =
|
||||
{
|
||||
/*
|
||||
* Single Read. (Offset 0 in UPMA RAM)
|
||||
*/
|
||||
0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
|
||||
0x1FF5FC47, /* last */
|
||||
/*
|
||||
* SDRAM Initialization (offset 5 in UPMA RAM)
|
||||
*
|
||||
* This is no UPM entry point. The following definition uses
|
||||
* the remaining space to establish an initialization
|
||||
* sequence, which is executed by a RUN command.
|
||||
*
|
||||
*/
|
||||
0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
|
||||
/*
|
||||
* Burst Read. (Offset 8 in UPMA RAM)
|
||||
*/
|
||||
0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
|
||||
0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
/*
|
||||
* Single Write. (Offset 18 in UPMA RAM)
|
||||
*/
|
||||
0x1F0DFC04, 0xEEABBC00, 0x11B77C04, 0xEFFAFC44,
|
||||
0x1FF5FC47, /* last */
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
/*
|
||||
* Burst Write. (Offset 20 in UPMA RAM)
|
||||
*/
|
||||
0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
|
||||
0xF0AFFC00, 0xF0AFFC04, 0xE1BAFC44, 0x1FF5FC47, /* last */
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
/*
|
||||
* Refresh (Offset 30 in UPMA RAM)
|
||||
*/
|
||||
0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
|
||||
0xFFFFFC84, 0xFFFFFC07, /* last */
|
||||
_NOT_USED_, _NOT_USED_,
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
/*
|
||||
* Exception. (Offset 3c in UPMA RAM)
|
||||
*/
|
||||
0xFFFFFC07, /* last */
|
||||
_NOT_USED_, _NOT_USED_, _NOT_USED_,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/*
|
||||
* Check Board Identity:
|
||||
*
|
||||
* Test TQ ID string (TQM8xx...)
|
||||
* If present, check for "L" type (no second DRAM bank),
|
||||
* otherwise "L" type is assumed as default.
|
||||
*
|
||||
* Set board_type to 'L' for "L" type, 'M' for "M" type, 0 else.
|
||||
*/
|
||||
|
||||
int checkboard (void)
|
||||
{
|
||||
char buf[64];
|
||||
int i;
|
||||
int l = getenv_f("serial#", buf, sizeof(buf));
|
||||
|
||||
puts ("Board: ");
|
||||
|
||||
if (l < 0 || strncmp(buf, "TQM8", 4)) {
|
||||
puts ("### No HW ID - assuming TQM8xxL\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((buf[6] == 'L')) { /* a TQM8xxL type */
|
||||
gd->board_type = 'L';
|
||||
}
|
||||
|
||||
if ((buf[6] == 'M')) { /* a TQM8xxM type */
|
||||
gd->board_type = 'M';
|
||||
}
|
||||
|
||||
if ((buf[6] == 'D')) { /* a TQM885D type */
|
||||
gd->board_type = 'D';
|
||||
}
|
||||
|
||||
for (i = 0; i < l; ++i) {
|
||||
if (buf[i] == ' ')
|
||||
break;
|
||||
putc (buf[i]);
|
||||
}
|
||||
#ifdef CONFIG_VIRTLAB2
|
||||
puts (" (Virtlab2)");
|
||||
#endif
|
||||
putc ('\n');
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
phys_size_t initdram (int board_type)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
long int size8, size9, size10;
|
||||
long int size_b0 = 0;
|
||||
long int size_b1 = 0;
|
||||
|
||||
upmconfig (UPMA, (uint *) sdram_table,
|
||||
sizeof (sdram_table) / sizeof (uint));
|
||||
|
||||
/*
|
||||
* Preliminary prescaler for refresh (depends on number of
|
||||
* banks): This value is selected for four cycles every 62.4 us
|
||||
* with two SDRAM banks or four cycles every 31.2 us with one
|
||||
* bank. It will be adjusted after memory sizing.
|
||||
*/
|
||||
memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_8K;
|
||||
|
||||
/*
|
||||
* The following value is used as an address (i.e. opcode) for
|
||||
* the LOAD MODE REGISTER COMMAND during SDRAM initialisation. If
|
||||
* the port size is 32bit the SDRAM does NOT "see" the lower two
|
||||
* address lines, i.e. mar=0x00000088 -> opcode=0x00000022 for
|
||||
* MICRON SDRAMs:
|
||||
* -> 0 00 010 0 010
|
||||
* | | | | +- Burst Length = 4
|
||||
* | | | +----- Burst Type = Sequential
|
||||
* | | +------- CAS Latency = 2
|
||||
* | +----------- Operating Mode = Standard
|
||||
* +-------------- Write Burst Mode = Programmed Burst Length
|
||||
*/
|
||||
memctl->memc_mar = 0x00000088;
|
||||
|
||||
/*
|
||||
* Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
|
||||
* preliminary addresses - these have to be modified after the
|
||||
* SDRAM size has been determined.
|
||||
*/
|
||||
memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM;
|
||||
memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM;
|
||||
|
||||
#ifndef CONFIG_CAN_DRIVER
|
||||
if ((board_type != 'L') &&
|
||||
(board_type != 'M') &&
|
||||
(board_type != 'D') ) { /* only one SDRAM bank on L, M and D modules */
|
||||
memctl->memc_or3 = CONFIG_SYS_OR3_PRELIM;
|
||||
memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM;
|
||||
}
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
|
||||
memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
|
||||
|
||||
udelay (200);
|
||||
|
||||
/* perform SDRAM initializsation sequence */
|
||||
|
||||
memctl->memc_mcr = 0x80004105; /* SDRAM bank 0 */
|
||||
udelay (1);
|
||||
memctl->memc_mcr = 0x80004230; /* SDRAM bank 0 - execute twice */
|
||||
udelay (1);
|
||||
|
||||
#ifndef CONFIG_CAN_DRIVER
|
||||
if ((board_type != 'L') &&
|
||||
(board_type != 'M') &&
|
||||
(board_type != 'D') ) { /* only one SDRAM bank on L, M and D modules */
|
||||
memctl->memc_mcr = 0x80006105; /* SDRAM bank 1 */
|
||||
udelay (1);
|
||||
memctl->memc_mcr = 0x80006230; /* SDRAM bank 1 - execute twice */
|
||||
udelay (1);
|
||||
}
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
|
||||
memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
|
||||
|
||||
udelay (1000);
|
||||
|
||||
/*
|
||||
* Check Bank 0 Memory Size for re-configuration
|
||||
*
|
||||
* try 8 column mode
|
||||
*/
|
||||
size8 = dram_size (CONFIG_SYS_MAMR_8COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
|
||||
debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size8 >> 20);
|
||||
|
||||
udelay (1000);
|
||||
|
||||
/*
|
||||
* try 9 column mode
|
||||
*/
|
||||
size9 = dram_size (CONFIG_SYS_MAMR_9COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
|
||||
debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size9 >> 20);
|
||||
|
||||
udelay(1000);
|
||||
|
||||
#if defined(CONFIG_SYS_MAMR_10COL)
|
||||
/*
|
||||
* try 10 column mode
|
||||
*/
|
||||
size10 = dram_size (CONFIG_SYS_MAMR_10COL, SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
|
||||
debug ("SDRAM Bank 0 in 10 column mode: %ld MB\n", size10 >> 20);
|
||||
#else
|
||||
size10 = 0;
|
||||
#endif /* CONFIG_SYS_MAMR_10COL */
|
||||
|
||||
if ((size8 < size10) && (size9 < size10)) {
|
||||
size_b0 = size10;
|
||||
} else if ((size8 < size9) && (size10 < size9)) {
|
||||
size_b0 = size9;
|
||||
memctl->memc_mamr = CONFIG_SYS_MAMR_9COL;
|
||||
udelay (500);
|
||||
} else {
|
||||
size_b0 = size8;
|
||||
memctl->memc_mamr = CONFIG_SYS_MAMR_8COL;
|
||||
udelay (500);
|
||||
}
|
||||
debug ("SDRAM Bank 0: %ld MB\n", size_b0 >> 20);
|
||||
|
||||
#ifndef CONFIG_CAN_DRIVER
|
||||
if ((board_type != 'L') &&
|
||||
(board_type != 'M') &&
|
||||
(board_type != 'D') ) { /* only one SDRAM bank on L, M and D modules */
|
||||
/*
|
||||
* Check Bank 1 Memory Size
|
||||
* use current column settings
|
||||
* [9 column SDRAM may also be used in 8 column mode,
|
||||
* but then only half the real size will be used.]
|
||||
*/
|
||||
size_b1 = dram_size (memctl->memc_mamr, (long int *)SDRAM_BASE3_PRELIM,
|
||||
SDRAM_MAX_SIZE);
|
||||
debug ("SDRAM Bank 1: %ld MB\n", size_b1 >> 20);
|
||||
} else {
|
||||
size_b1 = 0;
|
||||
}
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
|
||||
udelay (1000);
|
||||
|
||||
/*
|
||||
* Adjust refresh rate depending on SDRAM type, both banks
|
||||
* For types > 128 MBit leave it at the current (fast) rate
|
||||
*/
|
||||
if ((size_b0 < 0x02000000) && (size_b1 < 0x02000000)) {
|
||||
/* reduce to 15.6 us (62.4 us / quad) */
|
||||
memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K;
|
||||
udelay (1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final mapping: map bigger bank first
|
||||
*/
|
||||
if (size_b1 > size_b0) { /* SDRAM Bank 1 is bigger - map first */
|
||||
|
||||
memctl->memc_or3 = ((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
|
||||
memctl->memc_br3 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
|
||||
|
||||
if (size_b0 > 0) {
|
||||
/*
|
||||
* Position Bank 0 immediately above Bank 1
|
||||
*/
|
||||
memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
|
||||
memctl->memc_br2 = ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
|
||||
+ size_b1;
|
||||
} else {
|
||||
unsigned long reg;
|
||||
|
||||
/*
|
||||
* No bank 0
|
||||
*
|
||||
* invalidate bank
|
||||
*/
|
||||
memctl->memc_br2 = 0;
|
||||
|
||||
/* adjust refresh rate depending on SDRAM type, one bank */
|
||||
reg = memctl->memc_mptpr;
|
||||
reg >>= 1; /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
|
||||
memctl->memc_mptpr = reg;
|
||||
}
|
||||
|
||||
} else { /* SDRAM Bank 0 is bigger - map first */
|
||||
|
||||
memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
|
||||
memctl->memc_br2 =
|
||||
(CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
|
||||
|
||||
if (size_b1 > 0) {
|
||||
/*
|
||||
* Position Bank 1 immediately above Bank 0
|
||||
*/
|
||||
memctl->memc_or3 =
|
||||
((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
|
||||
memctl->memc_br3 =
|
||||
((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
|
||||
+ size_b0;
|
||||
} else {
|
||||
unsigned long reg;
|
||||
|
||||
#ifndef CONFIG_CAN_DRIVER
|
||||
/*
|
||||
* No bank 1
|
||||
*
|
||||
* invalidate bank
|
||||
*/
|
||||
memctl->memc_br3 = 0;
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
|
||||
/* adjust refresh rate depending on SDRAM type, one bank */
|
||||
reg = memctl->memc_mptpr;
|
||||
reg >>= 1; /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
|
||||
memctl->memc_mptpr = reg;
|
||||
}
|
||||
}
|
||||
|
||||
udelay (10000);
|
||||
|
||||
#ifdef CONFIG_CAN_DRIVER
|
||||
/* UPM initialization for CAN @ CLKOUT <= 66 MHz */
|
||||
|
||||
/* Initialize OR3 / BR3 */
|
||||
memctl->memc_or3 = CONFIG_SYS_OR3_CAN;
|
||||
memctl->memc_br3 = CONFIG_SYS_BR3_CAN;
|
||||
|
||||
/* Initialize MBMR */
|
||||
memctl->memc_mbmr = MBMR_GPL_B4DIS; /* GPL_B4 ouput line Disable */
|
||||
|
||||
/* Initialize UPMB for CAN: single read */
|
||||
memctl->memc_mdr = 0xFFFFCC04;
|
||||
memctl->memc_mcr = 0x0100 | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0x0FFFD004;
|
||||
memctl->memc_mcr = 0x0101 | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0x0FFFC000;
|
||||
memctl->memc_mcr = 0x0102 | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0x3FFFC004;
|
||||
memctl->memc_mcr = 0x0103 | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0xFFFFDC07;
|
||||
memctl->memc_mcr = 0x0104 | UPMB;
|
||||
|
||||
/* Initialize UPMB for CAN: single write */
|
||||
memctl->memc_mdr = 0xFFFCCC04;
|
||||
memctl->memc_mcr = 0x0118 | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0xCFFCDC04;
|
||||
memctl->memc_mcr = 0x0119 | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0x3FFCC000;
|
||||
memctl->memc_mcr = 0x011A | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0xFFFCC004;
|
||||
memctl->memc_mcr = 0x011B | UPMB;
|
||||
|
||||
memctl->memc_mdr = 0xFFFDC405;
|
||||
memctl->memc_mcr = 0x011C | UPMB;
|
||||
#endif /* CONFIG_CAN_DRIVER */
|
||||
|
||||
#ifdef CONFIG_ISP1362_USB
|
||||
/* Initialize OR5 / BR5 */
|
||||
memctl->memc_or5 = CONFIG_SYS_OR5_ISP1362;
|
||||
memctl->memc_br5 = CONFIG_SYS_BR5_ISP1362;
|
||||
#endif /* CONFIG_ISP1362_USB */
|
||||
return (size_b0 + size_b1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
static long int dram_size (long int mamr_value, long int *base, long int maxsize)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
|
||||
memctl->memc_mamr = mamr_value;
|
||||
|
||||
return (get_ram_size(base, maxsize));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_MISC_INIT_R
|
||||
extern void load_sernum_ethaddr(void);
|
||||
int misc_init_r (void)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
volatile memctl8xx_t *memctl = &immap->im_memctl;
|
||||
|
||||
load_sernum_ethaddr();
|
||||
|
||||
#ifdef CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ
|
||||
int scy, trlx, flash_or_timing, clk_diff;
|
||||
|
||||
scy = (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & OR_SCY_MSK) >> 4;
|
||||
if (CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & OR_TRLX) {
|
||||
trlx = OR_TRLX;
|
||||
scy *= 2;
|
||||
} else {
|
||||
trlx = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We assume that each 10MHz of bus clock require 1-clk SCY
|
||||
* adjustment.
|
||||
*/
|
||||
clk_diff = (gd->bus_clk / 1000000) - 50;
|
||||
|
||||
/*
|
||||
* We need proper rounding here. This is what the "+5" and "-5"
|
||||
* are here for.
|
||||
*/
|
||||
if (clk_diff >= 0)
|
||||
scy += (clk_diff + 5) / 10;
|
||||
else
|
||||
scy += (clk_diff - 5) / 10;
|
||||
|
||||
/*
|
||||
* For bus frequencies above 50MHz, we want to use relaxed timing
|
||||
* (OR_TRLX).
|
||||
*/
|
||||
if (gd->bus_clk >= 50000000)
|
||||
trlx = OR_TRLX;
|
||||
else
|
||||
trlx = 0;
|
||||
|
||||
if (trlx)
|
||||
scy /= 2;
|
||||
|
||||
if (scy > 0xf)
|
||||
scy = 0xf;
|
||||
if (scy < 1)
|
||||
scy = 1;
|
||||
|
||||
flash_or_timing = (scy << 4) | trlx |
|
||||
(CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ & ~(OR_TRLX | OR_SCY_MSK));
|
||||
|
||||
memctl->memc_or0 =
|
||||
flash_or_timing | (-flash_info[0].size & OR_AM_MSK);
|
||||
#else
|
||||
memctl->memc_or0 =
|
||||
CONFIG_SYS_OR_TIMING_FLASH | (-flash_info[0].size & OR_AM_MSK);
|
||||
#endif
|
||||
memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
|
||||
|
||||
debug ("## BR0: 0x%08x OR0: 0x%08x\n",
|
||||
memctl->memc_br0, memctl->memc_or0);
|
||||
|
||||
if (flash_info[1].size) {
|
||||
#ifdef CONFIG_SYS_OR_TIMING_FLASH_AT_50MHZ
|
||||
memctl->memc_or1 = flash_or_timing |
|
||||
(-flash_info[1].size & 0xFFFF8000);
|
||||
#else
|
||||
memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH |
|
||||
(-flash_info[1].size & 0xFFFF8000);
|
||||
#endif
|
||||
memctl->memc_br1 =
|
||||
((CONFIG_SYS_FLASH_BASE +
|
||||
flash_info[0].
|
||||
size) & BR_BA_MSK) | BR_MS_GPCM | BR_V;
|
||||
|
||||
debug ("## BR1: 0x%08x OR1: 0x%08x\n",
|
||||
memctl->memc_br1, memctl->memc_or1);
|
||||
} else {
|
||||
memctl->memc_br1 = 0; /* invalidate bank */
|
||||
|
||||
debug ("## DISABLE BR1: 0x%08x OR1: 0x%08x\n",
|
||||
memctl->memc_br1, memctl->memc_or1);
|
||||
}
|
||||
|
||||
# ifdef CONFIG_IDE_LED
|
||||
/* Configure PA15 as output port */
|
||||
immap->im_ioport.iop_padir |= 0x0001;
|
||||
immap->im_ioport.iop_paodr |= 0x0001;
|
||||
immap->im_ioport.iop_papar &= ~0x0001;
|
||||
immap->im_ioport.iop_padat &= ~0x0001; /* turn it off */
|
||||
# endif
|
||||
|
||||
#ifdef CONFIG_NSCU
|
||||
/* wake up ethernet module */
|
||||
immap->im_ioport.iop_pcpar &= ~0x0004; /* GPIO pin */
|
||||
immap->im_ioport.iop_pcdir |= 0x0004; /* output */
|
||||
immap->im_ioport.iop_pcso &= ~0x0004; /* for clarity */
|
||||
immap->im_ioport.iop_pcdat |= 0x0004; /* enable */
|
||||
#endif /* CONFIG_NSCU */
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif /* CONFIG_MISC_INIT_R */
|
||||
|
||||
|
||||
# ifdef CONFIG_IDE_LED
|
||||
void ide_led (uchar led, uchar status)
|
||||
{
|
||||
volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
|
||||
|
||||
/* We have one led for both pcmcia slots */
|
||||
if (status) { /* led on */
|
||||
immap->im_ioport.iop_padat |= 0x0001;
|
||||
} else {
|
||||
immap->im_ioport.iop_padat &= ~0x0001;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
#ifdef CONFIG_LCD_INFO
|
||||
#include <lcd.h>
|
||||
#include <version.h>
|
||||
#include <timestamp.h>
|
||||
|
||||
void lcd_show_board_info(void)
|
||||
{
|
||||
char temp[32];
|
||||
|
||||
lcd_printf ("%s (%s - %s)\n", U_BOOT_VERSION, U_BOOT_DATE, U_BOOT_TIME);
|
||||
lcd_printf ("(C) 2008 DENX Software Engineering GmbH\n");
|
||||
lcd_printf (" Wolfgang DENK, wd@denx.de\n");
|
||||
#ifdef CONFIG_LCD_INFO_BELOW_LOGO
|
||||
lcd_printf ("MPC823 CPU at %s MHz\n",
|
||||
strmhz(temp, gd->cpu_clk));
|
||||
lcd_printf (" %ld MB RAM, %ld MB Flash\n",
|
||||
gd->ram_size >> 20,
|
||||
gd->bd->bi_flashsize >> 20 );
|
||||
#else
|
||||
/* leave one blank line */
|
||||
lcd_printf ("\nMPC823 CPU at %s MHz, %ld MB RAM, %ld MB Flash\n",
|
||||
strmhz(temp, gd->cpu_clk),
|
||||
gd->ram_size >> 20,
|
||||
gd->bd->bi_flashsize >> 20 );
|
||||
#endif /* CONFIG_LCD_INFO_BELOW_LOGO */
|
||||
}
|
||||
#endif /* CONFIG_LCD_INFO */
|
||||
|
||||
/*
|
||||
* Device Tree Support
|
||||
*/
|
||||
#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
|
||||
int fdt_set_node_and_value (void *blob,
|
||||
char *nodename,
|
||||
char *regname,
|
||||
void *var,
|
||||
int size)
|
||||
{
|
||||
int ret = 0;
|
||||
int nodeoffset = 0;
|
||||
|
||||
nodeoffset = fdt_path_offset (blob, nodename);
|
||||
if (nodeoffset >= 0) {
|
||||
ret = fdt_setprop (blob, nodeoffset, regname, var,
|
||||
size);
|
||||
if (ret < 0) {
|
||||
printf("ft_blob_update(): "
|
||||
"cannot set %s/%s property; err: %s\n",
|
||||
nodename, regname, fdt_strerror (ret));
|
||||
}
|
||||
} else {
|
||||
printf("ft_blob_update(): "
|
||||
"cannot find %s node err:%s\n",
|
||||
nodename, fdt_strerror (nodeoffset));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fdt_del_node_name (void *blob, char *nodename)
|
||||
{
|
||||
int ret = 0;
|
||||
int nodeoffset = 0;
|
||||
|
||||
nodeoffset = fdt_path_offset (blob, nodename);
|
||||
if (nodeoffset >= 0) {
|
||||
ret = fdt_del_node (blob, nodeoffset);
|
||||
if (ret < 0) {
|
||||
printf("%s: cannot delete %s; err: %s\n",
|
||||
__func__, nodename, fdt_strerror (ret));
|
||||
}
|
||||
} else {
|
||||
printf("%s: cannot find %s node err:%s\n",
|
||||
__func__, nodename, fdt_strerror (nodeoffset));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fdt_del_prop_name (void *blob, char *nodename, char *propname)
|
||||
{
|
||||
int ret = 0;
|
||||
int nodeoffset = 0;
|
||||
|
||||
nodeoffset = fdt_path_offset (blob, nodename);
|
||||
if (nodeoffset >= 0) {
|
||||
ret = fdt_delprop (blob, nodeoffset, propname);
|
||||
if (ret < 0) {
|
||||
printf("%s: cannot delete %s %s; err: %s\n",
|
||||
__func__, nodename, propname,
|
||||
fdt_strerror (ret));
|
||||
}
|
||||
} else {
|
||||
printf("%s: cannot find %s node err:%s\n",
|
||||
__func__, nodename, fdt_strerror (nodeoffset));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* update "brg" property in the blob
|
||||
*/
|
||||
void ft_blob_update (void *blob, bd_t *bd)
|
||||
{
|
||||
uchar enetaddr[6];
|
||||
ulong brg_data = 0;
|
||||
|
||||
/* BRG */
|
||||
brg_data = cpu_to_be32(bd->bi_busfreq);
|
||||
fdt_set_node_and_value(blob,
|
||||
"/soc/cpm", "brg-frequency",
|
||||
&brg_data, sizeof(brg_data));
|
||||
|
||||
/* MAC addr */
|
||||
if (eth_getenv_enetaddr("ethaddr", enetaddr)) {
|
||||
fdt_set_node_and_value(blob,
|
||||
"ethernet0", "local-mac-address",
|
||||
enetaddr, sizeof(u8) * 6);
|
||||
}
|
||||
|
||||
if (hwconfig_arg_cmp("fec", "off")) {
|
||||
/* no FEC on this plattform, delete DTS nodes */
|
||||
fdt_del_node_name (blob, "ethernet1");
|
||||
fdt_del_node_name (blob, "mdio1");
|
||||
/* also the aliases entries */
|
||||
fdt_del_prop_name (blob, "/aliases", "ethernet1");
|
||||
fdt_del_prop_name (blob, "/aliases", "mdio1");
|
||||
} else {
|
||||
/* adjust local-mac-address for FEC ethernet */
|
||||
if (eth_getenv_enetaddr("eth1addr", enetaddr)) {
|
||||
fdt_set_node_and_value(blob,
|
||||
"ethernet1", "local-mac-address",
|
||||
enetaddr, sizeof(u8) * 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
ft_cpu_setup(blob, bd);
|
||||
ft_blob_update(blob, bd);
|
||||
}
|
||||
#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
/* TK885D specific initializaion */
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_TK885D
|
||||
#include <miiphy.h>
|
||||
int last_stage_init(void)
|
||||
{
|
||||
const unsigned char phy[] = {CONFIG_FEC1_PHY, CONFIG_FEC2_PHY};
|
||||
unsigned short reg;
|
||||
int ret, i = 100;
|
||||
char *s;
|
||||
|
||||
mii_init();
|
||||
/* Without this delay 0xff is read from the UART buffer later in
|
||||
* abortboot() and autoboot is aborted */
|
||||
udelay(10000);
|
||||
while (tstc() && i--)
|
||||
(void)getc();
|
||||
|
||||
/* Check if auto-negotiation is prohibited */
|
||||
s = getenv("phy_auto_nego");
|
||||
|
||||
if (!s || !strcmp(s, "on"))
|
||||
/* Nothing to do - autonegotiation by default */
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
ret = miiphy_read("FEC", phy[i], MII_BMCR, ®);
|
||||
if (ret) {
|
||||
printf("Cannot read BMCR on PHY %d\n", phy[i]);
|
||||
return 0;
|
||||
}
|
||||
/* Auto-negotiation off, hard set full duplex, 100Mbps */
|
||||
ret = miiphy_write("FEC", phy[i],
|
||||
MII_BMCR, (reg | BMCR_SPEED100 |
|
||||
BMCR_FULLDPLX) & ~BMCR_ANENABLE);
|
||||
if (ret) {
|
||||
printf("Cannot write BMCR on PHY %d\n", phy[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* (C) Copyright 2000
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH(powerpc)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = + SIZEOF_HEADERS;
|
||||
.text :
|
||||
{
|
||||
/* WARNING - the following is hand-optimized to fit within */
|
||||
/* the sector layout of our flash chips! XXX FIXME XXX */
|
||||
|
||||
arch/powerpc/cpu/mpc8xx/start.o (.text*)
|
||||
arch/powerpc/cpu/mpc8xx/traps.o (.text*)
|
||||
arch/powerpc/cpu/mpc8xx/libmpc8xx.o (.text*)
|
||||
arch/powerpc/lib/libpowerpc.o (.text*)
|
||||
board/tqc/tqm8xx/libtqm8xx.o (.text*)
|
||||
disk/libdisk.o (.text*)
|
||||
drivers/net/libnet.o (.text*)
|
||||
drivers/pcmcia/libpcmcia.o (.text.pcmcia_on)
|
||||
drivers/pcmcia/libpcmcia.o (.text.pcmcia_hardware_enable)
|
||||
drivers/rtc/librtc.o (.text*)
|
||||
drivers/misc/libmisc.o (.text*)
|
||||
*(.text.print_buffer)
|
||||
*(.text.print_size)
|
||||
|
||||
. = DEFINED(env_offset) ? env_offset : .;
|
||||
common/env_embedded.o (.ppcenv*)
|
||||
|
||||
*(.text*)
|
||||
}
|
||||
_etext = .;
|
||||
PROVIDE (etext = .);
|
||||
.rodata :
|
||||
{
|
||||
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
||||
}
|
||||
|
||||
/* Read-write section, merged into data segment: */
|
||||
. = (. + 0x00FF) & 0xFFFFFF00;
|
||||
_erotext = .;
|
||||
PROVIDE (erotext = .);
|
||||
.reloc :
|
||||
{
|
||||
_GOT2_TABLE_ = .;
|
||||
KEEP(*(.got2))
|
||||
KEEP(*(.got))
|
||||
PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
|
||||
_FIXUP_TABLE_ = .;
|
||||
KEEP(*(.fixup))
|
||||
}
|
||||
__got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
|
||||
__fixup_entries = (. - _FIXUP_TABLE_)>>2;
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data*)
|
||||
*(.sdata*)
|
||||
}
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
|
||||
. = .;
|
||||
__u_boot_cmd_start = .;
|
||||
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||
__u_boot_cmd_end = .;
|
||||
|
||||
|
||||
. = .;
|
||||
__start___ex_table = .;
|
||||
__ex_table : { *(__ex_table) }
|
||||
__stop___ex_table = .;
|
||||
|
||||
. = ALIGN(256);
|
||||
__init_begin = .;
|
||||
.text.init : { *(.text.init) }
|
||||
.data.init : { *(.data.init) }
|
||||
. = ALIGN(256);
|
||||
__init_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
*(.bss*)
|
||||
*(.sbss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
}
|
||||
__bss_end__ = . ;
|
||||
PROVIDE (end = .);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue