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>master
parent
27801b8ab1
commit
87c4db0969
@ -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