mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-22 08:38:15 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			666 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			666 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*****************************************************************************
 | |
|  * (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>
 | |
| 
 | |
| 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
 | |
| 	 * (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 (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;
 | |
| }
 |