diff options
author | Wolfgang Denk <wd@pollux.denx.de> | 2007-03-04 01:17:20 +0100 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2007-03-04 01:17:20 +0100 |
commit | b24444f1b3ef428b8f85974d23d4edb16e9a046f (patch) | |
tree | a34b697e8ae0d054cc7729b25f7f209c07471245 /board/mpc7448hpc2/tsi108_init.c | |
parent | fdd1d6dcc97c595bd9d598ed3b22a7038781272c (diff) | |
parent | 00b574bdc8c54dbc9e03f63c24f62955d483e3ef (diff) | |
download | u-boot-imx-b24444f1b3ef428b8f85974d23d4edb16e9a046f.zip u-boot-imx-b24444f1b3ef428b8f85974d23d4edb16e9a046f.tar.gz u-boot-imx-b24444f1b3ef428b8f85974d23d4edb16e9a046f.tar.bz2 |
Merge with http://opensource.freescale.com/pub/scm/u-boot-7448hpc2.git
Diffstat (limited to 'board/mpc7448hpc2/tsi108_init.c')
-rw-r--r-- | board/mpc7448hpc2/tsi108_init.c | 665 |
1 files changed, 665 insertions, 0 deletions
diff --git a/board/mpc7448hpc2/tsi108_init.c b/board/mpc7448hpc2/tsi108_init.c new file mode 100644 index 0000000..e3b09cf --- /dev/null +++ b/board/mpc7448hpc2/tsi108_init.c @@ -0,0 +1,665 @@ +/***************************************************************************** + * (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; /* Get GD PLL multiplier */ + switch (i) { + case 0: /* external clock */ + printf ("Using external clock\n"); + break; + case 1: /* system clock */ + gd->mem_clk = gd->bus_clk; + break; + case 4: /* 133 MHz */ + case 5: /* 166 MHz */ + case 6: /* 200 MHz */ + 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; +} |