| /***************************************************************************** | |
| * (C) Copyright 2003; Tundra Semiconductor Corp. | |
| * | |
| * SPDX-License-Identifier: GPL-2.0+ | |
| *****************************************************************************/ | |
| /*---------------------------------------------------------------------------- | |
| * 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> | |
| DECLARE_GLOBAL_DATA_PTR; | |
| 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, 0x00000241}, /* PBA=0xFA00_0000 -> PCI/X PCI I/O (Byte-Swap + Translate) */ | |
| {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 CONFIG_SYS_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 /* CONFIG_SYS_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(CONFIG_SYS_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) | |
| { | |
| ulong i; | |
| gd->mem_clk = 0; | |
| i = in32 (CONFIG_SYS_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: %lu MHz\n", get_board_bus_clk() / 1000000); | |
| printf ("MEM: %lu 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 *) (CONFIG_SYS_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 (CONFIG_SYS_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(CONFIG_SYS_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 *) (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_ADDR, | |
| 0x00000000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_ADDR, | |
| 0x00100000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_ADDR, | |
| 0x00200000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_ADDR, | |
| 0x00300000); | |
| __asm__ __volatile__ ("sync"); | |
| /* Masks for HLP banks */ | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_MASK, | |
| 0xFFF00000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_MASK, | |
| 0xFFF00000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_MASK, | |
| 0xFFF00000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B3_MASK, | |
| 0xFFF00000); | |
| __asm__ __volatile__ ("sync"); | |
| /* Set CTRL0 values for banks */ | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL0, | |
| 0x7FFC44C2); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL0, | |
| 0x7FFC44C0); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL0, | |
| 0x7FFC44C0); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B0_CTRL1, | |
| 0x7C0F2000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B1_CTRL1, | |
| 0x7C0F2000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_HLP_REG_OFFSET + HLP_B2_CTRL1, | |
| 0x7C0F2000); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_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 (CONFIG_SYS_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(CONFIG_SYS_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 | |
| * (arch/powerpc/lib/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 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + | |
| PCI_PFAB_BAR0_UPPER, 0); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_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(CONFIG_SYS_TSI108_CSR_BASE + | |
| TSI108_PCI_REG_OFFSET + PCI_PCIX_STAT); | |
| temp &= ~0xFF00; /* Clear the BUS_NUM field */ | |
| out32 (CONFIG_SYS_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 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_PFAB_IO, | |
| 0x00000001); | |
| __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 *) (CONFIG_SYS_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 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR2, | |
| 0x00000000); | |
| out32 (CONFIG_SYS_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 *) (CONFIG_SYS_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(CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + | |
| PCI_P2O_PAGE_SIZES); | |
| reg_val &= ~0x00FF; | |
| reg_val |= 0x0071; | |
| out32 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR3_UPPER, | |
| 0x00000000); | |
| out32 (CONFIG_SYS_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(CONFIG_SYS_TSI108_CSR_BASE + | |
| TSI108_PCI_REG_OFFSET + PCI_MISC_CSR); | |
| reg_val |= 0x02; | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_MISC_CSR, | |
| reg_val); | |
| __asm__ __volatile__ ("sync"); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0_UPPER, | |
| 0x00000000); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_P2O_BAR0, | |
| CONFIG_SYS_TSI108_CSR_BASE); | |
| __asm__ __volatile__ ("sync"); | |
| #endif | |
| /* | |
| * Finally enable PCI/X Bus Master and Memory Space access | |
| */ | |
| reg_val = in32(CONFIG_SYS_TSI108_CSR_BASE + TSI108_PCI_REG_OFFSET + PCI_CSR); | |
| reg_val |= 0x06; | |
| out32 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(0), 0x02); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(1), 0x02); | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_MPIC_REG_OFFSET + MPIC_CSR(2), 0x02); | |
| out32 (CONFIG_SYS_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) | |
| { | |
| #ifdef CONFIG_SYS_CLK_SPREAD /* Initialize Spread-Spectrum Clock generation */ | |
| ulong i; | |
| /* Ensure that Spread-Spectrum is disabled */ | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, 0); | |
| out32 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, | |
| 0x002e0044); /* D = 0.25% */ | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL1, | |
| 0x00000039); /* BWADJ */ | |
| /* Initialize PLL0: CG_PB_CLKO */ | |
| /* Detect PB clock freq. */ | |
| i = in32(CONFIG_SYS_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PWRUP_STATUS); | |
| i = (i >> 16) & 0x07; /* Get PB PLL multiplier */ | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + | |
| TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, pll0_config[i].ctrl0); | |
| out32 (CONFIG_SYS_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 (CONFIG_SYS_TSI108_CSR_BASE + TSI108_CLK_REG_OFFSET + CG_PLL1_CTRL0, | |
| 0x802e0044); /* D=0.25% */ | |
| out32 (CONFIG_SYS_TSI108_CSR_BASE + | |
| TSI108_CLK_REG_OFFSET + CG_PLL0_CTRL0, | |
| 0x80000000 | pll0_config[i].ctrl0); | |
| #endif /* CONFIG_SYS_CLK_SPREAD */ | |
| #ifdef CONFIG_SYS_L2 | |
| l2cache_enable (); | |
| #endif | |
| printf ("BUS: %lu MHz\n", gd->bus_clk / 1000000); | |
| printf ("MEM: %lu 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; | |
| } |