summaryrefslogtreecommitdiff
path: root/board/mpc7448hpc2/tsi108_init.c
diff options
context:
space:
mode:
authorPeter Pearse <peter.pearse@arm.com>2007-04-19 13:17:20 +0100
committerPeter Pearse <peter.pearse@arm.com>2007-04-19 13:17:20 +0100
commitee89bf2782406b1f87088b4764aeb6f811d82526 (patch)
treeb144476f4b5e92a414efff165d214d34062d4365 /board/mpc7448hpc2/tsi108_init.c
parent9c00dfb0bf89c8c23e8af5b5bdf49cf66d769f85 (diff)
parent37837828d89084879bee2f2b8c7c68d4695940df (diff)
downloadu-boot-imx-ee89bf2782406b1f87088b4764aeb6f811d82526.zip
u-boot-imx-ee89bf2782406b1f87088b4764aeb6f811d82526.tar.gz
u-boot-imx-ee89bf2782406b1f87088b4764aeb6f811d82526.tar.bz2
Merge with git://www.denx.de/git/u-boot.git
Diffstat (limited to 'board/mpc7448hpc2/tsi108_init.c')
-rw-r--r--board/mpc7448hpc2/tsi108_init.c665
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..8a7efef
--- /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;
+}