summaryrefslogtreecommitdiff
path: root/board/amcc
diff options
context:
space:
mode:
Diffstat (limited to 'board/amcc')
-rw-r--r--board/amcc/bamboo/bamboo.c321
-rw-r--r--board/amcc/bamboo/init.S3
-rw-r--r--board/amcc/bamboo/u-boot.lds2
-rw-r--r--board/amcc/bubinga/bubinga.c13
-rw-r--r--board/amcc/common/flash.c18
-rw-r--r--board/amcc/luan/luan.c7
-rw-r--r--board/amcc/taihu/Makefile49
-rw-r--r--board/amcc/taihu/config.mk24
-rw-r--r--board/amcc/taihu/flash.c1083
-rw-r--r--board/amcc/taihu/lcd.c257
-rw-r--r--board/amcc/taihu/taihu.c240
-rw-r--r--board/amcc/taihu/u-boot.lds150
-rw-r--r--board/amcc/taihu/update.c132
-rw-r--r--board/amcc/yucca/yucca.c34
14 files changed, 2228 insertions, 105 deletions
diff --git a/board/amcc/bamboo/bamboo.c b/board/amcc/bamboo/bamboo.c
index caf66909b9..00c793afd0 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 1459eec363..f4d2ae3f41 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 f6d7183199..0375618d72 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 fe6ce8a6d1..66e7509da8 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 e6429ecd13..eba0511f26 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 2eff3b33fd..7b16f8a39a 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 0000000000..9731c6e332
--- /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 0000000000..1bdf5e4fcf
--- /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 0000000000..290259e73f
--- /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 0000000000..3d042dfa73
--- /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 0000000000..ea83671988
--- /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 0000000000..be030923b8
--- /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 0000000000..55ad535c8c
--- /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 7316c34b4a..d08fcf3565 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)
{