diff options
Diffstat (limited to 'board/amcc')
| -rw-r--r-- | board/amcc/bamboo/bamboo.c | 321 | ||||
| -rw-r--r-- | board/amcc/bamboo/init.S | 3 | ||||
| -rw-r--r-- | board/amcc/bamboo/u-boot.lds | 2 | ||||
| -rw-r--r-- | board/amcc/bubinga/bubinga.c | 13 | ||||
| -rw-r--r-- | board/amcc/common/flash.c | 18 | ||||
| -rw-r--r-- | board/amcc/luan/luan.c | 7 | ||||
| -rw-r--r-- | board/amcc/taihu/Makefile | 49 | ||||
| -rw-r--r-- | board/amcc/taihu/config.mk | 24 | ||||
| -rw-r--r-- | board/amcc/taihu/flash.c | 1083 | ||||
| -rw-r--r-- | board/amcc/taihu/lcd.c | 257 | ||||
| -rw-r--r-- | board/amcc/taihu/taihu.c | 240 | ||||
| -rw-r--r-- | board/amcc/taihu/u-boot.lds | 150 | ||||
| -rw-r--r-- | board/amcc/taihu/update.c | 132 | ||||
| -rw-r--r-- | board/amcc/yucca/yucca.c | 34 | 
14 files changed, 2228 insertions, 105 deletions
| diff --git a/board/amcc/bamboo/bamboo.c b/board/amcc/bamboo/bamboo.c index caf66909b..00c793afd 100644 --- a/board/amcc/bamboo/bamboo.c +++ b/board/amcc/bamboo/bamboo.c @@ -32,9 +32,170 @@ void ext_bus_cntlr_init(void);  void configure_ppc440ep_pins(void);  int is_nand_selected(void); -unsigned char cfg_simulate_spd_eeprom[128]; +#if !(defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)) +/************************************************************************* + * + * Bamboo has one bank onboard sdram (plus DIMM) + * + * Fixed memory is composed of : + *	MT46V16M16TG-75 from Micron (x 2), 256Mb, 16 M x16, DDR266, + *	13 row add bits, 10 column add bits (but 12 row used only). + *	ECC device: MT46V16M8TG-75 from Micron (x 1), 128Mb, x8, DDR266, + *	12 row add bits, 10 column add bits. + *	Prepare a subset (only the used ones) of SPD data + * + *	Note : if the ECC is enabled (SDRAM_ECC_ENABLE) the size of + *	the corresponding bank is divided by 2 due to number of Row addresses + *	12 in the ECC module + * + *  Assumes:	64 MB, ECC, non-registered + *		PLB @ 133 MHz + * + ************************************************************************/ +const unsigned char cfg_simulate_spd_eeprom[128] = { +	0x80,    /* number of SPD bytes used: 128 */ +	0x08,    /*  total number bytes in SPD device = 256 */ +	0x07,    /* DDR ram */ +#ifdef CONFIG_DDR_ECC +	0x0C,    /* num Row Addr: 12 */ +#else +	0x0D,    /* num Row Addr: 13 */ +#endif +	0x09,    /* numColAddr: 9  */ +	0x01,    /* numBanks: 1 */ +	0x20,    /* Module data width: 32 bits */ +	0x00,    /* Module data width continued: +0 */ +	0x04,    /* 2.5 Volt */ +	0x75,    /* SDRAM Cycle Time (cas latency 2.5) = 7.5 ns */ +#ifdef CONFIG_DDR_ECC +	0x02,    /* ECC ON : 02 OFF : 00 */ +#else +	0x00,    /* ECC ON : 02 OFF : 00 */ +#endif +	0x82,    /* refresh Rate Type: Normal (15.625us) + Self refresh */ +	0, +	0, +	0, +	0x01,    /* wcsbc = 1 */ +	0, +	0, +	0x0C,    /* casBit (2,2.5) */ +	0, +	0, +	0x00,    /* not registered: 0  registered : 0x02*/ +	0, +	0xA0,    /* SDRAM Cycle Time (cas latency 2) = 10 ns */ +	0, +	0x00,    /* SDRAM Cycle Time (cas latency 1.5) = N.A */ +	0, +	0x50,    /* tRpNs = 20 ns  */ +	0, +	0x50,    /* tRcdNs = 20 ns */ +	45,      /* tRasNs */ +#ifdef CONFIG_DDR_ECC +	0x08,    /* bankSizeID: 32MB */ +#else +	0x10,    /* bankSizeID: 64MB */ +#endif +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0, +	0 +}; +#endif -gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX];  #if 0  {	   /* GPIO   Alternate1	      Alternate2	Alternate3 */      { @@ -291,73 +452,12 @@ int checkboard(void)  	return (0);  } -#if !(defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL)) -/************************************************************************* - * - * init_spd_array -- Bamboo has one bank onboard sdram (plus DIMM) - * - * Fixed memory is composed of : - *	MT46V16M16TG-75 from Micron (x 2), 256Mb, 16 M x16, DDR266, - *	13 row add bits, 10 column add bits (but 12 row used only). - *	ECC device: MT46V16M8TG-75 from Micron (x 1), 128Mb, x8, DDR266, - *	12 row add bits, 10 column add bits. - *	Prepare a subset (only the used ones) of SPD data - * - *	Note : if the ECC is enabled (SDRAM_ECC_ENABLE) the size of - *	the corresponding bank is divided by 2 due to number of Row addresses - *	12 in the ECC module - * - *  Assumes:	64 MB, ECC, non-registered - *		PLB @ 133 MHz - * - ************************************************************************/ -static void init_spd_array(void) -{ -	cfg_simulate_spd_eeprom[8]     = 0x04;    /* 2.5 Volt */ -	cfg_simulate_spd_eeprom[2]     = 0x07;    /* DDR ram */ - -#ifdef CONFIG_DDR_ECC -	cfg_simulate_spd_eeprom[11]    = 0x02;    /* ECC ON : 02 OFF : 00 */ -	cfg_simulate_spd_eeprom[31]    = 0x08;    /* bankSizeID: 32MB */ -	cfg_simulate_spd_eeprom[3]     = 0x0C;    /* num Row Addr: 12 */ -#else -	cfg_simulate_spd_eeprom[11]    = 0x00;    /* ECC ON : 02 OFF : 00 */ -	cfg_simulate_spd_eeprom[31]    = 0x10;    /* bankSizeID: 64MB */ -	cfg_simulate_spd_eeprom[3]     = 0x0D;    /* num Row Addr: 13 */ -#endif - -	cfg_simulate_spd_eeprom[4]     = 0x09;    /* numColAddr: 9  */ -	cfg_simulate_spd_eeprom[5]     = 0x01;    /* numBanks: 1 */ -	cfg_simulate_spd_eeprom[0]     = 0x80;    /* number of SPD bytes used: 128 */ -	cfg_simulate_spd_eeprom[1]     = 0x08;    /*  total number bytes in SPD device = 256 */ -	cfg_simulate_spd_eeprom[21]    = 0x00;    /* not registered: 0  registered : 0x02*/ -	cfg_simulate_spd_eeprom[6]     = 0x20;    /* Module data width: 32 bits */ -	cfg_simulate_spd_eeprom[7]     = 0x00;    /* Module data width continued: +0 */ -	cfg_simulate_spd_eeprom[15]    = 0x01;    /* wcsbc = 1 */ -	cfg_simulate_spd_eeprom[27]    = 0x50;    /* tRpNs = 20 ns  */ -	cfg_simulate_spd_eeprom[29]    = 0x50;    /* tRcdNs = 20 ns */ - -	cfg_simulate_spd_eeprom[30]    = 45;      /* tRasNs */ - -	cfg_simulate_spd_eeprom[18]    = 0x0C;    /* casBit (2,2.5) */ - -	cfg_simulate_spd_eeprom[9]     = 0x75;    /* SDRAM Cycle Time (cas latency 2.5) = 7.5 ns */ -	cfg_simulate_spd_eeprom[23]    = 0xA0;    /* SDRAM Cycle Time (cas latency 2) = 10 ns */ -	cfg_simulate_spd_eeprom[25]    = 0x00;    /* SDRAM Cycle Time (cas latency 1.5) = N.A */ -	cfg_simulate_spd_eeprom[12]    = 0x82;    /* refresh Rate Type: Normal (15.625us) + Self refresh */ -} -#endif  long int initdram (int board_type)  {  #if !(defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL))  	long dram_size; -	/* -	 * First write simulated values in eeprom array for onboard bank 0 -	 */ -	init_spd_array(); -  	dram_size = spd_sdram();  	return dram_size; @@ -371,11 +471,12 @@ int testdram(void)  {  	unsigned long *mem = (unsigned long *)0;  	const unsigned long kend = (1024 / sizeof(unsigned long)); -	unsigned long k, n; +	unsigned long k, n, *p32, ctr; +	const unsigned long bend = CFG_MBYTES_SDRAM * 1024 * 1024;  	mtmsr(0); -	for (k = 0; k < CFG_KBYTES_SDRAM; +	for (k = 0; k <	CFG_MBYTES_SDRAM*1024;  	     ++k, mem += (1024 / sizeof(unsigned long))) {  		if ((k & 1023) == 0) {  			printf("%3d MB\r", k / 1024); @@ -399,6 +500,34 @@ int testdram(void)  			}  		}  	} + +	/* +	 * Perform a sequence test to ensure that all +	 * memory locations are uniquely addressable +	 */ +	ctr = 0; +	p32 = 0; +	while ((unsigned long)p32 != bend) { +		if (0 == ((unsigned long)p32 & ((1<<20)-1))) +			printf("Writing	%3d MB\r", (unsigned long)p32 >> 20); +		*p32++ = ctr++; +	} + +	ctr = 0; +	p32 = 0; +	while ((unsigned long)p32 != bend) { +		if (0 == ((unsigned long)p32 & ((1<<20)-1))) +			printf("Verifying %3d MB\r", (unsigned long)p32 >> 20); + +		if (*p32 != ctr) { +			printf("SDRAM test fails at: %08x\n", p32); +			return 1; +		} + +		ctr++; +		p32++; +	} +  	printf("SDRAM test passes\n");  	return 0;  } @@ -1211,7 +1340,7 @@ void uart_selection_in_fpga(uart_config_nb_t uart_config)  /*----------------------------------------------------------------------------+    | init_default_gpio    +----------------------------------------------------------------------------*/ -void init_default_gpio(void) +void init_default_gpio(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	int i; @@ -1281,7 +1410,7 @@ void init_default_gpio(void)    |    +----------------------------------------------------------------------------*/ -void update_uart_ios(uart_config_nb_t uart_config) +void update_uart_ios(uart_config_nb_t uart_config, gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	switch (uart_config)  	{ @@ -1409,7 +1538,7 @@ void update_uart_ios(uart_config_nb_t uart_config)  /*----------------------------------------------------------------------------+    | update_ndfc_ios(void).    +----------------------------------------------------------------------------*/ -void update_ndfc_ios(void) +void update_ndfc_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	/* Update GPIO Configuration Table */  	gpio_tab[GPIO0][6].in_out = GPIO_OUT;	    /* EBC_CS_N(1) */ @@ -1427,7 +1556,7 @@ void update_ndfc_ios(void)  /*----------------------------------------------------------------------------+    | update_zii_ios(void).    +----------------------------------------------------------------------------*/ -void update_zii_ios(void) +void update_zii_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	/* Update GPIO Configuration Table */  	gpio_tab[GPIO0][12].in_out = GPIO_IN;	    /* ZII_p0Rxd(0) */ @@ -1477,7 +1606,7 @@ void update_zii_ios(void)  /*----------------------------------------------------------------------------+    | update_uic_0_3_irq_ios().    +----------------------------------------------------------------------------*/ -void update_uic_0_3_irq_ios(void) +void update_uic_0_3_irq_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	gpio_tab[GPIO1][8].in_out = GPIO_IN;	    /* UIC_IRQ(0) */  	gpio_tab[GPIO1][8].alt_nb = GPIO_ALT1; @@ -1495,7 +1624,7 @@ void update_uic_0_3_irq_ios(void)  /*----------------------------------------------------------------------------+    | update_uic_4_9_irq_ios().    +----------------------------------------------------------------------------*/ -void update_uic_4_9_irq_ios(void) +void update_uic_4_9_irq_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	gpio_tab[GPIO1][12].in_out = GPIO_IN;	    /* UIC_IRQ(4) */  	gpio_tab[GPIO1][12].alt_nb = GPIO_ALT1; @@ -1516,7 +1645,7 @@ void update_uic_4_9_irq_ios(void)  /*----------------------------------------------------------------------------+    | update_dma_a_b_ios().    +----------------------------------------------------------------------------*/ -void update_dma_a_b_ios(void) +void update_dma_a_b_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	gpio_tab[GPIO1][12].in_out = GPIO_OUT;	    /* DMA_ACK(1) */  	gpio_tab[GPIO1][12].alt_nb = GPIO_ALT2; @@ -1537,7 +1666,7 @@ void update_dma_a_b_ios(void)  /*----------------------------------------------------------------------------+    | update_dma_c_d_ios().    +----------------------------------------------------------------------------*/ -void update_dma_c_d_ios(void) +void update_dma_c_d_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	gpio_tab[GPIO0][0].in_out = GPIO_IN;	    /* DMA_REQ(2) */  	gpio_tab[GPIO0][0].alt_nb = GPIO_ALT2; @@ -1562,7 +1691,7 @@ void update_dma_c_d_ios(void)  /*----------------------------------------------------------------------------+    | update_ebc_master_ios().    +----------------------------------------------------------------------------*/ -void update_ebc_master_ios(void) +void update_ebc_master_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	gpio_tab[GPIO0][27].in_out = GPIO_IN;	    /* EXT_EBC_REQ */  	gpio_tab[GPIO0][27].alt_nb = GPIO_ALT1; @@ -1580,7 +1709,7 @@ void update_ebc_master_ios(void)  /*----------------------------------------------------------------------------+    | update_usb2_device_ios().    +----------------------------------------------------------------------------*/ -void update_usb2_device_ios(void) +void update_usb2_device_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	gpio_tab[GPIO0][26].in_out = GPIO_IN;	    /* USB2D_RXVALID */  	gpio_tab[GPIO0][26].alt_nb = GPIO_ALT2; @@ -1611,20 +1740,21 @@ void update_usb2_device_ios(void)  /*----------------------------------------------------------------------------+    | update_pci_patch_ios().    +----------------------------------------------------------------------------*/ -void update_pci_patch_ios(void) +void update_pci_patch_ios(gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	gpio_tab[GPIO0][29].in_out = GPIO_OUT;	    /* EBC_EXT_HDLA */  	gpio_tab[GPIO0][29].alt_nb = GPIO_ALT1;  }  /*----------------------------------------------------------------------------+ -  |   set_chip_gpio_configuration(unsigned char gpio_core) +  |   set_chip_gpio_configuration(unsigned char gpio_core, +  |                               gpio_param_s (*gpio_tab)[GPIO_MAX])    |   Put the core impacted by clock modification and sharing in reset.    |   Config the select registers to resolve the sharing depending of the config.    |   Configure the GPIO registers.    |    +----------------------------------------------------------------------------*/ -void set_chip_gpio_configuration(unsigned char gpio_core) +void set_chip_gpio_configuration(unsigned char gpio_core, gpio_param_s (*gpio_tab)[GPIO_MAX])  {  	unsigned char i=0, j=0, reg_offset = 0;  	unsigned long gpio_reg, gpio_core_add; @@ -1778,11 +1908,12 @@ void configure_ppc440ep_pins(void)  			CORE_NOT_SELECTED	/* PCI_PATCH */  		}; +	gpio_param_s gpio_tab[GPIO_GROUP_MAX][GPIO_MAX];  	/* Table Default Initialisation + FPGA Access */ -	init_default_gpio(); -	set_chip_gpio_configuration(GPIO0); -	set_chip_gpio_configuration(GPIO1); +	init_default_gpio(gpio_tab); +	set_chip_gpio_configuration(GPIO0, gpio_tab); +	set_chip_gpio_configuration(GPIO1, gpio_tab);  	/* Update Table */  	force_bup_core_selection(ppc440ep_core_selection, &config_val); @@ -1817,7 +1948,7 @@ void configure_ppc440ep_pins(void)  	/* UIC 0:3 Selection */  	if (ppc440ep_core_selection[UIC_0_3] == CORE_SELECTED)  	{ -		update_uic_0_3_irq_ios(); +		update_uic_0_3_irq_ios(gpio_tab);  		dma_a_b_unselect_in_fpga();  	} @@ -1825,21 +1956,21 @@ void configure_ppc440ep_pins(void)  	if (ppc440ep_core_selection[UIC_4_9] == CORE_SELECTED)  	{  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_DIS_MASK) | SDR0_PFC1_DIS_UICIRQ5_SEL; -		update_uic_4_9_irq_ios(); +		update_uic_4_9_irq_ios(gpio_tab);  	}  	/* DMA AB Selection */  	if (ppc440ep_core_selection[DMA_CHANNEL_AB] == CORE_SELECTED)  	{  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_DIS_MASK) | SDR0_PFC1_DIS_DMAR_SEL; -		update_dma_a_b_ios(); +		update_dma_a_b_ios(gpio_tab);  		dma_a_b_selection_in_fpga();  	}  	/* DMA CD Selection */  	if (ppc440ep_core_selection[DMA_CHANNEL_CD] == CORE_SELECTED)  	{ -		update_dma_c_d_ios(); +		update_dma_c_d_ios(gpio_tab);  		dma_c_d_selection_in_fpga();  	} @@ -1848,14 +1979,14 @@ void configure_ppc440ep_pins(void)  	{  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_ERE_MASK) | SDR0_PFC1_ERE_EXTR_SEL;  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_UES_MASK) | SDR0_PFC1_UES_EBCHR_SEL; -		update_ebc_master_ios(); +		update_ebc_master_ios(gpio_tab);  	}  	/* PCI Patch Enable */  	if (ppc440ep_core_selection[PCI_PATCH] == CORE_SELECTED)  	{  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_UES_MASK) | SDR0_PFC1_UES_EBCHR_SEL; -		update_pci_patch_ios(); +		update_pci_patch_ios(gpio_tab);  	}  	/* USB2 Host Selection - Not Implemented in PowerPC 440EP Pass1 */ @@ -1871,7 +2002,7 @@ void configure_ppc440ep_pins(void)  	/* USB2.0 Device Selection */  	if (ppc440ep_core_selection[USB2_DEVICE] == CORE_SELECTED)  	{ -		update_usb2_device_ios(); +		update_usb2_device_ios(gpio_tab);  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_UES_MASK) | SDR0_PFC1_UES_USB2D_SEL;  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_UPR_MASK) | SDR0_PFC1_UPR_DISABLE; @@ -1904,7 +2035,7 @@ void configure_ppc440ep_pins(void)  	/* NAND Flash Selection */  	if (ppc440ep_core_selection[NAND_FLASH] == CORE_SELECTED)  	{ -		update_ndfc_ios(); +		update_ndfc_ios(gpio_tab);  #if !(defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL))  		mtsdr(sdr_cust0, SDR0_CUST0_MUX_NDFC_SEL   | @@ -1933,7 +2064,7 @@ void configure_ppc440ep_pins(void)  	/* MII Selection */  	if (ppc440ep_core_selection[MII_SEL] == CORE_SELECTED)  	{ -		update_zii_ios(); +		update_zii_ios(gpio_tab);  		mfsdr(sdr_mfr, sdr0_mfr);  		sdr0_mfr = (sdr0_mfr & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_MII;  		mtsdr(sdr_mfr, sdr0_mfr); @@ -1944,7 +2075,7 @@ void configure_ppc440ep_pins(void)  	/* RMII Selection */  	if (ppc440ep_core_selection[RMII_SEL] == CORE_SELECTED)  	{ -		update_zii_ios(); +		update_zii_ios(gpio_tab);  		mfsdr(sdr_mfr, sdr0_mfr);  		sdr0_mfr = (sdr0_mfr & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_RMII_10M;  		mtsdr(sdr_mfr, sdr0_mfr); @@ -1955,7 +2086,7 @@ void configure_ppc440ep_pins(void)  	/* SMII Selection */  	if (ppc440ep_core_selection[SMII_SEL] == CORE_SELECTED)  	{ -		update_zii_ios(); +		update_zii_ios(gpio_tab);  		mfsdr(sdr_mfr, sdr0_mfr);  		sdr0_mfr = (sdr0_mfr & ~SDR0_MFR_ZMII_MODE_MASK) | SDR0_MFR_ZMII_MODE_SMII;  		mtsdr(sdr_mfr, sdr0_mfr); @@ -1992,7 +2123,7 @@ void configure_ppc440ep_pins(void)  		sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_U1ME_MASK) | SDR0_PFC1_U1ME_DSR_DTR;  		break;  	} -	update_uart_ios(uart_configuration); +	update_uart_ios(uart_configuration, gpio_tab);  	/* UART Selection in all cases */  	uart_selection_in_fpga(uart_configuration); @@ -2014,8 +2145,8 @@ void configure_ppc440ep_pins(void)  	/* Perform effective access to hardware */  	mtsdr(sdr_pfc1, sdr0_pfc1); -	set_chip_gpio_configuration(GPIO0); -	set_chip_gpio_configuration(GPIO1); +	set_chip_gpio_configuration(GPIO0, gpio_tab); +	set_chip_gpio_configuration(GPIO1, gpio_tab);  	/* USB2.0 Device Reset must be done after GPIO setting */  	if (ppc440ep_core_selection[USB2_DEVICE] == CORE_SELECTED) diff --git a/board/amcc/bamboo/init.S b/board/amcc/bamboo/init.S index 1459eec36..f4d2ae3f4 100644 --- a/board/amcc/bamboo/init.S +++ b/board/amcc/bamboo/init.S @@ -51,13 +51,12 @@ tlbtab:  	tlbentry(CFG_BOOT_BASE_ADDR, SZ_256M, CFG_BOOT_BASE_ADDR, 0, AC_R|AC_W|AC_X|SA_G)  #else  	tlbentry(CFG_NAND_BOOT_SPL_SRC, SZ_4K, CFG_NAND_BOOT_SPL_SRC, 0, AC_R|AC_W|AC_X|SA_G) +	tlbentry(CFG_SDRAM_BASE, SZ_256M, CFG_SDRAM_BASE, 0, AC_R|AC_W|AC_X|SA_G|SA_I)  #endif  	/* TLB-entry for init-ram in dcache (SA_I must be turned off!) */  	tlbentry(CFG_INIT_RAM_ADDR, SZ_4K, CFG_INIT_RAM_ADDR, 0, AC_R|AC_W|AC_X|SA_G) -	tlbentry(CFG_SDRAM_BASE, SZ_256M, CFG_SDRAM_BASE, 0, AC_R|AC_W|AC_X|SA_G|SA_I) -  	/* PCI base & peripherals */  	tlbentry(CFG_PCI_BASE, SZ_256M, CFG_PCI_BASE, 0, AC_R|AC_W|SA_G|SA_I) diff --git a/board/amcc/bamboo/u-boot.lds b/board/amcc/bamboo/u-boot.lds index f6d718319..0375618d7 100644 --- a/board/amcc/bamboo/u-boot.lds +++ b/board/amcc/bamboo/u-boot.lds @@ -141,8 +141,6 @@ SECTIONS     *(COMMON)    } -  ppcenv_assert = ASSERT(. < 0xFFFF8000, ".bss section too big, overlaps .ppcenv section. Please update your confguration: CFG_MONITOR_BASE, CFG_MONITOR_LEN and TEXT_BASE may need to be modified."); -    _end = . ;    PROVIDE (end = .);  } diff --git a/board/amcc/bubinga/bubinga.c b/board/amcc/bubinga/bubinga.c index fe6ce8a6d..66e7509da 100644 --- a/board/amcc/bubinga/bubinga.c +++ b/board/amcc/bubinga/bubinga.c @@ -20,10 +20,12 @@   * Foundation, Inc., 59 Temple Place, Suite 330, Boston,   * MA 02111-1307 USA   */ -long int spd_sdram(void);  #include <common.h>  #include <asm/processor.h> +#include <asm/io.h> + +long int spd_sdram(void);  int board_early_init_f(void)  { @@ -34,6 +36,15 @@ int board_early_init_f(void)  	mtdcr(uictr, 0x00000010);	/* set int trigger levels */  	mtdcr(uicsr, 0xFFFFFFFF);	/* clear all ints */ +	/* +	 * Configure CPC0_PCI to enable PerWE as output +	 * and enable the internal PCI arbiter if selected +	 */ +	if (in_8((void *)FPGA_REG1) & FPGA_REG1_PCI_INT_ARB) +		mtdcr(cpc0_pci, CPC0_PCI_HOST_CFG_EN | CPC0_PCI_ARBIT_EN); +	else +		mtdcr(cpc0_pci, CPC0_PCI_HOST_CFG_EN); +  	return 0;  } diff --git a/board/amcc/common/flash.c b/board/amcc/common/flash.c index e6429ecd1..eba0511f2 100644 --- a/board/amcc/common/flash.c +++ b/board/amcc/common/flash.c @@ -745,19 +745,27 @@ static ulong flash_get_size_2(vu_long * addr, flash_info_t * info)  		if (info->flash_id & FLASH_BTYPE) {  			/* set sector offsets for bottom boot block type */  			info->start[0] = base + 0x00000000; -			info->start[1] = base + 0x00004000; -			info->start[2] = base + 0x00006000; -			info->start[3] = base + 0x00008000; -			for (i = 4; i < info->sector_count; i++) { +			info->start[1] = base + 0x00002000; +			info->start[2] = base + 0x00004000; +			info->start[3] = base + 0x00006000; +			info->start[4] = base + 0x00008000; +			info->start[5] = base + 0x0000a000; +			info->start[6] = base + 0x0000c000; +			info->start[7] = base + 0x0000e000; +			for (i = 8; i < info->sector_count; i++) {  				info->start[i] = -				    base + (i * 0x00010000) - 0x00030000; +				    base + ((i-7) * 0x00010000);  			}  		} else {  			/* set sector offsets for top boot block type */  			i = info->sector_count - 1; +			info->start[i--] = base + info->size - 0x00002000;  			info->start[i--] = base + info->size - 0x00004000;  			info->start[i--] = base + info->size - 0x00006000;  			info->start[i--] = base + info->size - 0x00008000; +			info->start[i--] = base + info->size - 0x0000a000; +			info->start[i--] = base + info->size - 0x0000c000; +			info->start[i--] = base + info->size - 0x0000e000;  			for (; i >= 0; i--) {  				info->start[i] = base + i * 0x00010000;  			} diff --git a/board/amcc/luan/luan.c b/board/amcc/luan/luan.c index 2eff3b33f..7b16f8a39 100644 --- a/board/amcc/luan/luan.c +++ b/board/amcc/luan/luan.c @@ -104,6 +104,13 @@ int checkboard(void)  	return  0;  } +/* + * Override the default functions in cpu/ppc4xx/44x_spd_ddr2.c with + * board specific values. + */ +u32 ddr_clktr(u32 default_val) { +	return (SDRAM_CLKTR_CLKP_180_DEG_ADV); +}  /*************************************************************************   *  int testdram() diff --git a/board/amcc/taihu/Makefile b/board/amcc/taihu/Makefile new file mode 100644 index 000000000..9731c6e33 --- /dev/null +++ b/board/amcc/taihu/Makefile @@ -0,0 +1,49 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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 +# + +include $(TOPDIR)/config.mk + +LIB	= $(obj)lib$(BOARD).a + +COBJS	= $(BOARD).o flash.o lcd.o update.o + +SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS	:= $(addprefix $(obj),$(COBJS)) + +$(LIB):	$(OBJS) +	$(AR) $(ARFLAGS) $@ $(OBJS) + +clean: +	rm -f $(OBJS) + +distclean:	clean +	rm -f $(LIB) core *.bak .depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/amcc/taihu/config.mk b/board/amcc/taihu/config.mk new file mode 100644 index 000000000..1bdf5e4fc --- /dev/null +++ b/board/amcc/taihu/config.mk @@ -0,0 +1,24 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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 +# + +TEXT_BASE = 0xFFFC0000 diff --git a/board/amcc/taihu/flash.c b/board/amcc/taihu/flash.c new file mode 100644 index 000000000..290259e73 --- /dev/null +++ b/board/amcc/taihu/flash.c @@ -0,0 +1,1083 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips        */ + +#undef DEBUG +#ifdef DEBUG +#define DEBUGF(x...) printf(x) +#else +#define DEBUGF(x...) +#endif				/* DEBUG */ + +#define CFG_FLASH_CHAR_SIZE unsigned char +#define CFG_FLASH_CHAR_ADDR0 (0x0aaa) +#define CFG_FLASH_CHAR_ADDR1 (0x0555) +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size(vu_long * addr, flash_info_t * info); +static void flash_get_offsets(ulong base, flash_info_t * info); +static int write_word(flash_info_t * info, ulong dest, ulong data); +#ifdef FLASH_BASE1_PRELIM +static int write_word_1(flash_info_t * info, ulong dest, ulong data); +static int write_word_2(flash_info_t * info, ulong dest, ulong data); +static int flash_erase_1(flash_info_t * info, int s_first, int s_last); +static int flash_erase_2(flash_info_t * info, int s_first, int s_last); +static ulong flash_get_size_1(vu_long * addr, flash_info_t * info); +static ulong flash_get_size_2(vu_long * addr, flash_info_t * info); +#endif + +unsigned long flash_init(void) +{ +	unsigned long size_b0, size_b1=0; +	int i; + +	/* Init: no FLASHes known */ +	for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) { +		flash_info[i].flash_id = FLASH_UNKNOWN; +	} + +	/* Static FLASH Bank configuration here - FIXME XXX */ + +	size_b0 = +	    flash_get_size((vu_long *) FLASH_BASE0_PRELIM, &flash_info[0]); + +	if (flash_info[0].flash_id == FLASH_UNKNOWN) { +		printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", +		       size_b0, size_b0 << 20); +	} + +	if (size_b0) { +		/* Setup offsets */ +		flash_get_offsets(FLASH_BASE0_PRELIM, &flash_info[0]); +		/* Monitor protection ON by default */ +		(void)flash_protect(FLAG_PROTECT_SET, +				    CFG_MONITOR_BASE, +				    CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, +				    &flash_info[0]); +#ifdef CFG_ENV_IS_IN_FLASH +		(void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR, +				    CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1, +				    &flash_info[0]); +		(void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR_REDUND, +				    CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1, +				    &flash_info[0]); +#endif +		/* Also protect sector containing initial power-up instruction */ +		/* (flash_protect() checks address range - other call ignored) */ +		(void)flash_protect(FLAG_PROTECT_SET, +				    0xFFFFFFFC, 0xFFFFFFFF, &flash_info[0]); + +		flash_info[0].size = size_b0; +	} +#ifdef FLASH_BASE1_PRELIM +	size_b1 = +	    flash_get_size((vu_long *) FLASH_BASE1_PRELIM, &flash_info[1])*2; + +	if (flash_info[1].flash_id == FLASH_UNKNOWN) { +		printf("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n", +		       size_b1, size_b1 << 20); +	} + +	if (size_b1) { +		/* Setup offsets */ +		flash_get_offsets(FLASH_BASE1_PRELIM, &flash_info[1]); +		flash_info[1].size = size_b1; +	} +#endif +	return (size_b0 + size_b1); +} + +static void flash_get_offsets(ulong base, flash_info_t * info) +{ +	int i; + +	/* set up sector start address table */ +	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || +	    (info->flash_id == FLASH_AM040)) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00010000); +	} else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) { +		for (i = 0; i < info->sector_count; i++) { +			info->start[i] = base + (i * 0x00010000*2); +		} +	} else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N ) { +		for (i = 0; i < info->sector_count; i++) { +			info->start[i] = base + (i * 0x00020000*2); +		} +	} else { +		if (info->flash_id & FLASH_BTYPE) { +			/* set sector offsets for bottom boot block type        */ +			info->start[0] = base + 0x00000000; +			info->start[1] = base + 0x00004000; +			info->start[2] = base + 0x00006000; +			info->start[3] = base + 0x00008000; +			for (i = 4; i < info->sector_count; i++) { +				info->start[i] = +				    base + (i * 0x00010000) - 0x00030000; +			} +		} else { +			/* set sector offsets for top boot block type           */ +			i = info->sector_count - 1; +			info->start[i--] = base + info->size - 0x00004000; +			info->start[i--] = base + info->size - 0x00006000; +			info->start[i--] = base + info->size - 0x00008000; +			for (; i >= 0; i--) { +				info->start[i] = base + i * 0x00010000; +			} +		} +	} +} + + +void flash_print_info(flash_info_t * info) +{ +	int i; +	int k; +	int size; +	int erased; +	volatile unsigned long *flash; + +	if (info->flash_id == FLASH_UNKNOWN) { +		printf("missing or unknown FLASH type\n"); +		return; +	} + +	switch (info->flash_id & FLASH_VENDMASK) { +	case FLASH_MAN_AMD: +		printf("AMD "); +		break; +	case FLASH_MAN_STM: +		printf("STM "); +		break; +	case FLASH_MAN_FUJ: +		printf("FUJITSU "); +		break; +	case FLASH_MAN_SST: +		printf("SST "); +		break; +	default: +		printf("Unknown Vendor "); +		break; +	} + +	switch (info->flash_id & FLASH_TYPEMASK) { +	case FLASH_AM040: +		printf("AM29F040 (512 Kbit, uniform sector size)\n"); +		break; +	case FLASH_AM400B: +		printf("AM29LV400B (4 Mbit, bottom boot sect)\n"); +		break; +	case FLASH_AM400T: +		printf("AM29LV400T (4 Mbit, top boot sector)\n"); +		break; +	case FLASH_AM800B: +		printf("AM29LV800B (8 Mbit, bottom boot sect)\n"); +		break; +	case FLASH_AM800T: +		printf("AM29LV800T (8 Mbit, top boot sector)\n"); +		break; +	case FLASH_AMD016: +		printf("AM29F016D (16 Mbit, uniform sector size)\n"); +		break; +	case FLASH_AM160B: +		printf("AM29LV160B (16 Mbit, bottom boot sect)\n"); +		break; +	case FLASH_AM160T: +		printf("AM29LV160T (16 Mbit, top boot sector)\n"); +		break; +	case FLASH_AM320B: +		printf("AM29LV320B (32 Mbit, bottom boot sect)\n"); +		break; +	case FLASH_AM320T: +		printf("AM29LV320T (32 Mbit, top boot sector)\n"); +		break; +	case FLASH_AM033C: +		printf("AM29LV033C (32 Mbit, top boot sector)\n"); +		break; +	case FLASH_AMLV128U: +		printf("AM29LV128U (128 Mbit * 2, top boot sector)\n"); +		break; +	case FLASH_SST800A: +		printf("SST39LF/VF800 (8 Mbit, uniform sector size)\n"); +		break; +	case FLASH_SST160A: +		printf("SST39LF/VF160 (16 Mbit, uniform sector size)\n"); +		break; +	case FLASH_STMW320DT: +		printf ("M29W320DT (32 M, top sector)\n"); +		break; +	case FLASH_S29GL128N: +		printf ("S29GL128N (256 Mbit, uniform sector size)\n"); +		break; +	default: +		printf("Unknown Chip Type\n"); +		break; +	} + +	printf("  Size: %ld KB in %d Sectors\n", +	       info->size >> 10, info->sector_count); + +	printf("  Sector Start Addresses:"); +	for (i = 0; i < info->sector_count; ++i) { +		/* +		 * Check if whole sector is erased +		 */ +		if (i != (info->sector_count - 1)) +			size = info->start[i + 1] - info->start[i]; +		else +			size = info->start[0] + info->size - info->start[i]; +		erased = 1; +		flash = (volatile unsigned long *)info->start[i]; +		size = size >> 2;	/* divide by 4 for longword access */ +		for (k = 0; k < size; k++) { +			if (*flash++ != 0xffffffff) { +				erased = 0; +				break; +			} +		} + +		if ((i % 5) == 0) +			printf("\n   "); +		printf(" %08lX%s%s", +		       info->start[i], +		       erased ? " E" : "  ", info->protect[i] ? "RO " : "   "); +	} +	printf("\n"); +	return; +} + + +/* + * The following code cannot be run from FLASH! + */ +#ifdef FLASH_BASE1_PRELIM +static ulong flash_get_size(vu_long * addr, flash_info_t * info) +{ +	if ((ulong)addr == FLASH_BASE1_PRELIM) { +		return flash_get_size_2(addr, info); +	} else { +		return flash_get_size_1(addr, info); +	} +} + +static ulong flash_get_size_1(vu_long * addr, flash_info_t * info) +#else +static ulong flash_get_size(vu_long * addr, flash_info_t * info) +#endif +{ +	short i; +	CFG_FLASH_WORD_SIZE value; +	ulong base = (ulong) addr; +	volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr; + +	DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr); + +	/* Write auto select command: read Manufacturer ID */ +	addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA; +	addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055; +	addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00900090; +	udelay(1000); + +	value = addr2[0]; +	DEBUGF("FLASH MANUFACT: %x\n", value); + +	switch (value) { +	case (CFG_FLASH_WORD_SIZE) AMD_MANUFACT: +		info->flash_id = FLASH_MAN_AMD; +		break; +	case (CFG_FLASH_WORD_SIZE) FUJ_MANUFACT: +		info->flash_id = FLASH_MAN_FUJ; +		break; +	case (CFG_FLASH_WORD_SIZE) SST_MANUFACT: +		info->flash_id = FLASH_MAN_SST; +		break; +	case (CFG_FLASH_WORD_SIZE) STM_MANUFACT: +		info->flash_id = FLASH_MAN_STM; +		break; +	default: +		info->flash_id = FLASH_UNKNOWN; +		info->sector_count = 0; +		info->size = 0; +		return 0;	/* no or unknown flash  */ +	} + +	value = addr2[1];	/* device ID            */ +	DEBUGF("\nFLASH DEVICEID: %x\n", value); + +	switch (value) { +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_F040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; + +	case (CFG_FLASH_WORD_SIZE) STM_ID_M29W040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_F016D: +		info->flash_id += FLASH_AMD016; +		info->sector_count = 32; +		info->size = 0x00200000; +		break;		/* => 2 MB              */ + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV033C: +		info->flash_id += FLASH_AMDLV033C; +		info->sector_count = 64; +		info->size = 0x00400000; +		break;		/* => 4 MB              */ + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV400T: +		info->flash_id += FLASH_AM400T; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;		/* => 0.5 MB            */ + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV400B: +		info->flash_id += FLASH_AM400B; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;		/* => 0.5 MB            */ + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV800T: +		info->flash_id += FLASH_AM800T; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;		/* => 1 MB              */ + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV800B: +		info->flash_id += FLASH_AM800B; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;		/* => 1 MB              */ + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV160T: +		info->flash_id += FLASH_AM160T; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;		/* => 2 MB              */ + +	case (CFG_FLASH_WORD_SIZE) AMD_ID_LV160B: +		info->flash_id += FLASH_AM160B; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;		/* => 2 MB              */ +	default: +		info->flash_id = FLASH_UNKNOWN; +		return 0;	/* => no or unknown flash */ +	} + +	/* set up sector start address table */ +	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00010000); +	} +	else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00010000 * 2); +	} else { +		if (info->flash_id & FLASH_BTYPE) { +			/* set sector offsets for bottom boot block type        */ +			info->start[0] = base + 0x00000000; +			info->start[1] = base + 0x00004000; +			info->start[2] = base + 0x00006000; +			info->start[3] = base + 0x00008000; +			for (i = 4; i < info->sector_count; i++) { +				info->start[i] = +				    base + (i * 0x00010000) - 0x00030000; +			} +		} else { +			/* set sector offsets for top boot block type           */ +			i = info->sector_count - 1; +			info->start[i--] = base + info->size - 0x00004000; +			info->start[i--] = base + info->size - 0x00006000; +			info->start[i--] = base + info->size - 0x00008000; +			for (; i >= 0; i--) { +				info->start[i] = base + i * 0x00010000; +			} +		} +	} + +	/* check for protected sectors */ +	for (i = 0; i < info->sector_count; i++) { +		/* read sector protection at sector address, (A7 .. A0) = 0x02 */ +		/* D0 = 1 if protected */ +		addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]); + +		/* For AMD29033C flash we need to resend the command of * +		 * reading flash protection for upper 8 Mb of flash     */ +		if (i == 32) { +			addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +			addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +			addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090; +		} + +		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) +			info->protect[i] = 0; +		else +			info->protect[i] = addr2[2] & 1; +	} + +	/* issue bank reset to return to read mode */ +	addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0; + +	return info->size; +} + +static int wait_for_DQ7_1(flash_info_t * info, int sect) +{ +	ulong start, now, last; +	volatile CFG_FLASH_WORD_SIZE *addr = +	    (CFG_FLASH_WORD_SIZE *) (info->start[sect]); + +	start = get_timer(0); +	last = start; +	while ((addr[0] & (CFG_FLASH_WORD_SIZE) 0x00800080) != +	       (CFG_FLASH_WORD_SIZE) 0x00800080) { +		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { +			printf("Timeout\n"); +			return -1; +		} +		/* show that we're waiting */ +		if ((now - last) > 1000) {	/* every second */ +			putc('.'); +			last = now; +		} +	} +	return 0; +} + +#ifdef FLASH_BASE1_PRELIM +int flash_erase(flash_info_t * info, int s_first, int s_last) +{ +	if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT)) { +		return flash_erase_2(info, s_first, s_last); +	} else { +		return flash_erase_1(info, s_first, s_last); +	} +} + +static int flash_erase_1(flash_info_t * info, int s_first, int s_last) +#else +int flash_erase(flash_info_t * info, int s_first, int s_last) +#endif +{ +	volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]); +	volatile CFG_FLASH_WORD_SIZE *addr2; +	int flag, prot, sect, l_sect; +	int i; + +	if ((s_first < 0) || (s_first > s_last)) { +		if (info->flash_id == FLASH_UNKNOWN) { +			printf("- missing\n"); +		} else { +			printf("- no sectors to erase\n"); +		} +		return 1; +	} + +	if (info->flash_id == FLASH_UNKNOWN) { +		printf("Can't erase unknown flash type - aborted\n"); +		return 1; +	} + +	prot = 0; +	for (sect = s_first; sect <= s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		} +	} + +	if (prot) { +		printf("- Warning: %d protected sectors will not be erased!\n", +		       prot); +	} else { +		printf("\n"); +	} + +	l_sect = -1; + +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts(); + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect <= s_last; sect++) { +		if (info->protect[sect] == 0) {	/* not protected */ +			addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]); + +			if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) { +				addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA; +				addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055; +				addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080; +				addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA; +				addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055; +				addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00500050;	/* block erase */ +				for (i = 0; i < 50; i++) +					udelay(1000);	/* wait 1 ms */ +			} else { +				addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA; +				addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055; +				addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00800080; +				addr[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA; +				addr[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055; +				addr2[0] = (CFG_FLASH_WORD_SIZE) 0x00300030;	/* sector erase */ +			} +			l_sect = sect; +			/* +			 * Wait for each sector to complete, it's more +			 * reliable.  According to AMD Spec, you must +			 * issue all erase commands within a specified +			 * timeout.  This has been seen to fail, especially +			 * if printf()s are included (for debug)!! +			 */ +			wait_for_DQ7_1(info, sect); +		} +	} + +	/* re-enable interrupts if necessary */ +	if (flag) +		enable_interrupts(); + +	/* wait at least 80us - let's wait 1 ms */ +	udelay(1000); + +	/* reset to read mode */ +	addr = (CFG_FLASH_WORD_SIZE *) info->start[0]; +	addr[0] = (CFG_FLASH_WORD_SIZE) 0x00F000F0;	/* reset bank */ + +	printf(" done\n"); +	return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ +	ulong cp, wp, data; +	int i, l, rc; + +	wp = (addr & ~3);	/* get lower word aligned address */ + +	/* +	 * handle unaligned start bytes +	 */ +	if ((l = addr - wp) != 0) { +		data = 0; +		for (i = 0, cp = wp; i < l; ++i, ++cp) { +			data = (data << 8) | (*(uchar *) cp); +		} +		for (; i < 4 && cnt > 0; ++i) { +			data = (data << 8) | *src++; +			--cnt; +			++cp; +		} +		for (; cnt == 0 && i < 4; ++i, ++cp) { +			data = (data << 8) | (*(uchar *) cp); +		} + +		if ((rc = write_word(info, wp, data)) != 0) { +			return rc; +		} +		wp += 4; +	} + +	/* +	 * handle word aligned part +	 */ +	while (cnt >= 4) { +		data = 0; +		for (i = 0; i < 4; ++i) { +			data = (data << 8) | *src++; +		} +		if ((rc = write_word(info, wp, data)) != 0) { +			return rc; +		} +		wp += 4; +		cnt -= 4; +	} + +	if (cnt == 0) { +		return 0; +	} + +	/* +	 * handle unaligned tail bytes +	 */ +	data = 0; +	for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) { +		data = (data << 8) | *src++; +		--cnt; +	} +	for (; i < 4; ++i, ++cp) { +		data = (data << 8) | (*(uchar *) cp); +	} + +	return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +#ifdef FLASH_BASE1_PRELIM +static int write_word(flash_info_t * info, ulong dest, ulong data) +{ +	if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_STMW320DT)) { +		return write_word_2(info, dest, data); +	} else { +		return write_word_1(info, dest, data); +	} +} + +static int write_word_1(flash_info_t * info, ulong dest, ulong data) +#else +static int write_word(flash_info_t * info, ulong dest, ulong data) +#endif +{ +	volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]); +	volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest; +	volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data; +	ulong start; +	int i; + +	/* Check if Flash is (sufficiently) erased */ +	if ((*((vu_long *)dest) & data) != data) { +		return 2; +	} + +	for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) { +		int flag; + +		/* Disable interrupts which might cause a timeout here */ +		flag = disable_interrupts(); + +		addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00AA00AA; +		addr2[CFG_FLASH_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x00550055; +		addr2[CFG_FLASH_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x00A000A0; + +		dest2[i] = data2[i]; + +		/* re-enable interrupts if necessary */ +		if (flag) +			enable_interrupts(); + +		/* data polling for D7 */ +		start = get_timer(0); +		while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080) != +		       (data2[i] & (CFG_FLASH_WORD_SIZE) 0x00800080)) { + +			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { +				return 1; +			} +		} +	} + +	return 0; +} + +#ifdef FLASH_BASE1_PRELIM + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size_2(vu_long * addr, flash_info_t * info) +{ +	short i; +	CFG_FLASH_CHAR_SIZE value; +	ulong base = (ulong) addr; +	volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) addr; + +	DEBUGF("FLASH ADDR: %08x\n", (unsigned)addr); + +	/* Write auto select command: read Manufacturer ID */ +	addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +	addr2[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +	addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090; +	udelay(1000); + +	value = (CFG_FLASH_CHAR_SIZE)addr2[0]; +	DEBUGF("FLASH MANUFACT: %x\n", value); + +	switch (value) { +	case (CFG_FLASH_CHAR_SIZE) AMD_MANUFACT: +		info->flash_id = FLASH_MAN_AMD; +		break; +	case (CFG_FLASH_CHAR_SIZE) FUJ_MANUFACT: +		info->flash_id = FLASH_MAN_FUJ; +		break; +	case (CFG_FLASH_CHAR_SIZE) SST_MANUFACT: +		info->flash_id = FLASH_MAN_SST; +		break; +	case (CFG_FLASH_CHAR_SIZE) STM_MANUFACT: +		info->flash_id = FLASH_MAN_STM; +		break; +	default: +		info->flash_id = FLASH_UNKNOWN; +		info->sector_count = 0; +		info->size = 0; +		return 0;		/* no or unknown flash */ +	} + +	value = (CFG_FLASH_CHAR_SIZE)addr2[2];	/* device ID */ +	DEBUGF("\nFLASH DEVICEID: %x\n", value); + +	switch (value) { +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_F040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; + +	case (CFG_FLASH_CHAR_SIZE) STM_ID_M29W040B: +		info->flash_id += FLASH_AM040; +		info->sector_count = 8; +		info->size = 0x0080000;	/* => 512 ko */ +		break; + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_F016D: +		info->flash_id += FLASH_AMD016; +		info->sector_count = 32; +		info->size = 0x00200000; +		break;			/* => 2 MB */ + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV033C: +		info->flash_id += FLASH_AMDLV033C; +		info->sector_count = 64; +		info->size = 0x00400000; +		break;			/* => 4 MB */ + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV400T: +		info->flash_id += FLASH_AM400T; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;			/* => 0.5 MB */ + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV400B: +		info->flash_id += FLASH_AM400B; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;			/* => 0.5 MB */ + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV800T: +		info->flash_id += FLASH_AM800T; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;			/* => 1 MB */ + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV800B: +		info->flash_id += FLASH_AM800B; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;			/* => 1 MB */ + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV160T: +		info->flash_id += FLASH_AM160T; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;			/* => 2 MB */ + +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_LV160B: +		info->flash_id += FLASH_AM160B; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;			/* => 2 MB */ +	case (CFG_FLASH_CHAR_SIZE) AMD_ID_MIRROR: +		if ((CFG_FLASH_CHAR_SIZE)addr2[0x1c] == (CFG_FLASH_CHAR_SIZE)AMD_ID_LV128U_2 +				&& (CFG_FLASH_CHAR_SIZE)addr2[0x1e] ==  (CFG_FLASH_CHAR_SIZE)AMD_ID_LV128U_3) { +			info->flash_id += FLASH_AMLV128U; +			info->sector_count = 256; +			info->size = 0x01000000; +		} else if ((CFG_FLASH_CHAR_SIZE)addr2[0x1c] == (CFG_FLASH_CHAR_SIZE)AMD_ID_GL128N_2 +				&& (CFG_FLASH_CHAR_SIZE)addr2[0x1e] ==  (CFG_FLASH_CHAR_SIZE)AMD_ID_GL128N_3 ) { +			info->flash_id += FLASH_S29GL128N; +			info->sector_count = 128; +			info->size = 0x01000000; +		} +		else +			info->flash_id = FLASH_UNKNOWN; +		break;			/* => 2 MB */ + +	default: +		info->flash_id = FLASH_UNKNOWN; +		return 0;		/* => no or unknown flash */ +	} + +	/* set up sector start address table */ +	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMD016)) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00010000); +	} else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMLV128U) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00010000); +	} else if ((info->flash_id & FLASH_TYPEMASK) == FLASH_S29GL128N ) { +		for (i = 0; i < info->sector_count; i++) +			info->start[i] = base + (i * 0x00020000); +	} else { +		if (info->flash_id & FLASH_BTYPE) { +			/* set sector offsets for bottom boot block type */ +			info->start[0] = base + 0x00000000; +			info->start[1] = base + 0x00004000; +			info->start[2] = base + 0x00006000; +			info->start[3] = base + 0x00008000; +			for (i = 4; i < info->sector_count; i++) { +				info->start[i] = +				    base + (i * 0x00010000) - 0x00030000; +			} +		} else { +			/* set sector offsets for top boot block type */ +			i = info->sector_count - 1; +			info->start[i--] = base + info->size - 0x00004000; +			info->start[i--] = base + info->size - 0x00006000; +			info->start[i--] = base + info->size - 0x00008000; +			for (; i >= 0; i--) { +				info->start[i] = base + i * 0x00010000; +			} +		} +	} + +	/* check for protected sectors */ +	for (i = 0; i < info->sector_count; i++) { +		/* read sector protection at sector address, (A7 .. A0) = 0x02 */ +		/* D0 = 1 if protected */ +		addr2 = (volatile CFG_FLASH_WORD_SIZE *)(info->start[i]); + +		/* For AMD29033C flash we need to resend the command of * +		 * reading flash protection for upper 8 Mb of flash     */ +		if (i == 32) { +			addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +			addr2[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +			addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x90909090; +		} + +		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) +			info->protect[i] = 0; +		else +			info->protect[i] = (CFG_FLASH_CHAR_SIZE)addr2[4] & 1; +	} + +	/* issue bank reset to return to read mode */ +	addr2[0] = (CFG_FLASH_WORD_SIZE) 0xF0F0F0F0; +	return info->size; +} + +static int wait_for_DQ7_2(flash_info_t * info, int sect) +{ +	ulong start, now, last; +	volatile CFG_FLASH_WORD_SIZE *addr = +	    (CFG_FLASH_WORD_SIZE *) (info->start[sect]); + +	start = get_timer(0); +	last = start; +	while (((CFG_FLASH_WORD_SIZE)addr[0] & (CFG_FLASH_WORD_SIZE) 0x80808080) != +	       (CFG_FLASH_WORD_SIZE) 0x80808080) { +		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { +			printf("Timeout\n"); +			return -1; +		} +		/* show that we're waiting */ +		if ((now - last) > 1000) { /* every second */ +			putc('.'); +			last = now; +		} +	} +	return 0; +} + +static int flash_erase_2(flash_info_t * info, int s_first, int s_last) +{ +	volatile CFG_FLASH_WORD_SIZE *addr = (CFG_FLASH_WORD_SIZE *) (info->start[0]); +	volatile CFG_FLASH_WORD_SIZE *addr2; +	int flag, prot, sect, l_sect; +	int i; + +	if ((s_first < 0) || (s_first > s_last)) { +		if (info->flash_id == FLASH_UNKNOWN) { +			printf("- missing\n"); +		} else { +			printf("- no sectors to erase\n"); +		} +		return 1; +	} + +	if (info->flash_id == FLASH_UNKNOWN) { +		printf("Can't erase unknown flash type - aborted\n"); +		return 1; +	} + +	prot = 0; +	for (sect = s_first; sect <= s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		} +	} + +	if (prot) { +		printf("- Warning: %d protected sectors will not be erased!\n", +		       prot); +	} else { +		printf("\n"); +	} + +	l_sect = -1; + +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts(); + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect <= s_last; sect++) { +		if (info->protect[sect] == 0) {	/* not protected */ +			addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[sect]); + +			if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) { +				addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +				addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +				addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x80808080; +				addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +				addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +				addr2[0] = (CFG_FLASH_WORD_SIZE) 0x50505050;	/* block erase */ +				for (i = 0; i < 50; i++) +					udelay(1000);	/* wait 1 ms */ +			} else { +				addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +				addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +				addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0x80808080; +				addr[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +				addr[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +				addr2[0] = (CFG_FLASH_WORD_SIZE) 0x30303030;	/* sector erase */ +			} +			l_sect = sect; +			/* +			 * Wait for each sector to complete, it's more +			 * reliable.  According to AMD Spec, you must +			 * issue all erase commands within a specified +			 * timeout.  This has been seen to fail, especially +			 * if printf()s are included (for debug)!! +			 */ +			wait_for_DQ7_2(info, sect); +		} +	} + +	/* re-enable interrupts if necessary */ +	if (flag) +		enable_interrupts(); + +	/* wait at least 80us - let's wait 1 ms */ +	udelay(1000); + +	/* reset to read mode */ +	addr = (CFG_FLASH_WORD_SIZE *) info->start[0]; +	addr[0] = (CFG_FLASH_WORD_SIZE) 0xF0F0F0F0; /* reset bank */ + +	printf(" done\n"); +	return 0; +} + +static int write_word_2(flash_info_t * info, ulong dest, ulong data) +{ +	volatile CFG_FLASH_WORD_SIZE *addr2 = (CFG_FLASH_WORD_SIZE *) (info->start[0]); +	volatile CFG_FLASH_WORD_SIZE *dest2 = (CFG_FLASH_WORD_SIZE *) dest; +	volatile CFG_FLASH_WORD_SIZE *data2 = (CFG_FLASH_WORD_SIZE *) & data; +	ulong start; +	int i; + +	/* Check if Flash is (sufficiently) erased */ +	if ((*((vu_long *)dest) & data) != data) { +		return 2; +	} + +	for (i = 0; i < 4 / sizeof(CFG_FLASH_WORD_SIZE); i++) { +		int flag; + +		/* Disable interrupts which might cause a timeout here */ +		flag = disable_interrupts(); + +		addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xAAAAAAAA; +		addr2[CFG_FLASH_CHAR_ADDR1] = (CFG_FLASH_WORD_SIZE) 0x55555555; +		addr2[CFG_FLASH_CHAR_ADDR0] = (CFG_FLASH_WORD_SIZE) 0xA0A0A0A0; + +		dest2[i] = data2[i]; + +		/* re-enable interrupts if necessary */ +		if (flag) +			enable_interrupts(); + +		/* data polling for D7 */ +		start = get_timer(0); +		while ((dest2[i] & (CFG_FLASH_WORD_SIZE) 0x80808080) != +		       (data2[i] & (CFG_FLASH_WORD_SIZE) 0x80808080)) { + +			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { +				return 1; +			} +		} +	} + +	return 0; +} + +#endif /* FLASH_BASE1_PRELIM */ diff --git a/board/amcc/taihu/lcd.c b/board/amcc/taihu/lcd.c new file mode 100644 index 000000000..3d042dfa7 --- /dev/null +++ b/board/amcc/taihu/lcd.c @@ -0,0 +1,257 @@ +/* + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ + +#include <config.h> +#include <common.h> +#include <command.h> +#include <asm/io.h> +#include <asm/gpio.h> + +#define LCD_CMD_ADDR	0x50100002 +#define LCD_DATA_ADDR	0x50100003 +#define LCD_BLK_CTRL	CPLD_REG1_ADDR + +static char *amcc_logo = "AMCC 405EP TAIHU EVALUATION KIT"; +static int addr_flag = 0x80; + +static void lcd_bl_ctrl(char val) +{ +	out_8((u8 *) LCD_BLK_CTRL, in_8((u8 *) LCD_BLK_CTRL) | val); +} + +static void lcd_putc(int val) +{ +	int i = 100; +	char addr; + +	while (i--) { +		if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/ +			udelay(50); +			break; +		} +		udelay(50); +	} + +	if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) { +		printf("LCD is busy\n"); +		return; +	} + +	addr = in_8((u8 *) LCD_CMD_ADDR); +	udelay(50); +	if ((addr != 0) && (addr % 0x10 == 0)) { +		addr_flag ^= 0x40; +		out_8((u8 *) LCD_CMD_ADDR, addr_flag); +	} + +	udelay(50); +	out_8((u8 *) LCD_DATA_ADDR, val); +	udelay(50); +} + +static void lcd_puts(char *s) +{ +	char *p = s; +	int i = 100; + +	while (i--) { +		if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/ +			udelay(50); +			break; +		} +		udelay(50); +	} + +	if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) { +		printf("LCD is busy\n"); +		return; +	} + +	while (*p) +		lcd_putc(*p++); +} + +static void lcd_put_logo(void) +{ +	int i = 100; +	char *p = amcc_logo; + +	while (i--) { +		if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/ +			udelay(50); +			break; +		} +		udelay(50); +	} + +	if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) { +		printf("LCD is busy\n"); +		return; +	} + +	out_8((u8 *) LCD_CMD_ADDR, 0x80); +	while (*p) +		lcd_putc(*p++); +} + +int lcd_init(void) +{ +	puts("LCD: "); +	out_8((u8 *) LCD_CMD_ADDR, 0x38); /* set function:8-bit,2-line,5x7 font type */ +	udelay(50); +	out_8((u8 *) LCD_CMD_ADDR, 0x0f); /* set display on,cursor on,blink on */ +	udelay(50); +	out_8((u8 *) LCD_CMD_ADDR, 0x01); /* display clear */ +	udelay(2000); +	out_8((u8 *) LCD_CMD_ADDR, 0x06); /* set entry */ +	udelay(50); +	lcd_bl_ctrl(0x02);		/* set backlight on */ +	lcd_put_logo(); +	puts("ready\n"); + +	return 0; +} + +static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	out_8((u8 *) LCD_CMD_ADDR, 0x01); +	udelay(2000); + +	return 0; +} + +static int do_lcd_puts (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	if (argc < 2) { +		printf("%s", cmdtp->usage); +		return 1; +	} +	lcd_puts(argv[1]); + +	return 0; +} + +static int do_lcd_putc (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	if (argc < 2) { +		printf("%s", cmdtp->usage); +		return 1; +	} +	lcd_putc((char)argv[1][0]); + +	return 0; +} + +static int do_lcd_cur (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	ulong count; +	ulong dir; +	char cur_addr; + +	if (argc < 3) { +		printf("%s", cmdtp->usage); +		return 1; +	} + +	count = simple_strtoul(argv[1], NULL, 16); +	if (count > 31) { +		printf("unable to shift > 0x20\n"); +		count = 0; +	} + +	dir = simple_strtoul(argv[2], NULL, 16); +	cur_addr = in_8((u8 *) LCD_CMD_ADDR); +	udelay(50); + +	if (dir == 0x0) { +		if (addr_flag == 0x80) { +			if (count >= (cur_addr & 0xf)) { +				out_8((u8 *) LCD_CMD_ADDR, 0x80); +				udelay(50); +				count = 0; +			} +		} else { +			if (count >= ((cur_addr & 0x0f) + 0x0f)) { +				out_8((u8 *) LCD_CMD_ADDR, 0x80); +				addr_flag = 0x80; +				udelay(50); +				count = 0x0; +			} else if (count >= ( cur_addr & 0xf)) { +				count -= cur_addr & 0xf ; +				out_8((u8 *) LCD_CMD_ADDR, 0x80 | 0xf); +				addr_flag = 0x80; +				udelay(50); +			} +		} +	} else { +		if (addr_flag == 0x80) { +			if (count >= (0x1f - (cur_addr & 0xf))) { +				count = 0x0; +				addr_flag = 0xc0; +				out_8((u8 *) LCD_CMD_ADDR, 0xc0 | 0xf); +				udelay(50); +			} else if ((count + (cur_addr & 0xf ))>=  0x0f) { +				count = count + (cur_addr & 0xf) - 0x0f; +				addr_flag = 0xc0; +				out_8((u8 *) LCD_CMD_ADDR, 0xc0); +				udelay(50); +			} +		} else if ((count + (cur_addr & 0xf )) >= 0x0f) { +			count = 0x0; +			out_8((u8 *) LCD_CMD_ADDR, 0xC0 | 0x0F); +			udelay(50); +		} +	} +	while (count--) { +		if (dir == 0) +			out_8((u8 *) LCD_CMD_ADDR, 0x10); +		else +			out_8((u8 *) LCD_CMD_ADDR, 0x14); +		udelay(50); +	} + +	return 0; +} + +U_BOOT_CMD( +	lcd_cls, 1, 1, do_lcd_clear, +	"lcd_cls - lcd clear display\n", +	NULL +	); + +U_BOOT_CMD( +	lcd_puts, 2, 1, do_lcd_puts, +	"lcd_puts - display string on lcd\n", +	"<string> - <string> to be displayed\n" +	); + +U_BOOT_CMD( +	lcd_putc, 2, 1, do_lcd_putc, +	"lcd_putc - display char on lcd\n", +	"<char> - <char> to be displayed\n" +	); + +U_BOOT_CMD( +	lcd_cur, 3, 1, do_lcd_cur, +	"lcd_cur - shift cursor on lcd\n", +	"<count> <dir> - shift cursor on lcd <count> times, direction is <dir> \n" +	" <count> - 0..31\n" +	" <dir>   - 0=backward 1=forward\n" +	); diff --git a/board/amcc/taihu/taihu.c b/board/amcc/taihu/taihu.c new file mode 100644 index 000000000..ea8367198 --- /dev/null +++ b/board/amcc/taihu/taihu.c @@ -0,0 +1,240 @@ +/* + * (C) Copyright 2000-2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2005-2007 + * Beijing UD Technology Co., Ltd., taihusupport@amcc.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ +#include <common.h> +#include <command.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <spi.h> +#include <asm/gpio.h> + +extern int lcd_init(void); + +/* + * board_early_init_f + */ +int board_early_init_f(void) +{ +	lcd_init(); + +	mtdcr(uicsr, 0xFFFFFFFF);	/* clear all ints */ +	mtdcr(uicer, 0x00000000);	/* disable all ints */ +	mtdcr(uiccr, 0x00000000); +	mtdcr(uicpr, 0xFFFF7F00);	/* set int polarities */ +	mtdcr(uictr, 0x00000000);	/* set int trigger levels */ +	mtdcr(uicsr, 0xFFFFFFFF);	/* clear all ints */ +	mtdcr(uicvcr, 0x00000001);	/* set vect base=0,INT0 highest priority */ + +	mtebc(pb3ap, CFG_EBC_PB3AP);	/* memory bank 3 (CPLD_LCM) initialization */ +	mtebc(pb3cr, CFG_EBC_PB3CR); + +	/* +	 * Configure CPC0_PCI to enable PerWE as output +	 * and enable the internal PCI arbiter +	 */ +	mtdcr(cpc0_pci, CPC0_PCI_SPE | CPC0_PCI_HOST_CFG_EN | CPC0_PCI_ARBIT_EN); + +	return 0; +} + +/* + * Check Board Identity: + */ +int checkboard(void) +{ +	char *s = getenv("serial#"); + +	puts("Board: Taihu - AMCC PPC405EP Evaluation Board"); + +	if (s != NULL) { +		puts(", serial# "); +		puts(s); +	} +	putc('\n'); + +	return 0; +} + +/************************************************************************* + *  long int initdram + * + ************************************************************************/ +long int initdram(int board) +{ +	return CFG_SDRAM_SIZE_PER_BANK * CFG_SDRAM_BANKS; /* 128Mbytes */ +} + +static int do_sw_stat(cmd_tbl_t* cmd_tp, int flags, int argc, char *argv[]) +{ +	char stat; +	int i; + +	stat = in_8((u8 *) CPLD_REG0_ADDR); +	printf("SW2 status: "); +	for (i=0; i<4; i++) /* 4-position */ +		printf("%d:%s ", i, stat & (0x08 >> i)?"on":"off"); +	printf("\n"); +	return 0; +} + +U_BOOT_CMD ( +	sw2_stat, 1, 1, do_sw_stat, +	"sw2_stat - show status of switch 2\n", +	NULL +	); + +static int do_led_ctl(cmd_tbl_t* cmd_tp, int flags, int argc, char *argv[]) +{ +	int led_no; + +	if (argc != 3) { +		printf("%s", cmd_tp->usage); +		return -1; +	} + +	led_no = simple_strtoul(argv[1], NULL, 16); +	if (led_no != 1 && led_no != 2) { +		printf("%s", cmd_tp->usage); +		return -1; +	} + +	if (strcmp(argv[2],"off") == 0x0) { +		if (led_no == 1) +			gpio_write_bit(30, 1); +		else +			gpio_write_bit(31, 1); +	} else if (strcmp(argv[2],"on") == 0x0) { +		if (led_no == 1) +			gpio_write_bit(30, 0); +		else +			gpio_write_bit(31, 0); +	} else { +		printf("%s", cmd_tp->usage); +		return -1; +	} + +	return 0; +} + +U_BOOT_CMD ( +	led_ctl, 3, 1, do_led_ctl, +	"led_ctl	- make led 1 or 2  on or off\n", +	"<led_no> <on/off>	-  make led <led_no> on/off,\n" +	"\tled_no is 1 or 2\t" +	); + +#define SPI_CS_GPIO0	0 +#define SPI_SCLK_GPIO14	14 +#define SPI_DIN_GPIO15	15 +#define SPI_DOUT_GPIO16	16 + +void spi_scl(int bit) +{ +	gpio_write_bit(SPI_SCLK_GPIO14, bit); +} + +void spi_sda(int bit) +{ +	gpio_write_bit(SPI_DOUT_GPIO16, bit); +} + +unsigned char spi_read(void) +{ +	return (unsigned char)gpio_read_out_bit(SPI_DIN_GPIO15); +} + +void taihu_spi_chipsel(int cs) +{ +	gpio_write_bit(SPI_CS_GPIO0, cs); +} + +spi_chipsel_type spi_chipsel[]= { +	taihu_spi_chipsel +}; + +int spi_chipsel_cnt = sizeof(spi_chipsel) / sizeof(spi_chipsel[0]); + +#ifdef CONFIG_PCI +static unsigned char int_lines[32] = { +	29, 30, 27, 28, 29, 30, 25, 27, +	29, 30, 27, 28, 29, 30, 27, 28, +	29, 30, 27, 28, 29, 30, 27, 28, +	29, 30, 27, 28, 29, 30, 27, 28}; + +static void taihu_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev) +{ +	unsigned char int_line = int_lines[PCI_DEV(dev) & 31]; + +	pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, int_line); +} + +int pci_pre_init(struct pci_controller *hose) +{ +	hose->fixup_irq = taihu_pci_fixup_irq; +	return 1; +} +#endif /* CONFIG_PCI */ + +#ifdef CFG_DRAM_TEST +int testdram(void) +{ +	unsigned long *mem = (unsigned long *)0; +	const unsigned long kend = (1024 / sizeof(unsigned long)); +	unsigned long k, n; +	unsigned long msr; +	unsigned long total_kbytes = CFG_SDRAM_SIZE_PER_BANK * CFG_SDRAM_BANKS / 1024; + +	msr = mfmsr(); +	mtmsr(msr & ~(MSR_EE)); + +	for (k = 0; k < total_kbytes ; +	     ++k, mem += (1024 / sizeof(unsigned long))) { +		if ((k & 1023) == 0) +			printf("%3d MB\r", k / 1024); + +		memset(mem, 0xaaaaaaaa, 1024); +		for (n = 0; n < kend; ++n) { +			if (mem[n] != 0xaaaaaaaa) { +				printf("SDRAM test fails at: %08x\n", +				       (uint) & mem[n]); +				return 1; +			} +		} + +		memset(mem, 0x55555555, 1024); +		for (n = 0; n < kend; ++n) { +			if (mem[n] != 0x55555555) { +				printf("SDRAM test fails at: %08x\n", +				       (uint) & mem[n]); +				return 1; +			} +		} +	} +	printf("SDRAM test passes\n"); +	mtmsr(msr); + +	return 0; +} +#endif /* CFG_DRAM_TEST */ diff --git a/board/amcc/taihu/u-boot.lds b/board/amcc/taihu/u-boot.lds new file mode 100644 index 000000000..be030923b --- /dev/null +++ b/board/amcc/taihu/u-boot.lds @@ -0,0 +1,150 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? +   __DYNAMIC = 0;    */ +SECTIONS +{ +  .resetvec 0xFFFFFFFC : +  { +    *(.resetvec) +  } = 0xffff + +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .interp : { *(.interp) } +  .hash          : { *(.hash)		} +  .dynsym        : { *(.dynsym)		} +  .dynstr        : { *(.dynstr)		} +  .rel.text      : { *(.rel.text)		} +  .rela.text     : { *(.rela.text) 	} +  .rel.data      : { *(.rel.data)		} +  .rela.data     : { *(.rela.data) 	} +  .rel.rodata    : { *(.rel.rodata) 	} +  .rela.rodata   : { *(.rela.rodata) 	} +  .rel.got       : { *(.rel.got)		} +  .rela.got      : { *(.rela.got)		} +  .rel.ctors     : { *(.rel.ctors)	} +  .rela.ctors    : { *(.rela.ctors)	} +  .rel.dtors     : { *(.rel.dtors)	} +  .rela.dtors    : { *(.rela.dtors)	} +  .rel.bss       : { *(.rel.bss)		} +  .rela.bss      : { *(.rela.bss)		} +  .rel.plt       : { *(.rel.plt)		} +  .rela.plt      : { *(.rela.plt)		} +  .init          : { *(.init)	} +  .plt : { *(.plt) } +  .text      : +  { +    /* WARNING - the following is hand-optimized to fit within	*/ +    /* the sector layout of our flash chips!	XXX FIXME XXX	*/ + +    cpu/ppc4xx/start.o	(.text) +    cpu/ppc4xx/kgdb.o	(.text) +    cpu/ppc4xx/traps.o	(.text) +    cpu/ppc4xx/interrupts.o	(.text) +    cpu/ppc4xx/serial.o	(.text) +    cpu/ppc4xx/cpu_init.o	(.text) +    cpu/ppc4xx/speed.o	(.text) +    common/dlmalloc.o	(.text) +    lib_generic/crc32.o		(.text) +    lib_ppc/extable.o	(.text) +    lib_generic/zlib.o		(.text) + +/*    . = env_offset;*/ +/*    common/environment.o(.text)*/ + +    *(.text) +    *(.fixup) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +    *(.rodata.str1.4) +    *(.eh_frame) +  } +  .fini      : { *(.fini)    } =0 +  .ctors     : { *(.ctors)   } +  .dtors     : { *(.dtors)   } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x00FF) & 0xFFFFFF00; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    *(.got) +    _GOT2_TABLE_ = .; +    *(.got2) +    _FIXUP_TABLE_ = .; +    *(.fixup) +  } +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data) +    *(.data1) +    *(.sdata) +    *(.sdata2) +    *(.dynamic) +    CONSTRUCTORS +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  . = .; +  __u_boot_cmd_start = .; +  .u_boot_cmd : { *(.u_boot_cmd) } +  __u_boot_cmd_end = .; + +  . = .; +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(256); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(256); +  __init_end = .; + +  __bss_start = .; +  .bss       : +  { +   *(.sbss) *(.scommon) +   *(.dynbss) +   *(.bss) +   *(COMMON) +  } +  _end = . ; +  PROVIDE (end = .); +} diff --git a/board/amcc/taihu/update.c b/board/amcc/taihu/update.c new file mode 100644 index 000000000..55ad535c8 --- /dev/null +++ b/board/amcc/taihu/update.c @@ -0,0 +1,132 @@ +/* + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ + +#include <config.h> +#include <common.h> +#include <command.h> +#include <asm/processor.h> +#include <i2c.h> + +#define PCI_M66EN 0x10 + +static uchar buf_33[] = +{ +	0xb5,	/* 0x00:hce =1, bss = 0, pae=1, ppdv= 0b10,spe = 1,ebw=0b01*/ +	0x80,	/* 0x01~0x03:ptm1ms =0x80000001 */ +	0x00, +	0x00, +	0x00,	/* 0x04~0x06:ptm1la = 0x00000000 */ +	0x00, +	0x00, +	0x00,	/* 0x07~0x09:ptm2ma = 0x00000000 */ +	0x00, +	0x00, +	0x00,	/* 0x0a~0x0c:ptm2la = 0x00000000 */ +	0x00, +	0x00, +	0x10,	/* 0x0d~0x0e:vendor id 0x1014*/ +	0x14, +	0x00,	/* 0x0f~0x10:device id 0x0000*/ +	0x00, +	0x00,	/* 0x11:revision 0x00 */ +	0x00,	/* 0x12~0x14:class 0x000000 */ +	0x00, +	0x00, +	0x10,	/* 0x15~0x16:subsystem vendor id */ +	0xe8, +	0x00,	/* 0x17~0x18:subsystem device id */ +	0x00, +	0x61,	/* 0x19: opdv=0b01,cbdv=0b10,ccdv=0b00,ptm2ms_ena=0, ptm1ms_ena=1 */ +	0x68,	/* 0x1a: rpci=1,fbmul=0b1010,epdv=0b00 */ +	0x2d,	/* 0x1b: fwdvb=0b101,fwdva=0b101 */ +	0x82,	/* 0x1c: pllr=1,sscs=0,mpdv=0b00,tun[22-23]=0b10 */ +	0xbe,	/* 0x1d: tun[24-31]=0xbe */ +	0x00, +	0x00 +}; + +static uchar buf_66[] = +{ +	0xb5,	/* 0x00:hce =1, bss = 0, pae=1, ppdv= 0b10,spe = 1,ebw=0b01*/ +	0x80,	/* 0x01~0x03:ptm1ms =0x80000001 */ +	0x00, +	0x00, +	0x00,	/* 0x04~0x06:ptm1la = 0x00000000 */ +	0x00, +	0x00, +	0x00,	/* 0x07~0x09:ptm2ma = 0x00000000 */ +	0x00, +	0x00, +	0x00,	/* 0x0a~0x0c:ptm2la = 0x00000000 */ +	0x00, +	0x00, +	0x10,	/* 0x0d~0x0e:vendor id 0x1014*/ +	0x14, +	0x00,	/* 0x0f~0x10:device id 0x0000*/ +	0x00, +	0x00,	/* 0x11:revision 0x00 */ +	0x00,	/* 0x12~0x14:class 0x000000 */ +	0x00, +	0x00, +	0x10,	/* 0x15~0x16:subsystem vendor id */ +	0xe8, +	0x00,	/* 0x17~0x18:subsystem device id */ +	0x00, +	0x61,	/* 0x19: opdv=0b01,cbdv=0b10,ccdv=0b00,ptm2ms_ena=0, ptm1ms_ena=1 */ +	0x68,	/* 0x1a: rpci=1,fbmul=0b1010,epdv=0b00 */ +	0x2d,	/* 0x1b: fwdvb=0b101,fwdva=0b101 */ +	0x82,	/* 0x1c: pllr=1,sscs=0,mpdv=0b00,tun[22-23]=0b10 */ +	0xbe,	/* 0x1d: tun[24-31]=0xbe */ +	0x00, +	0x00 +}; + +static int update_boot_eeprom(cmd_tbl_t* cmdtp, int flag, int argc, char *argv[]) +{ +	ulong len = 0x20; +	uchar chip = CFG_I2C_EEPROM_ADDR; +	uchar *pbuf; +	uchar base; +	int i; + +	if ((*(volatile char*)CPLD_REG0_ADDR & PCI_M66EN) != PCI_M66EN) { +		pbuf = buf_33; +		base = 0x00; +	} else { +		pbuf = buf_66; +		base = 0x40; +	} + +	for (i = 0; i< len; i++, base++) { +		if (i2c_write(chip, base, 1, &pbuf[i],1)!= 0) { +			printf("i2c_write fail\n"); +			return 1; +		} +		udelay(11000); +	} + +	return 0; +} + +U_BOOT_CMD ( +	update_boot_eeprom, 1, 1, update_boot_eeprom, +	"update_boot_eeprom  - update boot eeprom content\n", +	NULL +	); diff --git a/board/amcc/yucca/yucca.c b/board/amcc/yucca/yucca.c index 7316c34b4..d08fcf356 100644 --- a/board/amcc/yucca/yucca.c +++ b/board/amcc/yucca/yucca.c @@ -562,6 +562,40 @@ int checkboard (void)  	return 0;  } +/* + * Override the default functions in cpu/ppc4xx/44x_spd_ddr2.c with + * board specific values. + */ +static int ppc440spe_rev_a(void) +{ +	if ((get_pvr() == PVR_440SPe_6_RA) || (get_pvr() == PVR_440SPe_RA)) +		return 1; +	else +		return 0; +} + +u32 ddr_wrdtr(u32 default_val) { +	/* +	 * Yucca boards with 440SPe rev. A need a slightly different setup +	 * for the MCIF0_WRDTR register. +	 */ +	if (ppc440spe_rev_a()) +		return (SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_270_DEG_ADV); + +	return default_val; +} + +u32 ddr_clktr(u32 default_val) { +	/* +	 * Yucca boards with 440SPe rev. A need a slightly different setup +	 * for the MCIF0_CLKTR register. +	 */ +	if (ppc440spe_rev_a()) +		return (SDRAM_CLKTR_CLKP_180_DEG_ADV); + +	return default_val; +} +  #if defined(CFG_DRAM_TEST)  int testdram (void)  { |