Add mpc7448hpc2 (mpc7448 + tsi108) board associated code support.
mpc7448hpc2 board support high level code:tsi108 init + mpc7448hpc2. Signed-off-by: Alexandre Bounine <alexandreb@tundra.com> Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
This commit is contained in:
parent
27801b8ab1
commit
87c4db0969
board/mpc7448hpc2
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
* (C) Copyright 2005 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* Roy Zang <tie-fei.zang@freescale.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
|
||||
*
|
||||
* modifications for the Tsi108 Emul Board by avb@Tundra
|
||||
*/
|
||||
|
||||
/*
|
||||
* board support/init functions for the
|
||||
* Freescale MPC7448 HPC2 (High-Performance Computing 2 Platform).
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <74xx_7xx.h>
|
||||
#if defined(CONFIG_OF_FLAT_TREE)
|
||||
#include <ft_build.h>
|
||||
extern void ft_cpu_setup(void *blob, bd_t *bd);
|
||||
#endif
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
extern void flush_data_cache(void);
|
||||
extern void invalidate_l1_instruction_cache(void);
|
||||
extern void tsi108_init_f(void);
|
||||
|
||||
int display_mem_map(void);
|
||||
|
||||
void after_reloc(ulong dest_addr)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* Jump to the main U-Boot board init code
|
||||
*/
|
||||
board_init_r((gd_t *) gd, dest_addr);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Board Identity:
|
||||
*
|
||||
* report board type
|
||||
*/
|
||||
|
||||
int checkboard(void)
|
||||
{
|
||||
int l_type = 0;
|
||||
|
||||
printf("BOARD: %s\n", CFG_BOARD_NAME);
|
||||
return (l_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read Processor ID:
|
||||
*
|
||||
* report calling processor number
|
||||
*/
|
||||
|
||||
int read_pid(void)
|
||||
{
|
||||
return 0; /* we are on single CPU platform for a while */
|
||||
}
|
||||
|
||||
long int dram_size(int board_type)
|
||||
{
|
||||
return 0x20000000; /* 256M bytes */
|
||||
}
|
||||
|
||||
long int initdram(int board_type)
|
||||
{
|
||||
return dram_size(board_type);
|
||||
}
|
||||
|
||||
/* DRAM check routines copied from gw8260 */
|
||||
|
||||
#if defined (CFG_DRAM_TEST)
|
||||
|
||||
/*********************************************************************/
|
||||
/* NAME: move64() - moves a double word (64-bit) */
|
||||
/* */
|
||||
/* DESCRIPTION: */
|
||||
/* this function performs a double word move from the data at */
|
||||
/* the source pointer to the location at the destination pointer. */
|
||||
/* */
|
||||
/* INPUTS: */
|
||||
/* unsigned long long *src - pointer to data to move */
|
||||
/* */
|
||||
/* OUTPUTS: */
|
||||
/* unsigned long long *dest - pointer to locate to move data */
|
||||
/* */
|
||||
/* RETURNS: */
|
||||
/* None */
|
||||
/* */
|
||||
/* RESTRICTIONS/LIMITATIONS: */
|
||||
/* May cloober fr0. */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
static void move64(unsigned long long *src, unsigned long long *dest)
|
||||
{
|
||||
asm("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
|
||||
"stfd 0, 0(4)" /* *dest = fpr0 */
|
||||
: : :"fr0"); /* Clobbers fr0 */
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined (CFG_DRAM_TEST_DATA)
|
||||
|
||||
unsigned long long pattern[] = {
|
||||
0xaaaaaaaaaaaaaaaaULL,
|
||||
0xccccccccccccccccULL,
|
||||
0xf0f0f0f0f0f0f0f0ULL,
|
||||
0xff00ff00ff00ff00ULL,
|
||||
0xffff0000ffff0000ULL,
|
||||
0xffffffff00000000ULL,
|
||||
0x00000000ffffffffULL,
|
||||
0x0000ffff0000ffffULL,
|
||||
0x00ff00ff00ff00ffULL,
|
||||
0x0f0f0f0f0f0f0f0fULL,
|
||||
0x3333333333333333ULL,
|
||||
0x5555555555555555ULL
|
||||
};
|
||||
|
||||
/*********************************************************************/
|
||||
/* NAME: mem_test_data() - test data lines for shorts and opens */
|
||||
/* */
|
||||
/* DESCRIPTION: */
|
||||
/* Tests data lines for shorts and opens by forcing adjacent data */
|
||||
/* to opposite states. Because the data lines could be routed in */
|
||||
/* an arbitrary manner the must ensure test patterns ensure that */
|
||||
/* every case is tested. By using the following series of binary */
|
||||
/* patterns every combination of adjacent bits is test regardless */
|
||||
/* of routing. */
|
||||
/* */
|
||||
/* ...101010101010101010101010 */
|
||||
/* ...110011001100110011001100 */
|
||||
/* ...111100001111000011110000 */
|
||||
/* ...111111110000000011111111 */
|
||||
/* */
|
||||
/* Carrying this out, gives us six hex patterns as follows: */
|
||||
/* */
|
||||
/* 0xaaaaaaaaaaaaaaaa */
|
||||
/* 0xcccccccccccccccc */
|
||||
/* 0xf0f0f0f0f0f0f0f0 */
|
||||
/* 0xff00ff00ff00ff00 */
|
||||
/* 0xffff0000ffff0000 */
|
||||
/* 0xffffffff00000000 */
|
||||
/* */
|
||||
/* The number test patterns will always be given by: */
|
||||
/* */
|
||||
/* log(base 2)(number data bits) = log2 (64) = 6 */
|
||||
/* */
|
||||
/* To test for short and opens to other signals on our boards. we */
|
||||
/* simply */
|
||||
/* test with the 1's complemnt of the paterns as well. */
|
||||
/* */
|
||||
/* OUTPUTS: */
|
||||
/* Displays failing test pattern */
|
||||
/* */
|
||||
/* RETURNS: */
|
||||
/* 0 - Passed test */
|
||||
/* 1 - Failed test */
|
||||
/* */
|
||||
/* RESTRICTIONS/LIMITATIONS: */
|
||||
/* Assumes only one one SDRAM bank */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
int mem_test_data(void)
|
||||
{
|
||||
unsigned long long *pmem = (unsigned long long *)CFG_MEMTEST_START;
|
||||
unsigned long long temp64;
|
||||
int num_patterns = sizeof(pattern) / sizeof(pattern[0]);
|
||||
int i;
|
||||
unsigned int hi, lo;
|
||||
|
||||
for (i = 0; i < num_patterns; i++) {
|
||||
move64(&(pattern[i]), pmem);
|
||||
move64(pmem, &temp64);
|
||||
|
||||
/* hi = (temp64>>32) & 0xffffffff; */
|
||||
/* lo = temp64 & 0xffffffff; */
|
||||
/* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
|
||||
|
||||
hi = (pattern[i] >> 32) & 0xffffffff;
|
||||
lo = pattern[i] & 0xffffffff;
|
||||
/* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */
|
||||
|
||||
if (temp64 != pattern[i]) {
|
||||
printf("\n Data Test Failed, pattern 0x%08x%08x",
|
||||
hi, lo);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CFG_DRAM_TEST_DATA */
|
||||
|
||||
#if defined (CFG_DRAM_TEST_ADDRESS)
|
||||
/*********************************************************************/
|
||||
/* NAME: mem_test_address() - test address lines */
|
||||
/* */
|
||||
/* DESCRIPTION: */
|
||||
/* This function performs a test to verify that each word im */
|
||||
/* memory is uniquly addressable. The test sequence is as follows: */
|
||||
/* */
|
||||
/* 1) write the address of each word to each word. */
|
||||
/* 2) verify that each location equals its address */
|
||||
/* */
|
||||
/* OUTPUTS: */
|
||||
/* Displays failing test pattern and address */
|
||||
/* */
|
||||
/* RETURNS: */
|
||||
/* 0 - Passed test */
|
||||
/* 1 - Failed test */
|
||||
/* */
|
||||
/* RESTRICTIONS/LIMITATIONS: */
|
||||
/* */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
int mem_test_address(void)
|
||||
{
|
||||
volatile unsigned int *pmem =
|
||||
(volatile unsigned int *)CFG_MEMTEST_START;
|
||||
const unsigned int size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 4;
|
||||
unsigned int i;
|
||||
|
||||
/* write address to each location */
|
||||
for (i = 0; i < size; i++) {
|
||||
pmem[i] = i;
|
||||
}
|
||||
|
||||
/* verify each loaction */
|
||||
for (i = 0; i < size; i++) {
|
||||
if (pmem[i] != i) {
|
||||
printf("\n Address Test Failed at 0x%x", i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CFG_DRAM_TEST_ADDRESS */
|
||||
|
||||
#if defined (CFG_DRAM_TEST_WALK)
|
||||
/*********************************************************************/
|
||||
/* NAME: mem_march() - memory march */
|
||||
/* */
|
||||
/* DESCRIPTION: */
|
||||
/* Marches up through memory. At each location verifies rmask if */
|
||||
/* read = 1. At each location write wmask if write = 1. Displays */
|
||||
/* failing address and pattern. */
|
||||
/* */
|
||||
/* INPUTS: */
|
||||
/* volatile unsigned long long * base - start address of test */
|
||||
/* unsigned int size - number of dwords(64-bit) to test */
|
||||
/* unsigned long long rmask - read verify mask */
|
||||
/* unsigned long long wmask - wrtie verify mask */
|
||||
/* short read - verifies rmask if read = 1 */
|
||||
/* short write - writes wmask if write = 1 */
|
||||
/* */
|
||||
/* OUTPUTS: */
|
||||
/* Displays failing test pattern and address */
|
||||
/* */
|
||||
/* RETURNS: */
|
||||
/* 0 - Passed test */
|
||||
/* 1 - Failed test */
|
||||
/* */
|
||||
/* RESTRICTIONS/LIMITATIONS: */
|
||||
/* */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
int mem_march(volatile unsigned long long *base,
|
||||
unsigned int size,
|
||||
unsigned long long rmask,
|
||||
unsigned long long wmask, short read, short write)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned long long temp;
|
||||
unsigned int hitemp, lotemp, himask, lomask;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (read != 0) {
|
||||
/* temp = base[i]; */
|
||||
move64((unsigned long long *)&(base[i]), &temp);
|
||||
if (rmask != temp) {
|
||||
hitemp = (temp >> 32) & 0xffffffff;
|
||||
lotemp = temp & 0xffffffff;
|
||||
himask = (rmask >> 32) & 0xffffffff;
|
||||
lomask = rmask & 0xffffffff;
|
||||
|
||||
printf("\n Walking one's test failed: \
|
||||
address = 0x%08x," "\n\texpected \
|
||||
0x%08x%08x, found 0x%08x%08x", i << 3,\
|
||||
himask, lomask, hitemp, lotemp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (write != 0) {
|
||||
/* base[i] = wmask; */
|
||||
move64(&wmask, (unsigned long long *)&(base[i]));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CFG_DRAM_TEST_WALK */
|
||||
|
||||
/*********************************************************************/
|
||||
/* NAME: mem_test_walk() - a simple walking ones test */
|
||||
/* */
|
||||
/* DESCRIPTION: */
|
||||
/* Performs a walking ones through entire physical memory. The */
|
||||
/* test uses as series of memory marches, mem_march(), to verify */
|
||||
/* and write the test patterns to memory. The test sequence is as */
|
||||
/* follows: */
|
||||
/* 1) march writing 0000...0001 */
|
||||
/* 2) march verifying 0000...0001 , writing 0000...0010 */
|
||||
/* 3) repeat step 2 shifting masks left 1 bit each time unitl */
|
||||
/* the write mask equals 1000...0000 */
|
||||
/* 4) march verifying 1000...0000 */
|
||||
/* The test fails if any of the memory marches return a failure. */
|
||||
/* */
|
||||
/* OUTPUTS: */
|
||||
/* Displays which pass on the memory test is executing */
|
||||
/* */
|
||||
/* RETURNS: */
|
||||
/* 0 - Passed test */
|
||||
/* 1 - Failed test */
|
||||
/* */
|
||||
/* RESTRICTIONS/LIMITATIONS: */
|
||||
/* */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
int mem_test_walk(void)
|
||||
{
|
||||
unsigned long long mask;
|
||||
volatile unsigned long long *pmem =
|
||||
(volatile unsigned long long *)CFG_MEMTEST_START;
|
||||
const unsigned long size = (CFG_MEMTEST_END - CFG_MEMTEST_START) / 8;
|
||||
|
||||
unsigned int i;
|
||||
|
||||
mask = 0x01;
|
||||
|
||||
printf("Initial Pass");
|
||||
mem_march(pmem, size, 0x0, 0x1, 0, 1);
|
||||
|
||||
printf("\b\b\b\b\b\b\b\b\b\b\b\b");
|
||||
printf(" ");
|
||||
printf(" ");
|
||||
printf("\b\b\b\b\b\b\b\b\b\b\b\b");
|
||||
|
||||
for (i = 0; i < 63; i++) {
|
||||
printf("Pass %2d", i + 2);
|
||||
if (mem_march(pmem, size, mask, mask << 1, 1, 1) != 0) {
|
||||
/*printf("mask: 0x%x, pass: %d, ", mask, i); */
|
||||
return 1;
|
||||
}
|
||||
mask = mask << 1;
|
||||
printf("\b\b\b\b\b\b\b");
|
||||
}
|
||||
|
||||
printf("Last Pass");
|
||||
if (mem_march(pmem, size, 0, mask, 0, 1) != 0) {
|
||||
/* printf("mask: 0x%x", mask); */
|
||||
return 1;
|
||||
}
|
||||
printf("\b\b\b\b\b\b\b\b\b");
|
||||
printf(" ");
|
||||
printf("\b\b\b\b\b\b\b\b\b");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* NAME: testdram() - calls any enabled memory tests */
|
||||
/* */
|
||||
/* DESCRIPTION: */
|
||||
/* Runs memory tests if the environment test variables are set to */
|
||||
/* 'y'. */
|
||||
/* */
|
||||
/* INPUTS: */
|
||||
/* testdramdata - If set to 'y', data test is run. */
|
||||
/* testdramaddress - If set to 'y', address test is run. */
|
||||
/* testdramwalk - If set to 'y', walking ones test is run */
|
||||
/* */
|
||||
/* OUTPUTS: */
|
||||
/* None */
|
||||
/* */
|
||||
/* RETURNS: */
|
||||
/* 0 - Passed test */
|
||||
/* 1 - Failed test */
|
||||
/* */
|
||||
/* RESTRICTIONS/LIMITATIONS: */
|
||||
/* */
|
||||
/* */
|
||||
/*********************************************************************/
|
||||
int testdram(void)
|
||||
{
|
||||
char *s;
|
||||
int rundata, runaddress, runwalk;
|
||||
|
||||
s = getenv("testdramdata");
|
||||
rundata = (s && (*s == 'y')) ? 1 : 0;
|
||||
s = getenv("testdramaddress");
|
||||
runaddress = (s && (*s == 'y')) ? 1 : 0;
|
||||
s = getenv("testdramwalk");
|
||||
runwalk = (s && (*s == 'y')) ? 1 : 0;
|
||||
|
||||
/* rundata = 1; */
|
||||
/* runaddress = 0; */
|
||||
/* runwalk = 0; */
|
||||
|
||||
if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
|
||||
printf("Testing RAM from 0x%08x to 0x%08x ... \
|
||||
(don't panic... that will take a moment !!!!)\n", \
|
||||
CFG_MEMTEST_START, CFG_MEMTEST_END);
|
||||
}
|
||||
#ifdef CFG_DRAM_TEST_DATA
|
||||
if (rundata == 1) {
|
||||
printf("Test DATA ... ");
|
||||
if (mem_test_data () == 1) {
|
||||
printf("failed \n");
|
||||
return 1;
|
||||
} else
|
||||
printf("ok \n");
|
||||
}
|
||||
#endif
|
||||
#ifdef CFG_DRAM_TEST_ADDRESS
|
||||
if (runaddress == 1) {
|
||||
printf("Test ADDRESS ... ");
|
||||
if (mem_test_address () == 1) {
|
||||
printf("failed \n");
|
||||
return 1;
|
||||
} else
|
||||
printf("ok \n");
|
||||
}
|
||||
#endif
|
||||
#ifdef CFG_DRAM_TEST_WALK
|
||||
if (runwalk == 1) {
|
||||
printf("Test WALKING ONEs ... ");
|
||||
if (mem_test_walk() == 1) {
|
||||
printf("failed \n");
|
||||
return 1;
|
||||
} else
|
||||
printf("ok \n");
|
||||
}
|
||||
#endif
|
||||
if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
|
||||
printf("passed\n");
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif /* CFG_DRAM_TEST */
|
||||
|
||||
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
|
||||
void
|
||||
ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
u32 *p;
|
||||
int len;
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
p = ft_get_prop(blob, "/memory/reg", &len);
|
||||
if (p != NULL) {
|
||||
*p++ = cpu_to_be32(bd->bi_memstart);
|
||||
*p = cpu_to_be32(bd->bi_memsize);
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,662 @@
|
|||
/*****************************************************************************
|
||||
* (C) Copyright 2003; Tundra Semiconductor Corp.
|
||||
*
|
||||
* 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
|
||||
*****************************************************************************/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* FILENAME: tsi108_init.c
|
||||
*
|
||||
* Originator: Alex Bounine
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Initialization code for the Tundra Tsi108 bridge chip
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <common.h>
|
||||
#include <74xx_7xx.h>
|
||||
#include <config.h>
|
||||
#include <version.h>
|
||||
#include <asm/processor.h>
|
||||
#include <tsi108.h>
|
||||
|
||||
extern void mpicInit(int verbose);
|
||||
|
||||
/*
|
||||
* Configuration Options
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
ulong upper;
|
||||
ulong lower;
|
||||
} PB2OCN_LUT_ENTRY;
|
||||
|
||||
PB2OCN_LUT_ENTRY pb2ocn_lut1[32] = {
|
||||
/* 0 - 7 */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE000_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE100_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE200_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE300_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE400_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE500_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE600_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE700_0000 -> PCI/X (Byte-Swap) */
|
||||
|
||||
/* 8 - 15 */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE800_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xE900_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xEA00_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xEB00_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xEC00_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xED00_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xEE00_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xEF00_0000 -> PCI/X (Byte-Swap) */
|
||||
|
||||
/* 16 - 23 */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF000_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF100_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF200_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF300_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF400_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF500_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF600_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF700_0000 -> PCI/X (Byte-Swap) */
|
||||
/* 24 - 31 */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF800_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xF900_0000 -> PCI/X (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xFA00_0000 -> PCI/X PCI I/O (Byte-Swap) */
|
||||
{0x00000000, 0x00000201}, /* PBA=0xFB00_0000 -> PCI/X PCI Config (Byte-Swap) */
|
||||
|
||||
{0x00000000, 0x02000240}, /* PBA=0xFC00_0000 -> HLP */
|
||||
{0x00000000, 0x01000240}, /* PBA=0xFD00_0000 -> HLP */
|
||||
{0x00000000, 0x03000240}, /* PBA=0xFE00_0000 -> HLP */
|
||||
{0x00000000, 0x00000240} /* PBA=0xFF00_0000 -> HLP : (Translation Enabled + Byte-Swap)*/
|
||||
};
|
||||
|
||||
#ifdef CFG_CLK_SPREAD
|
||||
typedef struct {
|
||||
ulong ctrl0;
|
||||
ulong ctrl1;
|
||||
} PLL_CTRL_SET;
|
||||
|
||||
/*
|
||||
* Clock Generator SPLL0 initialization values
|
||||
* PLL0 configuration table for various PB_CLKO freq.
|
||||
* Uses pre-calculated values for Fs = 30 kHz, D = 0.5%
|
||||
* Fout depends on required PB_CLKO. Based on Fref = 33 MHz
|
||||
*/
|
||||
|
||||
static PLL_CTRL_SET pll0_config[8] = {
|
||||
{0x00000000, 0x00000000}, /* 0: bypass */
|
||||
{0x00000000, 0x00000000}, /* 1: reserved */
|
||||
{0x00430044, 0x00000043}, /* 2: CG_PB_CLKO = 183 MHz */
|
||||
{0x005c0044, 0x00000039}, /* 3: CG_PB_CLKO = 100 MHz */
|
||||
{0x005c0044, 0x00000039}, /* 4: CG_PB_CLKO = 133 MHz */
|
||||
{0x004a0044, 0x00000040}, /* 5: CG_PB_CLKO = 167 MHz */
|
||||
{0x005c0044, 0x00000039}, /* 6: CG_PB_CLKO = 200 MHz */
|
||||
{0x004f0044, 0x0000003e} /* 7: CG_PB_CLKO = 233 MHz */
|
||||
};
|
||||
#endif /* CFG_CLK_SPREAD */
|
||||
|
||||
/*
|
||||
* Prosessor Bus Clock (in MHz) defined by CG_PB_SELECT
|
||||
* (based on recommended Tsi108 reference clock 33MHz)
|
||||
*/
|
||||
static int pb_clk_sel[8] = { 0, 0, 183, 100, 133, 167, 200, 233 };
|
||||
|
||||
/*
|
||||
* get_board_bus_clk()
|
||||
*
|
||||
* returns the bus clock in Hz.
|
||||
*/
|
||||
unsigned long get_board_bus_clk(void)
|
||||
{
|
||||
ulong i;
|
||||
|
||||
/* Detect PB clock freq. */
|
||||
i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
|
||||
i = (i >> 16) & 0x07; /* Get PB PLL multiplier */
|
||||
|
||||
return pb_clk_sel[i] * 1000000;
|
||||
}
|
||||
|
||||
/*
|
||||
* board_early_init_f()
|
||||
*
|
||||
* board-specific initialization executed from flash
|
||||
*/
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
ulong i;
|
||||
|
||||
gd->mem_clk = 0;
|
||||
i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
|
||||
i = (i >> 20) & 0x07;
|
||||
switch (i) {
|
||||
case 0:
|
||||
printf("Using external clock\n");
|
||||
break;
|
||||
case 1:
|
||||
gd->mem_clk = gd->bus_clk;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
gd->mem_clk = pb_clk_sel[i] * 1000000;
|
||||
break;
|
||||
default:
|
||||
printf("Invalid DDR2 clock setting\n");
|
||||
return -1;
|
||||
}
|
||||
printf("BUS! %d MHz\n", get_board_bus_clk() / 1000000);
|
||||
printf("MEM! %d MHz\n", gd->mem_clk / 1000000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* board_early_init_r() - Tsi108 initialization function executed right after
|
||||
* relocation. Contains code that cannot be executed from flash.
|
||||
*/
|
||||
|
||||
int board_early_init_r(void)
|
||||
{
|
||||
ulong temp, i;
|
||||
ulong reg_val;
|
||||
volatile ulong *reg_ptr;
|
||||
|
||||
reg_ptr =
|
||||
(ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x900);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
*reg_ptr++ = 0x00000201; /* SWAP ENABLED */
|
||||
*reg_ptr++ = 0x00;
|
||||
}
|
||||
|
||||
__asm__ __volatile__("eieio");
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Setup PB_OCN_BAR2: size 256B + ENable @ 0x0_80000000 */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2,
|
||||
0x80000001);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Make sure that OCN_BAR2 decoder is set (to allow following immediate
|
||||
* read from SDRAM)
|
||||
*/
|
||||
|
||||
temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR2);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/*
|
||||
* Remap PB_OCN_BAR1 to accomodate PCI-bus aperture and EPROM into the
|
||||
* processor bus address space. Immediately after reset LUT and address
|
||||
* translation are disabled for this BAR. Now we have to initialize LUT
|
||||
* and switch from the BOOT mode to the normal operation mode.
|
||||
*
|
||||
* The aperture defined by PB_OCN_BAR1 startes at address 0xE0000000
|
||||
* and covers 512MB of address space. To allow larger aperture we also
|
||||
* have to relocate register window of Tsi108
|
||||
*
|
||||
* Initialize LUT (32-entries) prior switching PB_OCN_BAR1 from BOOT
|
||||
* mode.
|
||||
*
|
||||
* initialize pointer to LUT associated with PB_OCN_BAR1
|
||||
*/
|
||||
reg_ptr =
|
||||
(ulong *) (CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + 0x800);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
*reg_ptr++ = pb2ocn_lut1[i].lower;
|
||||
*reg_ptr++ = pb2ocn_lut1[i].upper;
|
||||
}
|
||||
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Base addresses for Cs0, CS1, CS2, CS3 */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_ADDR,
|
||||
0x00000000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_ADDR,
|
||||
0x00100000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_ADDR,
|
||||
0x00200000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_ADDR,
|
||||
0x00300000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Masks for HLP banks */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_MASK,
|
||||
0xFFF00000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_MASK,
|
||||
0xFFF00000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_MASK,
|
||||
0xFFF00000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_MASK,
|
||||
0xFFF00000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Set CTRL0 values for banks */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL0,
|
||||
0x7FFC44C2);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL0,
|
||||
0x7FFC44C0);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL0,
|
||||
0x7FFC44C0);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL0,
|
||||
0x7FFC44C2);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Set banks to latched mode, enabled, and other default settings */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL1,
|
||||
0x7C0F2000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL1,
|
||||
0x7C0F2000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL1,
|
||||
0x7C0F2000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_CTRL1,
|
||||
0x7C0F2000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/*
|
||||
* Set new value for PB_OCN_BAR1: switch from BOOT to LUT mode.
|
||||
* value for PB_OCN_BAR1: (BA-0xE000_0000 + size 512MB + ENable)
|
||||
*/
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1,
|
||||
0xE0000011);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Make sure that OCN_BAR2 decoder is set (to allow following
|
||||
* immediate read from SDRAM)
|
||||
*/
|
||||
|
||||
temp = in32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_OCN_BAR1);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/*
|
||||
* SRI: At this point we have enabled the HLP banks. That means we can
|
||||
* now read from the NVRAM and initialize the environment variables.
|
||||
* We will over-ride the env_init called in board_init_f
|
||||
* This is really a work-around because, the HLP bank 1
|
||||
* where NVRAM resides is not visible during board_init_f
|
||||
* (lib_ppc/board.c)
|
||||
* Alternatively, we could use the I2C EEPROM at start-up to configure
|
||||
* and enable all HLP banks and not just HLP 0 as is being done for
|
||||
* Taiga Rev. 2.
|
||||
*/
|
||||
|
||||
env_init();
|
||||
|
||||
#ifndef DISABLE_PBM
|
||||
|
||||
/*
|
||||
* For IBM processors we have to set Address-Only commands generated
|
||||
* by PBM that are different from ones set after reset.
|
||||
*/
|
||||
|
||||
temp = get_cpu_type();
|
||||
|
||||
if ((CPU_750FX == temp) || (CPU_750GX == temp)) {
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PB_REG_OFFSET + PB_MCMD,
|
||||
0x00009955);
|
||||
}
|
||||
#endif /* DISABLE_PBM */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/*
|
||||
* Initialize PCI/X block
|
||||
*/
|
||||
|
||||
/* Map PCI/X Configuration Space (16MB @ 0x0_FE000000) */
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_BAR0_UPPER,
|
||||
0);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_BAR0,
|
||||
0xFB000001);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Set Bus Number for the attached PCI/X bus (we will use 0 for NB) */
|
||||
|
||||
temp =
|
||||
in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT);
|
||||
|
||||
temp &= ~0xFF00; /* Clear the BUS_NUM field */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT,
|
||||
temp);
|
||||
|
||||
/* Map PCI/X IO Space (64KB @ 0x0_FD000000) takes one 16MB LUT entry */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO_UPPER,
|
||||
0);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* This register is on the PCI side to interpret the address it receives
|
||||
* and maps it as a IO address.
|
||||
*/
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO,
|
||||
0xFA000001);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/*
|
||||
* Map PCI/X Memory Space
|
||||
*
|
||||
* Transactions directed from OCM to PCI Memory Space are directed
|
||||
* from PB to PCI
|
||||
* unchanged (as defined by PB_OCN_BAR1,2 and LUT settings).
|
||||
* If address remapping is required the corresponding PCI_PFAB_MEM32
|
||||
* and PCI_PFAB_PFMx register groups have to be configured.
|
||||
*
|
||||
* Map the path from the PCI/X bus into the system memory
|
||||
*
|
||||
* The memory mapped window assotiated with PCI P2O_BAR2 provides
|
||||
* access to the system memory without address remapping.
|
||||
* All system memory is opened for accesses initiated by PCI/X bus
|
||||
* masters.
|
||||
*
|
||||
* Initialize LUT associated with PCI P2O_BAR2
|
||||
*
|
||||
* set pointer to LUT associated with PCI P2O_BAR2
|
||||
*/
|
||||
|
||||
reg_ptr =
|
||||
(ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x500);
|
||||
|
||||
#ifdef DISABLE_PBM
|
||||
|
||||
/* In case when PBM is disabled (no HW supported cache snoopng on PB)
|
||||
* P2O_BAR2 is directly mapped into the system memory without address
|
||||
* translation.
|
||||
*/
|
||||
|
||||
reg_val = 0x00000004; /* SDRAM port + NO Addr_Translation */
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
*reg_ptr++ = reg_val; /* P2O_BAR2_LUTx */
|
||||
*reg_ptr++ = 0; /* P2O_BAR2_LUT_UPPERx */
|
||||
}
|
||||
|
||||
/* value for PCI BAR2 (size = 512MB, Enabled, No Addr. Translation) */
|
||||
reg_val = 0x00007500;
|
||||
#else
|
||||
|
||||
reg_val = 0x00000002; /* Destination port = PBM */
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
*reg_ptr++ = reg_val; /* P2O_BAR2_LUTx */
|
||||
/* P2O_BAR2_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
|
||||
*reg_ptr++ = 0x40000000;
|
||||
/* offset = 16MB, address translation is enabled to allow byte swapping */
|
||||
reg_val += 0x01000000;
|
||||
}
|
||||
|
||||
/* value for PCI BAR2 (size = 512MB, Enabled, Address Translation Enabled) */
|
||||
reg_val = 0x00007100;
|
||||
#endif
|
||||
|
||||
__asm__ __volatile__("eieio");
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
|
||||
reg_val);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Set 64-bit PCI bus address for system memory
|
||||
* ( 0 is the best choice for easy mapping)
|
||||
*/
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2,
|
||||
0x00000000);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2_UPPER,
|
||||
0x00000000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
#ifndef DISABLE_PBM
|
||||
/*
|
||||
* The memory mapped window assotiated with PCI P2O_BAR3 provides
|
||||
* access to the system memory using SDRAM OCN port and address
|
||||
* translation. This is alternative way to access SDRAM from PCI
|
||||
* required for Tsi108 emulation testing.
|
||||
* All system memory is opened for accesses initiated by
|
||||
* PCI/X bus masters.
|
||||
*
|
||||
* Initialize LUT associated with PCI P2O_BAR3
|
||||
*
|
||||
* set pointer to LUT associated with PCI P2O_BAR3
|
||||
*/
|
||||
reg_ptr =
|
||||
(ulong *) (CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + 0x600);
|
||||
|
||||
reg_val = 0x00000004; /* Destination port = SDC */
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
*reg_ptr++ = reg_val; /* P2O_BAR3_LUTx */
|
||||
|
||||
/* P2O_BAR3_LUT_UPPERx : Set data swapping mode for PBM (byte swapping) */
|
||||
*reg_ptr++ = 0;
|
||||
|
||||
/* offset = 16MB, address translation is enabled to allow byte swapping */
|
||||
reg_val += 0x01000000;
|
||||
}
|
||||
|
||||
__asm__ __volatile__("eieio");
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Configure PCI P2O_BAR3 (size = 512MB, Enabled) */
|
||||
|
||||
reg_val =
|
||||
in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET +
|
||||
PCI_P2O_PAGE_SIZES);
|
||||
reg_val &= ~0x00FF;
|
||||
reg_val |= 0x0071;
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_PAGE_SIZES,
|
||||
reg_val);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/* Set 64-bit base PCI bus address for window (0x20000000) */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3_UPPER,
|
||||
0x00000000);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3,
|
||||
0x20000000);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
#endif /* !DISABLE_PBM */
|
||||
|
||||
#ifdef ENABLE_PCI_CSR_BAR
|
||||
/* open if required access to Tsi108 CSRs from the PCI/X bus */
|
||||
/* enable BAR0 on the PCI/X bus */
|
||||
reg_val =
|
||||
in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR);
|
||||
reg_val |= 0x02;
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR,
|
||||
reg_val);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0_UPPER,
|
||||
0x00000000);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0,
|
||||
CFG_TSI108_CSR_BASE);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Finally enable PCI/X Bus Master and Memory Space access
|
||||
*/
|
||||
|
||||
reg_val = in32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR);
|
||||
reg_val |= 0x06;
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR, reg_val);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
* Initialize MPIC outputs (interrupt pins):
|
||||
* Interrupt routing on the Grendel Emul. Board:
|
||||
* PB_INT[0] -> INT (CPU0)
|
||||
* PB_INT[1] -> INT (CPU1)
|
||||
* PB_INT[2] -> MCP (CPU0)
|
||||
* PB_INT[3] -> MCP (CPU1)
|
||||
* Set interrupt controller outputs as Level_Sensitive/Active_Low
|
||||
*/
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(0), 0x02);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(1), 0x02);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(2), 0x02);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(3), 0x02);
|
||||
__asm__ __volatile__("sync");
|
||||
|
||||
/*
|
||||
* Ensure that Machine Check exception is enabled
|
||||
* We need it to support PCI Bus probing (configuration reads)
|
||||
*/
|
||||
|
||||
reg_val = mfmsr();
|
||||
mtmsr(reg_val | MSR_ME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Needed to print out L2 cache info
|
||||
* used in the misc_init_r function
|
||||
*/
|
||||
|
||||
unsigned long get_l2cr(void)
|
||||
{
|
||||
unsigned long l2controlreg;
|
||||
asm volatile ("mfspr %0, 1017":"=r" (l2controlreg):);
|
||||
return l2controlreg;
|
||||
}
|
||||
|
||||
/*
|
||||
* misc_init_r()
|
||||
*
|
||||
* various things to do after relocation
|
||||
*
|
||||
*/
|
||||
|
||||
int misc_init_r(void)
|
||||
{
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#ifdef CFG_CLK_SPREAD /* Initialize Spread-Spectrum Clock generation */
|
||||
ulong i;
|
||||
|
||||
/* Ensure that Spread-Spectrum is disabled */
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, 0);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0);
|
||||
|
||||
/* Initialize PLL1: CG_PCI_CLK , internal OCN_CLK
|
||||
* Uses pre-calculated value for Fout = 800 MHz, Fs = 30 kHz, D = 0.5%
|
||||
*/
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0x002e0044); /* D = 0.25% */
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL1, 0x00000039); /* BWADJ */
|
||||
|
||||
/* Initialize PLL0: CG_PB_CLKO */
|
||||
/* Detect PB clock freq. */
|
||||
i = in32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS);
|
||||
i = (i >> 16) & 0x07; /* Get PB PLL multiplier */
|
||||
|
||||
out32(CFG_TSI108_CSR_BASE +
|
||||
TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, pll0_config[i].ctrl0);
|
||||
out32(CFG_TSI108_CSR_BASE +
|
||||
TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL1, pll0_config[i].ctrl1);
|
||||
|
||||
/* Wait and set SSEN for both PLL0 and 1 */
|
||||
udelay(1000);
|
||||
out32(CFG_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, 0x802e0044); /* D=0.25% */
|
||||
out32(CFG_TSI108_CSR_BASE +
|
||||
TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0,
|
||||
0x80000000 | pll0_config[i].ctrl0);
|
||||
#endif /* CFG_CLK_SPREAD */
|
||||
|
||||
#ifdef CFG_L2
|
||||
l2cache_enable();
|
||||
#endif
|
||||
printf("BUS: %d MHz\n", gd->bus_clk / 1000000);
|
||||
printf("MEM: %d MHz\n", gd->mem_clk / 1000000);
|
||||
|
||||
/*
|
||||
* All the information needed to print the cache details is avaiblable
|
||||
* at this point i.e. above call to l2cache_enable is the very last
|
||||
* thing done with regards to enabling diabling the cache.
|
||||
* So this seems like a good place to print all this information
|
||||
*/
|
||||
|
||||
printf("CACHE: ");
|
||||
switch (get_cpu_type()) {
|
||||
case CPU_7447A:
|
||||
printf("L1 Instruction cache - 32KB 8-way");
|
||||
(get_hid0() & (1 << 15)) ? printf(" ENABLED\n") :
|
||||
printf(" DISABLED\n");
|
||||
printf(" L1 Data cache - 32KB 8-way");
|
||||
(get_hid0() & (1 << 14)) ? printf(" ENABLED\n") :
|
||||
printf(" DISABLED\n");
|
||||
printf(" Unified L2 cache - 512KB 8-way");
|
||||
(get_l2cr() & (1 << 31)) ? printf(" ENABLED\n") :
|
||||
printf(" DISABLED\n");
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case CPU_7448:
|
||||
printf("L1 Instruction cache - 32KB 8-way");
|
||||
(get_hid0() & (1 << 15)) ? printf(" ENABLED\n") :
|
||||
printf(" DISABLED\n");
|
||||
printf(" L1 Data cache - 32KB 8-way");
|
||||
(get_hid0() & (1 << 14)) ? printf(" ENABLED\n") :
|
||||
printf(" DISABLED\n");
|
||||
printf(" Unified L2 cache - 1MB 8-way");
|
||||
(get_l2cr() & (1 << 31)) ? printf(" ENABLED\n") :
|
||||
printf(" DISABLED\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue