diff options
Diffstat (limited to 'cpu')
| -rw-r--r-- | cpu/ppc4xx/440spe_pcie.c | 47 | ||||
| -rw-r--r-- | cpu/ppc4xx/440spe_pcie.h | 19 | ||||
| -rw-r--r-- | cpu/ppc4xx/44x_spd_ddr.c | 3 | ||||
| -rw-r--r-- | cpu/ppc4xx/44x_spd_ddr2.c | 58 | ||||
| -rw-r--r-- | cpu/ppc4xx/4xx_enet.c | 8 | ||||
| -rw-r--r-- | cpu/ppc4xx/gpio.c | 6 | ||||
| -rw-r--r-- | cpu/ppc4xx/sdram.c | 32 | ||||
| -rw-r--r-- | cpu/ppc4xx/sdram.h | 2 | ||||
| -rw-r--r-- | cpu/ppc4xx/serial.c | 9 | ||||
| -rw-r--r-- | cpu/ppc4xx/speed.c | 33 | ||||
| -rw-r--r-- | cpu/ppc4xx/start.S | 61 | ||||
| -rw-r--r-- | cpu/ppc4xx/tlb.c | 62 | ||||
| -rw-r--r-- | cpu/ppc4xx/traps.c | 49 | ||||
| -rw-r--r-- | cpu/ppc4xx/usb.c | 6 | 
14 files changed, 296 insertions, 99 deletions
| diff --git a/cpu/ppc4xx/440spe_pcie.c b/cpu/ppc4xx/440spe_pcie.c index d6c4be5f1..bf68cc1e9 100644 --- a/cpu/ppc4xx/440spe_pcie.c +++ b/cpu/ppc4xx/440spe_pcie.c @@ -1,5 +1,5 @@  /* - * (C) Copyright 2006 + * (C) Copyright 2006 - 2007   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.   *   * Copyright (c) 2005 Cisco Systems.  All rights reserved. @@ -40,6 +40,34 @@ enum {  	LNKW_X8			= 0x8  }; +static inline int pcie_in_8(const volatile unsigned char __iomem *addr) +{ +	int ret; + +	PCIE_IN(lbzx, ret, addr); + +	return ret; +} + +static inline int pcie_in_le16(const volatile unsigned short __iomem *addr) +{ +	int ret; + +	PCIE_IN(lhbrx, ret, addr) + +	return ret; +} + +static inline unsigned pcie_in_le32(const volatile unsigned __iomem *addr) +{ +	unsigned ret; + +	PCIE_IN(lwbrx, ret, addr); + +	return ret; +} + +  static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,  	int offset, int len, u32 *val) { @@ -55,13 +83,13 @@ static int pcie_read_config(struct pci_controller *hose, unsigned int devfn,  	switch (len) {  	case 1: -		*val = in_8(hose->cfg_data + offset); +		*val = pcie_in_8(hose->cfg_data + offset);  		break;  	case 2: -		*val = in_le16((u16 *)(hose->cfg_data + offset)); +		*val = pcie_in_le16((u16 *)(hose->cfg_data + offset));  		break;  	default: -		*val = in_le32((u32 *)(hose->cfg_data + offset)); +		*val = pcie_in_le32((u32*)(hose->cfg_data + offset));  		break;  	}  	return 0; @@ -783,9 +811,14 @@ void ppc440spe_setup_pcie_rootpoint(struct pci_controller *hose, int port)  	/*  	 * Set bus numbers on our root port  	 */ -	out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0); -	out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1); -	out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1); +	if (ppc440spe_revB()) { +		out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0); +		out_8((u8 *)mbase + PCI_SECONDARY_BUS, 1); +		out_8((u8 *)mbase + PCI_SUBORDINATE_BUS, 1); +	} else { +		out_8((u8 *)mbase + PCI_PRIMARY_BUS, 0); +		out_8((u8 *)mbase + PCI_SECONDARY_BUS, 0); +	}  	/*  	 * Set up outbound translation to hose->mem_space from PLB diff --git a/cpu/ppc4xx/440spe_pcie.h b/cpu/ppc4xx/440spe_pcie.h index 2becc7772..eb7cecf82 100644 --- a/cpu/ppc4xx/440spe_pcie.h +++ b/cpu/ppc4xx/440spe_pcie.h @@ -145,8 +145,8 @@  #define PECFG_PIMEN		0x33c  #define PECFG_PIM0LAL		0x340  #define PECFG_PIM0LAH		0x344 -#define PECFG_PIM1LAL     	0x348 -#define PECFG_PIM1LAH     	0x34c +#define PECFG_PIM1LAL		0x348 +#define PECFG_PIM1LAH		0x34c  #define PECFG_PIM01SAL		0x350  #define PECFG_PIM01SAH		0x354 @@ -161,6 +161,21 @@  	mtdcr(DCRN_SDR0_CFGADDR, offset); \  	mtdcr(DCRN_SDR0_CFGDATA,data);}) +#define PCIE_IN(opcode, ret, addr) \ +	__asm__ __volatile__(			\ +		"sync\n"			\ +		#opcode " %0,0,%1\n"		\ +		"1: twi 0,%0,0\n"		\ +		"isync\n"			\ +		"b 3f\n"			\ +		"2: li %0,-1\n"			\ +		"3:\n"				\ +		".section __ex_table,\"a\"\n"	\ +		".balign 4\n"			\ +		".long 1b,2b\n"			\ +		".previous\n"			\ +		: "=r" (ret) : "r" (addr), "m" (*addr)); +  int ppc440spe_init_pcie(void);  int ppc440spe_init_pcie_rootport(int port);  void yucca_setup_pcie_fpga_rootpoint(int port); diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c index 6d6fba180..4a4c6f29e 100644 --- a/cpu/ppc4xx/44x_spd_ddr.c +++ b/cpu/ppc4xx/44x_spd_ddr.c @@ -269,9 +269,8 @@ struct bank_param {  typedef struct bank_param BANKPARMS;  #ifdef CFG_SIMULATE_SPD_EEPROM -extern unsigned char cfg_simulate_spd_eeprom[128]; +extern const unsigned char cfg_simulate_spd_eeprom[128];  #endif -void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);  static unsigned char spd_read(uchar chip, uint addr);  static void get_spd_info(unsigned long *dimm_populated, diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 5fef27b98..18b90ba5a 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -109,7 +109,7 @@  /* Defines for the Read Cycle Delay test */  #define NUMMEMTESTS	8  #define NUMMEMWORDS	8 -#define NUMLOOPS	256		/* memory test loops */ +#define NUMLOOPS	64		/* memory test loops */  #undef CONFIG_ECC_ERROR_RESET		/* test-only: see description below, at check_ecc() */ @@ -138,6 +138,26 @@ void __spd_ddr_init_hang (void)  }  void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang"))); +/* + * To provide an interface for board specific config values in this common + * DDR setup code, we implement he "weak" default functions here. They return + * the default value back to the caller. + * + * Please see include/configs/yucca.h for an example fora board specific + * implementation. + */ +u32 __ddr_wrdtr(u32 default_val) +{ +	return default_val; +} +u32 ddr_wrdtr(u32) __attribute__((weak, alias("__ddr_wrdtr"))); + +u32 __ddr_clktr(u32 default_val) +{ +	return default_val; +} +u32 ddr_clktr(u32) __attribute__((weak, alias("__ddr_clktr"))); +  /* Private Structure Definitions */ @@ -154,7 +174,6 @@ typedef enum ddr_cas_id {   * Prototypes   *-----------------------------------------------------------------------------*/  static unsigned long sdram_memsize(void); -void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);  static void get_spd_info(unsigned long *dimm_populated,  			 unsigned char *iic0_dimm_addr,  			 unsigned long num_dimm_banks); @@ -216,9 +235,7 @@ static void	test(void);  #else  static void	DQS_calibration_process(void);  #endif -#if defined(DEBUG)  static void ppc440sp_sdram_register_dump(void); -#endif  int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);  void dcbz_area(u32 start_address, u32 num_bytes);  void dflush(void); @@ -469,17 +486,14 @@ long int initdram(int board_type)  	 *-----------------------------------------------------------------*/  	mfsdram(SDRAM_WRDTR, val);  	mtsdram(SDRAM_WRDTR, (val & ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) | -		(SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV)); +		ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV));  	/*------------------------------------------------------------------  	 * Set the SDRAM Clock Timing Register  	 *-----------------------------------------------------------------*/  	mfsdram(SDRAM_CLKTR, val); -#ifdef CFG_44x_DDR2_CKTR_180 -	mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | SDRAM_CLKTR_CLKP_180_DEG_ADV); -#else -	mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | SDRAM_CLKTR_CLKP_0_DEG); -#endif +	mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | +		ddr_clktr(SDRAM_CLKTR_CLKP_0_DEG));  	/*------------------------------------------------------------------  	 * Program the BxCF registers. @@ -538,7 +552,12 @@ long int initdram(int board_type)  	dram_size = sdram_memsize();  	/* and program tlb entries for this size (dynamic) */ -	program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE); + +	/* +	 * Program TLB entries with caches enabled, for best performace +	 * while auto-calibrating and ECC generation +	 */ +	program_tlb(0, 0, dram_size, 0);  	/*------------------------------------------------------------------  	 * DQS calibration. @@ -549,12 +568,18 @@ long int initdram(int board_type)  	/*------------------------------------------------------------------  	 * If ecc is enabled, initialize the parity bits.  	 *-----------------------------------------------------------------*/ -	program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks, MY_TLB_WORD2_I_ENABLE); +	program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks, 0);  #endif -#ifdef DEBUG +	/* +	 * Now after initialization (auto-calibration and ECC generation) +	 * remove the TLB entries with caches enabled and program again with +	 * desired cache functionality +	 */ +	remove_tlb(0, dram_size); +	program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE); +  	ppc440sp_sdram_register_dump(); -#endif  	return dram_size;  } @@ -2703,6 +2728,7 @@ calibration_loop:  		printf("\nERROR: Cannot determine a common read delay for the "  		       "DIMM(s) installed.\n");  		debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__); +		ppc440sp_sdram_register_dump();  		spd_ddr_init_hang ();  	} @@ -3028,5 +3054,9 @@ static void ppc440sp_sdram_register_dump(void)  	dcr_data = mfdcr(SDRAM_R3BAS);  	printf("        MQ3_B0BAS       = 0x%08X\n", dcr_data);  } +#else +static void ppc440sp_sdram_register_dump(void) +{ +}  #endif  #endif /* CONFIG_SPD_EEPROM */ diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c index d78279171..cc8e7346d 100644 --- a/cpu/ppc4xx/4xx_enet.c +++ b/cpu/ppc4xx/4xx_enet.c @@ -1415,10 +1415,8 @@ static void enet_rcv (struct eth_device *dev, unsigned long malisr)  			if ((MAL_RX_CTRL_EMPTY & hw_p->rx[i].ctrl)  			    || (loop_count >= NUM_RX_BUFF))  				break; +  			loop_count++; -			hw_p->rx_slot++; -			if (NUM_RX_BUFF == hw_p->rx_slot) -				hw_p->rx_slot = 0;  			handled++;  			data_len = (unsigned long) hw_p->rx[i].data_len;	/* Get len */  			if (data_len) { @@ -1468,6 +1466,10 @@ static void enet_rcv (struct eth_device *dev, unsigned long malisr)  				if (NUM_RX_BUFF == hw_p->rx_i_index)  					hw_p->rx_i_index = 0; +				hw_p->rx_slot++; +				if (NUM_RX_BUFF == hw_p->rx_slot) +					hw_p->rx_slot = 0; +  				/*  AS.HARNOIS  				 * free receive buffer only when  				 * buffer has been handled (eth_rx) diff --git a/cpu/ppc4xx/gpio.c b/cpu/ppc4xx/gpio.c index 5235203ea..50f2fdf11 100644 --- a/cpu/ppc4xx/gpio.c +++ b/cpu/ppc4xx/gpio.c @@ -186,6 +186,7 @@ void gpio_set_chip_configuration(void)  						out32(GPIO0_TCR, reg);  					} +#ifdef GPIO1  					if (gpio_core == GPIO1) {  						/*  						 * Setup output value @@ -193,16 +194,17 @@ void gpio_set_chip_configuration(void)  						 * 0 -> low level  						 * else -> don't touch  						 */ -						reg = in32(GPIO0_OR); +						reg = in32(GPIO1_OR);  						if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_1)  							reg |= (0x80000000 >> (i));  						else if (gpio_tab[gpio_core][i].out_val == GPIO_OUT_0)  							reg &= ~(0x80000000 >> (i)); -						out32(GPIO0_OR, reg); +						out32(GPIO1_OR, reg);  						reg = in32(GPIO1_TCR) | (0x80000000 >> (i));  						out32(GPIO1_TCR, reg);  					} +#endif /* GPIO1 */  					reg = in32(GPIO_OS(core_add+offs))  						& ~(GPIO_MASK >> (j*2)); diff --git a/cpu/ppc4xx/sdram.c b/cpu/ppc4xx/sdram.c index d520cd3ff..2724d91f0 100644 --- a/cpu/ppc4xx/sdram.c +++ b/cpu/ppc4xx/sdram.c @@ -187,14 +187,14 @@ void sdram_init(void)  		/*  		 * Disable memory controller.  		 */ -		mtsdram0(mem_mcopt1, 0x00000000); +		mtsdram(mem_mcopt1, 0x00000000);  		/*  		 * Set MB0CF for bank 0.  		 */ -		mtsdram0(mem_mb0cf, mb0cf[i].reg); -		mtsdram0(mem_sdtr1, sdtr1); -		mtsdram0(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64)); +		mtsdram(mem_mb0cf, mb0cf[i].reg); +		mtsdram(mem_sdtr1, sdtr1); +		mtsdram(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64));  		udelay(200); @@ -203,14 +203,34 @@ void sdram_init(void)  		 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst  		 * read/prefetch.  		 */ -		mtsdram0(mem_mcopt1, 0x80800000); +		mtsdram(mem_mcopt1, 0x80800000);  		udelay(10000);  		if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {  			/* -			 * OK, size detected -> all done +			 * OK, size detected.  Enable second bank if +			 * defined (assumes same type as bank 0)  			 */ +#ifdef CONFIG_SDRAM_BANK1 +			u32 b1cr = mb0cf[i].size | mb0cf[i].reg; + +			mtsdram(mem_mcopt1, 0x00000000); +			mtsdram(mem_mb1cf, b1cr); /* SDRAM0_B1CR */ +			mtsdram(mem_mcopt1, 0x80800000); +			udelay(10000); + +			/* +			 * Check if 2nd bank is really available. +			 * If the size not equal to the size of the first +			 * bank, then disable the 2nd bank completely. +			 */ +			if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) != +			    mb0cf[i].size) { +				mtsdram(mem_mb1cf, 0); +				mtsdram(mem_mcopt1, 0); +			} +#endif  			return;  		}  	} diff --git a/cpu/ppc4xx/sdram.h b/cpu/ppc4xx/sdram.h index 62b5442f3..4fb9b1ae1 100644 --- a/cpu/ppc4xx/sdram.h +++ b/cpu/ppc4xx/sdram.h @@ -29,8 +29,6 @@  #include <config.h> -#define mtsdram0(reg, data)  mtdcr(memcfga,reg);mtdcr(memcfgd,data) -  #define ONE_BILLION	1000000000  struct sdram_conf_s { diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c index 3f67136be..60712b151 100644 --- a/cpu/ppc4xx/serial.c +++ b/cpu/ppc4xx/serial.c @@ -448,12 +448,17 @@ static void serial_divs (int baudrate, unsigned long *pudiv,  	unsigned long i;  	unsigned long est;		/* current estimate */  	unsigned long plloutb; +	unsigned long cpr_pllc;  	u32 reg; +	/* check the pll feedback source */ +	mfcpr(cprpllc, cpr_pllc); +  	get_sys_info(&sysinfo); -	plloutb = ((CONFIG_SYS_CLK_FREQ * sysinfo.pllFwdDiv * sysinfo.pllFbkDiv) -		   / sysinfo.pllFwdDivB); +	plloutb = ((CONFIG_SYS_CLK_FREQ * ((cpr_pllc & PLLC_SRC_MASK) ? +		sysinfo.pllFwdDivB : sysinfo.pllFwdDiv) * sysinfo.pllFbkDiv) / +		sysinfo.pllFwdDivB);  	udiv = 256;			/* Assume lowest possible serial clk */  	div = plloutb / (16 * baudrate); /* total divisor */  	umin = (plloutb / get_OPB_freq()) << 1;	/* 2 x OPB divisor */ diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 028b11af8..da5330a36 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -771,6 +771,7 @@ ulong get_PCI_freq (void)  void get_sys_info (PPC405_SYS_INFO * sysInfo)  {  	unsigned long cpr_plld; +	unsigned long cpr_pllc;  	unsigned long cpr_primad;  	unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ/1000);  	unsigned long primad_cpudv; @@ -780,6 +781,7 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)  	 * Read PLL Mode registers  	 */  	mfcpr(cprplld, cpr_plld); +	mfcpr(cprpllc, cpr_pllc);  	/*  	 * Determine forward divider A @@ -787,20 +789,18 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)  	sysInfo->pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16);  	/* -	 * Determine forward divider B (should be equal to A) +	 * Determine forward divider B  	 */  	sysInfo->pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8); -	if (sysInfo->pllFwdDivB == 0) { +	if (sysInfo->pllFwdDivB == 0)  		sysInfo->pllFwdDivB = 8; -	}  	/*  	 * Determine FBK_DIV.  	 */  	sysInfo->pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24); -	if (sysInfo->pllFbkDiv == 0) { +	if (sysInfo->pllFbkDiv == 0)  		sysInfo->pllFbkDiv = 256; -	}  	/*  	 * Read CPR_PRIMAD register @@ -810,30 +810,30 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)  	 * Determine PLB_DIV.  	 */  	sysInfo->pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16); -	if (sysInfo->pllPlbDiv == 0) { +	if (sysInfo->pllPlbDiv == 0)  		sysInfo->pllPlbDiv = 16; -	}  	/*  	 * Determine EXTBUS_DIV.  	 */  	sysInfo->pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK); -	if (sysInfo->pllExtBusDiv == 0) { +	if (sysInfo->pllExtBusDiv == 0)  		sysInfo->pllExtBusDiv = 16; -	}  	/*  	 * Determine OPB_DIV.  	 */  	sysInfo->pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8); -	if (sysInfo->pllOpbDiv == 0) { +	if (sysInfo->pllOpbDiv == 0)  		sysInfo->pllOpbDiv = 16; -	}  	/*  	 * Determine the M factor  	 */ -	m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB; +	if (cpr_pllc & PLLC_SRC_MASK) +		m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB; +	else +		m = sysInfo->pllFbkDiv * sysInfo->pllFwdDiv;  	/*  	 * Determine VCO clock frequency @@ -845,16 +845,17 @@ void get_sys_info (PPC405_SYS_INFO * sysInfo)  	 * Determine CPU clock frequency  	 */  	primad_cpudv = ((cpr_primad & PRIMAD_CPUDV_MASK) >> 24); -	if (primad_cpudv == 0) { +	if (primad_cpudv == 0)  		primad_cpudv = 16; -	} -	sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) / primad_cpudv; +	sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * m) / +		sysInfo->pllFwdDiv / primad_cpudv;  	/*  	 * Determine PLB clock frequency  	 */ -	sysInfo->freqPLB = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) / sysInfo->pllPlbDiv; +	sysInfo->freqPLB = (CONFIG_SYS_CLK_FREQ * m) / +		sysInfo->pllFwdDiv / sysInfo->pllPlbDiv;  }  /******************************************** diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 8ecaaea4d..9626b65c8 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -1870,28 +1870,6 @@ ppc405ep_init:  	mtdcr	ebccfgd,r3  #endif -#ifndef CFG_CPC0_PCI -	li	r3,CPC0_PCI_HOST_CFG_EN -#ifdef CONFIG_BUBINGA -	/* -	!----------------------------------------------------------------------- -	! Check FPGA for PCI internal/external arbitration -	!   If board is set to internal arbitration, update cpc0_pci -	!----------------------------------------------------------------------- -	*/ -	addis	r5,r0,FPGA_REG1@h      /* set offset for FPGA_REG1 */ -	ori	r5,r5,FPGA_REG1@l -	lbz	r5,0x0(r5)		/* read to get PCI arb selection */ -	andi.	r6,r5,FPGA_REG1_PCI_INT_ARB  /* using internal arbiter ?*/ -	beq	..pci_cfg_set		  /* if not set, then bypass reg write*/ -#endif -	ori	r3,r3,CPC0_PCI_ARBIT_EN -#else /* CFG_CPC0_PCI */ -	li	r3,CFG_CPC0_PCI -#endif /* CFG_CPC0_PCI */ -..pci_cfg_set: -	mtdcr	CPC0_PCI, r3		 /* Enable internal arbiter*/ -  	/*  	!-----------------------------------------------------------------------  	! Check to see if chip is in bypass mode. @@ -1947,11 +1925,50 @@ ppc405ep_init:  ..no_pllset:  #endif /* CONFIG_BUBINGA */ +#ifdef CONFIG_TAIHU +	mfdcr	r4, CPC0_BOOT +	andi.	r5, r4, CPC0_BOOT_SEP@l +	bne	strap_1			/* serial eeprom present */ +	addis	r5,0,CPLD_REG0_ADDR@h +	ori	r5,r5,CPLD_REG0_ADDR@l +	andi.	r5, r5, 0x10 +	bne	_pci_66mhz +#endif /* CONFIG_TAIHU */ + +#if defined(CONFIG_ZEUS) +	mfdcr	r4, CPC0_BOOT +	andi.	r5, r4, CPC0_BOOT_SEP@l +	bne	strap_1  	/* serial eeprom present */ +	lis	r3,0x0000 +	addi	r3,r3,0x3030 +	lis	r4,0x8042 +	addi	r4,r4,0x223e +	b	1f +strap_1: +	mfdcr	r3, CPC0_PLLMR0 +	mfdcr	r4, CPC0_PLLMR1 +	b	1f +#endif +  	addis	r3,0,PLLMR0_DEFAULT@h	    /* PLLMR0 default value */  	ori	r3,r3,PLLMR0_DEFAULT@l	   /* */  	addis	r4,0,PLLMR1_DEFAULT@h	    /* PLLMR1 default value */  	ori	r4,r4,PLLMR1_DEFAULT@l	   /* */ +#ifdef CONFIG_TAIHU +	b	1f +_pci_66mhz: +	addis	r3,0,PLLMR0_DEFAULT_PCI66@h +	ori	r3,r3,PLLMR0_DEFAULT_PCI66@l +	addis	r4,0,PLLMR1_DEFAULT_PCI66@h +	ori	r4,r4,PLLMR1_DEFAULT_PCI66@l +	b	1f +strap_1: +	mfdcr	r3, CPC0_PLLMR0 +	mfdcr	r4, CPC0_PLLMR1 +#endif /* CONFIG_TAIHU */ + +1:  	b	pll_write		  /* Write the CPC0_PLLMR with new value */  pll_done: diff --git a/cpu/ppc4xx/tlb.c b/cpu/ppc4xx/tlb.c index 049a78549..098694caf 100644 --- a/cpu/ppc4xx/tlb.c +++ b/cpu/ppc4xx/tlb.c @@ -25,7 +25,6 @@  #if defined(CONFIG_440) -#include <ppc4xx.h>  #include <ppc440.h>  #include <asm/io.h>  #include <asm/mmu.h> @@ -36,6 +35,67 @@ typedef struct region {  	unsigned long tlb_word2_i_value;  } region_t; +void remove_tlb(u32 vaddr, u32 size) +{ +	int i; +	u32 tlb_word0_value; +	u32 tlb_vaddr; +	u32 tlb_size = 0; + +	/* First, find the index of a TLB entry not being used */ +	for (i=0; i<PPC4XX_TLB_SIZE; i++) { +		tlb_word0_value = mftlb1(i); +		tlb_vaddr = TLB_WORD0_EPN_DECODE(tlb_word0_value); +		if (((tlb_word0_value & TLB_WORD0_V_MASK) == TLB_WORD0_V_ENABLE) && +		    (tlb_vaddr >= vaddr)) { +			/* +			 * TLB is enabled and start address is lower or equal +			 * than the area we are looking for. Now we only have +			 * to check the size/end address for a match. +			 */ +			switch (tlb_word0_value & TLB_WORD0_SIZE_MASK) { +			case TLB_WORD0_SIZE_1KB: +				tlb_size = 1 << 10; +				break; +			case TLB_WORD0_SIZE_4KB: +				tlb_size = 4 << 10; +				break; +			case TLB_WORD0_SIZE_16KB: +				tlb_size = 16 << 10; +				break; +			case TLB_WORD0_SIZE_64KB: +				tlb_size = 64 << 10; +				break; +			case TLB_WORD0_SIZE_256KB: +				tlb_size = 256 << 10; +				break; +			case TLB_WORD0_SIZE_1MB: +				tlb_size = 1 << 20; +				break; +			case TLB_WORD0_SIZE_16MB: +				tlb_size = 16 << 20; +				break; +			case TLB_WORD0_SIZE_256MB: +				tlb_size = 256 << 20; +				break; +			} + +			/* +			 * Now check the end-address if it's in the range +			 */ +			if ((tlb_vaddr + tlb_size - 1) <= (vaddr + size - 1)) +				/* +				 * Found a TLB in the range. +				 * Disable it by writing 0 to tlb0 word. +				 */ +				mttlb1(i, 0); +		} +	} + +	/* Execute an ISYNC instruction so that the new TLB entry takes effect */ +	asm("isync"); +} +  static int add_tlb_entry(unsigned long phys_addr,  			 unsigned long virt_addr,  			 unsigned long tlb_word0_size_value, diff --git a/cpu/ppc4xx/traps.c b/cpu/ppc4xx/traps.c index 899cdbd1f..f5365cb76 100644 --- a/cpu/ppc4xx/traps.c +++ b/cpu/ppc4xx/traps.c @@ -147,14 +147,21 @@ MachineCheckException(struct pt_regs *regs)  	unsigned long fixup, val;  #if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)  	u32 value2; +	int corr_ecc = 0; +	int uncorr_ecc = 0;  #endif -	/* Probing PCI using config cycles cause this exception -	 * when a device is not present.  Catch it and return to -	 * the PCI exception handler. +	/* Probing PCI(E) using config cycles may cause this exception +	 * when a device is not present. To gracefully recover in such +	 * scenarios config read/write routines need to be instrumented in +	 * order to return via fixup handler. For examples refer to +	 * pcie_in_8(), pcie_in_le16() and pcie_in_le32()  	 */  	if ((fixup = search_exception_table(regs->nip)) != 0) {  		regs->nip = fixup; +		val = mfspr(MCSR); +		/* Clear MCSR */ +		mtspr(SPRN_MCSR, val);  		return;  	} @@ -214,14 +221,22 @@ MachineCheckException(struct pt_regs *regs)  		printf("DDR0: At least one interrupt active\n");  	if (val & 0x40)  		printf("DDR0: DRAM initialization complete.\n"); -	if (val & 0x20) +	if (val & 0x20) {  		printf("DDR0: Multiple uncorrectable ECC events.\n"); -	if (val & 0x10) +		uncorr_ecc = 1; +	} +	if (val & 0x10) {  		printf("DDR0: Single uncorrectable ECC event.\n"); -	if (val & 0x08) +		uncorr_ecc = 1; +	} +	if (val & 0x08) {  		printf("DDR0: Multiple correctable ECC events.\n"); -	if (val & 0x04) +		corr_ecc = 1; +	} +	if (val & 0x04) {  		printf("DDR0: Single correctable ECC event.\n"); +		corr_ecc = 1; +	}  	if (val & 0x02)  		printf("Multiple accesses outside the defined"  		       " physical memory space detected\n"); @@ -252,11 +267,11 @@ MachineCheckException(struct pt_regs *regs)  		printf("DDR0: No DDR0 error know 0x%x %p\n", val, value2);  	}  	mfsdram(DDR0_23, val); -	if ( (val >> 16) & 0xff) +	if (((val >> 16) & 0xff) && corr_ecc)  		printf("DDR0: Syndrome for correctable ECC event 0x%x\n",  		       (val >> 16) & 0xff);  	mfsdram(DDR0_23, val); -	if ( (val >> 8) & 0xff) +	if (((val >> 8) & 0xff) && uncorr_ecc)  		printf("DDR0: Syndrome for uncorrectable ECC event 0x%x\n",  		       (val >> 8) & 0xff);  	mfsdram(DDR0_33, val); @@ -264,28 +279,28 @@ MachineCheckException(struct pt_regs *regs)  		printf("DDR0: Address of command that caused an "  		       "Out-of-Range interrupt %p\n", val);  	mfsdram(DDR0_34, val); -	if (val) +	if (val && uncorr_ecc)  		printf("DDR0: Address of uncorrectable ECC event %p\n", val);  	mfsdram(DDR0_35, val); -	if (val) +	if (val && uncorr_ecc)  		printf("DDR0: Address of uncorrectable ECC event %p\n", val);  	mfsdram(DDR0_36, val); -	if (val) +	if (val && uncorr_ecc)  		printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);  	mfsdram(DDR0_37, val); -	if (val) +	if (val && uncorr_ecc)  		printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);  	mfsdram(DDR0_38, val); -	if (val) +	if (val && corr_ecc)  		printf("DDR0: Address of correctable ECC event %p\n", val);  	mfsdram(DDR0_39, val); -	if (val) +	if (val && corr_ecc)  		printf("DDR0: Address of correctable ECC event %p\n", val);  	mfsdram(DDR0_40, val); -	if (val) +	if (val && corr_ecc)  		printf("DDR0: Data of correctable ECC event 0x%08x\n", val);  	mfsdram(DDR0_41, val); -	if (val) +	if (val && corr_ecc)  		printf("DDR0: Data of correctable ECC event 0x%08x\n", val);  #endif /* CONFIG_440EPX */  #endif /* CONFIG_440 */ diff --git a/cpu/ppc4xx/usb.c b/cpu/ppc4xx/usb.c index 2837b37c5..272ed8c15 100644 --- a/cpu/ppc4xx/usb.c +++ b/cpu/ppc4xx/usb.c @@ -27,7 +27,7 @@  #include "usbdev.h" -int usb_cpu_init() +int usb_cpu_init(void)  {  #if defined(CONFIG_440EP) || defined(CONFIG_440EPX) @@ -37,12 +37,12 @@ int usb_cpu_init()  	return 0;  } -int usb_cpu_stop() +int usb_cpu_stop(void)  {  	return 0;  } -int usb_cpu_init_fail() +int usb_cpu_init_fail(void)  {  	return 0;  } |