summaryrefslogtreecommitdiff
path: root/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'cpu')
-rw-r--r--cpu/mpc512x/fixed_sdram.c33
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c366
-rw-r--r--cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c6
-rw-r--r--cpu/ppc4xx/4xx_pci.c48
-rw-r--r--cpu/ppc4xx/4xx_pcie.c3
-rw-r--r--cpu/ppc4xx/Makefile4
-rw-r--r--cpu/ppc4xx/cpu.c30
-rw-r--r--cpu/ppc4xx/cpu_init.c4
-rw-r--r--cpu/ppc4xx/denali_spd_ddr2.c2
-rw-r--r--cpu/ppc4xx/ecc.c167
-rw-r--r--cpu/ppc4xx/ecc.h52
-rw-r--r--cpu/ppc4xx/miiphy.c24
-rw-r--r--cpu/ppc4xx/reginfo.c370
-rw-r--r--cpu/ppc4xx/speed.c6
14 files changed, 733 insertions, 382 deletions
diff --git a/cpu/mpc512x/fixed_sdram.c b/cpu/mpc512x/fixed_sdram.c
index 673d61e..442b5fc 100644
--- a/cpu/mpc512x/fixed_sdram.c
+++ b/cpu/mpc512x/fixed_sdram.c
@@ -26,13 +26,13 @@
#include <asm/mpc512x.h>
/*
- * MDDRC Config Runtime Settings in order of the 4 MDDRC cfg registers
+ * MDDRC Config Runtime Settings
*/
-u32 default_mddrc_config[4] = {
- CONFIG_SYS_MDDRC_TIME_CFG0, /* time_config0 */
- CONFIG_SYS_MDDRC_TIME_CFG1, /* time_config1 */
- CONFIG_SYS_MDDRC_TIME_CFG2, /* time_config2 */
- CONFIG_SYS_MDDRC_SYS_CFG, /* sys_config */
+ddr512x_config_t default_mddrc_config = {
+ .ddr_sys_config = CONFIG_SYS_MDDRC_SYS_CFG,
+ .ddr_time_config0 = CONFIG_SYS_MDDRC_TIME_CFG0,
+ .ddr_time_config1 = CONFIG_SYS_MDDRC_TIME_CFG1,
+ .ddr_time_config2 = CONFIG_SYS_MDDRC_TIME_CFG2,
};
u32 default_init_seq[] = {
@@ -74,7 +74,8 @@ u32 default_init_seq[] = {
* The board doesn't use memory modules that have serial presence
* detect or similar mechanism for discovery of the DRAM settings
*/
-long int fixed_sdram(u32 *mddrc_config, u32 *dram_init_seq, int seq_sz)
+long int fixed_sdram(ddr512x_config_t *mddrc_config,
+ u32 *dram_init_seq, int seq_sz)
{
volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
u32 msize = CONFIG_SYS_DDR_SIZE * 1024 * 1024;
@@ -83,7 +84,7 @@ long int fixed_sdram(u32 *mddrc_config, u32 *dram_init_seq, int seq_sz)
/* take default settings and init sequence if necessary */
if (mddrc_config == NULL)
- mddrc_config = default_mddrc_config;
+ mddrc_config = &default_mddrc_config;
if (dram_init_seq == NULL) {
dram_init_seq = default_init_seq;
seq_sz = sizeof(default_init_seq)/sizeof(u32);
@@ -130,18 +131,22 @@ long int fixed_sdram(u32 *mddrc_config, u32 *dram_init_seq, int seq_sz)
* put MDDRC in CMD mode and
* set the max time between refreshes to 0 during init process
*/
- out_be32(&im->mddrc.ddr_sys_config, mddrc_config[3] | MDDRC_SYS_CFG_CMD_MASK);
- out_be32(&im->mddrc.ddr_time_config0, mddrc_config[0] & MDDRC_REFRESH_ZERO_MASK);
- out_be32(&im->mddrc.ddr_time_config1, mddrc_config[1]);
- out_be32(&im->mddrc.ddr_time_config2, mddrc_config[2]);
+ out_be32(&im->mddrc.ddr_sys_config,
+ mddrc_config->ddr_sys_config | MDDRC_SYS_CFG_CMD_MASK);
+ out_be32(&im->mddrc.ddr_time_config0,
+ mddrc_config->ddr_time_config0 & MDDRC_REFRESH_ZERO_MASK);
+ out_be32(&im->mddrc.ddr_time_config1,
+ mddrc_config->ddr_time_config1);
+ out_be32(&im->mddrc.ddr_time_config2,
+ mddrc_config->ddr_time_config2);
/* Initialize DDR with either default or supplied init sequence */
for (i = 0; i < seq_sz; i++)
out_be32(&im->mddrc.ddr_command, dram_init_seq[i]);
/* Start MDDRC */
- out_be32(&im->mddrc.ddr_time_config0, mddrc_config[0]);
- out_be32(&im->mddrc.ddr_sys_config, mddrc_config[3]);
+ out_be32(&im->mddrc.ddr_time_config0, mddrc_config->ddr_time_config0);
+ out_be32(&im->mddrc.ddr_sys_config, mddrc_config->ddr_sys_config);
return msize;
}
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 2ab2336..3975306 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -9,7 +9,7 @@
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
- * (C) Copyright 2007-2008
+ * (C) Copyright 2007-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* COPYRIGHT AMCC CORPORATION 2004
@@ -86,8 +86,133 @@
/* disable caching on SDRAM */
#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
#endif /* CONFIG_4xx_DCACHE */
+
+void dcbz_area(u32 start_address, u32 num_bytes);
#endif /* CONFIG_440 */
+#define MAXRANKS 4
+#define MAXBXCF 4
+
+#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
+
+#if !defined(CONFIG_NAND_SPL)
+/*-----------------------------------------------------------------------------+
+ * sdram_memsize
+ *-----------------------------------------------------------------------------*/
+phys_size_t sdram_memsize(void)
+{
+ phys_size_t mem_size;
+ unsigned long mcopt2;
+ unsigned long mcstat;
+ unsigned long mb0cf;
+ unsigned long sdsz;
+ unsigned long i;
+
+ mem_size = 0;
+
+ mfsdram(SDRAM_MCOPT2, mcopt2);
+ mfsdram(SDRAM_MCSTAT, mcstat);
+
+ /* DDR controller must be enabled and not in self-refresh. */
+ /* Otherwise memsize is zero. */
+ if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
+ && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
+ && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
+ == (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
+ for (i = 0; i < MAXBXCF; i++) {
+ mfsdram(SDRAM_MB0CF + (i << 2), mb0cf);
+ /* Banks enabled */
+ if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
+#if defined(CONFIG_440)
+ sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK;
+#else
+ sdsz = mb0cf & SDRAM_RXBAS_SDSZ_MASK;
+#endif
+ switch(sdsz) {
+ case SDRAM_RXBAS_SDSZ_8:
+ mem_size+=8;
+ break;
+ case SDRAM_RXBAS_SDSZ_16:
+ mem_size+=16;
+ break;
+ case SDRAM_RXBAS_SDSZ_32:
+ mem_size+=32;
+ break;
+ case SDRAM_RXBAS_SDSZ_64:
+ mem_size+=64;
+ break;
+ case SDRAM_RXBAS_SDSZ_128:
+ mem_size+=128;
+ break;
+ case SDRAM_RXBAS_SDSZ_256:
+ mem_size+=256;
+ break;
+ case SDRAM_RXBAS_SDSZ_512:
+ mem_size+=512;
+ break;
+ case SDRAM_RXBAS_SDSZ_1024:
+ mem_size+=1024;
+ break;
+ case SDRAM_RXBAS_SDSZ_2048:
+ mem_size+=2048;
+ break;
+ case SDRAM_RXBAS_SDSZ_4096:
+ mem_size+=4096;
+ break;
+ default:
+ printf("WARNING: Unsupported bank size (SDSZ=0x%lx)!\n"
+ , sdsz);
+ mem_size=0;
+ break;
+ }
+ }
+ }
+ }
+
+ return mem_size << 20;
+}
+
+/*-----------------------------------------------------------------------------+
+ * is_ecc_enabled
+ *-----------------------------------------------------------------------------*/
+static unsigned long is_ecc_enabled(void)
+{
+ unsigned long val;
+
+ mfsdram(SDRAM_MCOPT1, val);
+
+ return SDRAM_MCOPT1_MCHK_CHK_DECODE(val);
+}
+
+/*-----------------------------------------------------------------------------+
+ * board_add_ram_info
+ *-----------------------------------------------------------------------------*/
+void board_add_ram_info(int use_default)
+{
+ PPC4xx_SYS_INFO board_cfg;
+ u32 val;
+
+ if (is_ecc_enabled())
+ puts(" (ECC");
+ else
+ puts(" (ECC not");
+
+ get_sys_info(&board_cfg);
+
+#if defined(CONFIG_405EX)
+ val = board_cfg.freqPLB;
+#else
+ mfsdr(SDR0_DDR0, val);
+ val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1);
+#endif
+ printf(" enabled, %d MHz", (val * 2) / 1000000);
+
+ mfsdram(SDRAM_MMODE, val);
+ val = (val & SDRAM_MMODE_DCL_MASK) >> 4;
+ printf(", CL%d)", val);
+}
+#endif /* !CONFIG_NAND_SPL */
+
#if defined(CONFIG_SPD_EEPROM)
/*-----------------------------------------------------------------------------+
@@ -105,14 +230,10 @@
#define SDRAM_NONE 0
#define MAXDIMMS 2
-#define MAXRANKS 4
-#define MAXBXCF 4
#define MAX_SPD_BYTES 256 /* Max number of bytes on the DIMM's SPD EEPROM */
#define ONE_BILLION 1000000000
-#define MULDIV64(m1, m2, d) (u32)(((u64)(m1) * (u64)(m2)) / (u64)(d))
-
#define CMD_NOP (7 << 19)
#define CMD_PRECHARGE (2 << 19)
#define CMD_REFRESH (1 << 19)
@@ -213,7 +334,6 @@ typedef enum ddr_cas_id {
/*-----------------------------------------------------------------------------+
* Prototypes
*-----------------------------------------------------------------------------*/
-static phys_size_t sdram_memsize(void);
static void get_spd_info(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks);
@@ -257,15 +377,11 @@ static void program_initplr(unsigned long *dimm_populated,
unsigned long num_dimm_banks,
ddr_cas_id_t selected_cas,
int write_recovery);
-static unsigned long is_ecc_enabled(void);
#ifdef CONFIG_DDR_ECC
static void program_ecc(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks,
unsigned long tlb_word2_i_value);
-static void program_ecc_addr(unsigned long start_address,
- unsigned long num_bytes,
- unsigned long tlb_word2_i_value);
#endif
#if !defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
static void program_DQS_calibration(unsigned long *dimm_populated,
@@ -278,7 +394,6 @@ static void DQS_calibration_process(void);
#endif
#endif
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-void dcbz_area(u32 start_address, u32 num_bytes);
static unsigned char spd_read(uchar chip, uint addr)
{
@@ -292,79 +407,6 @@ static unsigned char spd_read(uchar chip, uint addr)
}
/*-----------------------------------------------------------------------------+
- * sdram_memsize
- *-----------------------------------------------------------------------------*/
-static phys_size_t sdram_memsize(void)
-{
- phys_size_t mem_size;
- unsigned long mcopt2;
- unsigned long mcstat;
- unsigned long mb0cf;
- unsigned long sdsz;
- unsigned long i;
-
- mem_size = 0;
-
- mfsdram(SDRAM_MCOPT2, mcopt2);
- mfsdram(SDRAM_MCSTAT, mcstat);
-
- /* DDR controller must be enabled and not in self-refresh. */
- /* Otherwise memsize is zero. */
- if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
- && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
- && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
- == (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
- for (i = 0; i < MAXBXCF; i++) {
- mfsdram(SDRAM_MB0CF + (i << 2), mb0cf);
- /* Banks enabled */
- if ((mb0cf & SDRAM_BXCF_M_BE_MASK) == SDRAM_BXCF_M_BE_ENABLE) {
- sdsz = mfdcr_any(SDRAM_R0BAS + i) & SDRAM_RXBAS_SDSZ_MASK;
-
- switch(sdsz) {
- case SDRAM_RXBAS_SDSZ_8:
- mem_size+=8;
- break;
- case SDRAM_RXBAS_SDSZ_16:
- mem_size+=16;
- break;
- case SDRAM_RXBAS_SDSZ_32:
- mem_size+=32;
- break;
- case SDRAM_RXBAS_SDSZ_64:
- mem_size+=64;
- break;
- case SDRAM_RXBAS_SDSZ_128:
- mem_size+=128;
- break;
- case SDRAM_RXBAS_SDSZ_256:
- mem_size+=256;
- break;
- case SDRAM_RXBAS_SDSZ_512:
- mem_size+=512;
- break;
- case SDRAM_RXBAS_SDSZ_1024:
- mem_size+=1024;
- break;
- case SDRAM_RXBAS_SDSZ_2048:
- mem_size+=2048;
- break;
- case SDRAM_RXBAS_SDSZ_4096:
- mem_size+=4096;
- break;
- default:
- printf("WARNING: Unsupported bank size (SDSZ=0x%lx)!\n"
- , sdsz);
- mem_size=0;
- break;
- }
- }
- }
- }
-
- return mem_size << 20;
-}
-
-/*-----------------------------------------------------------------------------+
* initdram. Initializes the 440SP Memory Queue and DDR SDRAM controller.
* Note: This routine runs from flash with a stack set up in the chip's
* sram space. It is important that the routine does not require .sbss, .bss or
@@ -643,26 +685,6 @@ static void get_spd_info(unsigned long *dimm_populated,
}
}
-void board_add_ram_info(int use_default)
-{
- PPC4xx_SYS_INFO board_cfg;
- u32 val;
-
- if (is_ecc_enabled())
- puts(" (ECC");
- else
- puts(" (ECC not");
-
- get_sys_info(&board_cfg);
-
- mfsdr(SDR0_DDR0, val);
- val = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(val), 1);
- printf(" enabled, %d MHz", (val * 2) / 1000000);
-
- mfsdram(SDRAM_MMODE, val);
- val = (val & SDRAM_MMODE_DCL_MASK) >> 4;
- printf(", CL%d)", val);
-}
/*------------------------------------------------------------------
* For the memory DIMMs installed, this routine verifies that they
@@ -2277,25 +2299,6 @@ static void program_memory_queue(unsigned long *dimm_populated,
#endif
}
-/*-----------------------------------------------------------------------------+
- * is_ecc_enabled.
- *-----------------------------------------------------------------------------*/
-static unsigned long is_ecc_enabled(void)
-{
- unsigned long dimm_num;
- unsigned long ecc;
- unsigned long val;
-
- ecc = 0;
- /* loop through all the DIMM slots on the board */
- for (dimm_num = 0; dimm_num < MAXDIMMS; dimm_num++) {
- mfsdram(SDRAM_MCOPT1, val);
- ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val));
- }
-
- return ecc;
-}
-
#ifdef CONFIG_DDR_ECC
/*-----------------------------------------------------------------------------+
* program_ecc.
@@ -2305,9 +2308,6 @@ static void program_ecc(unsigned long *dimm_populated,
unsigned long num_dimm_banks,
unsigned long tlb_word2_i_value)
{
- unsigned long mcopt1;
- unsigned long mcopt2;
- unsigned long mcstat;
unsigned long dimm_num;
unsigned long ecc;
@@ -2321,105 +2321,7 @@ static void program_ecc(unsigned long *dimm_populated,
if (ecc == 0)
return;
- if (sdram_memsize() > CONFIG_MAX_MEM_MAPPED) {
- printf("\nWarning: Can't enable ECC on systems with more than 2GB of SDRAM!\n");
- return;
- }
-
- mfsdram(SDRAM_MCOPT1, mcopt1);
- mfsdram(SDRAM_MCOPT2, mcopt2);
-
- if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
- /* DDR controller must be enabled and not in self-refresh. */
- mfsdram(SDRAM_MCSTAT, mcstat);
- if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
- && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
- && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
- == (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
-
- program_ecc_addr(0, sdram_memsize(), tlb_word2_i_value);
- }
- }
-
- return;
-}
-
-static void wait_ddr_idle(void)
-{
- u32 val;
-
- do {
- mfsdram(SDRAM_MCSTAT, val);
- } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
-}
-
-/*-----------------------------------------------------------------------------+
- * program_ecc_addr.
- *-----------------------------------------------------------------------------*/
-static void program_ecc_addr(unsigned long start_address,
- unsigned long num_bytes,
- unsigned long tlb_word2_i_value)
-{
- unsigned long current_address;
- unsigned long end_address;
- unsigned long address_increment;
- unsigned long mcopt1;
- char str[] = "ECC generation -";
- char slash[] = "\\|/-\\|/-";
- int loop = 0;
- int loopi = 0;
-
- current_address = start_address;
- mfsdram(SDRAM_MCOPT1, mcopt1);
- if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
- mtsdram(SDRAM_MCOPT1,
- (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN);
- sync();
- eieio();
- wait_ddr_idle();
-
- puts(str);
- if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) {
- /* ECC bit set method for non-cached memory */
- if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32)
- address_increment = 4;
- else
- address_increment = 8;
- end_address = current_address + num_bytes;
-
- while (current_address < end_address) {
- *((unsigned long *)current_address) = 0x00000000;
- current_address += address_increment;
-
- if ((loop++ % (2 << 20)) == 0) {
- putc('\b');
- putc(slash[loopi++ % 8]);
- }
- }
-
- } else {
- /* ECC bit set method for cached memory */
- dcbz_area(start_address, num_bytes);
- /* Write modified dcache lines back to memory */
- clean_dcache_range(start_address, start_address + num_bytes);
- }
-
- blank_string(strlen(str));
-
- sync();
- eieio();
- wait_ddr_idle();
-
- /* clear ECC error repoting registers */
- mtsdram(SDRAM_ECCCR, 0xffffffff);
- mtdcr(0x4c, 0xffffffff);
-
- mtsdram(SDRAM_MCOPT1,
- (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP);
- sync();
- eieio();
- wait_ddr_idle();
- }
+ do_program_ecc(tlb_word2_i_value);
}
#endif
@@ -3106,7 +3008,7 @@ phys_size_t initdram(int board_type)
#endif /* CONFIG_PPC4xx_DDR_AUTOCALIBRATION */
#if defined(CONFIG_DDR_ECC)
- ecc_init(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MBYTES_SDRAM << 20);
+ do_program_ecc(0);
#endif /* defined(CONFIG_DDR_ECC) */
#if defined(CONFIG_440)
@@ -3183,18 +3085,6 @@ void mtdcr_any(u32 dcr, u32 val)
}
}
#endif /* defined(CONFIG_440) */
-
-void blank_string(int size)
-{
- int i;
-
- for (i = 0; i < size; i++)
- putc('\b');
- for (i = 0; i < size; i++)
- putc(' ');
- for (i = 0; i < size; i++)
- putc('\b');
-}
#endif /* !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) */
inline void ppc4xx_ibm_ddr2_register_dump(void)
diff --git a/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
index 91bf582..0283c91 100644
--- a/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
+++ b/cpu/ppc4xx/4xx_ibm_ddr2_autocalib.c
@@ -42,6 +42,8 @@
#include <asm/io.h>
#include <asm/processor.h>
+#include "ecc.h"
+
#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION)
/*
@@ -177,7 +179,7 @@ static u32 *get_membase(int bxcr_num)
static inline void ecc_clear_status_reg(void)
{
- mtsdram(SDRAM_ECCCR, 0xffffffff);
+ mtsdram(SDRAM_ECCES, 0xffffffff);
#if defined(SDRAM_R0BAS)
mtdcr(SDRAM_ERRSTATLL, 0xffffffff);
#endif
@@ -210,7 +212,7 @@ static int ecc_check_status_reg(void)
* ecc error, then don't count
* this as a passing value
*/
- mfsdram(SDRAM_ECCCR, ecc_status);
+ mfsdram(SDRAM_ECCES, ecc_status);
if (ecc_status != 0x00000000) {
/* clear on error */
ecc_clear_status_reg();
diff --git a/cpu/ppc4xx/4xx_pci.c b/cpu/ppc4xx/4xx_pci.c
index e97f32c..fa521f0 100644
--- a/cpu/ppc4xx/4xx_pci.c
+++ b/cpu/ppc4xx/4xx_pci.c
@@ -518,7 +518,7 @@ int pci_440_init (struct pci_controller *hose)
/* PCI I/O space */
pci_set_region(hose->regions + reg_num++,
0x00000000,
- PCIX0_IOBASE,
+ PCIL0_IOBASE,
0x10000,
PCI_REGION_IO);
@@ -545,7 +545,7 @@ int pci_440_init (struct pci_controller *hose)
hose->region_count = reg_num;
- pci_setup_indirect(hose, PCIX0_CFGADR, PCIX0_CFGDATA);
+ pci_setup_indirect(hose, PCIL0_CFGADR, PCIL0_CFGDATA);
/* Let board change/modify hose & do initial checks */
if (pci_pre_init (hose) == 0) {
@@ -562,18 +562,18 @@ int pci_440_init (struct pci_controller *hose)
#if defined(CONFIG_SYS_PCI_TARGET_INIT)
pci_target_init(hose); /* Let board setup pci target */
#else
- out16r( PCIX0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID );
- out16r( PCIX0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_ID );
- out16r( PCIX0_CLS, 0x00060000 ); /* Bridge, host bridge */
+ out16r( PCIL0_SBSYSVID, CONFIG_SYS_PCI_SUBSYS_VENDORID );
+ out16r( PCIL0_SBSYSID, CONFIG_SYS_PCI_SUBSYS_ID );
+ out16r( PCIL0_CLS, 0x00060000 ); /* Bridge, host bridge */
#endif
#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)
- out32r( PCIX0_BRDGOPT1, 0x04000060 ); /* PLB Rq pri highest */
- out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1 */
-#elif defined(PCIX0_BRDGOPT1)
- out32r( PCIX0_BRDGOPT1, 0x10000060 ); /* PLB Rq pri highest */
- out32r( PCIX0_BRDGOPT2, in32(PCIX0_BRDGOPT2) | 1 ); /* Enable host config */
+ out32r( PCIL0_BRDGOPT1, 0x04000060 ); /* PLB Rq pri highest */
+ out32r( PCIL0_BRDGOPT2, in32(PCIL0_BRDGOPT2) | 0x83 ); /* Enable host config, clear Timeout, ensure int src1 */
+#elif defined(PCIL0_BRDGOPT1)
+ out32r( PCIL0_BRDGOPT1, 0x10000060 ); /* PLB Rq pri highest */
+ out32r( PCIL0_BRDGOPT2, in32(PCIL0_BRDGOPT2) | 1 ); /* Enable host config */
#endif
/*--------------------------------------------------------------------------+
@@ -583,23 +583,23 @@ int pci_440_init (struct pci_controller *hose)
#if defined(CONFIG_SYS_PCI_MASTER_INIT)
pci_master_init(hose); /* Let board setup pci master */
#else
- out32r( PCIX0_POM0SA, 0 ); /* disable */
- out32r( PCIX0_POM1SA, 0 ); /* disable */
- out32r( PCIX0_POM2SA, 0 ); /* disable */
+ out32r( PCIL0_POM0SA, 0 ); /* disable */
+ out32r( PCIL0_POM1SA, 0 ); /* disable */
+ out32r( PCIL0_POM2SA, 0 ); /* disable */
#if defined(CONFIG_440SPE)
- out32r( PCIX0_POM0LAL, 0x10000000 );
- out32r( PCIX0_POM0LAH, 0x0000000c );
+ out32r( PCIL0_POM0LAL, 0x10000000 );
+ out32r( PCIL0_POM0LAH, 0x0000000c );
#elif defined(CONFIG_460EX) || defined(CONFIG_460GT)
- out32r( PCIX0_POM0LAL, 0x20000000 );
- out32r( PCIX0_POM0LAH, 0x0000000c );
+ out32r( PCIL0_POM0LAL, 0x20000000 );
+ out32r( PCIL0_POM0LAH, 0x0000000c );
#else
- out32r( PCIX0_POM0LAL, 0x00000000 );
- out32r( PCIX0_POM0LAH, 0x00000003 );
+ out32r( PCIL0_POM0LAL, 0x00000000 );
+ out32r( PCIL0_POM0LAH, 0x00000003 );
#endif
- out32r( PCIX0_POM0PCIAL, CONFIG_SYS_PCI_MEMBASE );
- out32r( PCIX0_POM0PCIAH, 0x00000000 );
- out32r( PCIX0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
- out32r( PCIX0_STS, in32r( PCIX0_STS ) & ~0x0000fff8 );
+ out32r( PCIL0_POM0PCIAL, CONFIG_SYS_PCI_MEMBASE );
+ out32r( PCIL0_POM0PCIAH, 0x00000000 );
+ out32r( PCIL0_POM0SA, 0xf0000001 ); /* 256MB, enabled */
+ out32r( PCIL0_STS, in32r( PCIL0_STS ) & ~0x0000fff8 );
#endif
/*--------------------------------------------------------------------------+
@@ -614,7 +614,7 @@ int pci_440_init (struct pci_controller *hose)
#endif
#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) && \
!defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
- out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
+ out16r( PCIL0_CMD, in16r( PCIL0_CMD ) | PCI_COMMAND_MASTER);
#endif
hose->last_busno = pci_hose_scan(hose);
}
diff --git a/cpu/ppc4xx/4xx_pcie.c b/cpu/ppc4xx/4xx_pcie.c
index e880c28..19d2c7d 100644
--- a/cpu/ppc4xx/4xx_pcie.c
+++ b/cpu/ppc4xx/4xx_pcie.c
@@ -30,6 +30,7 @@
#include <ppc4xx.h>
#include <asm/processor.h>
#include <asm-ppc/io.h>
+#include <asm/errno.h>
#if (defined(CONFIG_440SPE) || defined(CONFIG_405EX) || \
defined(CONFIG_460EX) || defined(CONFIG_460GT)) && \
@@ -874,7 +875,7 @@ int ppc4xx_init_pcie_port(int port, int rootport)
val = SDR_READ(SDRN_PESDR_LOOP(port));
if (!(val & 0x00001000)) {
printf("PCIE%d: link is not up.\n", port);
- return -1;
+ return -ENODEV;
}
/*
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index 2050b17..365f966 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -33,6 +33,7 @@ SOBJS += dcr.o
SOBJS += kgdb.o
COBJS := 40x_spd_sdram.o
+
COBJS += 44x_spd_ddr.o
COBJS += 44x_spd_ddr2.o
ifdef CONFIG_PPC4xx_DDR_AUTOCALIBRATION
@@ -54,6 +55,9 @@ COBJS += fdt.o
COBJS += i2c.o
COBJS += interrupts.o
COBJS += iop480_uart.o
+ifdef CONFIG_CMD_REGINFO
+COBJS += reginfo.o
+endif
COBJS += sdram.o
COBJS += speed.o
COBJS += tlb.o
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index 2287904..a9a0ac3 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -371,16 +371,6 @@ int checkcpu (void)
strcpy(addstr, "Security support");
break;
- case PVR_405EX2_RA:
- puts("EX Rev. A");
- strcpy(addstr, "No Security support");
- break;
-
- case PVR_405EXR1_RA:
- puts("EXr Rev. A");
- strcpy(addstr, "Security support");
- break;
-
case PVR_405EXR2_RA:
puts("EXr Rev. A");
strcpy(addstr, "No Security support");
@@ -406,6 +396,26 @@ int checkcpu (void)
strcpy(addstr, "No Security support");
break;
+ case PVR_405EX1_RD:
+ puts("EX Rev. D");
+ strcpy(addstr, "Security support");
+ break;
+
+ case PVR_405EX2_RD:
+ puts("EX Rev. D");
+ strcpy(addstr, "No Security support");
+ break;
+
+ case PVR_405EXR1_RD:
+ puts("EXr Rev. D");
+ strcpy(addstr, "Security support");
+ break;
+
+ case PVR_405EXR2_RD:
+ puts("EXr Rev. D");
+ strcpy(addstr, "No Security support");
+ break;
+
#if defined(CONFIG_440)
case PVR_440GP_RB:
puts("GP Rev. B");
diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c
index bd06b9b..a00da40 100644
--- a/cpu/ppc4xx/cpu_init.c
+++ b/cpu/ppc4xx/cpu_init.c
@@ -58,13 +58,13 @@ void reconfigure_pll(u32 new_cpu_freq)
target_perdv0 = 4;
target_spcid0 = 4;
- mfcpr(CPR0_PRIMBD, reg);
+ mfcpr(CPR0_PRIMBD0, reg);
temp = (reg & PRBDV_MASK) >> 24;
prbdv0 = temp ? temp : 8;
if (prbdv0 != target_prbdv0) {
reg &= ~PRBDV_MASK;
reg |= ((target_prbdv0 == 8 ? 0 : target_prbdv0) << 24);
- mtcpr(CPR0_PRIMBD, reg);
+ mtcpr(CPR0_PRIMBD0, reg);
reset_needed = 1;
}
diff --git a/cpu/ppc4xx/denali_spd_ddr2.c b/cpu/ppc4xx/denali_spd_ddr2.c
index 4705e21..5858cb3 100644
--- a/cpu/ppc4xx/denali_spd_ddr2.c
+++ b/cpu/ppc4xx/denali_spd_ddr2.c
@@ -1159,7 +1159,7 @@ phys_size_t initdram(int board_type)
mtsdram(DDR0_31, DDR0_31_XOR_CHECK_BITS_ENCODE(0x0000));
- mtsdram(DDR0_42, DDR0_42_ADDR_PINS_DECODE(14 - rows) |
+ mtsdram(DDR0_42, DDR0_42_ADDR_PINS_ENCODE(14 - rows) |
DDR0_42_CASLAT_LIN_GATE_ENCODE(2 * cas_latency));
program_ddr0_43(dimm_ranks, iic0_dimm_addr, num_dimm_banks, sdram_freq,
diff --git a/cpu/ppc4xx/ecc.c b/cpu/ppc4xx/ecc.c
index 3f989e7..f105605 100644
--- a/cpu/ppc4xx/ecc.c
+++ b/cpu/ppc4xx/ecc.c
@@ -2,7 +2,7 @@
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
*
- * (C) Copyright 2005-2007
+ * (C) Copyright 2005-2009
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*
* (C) Copyright 2002
@@ -42,81 +42,144 @@
#include <ppc_defs.h>
#include <asm/processor.h>
#include <asm/io.h>
+#include <asm/mmu.h>
+#include <asm/cache.h>
#include "ecc.h"
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \
defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC)
+
+#if defined(CONFIG_405EX)
/*
- * void ecc_init()
- *
- * Description:
- * This routine initializes a range of DRAM ECC memory with known
- * data and enables ECC checking.
- *
- * TO DO:
- * - Improve performance by utilizing cache.
- * - Further generalize to make usable by other 4xx variants (e.g.
- * 440EPx, et al).
- *
- * Input(s):
- * start - A pointer to the start of memory covered by ECC requiring
- * initialization.
- * size - The size, in bytes, of the memory covered by ECC requiring
- * initialization.
- *
- * Output(s):
- * start - A pointer to the start of memory covered by ECC with
- * CONFIG_SYS_ECC_PATTERN written to all locations and ECC data
- * primed.
- *
- * Returns:
- * N/A
+ * Currently only 405EX uses 16bit data bus width as an alternative
+ * option to 32bit data width (SDRAM0_MCOPT1_WDTH)
*/
-void ecc_init(unsigned long * const start, unsigned long size)
+#define SDRAM_DATA_ALT_WIDTH 2
+#else
+#define SDRAM_DATA_ALT_WIDTH 8
+#endif
+
+static void wait_ddr_idle(void)
{
- const unsigned long pattern = CONFIG_SYS_ECC_PATTERN;
- unsigned long * const end = (unsigned long * const)((long)start + size);
- unsigned long * current = start;
+ u32 val;
+
+ do {
+ mfsdram(SDRAM_MCSTAT, val);
+ } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
+}
+
+static void program_ecc_addr(unsigned long start_address,
+ unsigned long num_bytes,
+ unsigned long tlb_word2_i_value)
+{
+ unsigned long current_address;
+ unsigned long end_address;
+ unsigned long address_increment;
unsigned long mcopt1;
- long increment;
+ char str[] = "ECC generation -";
+ char slash[] = "\\|/-\\|/-";
+ int loop = 0;
+ int loopi = 0;
- if (start >= end)
- return;
+ current_address = start_address;
+ mfsdram(SDRAM_MCOPT1, mcopt1);
+ if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
+ mtsdram(SDRAM_MCOPT1,
+ (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_GEN);
+ sync();
+ eieio();
+ wait_ddr_idle();
+
+ puts(str);
- mfsdram(SDRAM_ECC_CFG, mcopt1);
+#ifdef CONFIG_440
+ if (tlb_word2_i_value == TLB_WORD2_I_ENABLE) {
+#endif
+ /* ECC bit set method for non-cached memory */
+ if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32)
+ address_increment = 4;
+ else
+ address_increment = SDRAM_DATA_ALT_WIDTH;
+ end_address = current_address + num_bytes;
- /* Enable ECC generation without checking or reporting */
+ while (current_address < end_address) {
+ *((unsigned long *)current_address) = 0;
+ current_address += address_increment;
- mtsdram(SDRAM_ECC_CFG, ((mcopt1 & ~SDRAM_ECC_CFG_MCHK_MASK) |
- SDRAM_ECC_CFG_MCHK_GEN));
+ if ((loop++ % (2 << 20)) == 0) {
+ putc('\b');
+ putc(slash[loopi++ % 8]);
+ }
+ }
+#ifdef CONFIG_440
+ } else {
+ /* ECC bit set method for cached memory */
+ dcbz_area(start_address, num_bytes);
+ /* Write modified dcache lines back to memory */
+ clean_dcache_range(start_address, start_address + num_bytes);
+ }
+#endif /* CONFIG_440 */
- increment = sizeof(u32);
+ blank_string(strlen(str));
-#if defined(CONFIG_440)
+ sync();
+ eieio();
+ wait_ddr_idle();
+
+ /* clear ECC error repoting registers */
+ mtsdram(SDRAM_ECCES, 0xffffffff);
+ mtdcr(0x4c, 0xffffffff);
+
+ mtsdram(SDRAM_MCOPT1,
+ (mcopt1 & ~SDRAM_MCOPT1_MCHK_MASK) | SDRAM_MCOPT1_MCHK_CHK_REP);
+ sync();
+ eieio();
+ wait_ddr_idle();
+ }
+}
+
+#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
+void ecc_init(unsigned long * const start, unsigned long size)
+{
/*
- * Look at the geometry of SDRAM (data width) to determine whether we
- * can skip words when writing.
+ * Init ECC with cache disabled (on PPC's with IBM DDR
+ * controller (non DDR2), not tested with cache enabled yet
*/
+ program_ecc_addr((u32)start, size, TLB_WORD2_I_ENABLE);
+}
+#endif
- if ((mcopt1 & SDRAM_ECC_CFG_DMWD_MASK) != SDRAM_ECC_CFG_DMWD_32)
- increment = sizeof(u64);
-#endif /* defined(CONFIG_440) */
+#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
+void do_program_ecc(unsigned long tlb_word2_i_value)
+{
+ unsigned long mcopt1;
+ unsigned long mcopt2;
+ unsigned long mcstat;
+ phys_size_t memsize = sdram_memsize();
- while (current < end) {
- *current = pattern;
- current = (unsigned long *)((long)current + increment);
+ if (memsize > CONFIG_MAX_MEM_MAPPED) {
+ printf("\nWarning: Can't enable ECC on systems with more than 2GB of SDRAM!\n");
+ return;
}
- /* Wait until the writes are finished. */
+ mfsdram(SDRAM_MCOPT1, mcopt1);
+ mfsdram(SDRAM_MCOPT2, mcopt2);
- sync();
+ if ((mcopt1 & SDRAM_MCOPT1_MCHK_MASK) != SDRAM_MCOPT1_MCHK_NON) {
+ /* DDR controller must be enabled and not in self-refresh. */
+ mfsdram(SDRAM_MCSTAT, mcstat);
+ if (((mcopt2 & SDRAM_MCOPT2_DCEN_MASK) == SDRAM_MCOPT2_DCEN_ENABLE)
+ && ((mcopt2 & SDRAM_MCOPT2_SREN_MASK) == SDRAM_MCOPT2_SREN_EXIT)
+ && ((mcstat & (SDRAM_MCSTAT_MIC_MASK | SDRAM_MCSTAT_SRMS_MASK))
+ == (SDRAM_MCSTAT_MIC_COMP | SDRAM_MCSTAT_SRMS_NOT_SF))) {
- /* Enable ECC generation with checking and no reporting */
-
- mtsdram(SDRAM_ECC_CFG, ((mcopt1 & ~SDRAM_ECC_CFG_MCHK_MASK) |
- SDRAM_ECC_CFG_MCHK_CHK));
+ program_ecc_addr(0, memsize, tlb_word2_i_value);
+ }
+ }
}
+#endif
+
#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */
#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */
diff --git a/cpu/ppc4xx/ecc.h b/cpu/ppc4xx/ecc.h
index 67c3bff..b258891 100644
--- a/cpu/ppc4xx/ecc.h
+++ b/cpu/ppc4xx/ecc.h
@@ -2,7 +2,7 @@
* Copyright (c) 2008 Nuovation System Designs, LLC
* Grant Erickson <gerickson@nuovations.com>
*
- * Copyright (c) 2007 DENX Software Engineering, GmbH
+ * Copyright (c) 2007-2009 DENX Software Engineering, GmbH
* Stefan Roese <sr@denx.de>
*
* See file CREDITS for list of people who contributed to this
@@ -25,18 +25,13 @@
*
* Description:
* This file implements ECC initialization for PowerPC processors
- * using the SDRAM DDR2 controller, including the 405EX(r),
- * 440SP(E), 460EX and 460GT.
+ * using the IBM SDRAM DDR1 & DDR2 controller.
*
*/
#ifndef _ECC_H_
#define _ECC_H_
-#if !defined(CONFIG_SYS_ECC_PATTERN)
-#define CONFIG_SYS_ECC_PATTERN 0x00000000
-#endif /* !defined(CONFIG_SYS_ECC_PATTERN) */
-
/*
* Since the IBM DDR controller used on 440GP/GX/EP/GR is not register
* compatible to the IBM DDR/2 controller used on 405EX/440SP/SPe/460EX/GT
@@ -46,24 +41,35 @@
/* For 440GP/GX/EP/GR */
#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)
-#define SDRAM_ECC_CFG SDRAM_CFG0
-#define SDRAM_ECC_CFG_MCHK_MASK SDRAM_CFG0_MCHK_MASK
-#define SDRAM_ECC_CFG_MCHK_GEN SDRAM_CFG0_MCHK_GEN
-#define SDRAM_ECC_CFG_MCHK_CHK SDRAM_CFG0_MCHK_CHK
-#define SDRAM_ECC_CFG_DMWD_MASK SDRAM_CFG0_DMWD_MASK
-#define SDRAM_ECC_CFG_DMWD_32 SDRAM_CFG0_DMWD_32
-#endif
+#define SDRAM_MCOPT1 SDRAM_CFG0
+#define SDRAM_MCOPT1_MCHK_MASK SDRAM_CFG0_MCHK_MASK
+#define SDRAM_MCOPT1_MCHK_NON SDRAM_CFG0_MCHK_NON
+#define SDRAM_MCOPT1_MCHK_GEN SDRAM_CFG0_MCHK_GEN
+#define SDRAM_MCOPT1_MCHK_CHK SDRAM_CFG0_MCHK_CHK
+#define SDRAM_MCOPT1_MCHK_CHK_REP SDRAM_CFG0_MCHK_CHK
+#define SDRAM_MCOPT1_DMWD_MASK SDRAM_CFG0_DMWD_MASK
+#define SDRAM_MCOPT1_DMWD_32 SDRAM_CFG0_DMWD_32
+
+#define SDRAM_MCSTAT SDRAM0_MCSTS
+#define SDRAM_MCSTAT_IDLE_MASK SDRAM_MCSTS_CIS
+#define SDRAM_MCSTAT_IDLE_NOT SDRAM_MCSTS_IDLE_NOT
-/* For 405EX/440SP/SPe/460EX/GT */
-#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2)
-#define SDRAM_ECC_CFG SDRAM_MCOPT1
-#define SDRAM_ECC_CFG_MCHK_MASK SDRAM_MCOPT1_MCHK_MASK
-#define SDRAM_ECC_CFG_MCHK_GEN SDRAM_MCOPT1_MCHK_GEN
-#define SDRAM_ECC_CFG_MCHK_CHK SDRAM_MCOPT1_MCHK_CHK
-#define SDRAM_ECC_CFG_DMWD_MASK SDRAM_MCOPT1_DMWD_MASK
-#define SDRAM_ECC_CFG_DMWD_32 SDRAM_MCOPT1_DMWD_32
+#define SDRAM_ECCES SDRAM0_ECCESR
#endif
-extern void ecc_init(unsigned long * const start, unsigned long size);
+void ecc_init(unsigned long * const start, unsigned long size);
+void do_program_ecc(unsigned long tlb_word2_i_value);
+
+static void inline blank_string(int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ putc('\b');
+ for (i = 0; i < size; i++)
+ putc(' ');
+ for (i = 0; i < size; i++)
+ putc('\b');
+}
#endif /* _ECC_H_ */
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index fa3bfc8..22ed5c2 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -195,7 +195,7 @@ unsigned int miiphy_getemac_offset(u8 addr)
unsigned long eoffset;
/* Need to find out which mdi port we're using */
- zmii = in_be32((void *)ZMII_FER);
+ zmii = in_be32((void *)ZMII0_FER);
if (zmii & (ZMII_FER_MDI << ZMII_FER_V (0)))
/* using port 0 */
@@ -217,12 +217,12 @@ unsigned int miiphy_getemac_offset(u8 addr)
/* None of the mdi ports are enabled! */
/* enable port 0 */
zmii |= ZMII_FER_MDI << ZMII_FER_V (0);
- out_be32((void *)ZMII_FER, zmii);
+ out_be32((void *)ZMII0_FER, zmii);
eoffset = 0;
/* need to soft reset port 0 */
- zmii = in_be32((void *)EMAC_M0);
- zmii |= EMAC_M0_SRST;
- out_be32((void *)EMAC_M0, zmii);
+ zmii = in_be32((void *)EMAC0_MR0);
+ zmii |= EMAC_MR0_SRST;
+ out_be32((void *)EMAC0_MR0, zmii);
}
return (eoffset);
@@ -243,19 +243,19 @@ unsigned int miiphy_getemac_offset(u8 addr)
switch (addr) {
#if defined(CONFIG_HAS_ETH1) && defined(CONFIG_GPCS_PHY1_ADDR)
case CONFIG_GPCS_PHY1_ADDR:
- if (addr == EMAC_M1_IPPA_GET(in_be32((void *)EMAC_M1 + 0x100)))
+ if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x100)))
eoffset = 0x100;
break;
#endif
#if defined(CONFIG_HAS_ETH2) && defined(CONFIG_GPCS_PHY2_ADDR)
case CONFIG_GPCS_PHY2_ADDR:
- if (addr == EMAC_M1_IPPA_GET(in_be32((void *)EMAC_M1 + 0x300)))
+ if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x300)))
eoffset = 0x300;
break;
#endif
#if defined(CONFIG_HAS_ETH3) && defined(CONFIG_GPCS_PHY3_ADDR)
case CONFIG_GPCS_PHY3_ADDR:
- if (addr == EMAC_M1_IPPA_GET(in_be32((void *)EMAC_M1 + 0x400)))
+ if (addr == EMAC_MR1_IPPA_GET(in_be32((void *)EMAC0_MR1 + 0x400)))
eoffset = 0x400;
break;
#endif
@@ -278,9 +278,9 @@ static int emac_miiphy_wait(u32 emac_reg)
/* wait for completion */
i = 0;
do {
- sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
+ sta_reg = in_be32((void *)EMAC0_STACR + emac_reg);
if (i++ > 5) {
- debug("%s [%d]: Timeout! EMAC_STACR=0x%0x\n", __func__,
+ debug("%s [%d]: Timeout! EMAC0_STACR=0x%0x\n", __func__,
__LINE__, sta_reg);
return -1;
}
@@ -324,7 +324,7 @@ static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value)
if (cmd == EMAC_STACR_WRITE)
memcpy(&sta_reg, &value, 2); /* put in data */
- out_be32((void *)EMAC_STACR + emac_reg, sta_reg);
+ out_be32((void *)EMAC0_STACR + emac_reg, sta_reg);
debug("%s [%d]: sta_reg=%08x\n", __func__, __LINE__, sta_reg);
/* wait for completion */
@@ -349,7 +349,7 @@ int emac4xx_miiphy_read (char *devname, unsigned char addr, unsigned char reg,
if (emac_miiphy_command(addr, reg, EMAC_STACR_READ, 0) != 0)
return -1;
- sta_reg = in_be32((void *)EMAC_STACR + emac_reg);
+ sta_reg = in_be32((void *)EMAC0_STACR + emac_reg);
*value = sta_reg >> 16;
return 0;
diff --git a/cpu/ppc4xx/reginfo.c b/cpu/ppc4xx/reginfo.c
new file mode 100644
index 0000000..a975667
--- /dev/null
+++ b/cpu/ppc4xx/reginfo.c
@@ -0,0 +1,370 @@
+/*
+ *(C) Copyright 2005-2009 Netstal Maschinen AG
+ * Bruno Hars (Bruno.Hars@netstal.com)
+ * Niklaus Giger (Niklaus.Giger@netstal.com)
+ *
+ * This source code is free software; you can redistribute it
+ * and/or modify it in source code form 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
+ */
+
+/*
+ * reginfo.c - register dump of HW-configuratin register for PPC4xx based board
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/ppc4xx-uic.h>
+#include <ppc4xx_enet.h>
+
+enum REGISTER_TYPE {
+ IDCR1, /* Indirectly Accessed DCR via SDRAM0_CFGADDR/SDRAM0_CFGDATA */
+ IDCR2, /* Indirectly Accessed DCR via EBC0_CFGADDR/EBC0_CFGDATA */
+ IDCR3, /* Indirectly Accessed DCR via EBM0_CFGADDR/EBM0_CFGDATA */
+ IDCR4, /* Indirectly Accessed DCR via PPM0_CFGADDR/PPM0_CFGDATA */
+ IDCR5, /* Indirectly Accessed DCR via CPR0_CFGADDR/CPR0_CFGDATA */
+ IDCR6, /* Indirectly Accessed DCR via SDR0_CFGADDR/SDR0_CFGDATA */
+ MM /* Directly Accessed MMIO Register */
+};
+
+struct cpu_register {
+ char *name;
+ enum REGISTER_TYPE type;
+ u32 address;
+};
+
+/*
+ * PPC440EPx registers ordered for output
+ * name type addr size
+ * -------------------------------------------
+ */
+
+const struct cpu_register ppc4xx_reg[] = {
+ {"PB0CR", IDCR2, PB0CR},
+ {"PB0AP", IDCR2, PB0AP},
+ {"PB1CR", IDCR2, PB1CR},
+ {"PB1AP", IDCR2, PB1AP},
+ {"PB2CR", IDCR2, PB2CR},
+ {"PB2AP", IDCR2, PB2AP},
+ {"PB3CR", IDCR2, PB3CR},
+ {"PB3AP", IDCR2, PB3AP},
+
+ {"PB4CR", IDCR2, PB4CR},
+ {"PB4AP", IDCR2, PB4AP},
+#if !defined(CONFIG_405EP)
+ {"PB5CR", IDCR2, PB5CR},
+ {"PB5AP", IDCR2, PB5AP},
+ {"PB6CR", IDCR2, PB6CR},
+ {"PB6AP", IDCR2, PB6AP},
+ {"PB7CR", IDCR2, PB7CR},
+ {"PB7AP", IDCR2, PB7AP},
+#endif
+
+ {"PBEAR", IDCR2, PBEAR},
+#if defined(CONFIG_405EP) || defined (CONFIG_405GP)
+ {"PBESR0", IDCR2, PBESR0},
+ {"PBESR1", IDCR2, PBESR1},
+#endif
+ {"EBC0_CFG", IDCR2, EBC0_CFG},
+
+#ifdef CONFIG_405GP
+ {"SDRAM0_BESR0", IDCR1, SDRAM0_BESR0},
+ {"SDRAM0_BESRS0", IDCR1, SDRAM0_BESRS0},
+ {"SDRAM0_BESR1", IDCR1, SDRAM0_BESR1},
+ {"SDRAM0_BESRS1", IDCR1, SDRAM0_BESRS1},
+ {"SDRAM0_BEAR", IDCR1, SDRAM0_BEAR},
+ {"SDRAM0_CFG", IDCR1, SDRAM0_CFG},
+ {"SDRAM0_RTR", IDCR1, SDRAM0_RTR},
+ {"SDRAM0_PMIT", IDCR1, SDRAM0_PMIT},
+
+ {"SDRAM0_B0CR", IDCR1, SDRAM0_B0CR},
+ {"SDRAM0_B1CR", IDCR1, SDRAM0_B1CR},
+ {"SDRAM0_B2CR", IDCR1, SDRAM0_B2CR},
+ {"SDRAM0_B3CR", IDCR1, SDRAM0_B1CR},
+ {"SDRAM0_TR", IDCR1, SDRAM0_TR},
+ {"SDRAM0_ECCCFG", IDCR1, SDRAM0_B1CR},
+ {"SDRAM0_ECCESR", IDCR1, SDRAM0_ECCESR},
+
+
+#endif
+
+#ifdef CONFIG_440EPX
+ {"SDR0_SDSTP0", IDCR6, SDR0_SDSTP0},
+ {"SDR0_SDSTP1", IDCR6, SDR0_SDSTP1},
+ {"SDR0_SDSTP2", IDCR6, SDR0_SDSTP2},
+ {"SDR0_SDSTP3", IDCR6, SDR0_SDSTP3},
+ {"SDR0_CUST0", IDCR6, SDR0_CUST0},
+ {"SDR0_CUST1", IDCR6, SDR0_CUST1},
+ {"SDR0_EBC0", IDCR6, SDR0_EBC0},
+ {"SDR0_AMP0", IDCR6, SD0_AMP0},
+ {"SDR0_AMP1", IDCR6, SD0_AMP1},
+ {"SDR0_CP440", IDCR6, SDR0_CP440},
+ {"SDR0_CRYP0", IDCR6, SDR0_CRYP0},
+ {"SDR0_DDRCFG", IDCR6, SDR0_DDRCFG},
+ {"SDR0_EMAC0RXST", IDCR6, SDR0_EMAC0RXST},
+ {"SDR0_EMAC0TXST", IDCR6, SDR0_EMAC0TXST},
+ {"SDR0_MFR", IDCR6, SDR0_MFR},
+ {"SDR0_PCI0", IDCR6, SDR0_PCI0},
+ {"SDR0_PFC0", IDCR6, SDR0_PFC0},
+ {"SDR0_PFC1", IDCR6, SDR0_PFC1},
+ {"SDR0_PFC2", IDCR6, SDR0_PFC2},
+ {"SDR0_PFC4", IDCR6, SDR0_PFC4},
+ {"SDR0_UART0", IDCR6, SDR0_UART0},
+ {"SDR0_UART1", IDCR6, SDR0_UART1},
+ {"SDR0_UART2", IDCR6, SDR0_UART2},
+ {"SDR0_UART3", IDCR6, SDR0_UART3},
+ {"DDR0_02", IDCR1, DDR0_02},
+ {"DDR0_00", IDCR1, DDR0_00},
+ {"DDR0_01", IDCR1, DDR0_01},
+ {"DDR0_03", IDCR1, DDR0_03},
+ {"DDR0_04", IDCR1, DDR0_04},
+ {"DDR0_05", IDCR1, DDR0_05},
+ {"DDR0_06", IDCR1, DDR0_06},
+ {"DDR0_07", IDCR1, DDR0_07},
+ {"DDR0_08", IDCR1, DDR0_08},
+ {"DDR0_09", IDCR1, DDR0_09},
+ {"DDR0_10", IDCR1, DDR0_10},
+ {"DDR0_11", IDCR1, DDR0_11},
+ {"DDR0_12", IDCR1, DDR0_12},
+ {"DDR0_14", IDCR1, DDR0_14},
+ {"DDR0_17", IDCR1, DDR0_17},
+ {"DDR0_18", IDCR1, DDR0_18},
+ {"DDR0_19", IDCR1, DDR0_19},
+ {"DDR0_20", IDCR1, DDR0_20},
+ {"DDR0_21", IDCR1, DDR0_21},
+ {"DDR0_22", IDCR1, DDR0_22},
+ {"DDR0_23", IDCR1, DDR0_23},
+ {"DDR0_24", IDCR1, DDR0_24},
+ {"DDR0_25", IDCR1, DDR0_25},
+ {"DDR0_26", IDCR1, DDR0_26},
+ {"DDR0_27", IDCR1, DDR0_27},
+ {"DDR0_28", IDCR1, DDR0_28},
+ {"DDR0_31", IDCR1, DDR0_31},
+ {"DDR0_32", IDCR1, DDR0_32},
+ {"DDR0_33", IDCR1, DDR0_33},
+ {"DDR0_34", IDCR1, DDR0_34},
+ {"DDR0_35", IDCR1, DDR0_35},
+ {"DDR0_36", IDCR1, DDR0_36},
+ {"DDR0_37", IDCR1, DDR0_37},
+ {"DDR0_38", IDCR1, DDR0_38},
+ {"DDR0_39", IDCR1, DDR0_39},
+ {"DDR0_40", IDCR1, DDR0_40},
+ {"DDR0_41", IDCR1, DDR0_41},
+ {"DDR0_42", IDCR1, DDR0_42},
+ {"DDR0_43", IDCR1, DDR0_43},
+ {"DDR0_44", IDCR1, DDR0_44},
+ {"CPR0_ICFG", IDCR5, CPR0_ICFG},
+ {"CPR0_MALD", IDCR5, CPR0_MALD},
+ {"CPR0_OPBD00", IDCR5, CPR0_OPBD0},
+ {"CPR0_PERD0", IDCR5, CPR0_PERD},
+ {"CPR0_PLLC0", IDCR5, CPR0_PLLC},
+ {"CPR0_PLLD0", IDCR5, CPR0_PLLD},
+ {"CPR0_PRIMAD0", IDCR5, CPR0_PRIMAD0},
+ {"CPR0_PRIMBD0", IDCR5, CPR0_PRIMBD0},
+ {"CPR0_SPCID", IDCR5, CPR0_SPCID},
+ {"SPI0_MODE", MM, SPI0_MODE},
+ {"IIC0_CLKDIV", MM, PCIL0_PMM1MA},
+ {"PCIL0_PMM0MA", MM, PCIL0_PMM0MA},
+ {"PCIL0_PMM1MA", MM, PCIL0_PMM1MA},
+ {"PCIL0_PTM1LA", MM, PCIL0_PMM1MA},
+ {"PCIL0_PTM1MS", MM, PCIL0_PTM1MS},
+ {"PCIL0_PTM2LA", MM, PCIL0_PMM1MA},
+ {"PCIL0_PTM2MS", MM, PCIL0_PTM2MS},
+ {"ZMII0_FER", MM, ZMII0_FER},
+ {"ZMII0_SSR", MM, ZMII0_SSR},
+ {"EMAC0_IPGVR", MM, EMAC0_IPGVR},
+ {"EMAC0_MR1", MM, EMAC0_MR1},
+ {"EMAC0_PTR", MM, EMAC0_PTR},
+ {"EMAC0_RWMR", MM, EMAC0_RWMR},
+ {"EMAC0_STACR", MM, EMAC0_STACR},
+ {"EMAC0_TMR0", MM, EMAC0_TMR0},
+ {"EMAC0_TMR1", MM, EMAC0_TMR1},
+ {"EMAC0_TRTR", MM, EMAC0_TRTR},
+ {"EMAC1_MR1", MM, EMAC1_MR1},
+ {"GPIO0_OR", MM, GPIO0_OR},
+ {"GPIO1_OR", MM, GPIO1_OR},
+ {"GPIO0_TCR", MM, GPIO0_TCR},
+ {"GPIO1_TCR", MM, GPIO1_TCR},
+ {"GPIO0_ODR", MM, GPIO0_ODR},
+ {"GPIO1_ODR", MM, GPIO1_ODR},
+ {"GPIO0_OSRL", MM, GPIO0_OSRL},
+ {"GPIO0_OSRH", MM, GPIO0_OSRH},
+ {"GPIO1_OSRL", MM, GPIO1_OSRL},
+ {"GPIO1_OSRH", MM, GPIO1_OSRH},
+ {"GPIO0_TSRL", MM, GPIO0_TSRL},
+ {"GPIO0_TSRH", MM, GPIO0_TSRH},
+ {"GPIO1_TSRL", MM, GPIO1_TSRL},
+ {"GPIO1_TSRH", MM, GPIO1_TSRH},
+ {"GPIO0_IR", MM, GPIO0_IR},
+ {"GPIO1_IR", MM, GPIO1_IR},
+ {"GPIO0_ISR1L", MM, GPIO0_ISR1L},
+ {"GPIO0_ISR1H", MM, GPIO0_ISR1H},
+ {"GPIO1_ISR1L", MM, GPIO1_ISR1L},
+ {"GPIO1_ISR1H", MM, GPIO1_ISR1H},
+ {"GPIO0_ISR2L", MM, GPIO0_ISR2L},
+ {"GPIO0_ISR2H", MM, GPIO0_ISR2H},
+ {"GPIO1_ISR2L", MM, GPIO1_ISR2L},
+ {"GPIO1_ISR2H", MM, GPIO1_ISR2H},
+ {"GPIO0_ISR3L", MM, GPIO0_ISR3L},
+ {"GPIO0_ISR3H", MM, GPIO0_ISR3H},
+ {"GPIO1_ISR3L", MM, GPIO1_ISR3L},
+ {"GPIO1_ISR3H", MM, GPIO1_ISR3H},
+ {"SDR0_USB2PHY0CR", IDCR6, SDR0_USB2PHY0CR},
+ {"SDR0_USB2H0CR", IDCR6, SDR0_USB2H0CR},
+ {"SDR0_USB2D0CR", IDCR6, SDR0_USB2D0CR},
+#endif
+};
+
+/*
+ * CPU Register dump of PPC4xx HW configuration registers
+ * Output: first all DCR-registers, then in order of struct ppc4xx_reg
+ */
+#define PRINT_DCR(dcr) printf("0x%08x %-16s: 0x%08x\n", dcr,#dcr, mfdcr(dcr));
+
+void ppc4xx_reginfo(void)
+{
+ unsigned int i;
+ unsigned int n;
+ u32 value;
+ enum REGISTER_TYPE type;
+#if defined (CONFIG_405EP)
+ printf("Dump PPC405EP HW configuration registers\n\n");
+#elif CONFIG_405GP
+ printf ("Dump 405GP HW configuration registers\n\n");
+#elif CONFIG_440EPX
+ printf("Dump PPC440EPx HW configuration registers\n\n");
+#endif
+ printf("MSR: 0x%08x\n", mfmsr());
+
+ printf ("\nUniversal Interrupt Controller Regs\n");
+ PRINT_DCR(UIC0SR);
+ PRINT_DCR(UIC0ER);
+ PRINT_DCR(UIC0CR);
+ PRINT_DCR(UIC0PR);
+ PRINT_DCR(UIC0TR);
+ PRINT_DCR(UIC0MSR);
+ PRINT_DCR(UIC0VR);
+ PRINT_DCR(UIC0VCR);
+
+#if (UIC_MAX > 1)
+ PRINT_DCR(UIC2SR);
+ PRINT_DCR(UIC2ER);
+ PRINT_DCR(UIC2CR);
+ PRINT_DCR(UIC2PR);
+ PRINT_DCR(UIC2TR);
+ PRINT_DCR(UIC2MSR);
+ PRINT_DCR(UIC2VR);
+ PRINT_DCR(UIC2VCR);
+#endif
+
+#if (UIC_MAX > 2)
+ PRINT_DCR(UIC2SR);
+ PRINT_DCR(UIC2ER);
+ PRINT_DCR(UIC2CR);
+ PRINT_DCR(UIC2PR);
+ PRINT_DCR(UIC2TR);
+ PRINT_DCR(UIC2MSR);
+ PRINT_DCR(UIC2VR);
+ PRINT_DCR(UIC2VCR);
+#endif
+
+#if (UIC_MAX > 3)
+ PRINT_DCR(UIC3SR);
+ PRINT_DCR(UIC3ER);
+ PRINT_DCR(UIC3CR);
+ PRINT_DCR(UIC3PR);
+ PRINT_DCR(UIC3TR);
+ PRINT_DCR(UIC3MSR);
+ PRINT_DCR(UIC3VR);
+ PRINT_DCR(UIC3VCR);
+#endif
+
+#if defined (CONFIG_405EP) || defined (CONFIG_405GP)
+ printf ("\n\nDMA Channels\n");
+ PRINT_DCR(DMASR);
+ PRINT_DCR(DMASGC);
+ PRINT_DCR(DMAADR);
+
+ PRINT_DCR(DMACR0);
+ PRINT_DCR(DMACT0);
+ PRINT_DCR(DMADA0);
+ PRINT_DCR(DMASA0);
+ PRINT_DCR(DMASB0);
+
+ PRINT_DCR(DMACR1);
+ PRINT_DCR(DMACT1);
+ PRINT_DCR(DMADA1);
+ PRINT_DCR(DMASA1);
+ PRINT_DCR(DMASB1);
+
+ PRINT_DCR(DMACR2);
+ PRINT_DCR(DMACT2);
+ PRINT_DCR(DMADA2);
+ PRINT_DCR(DMASA2);
+ PRINT_DCR(DMASB2);
+
+ PRINT_DCR(DMACR3);
+ PRINT_DCR(DMACT3);
+ PRINT_DCR(DMADA3);
+ PRINT_DCR(DMASA3);
+ PRINT_DCR(DMASB3);
+#endif
+
+ printf ("\n\nVarious HW-Configuration registers\n");
+#if defined (CONFIG_440EPX)
+ PRINT_DCR(MAL0_CFG);
+ PRINT_DCR(CPM0_ER);
+ PRINT_DCR(CPM1_ER);
+ PRINT_DCR(PLB4A0_ACR);
+ PRINT_DCR(PLB4A1_ACR);
+ PRINT_DCR(PLB3A0_ACR);
+ PRINT_DCR(OPB2PLB40_BCTRL);
+ PRINT_DCR(P4P3BO0_CFG);
+#endif
+ n = sizeof(ppc4xx_reg) / sizeof(ppc4xx_reg[0]);
+ for (i = 0; i < n; i++) {
+ value = 0;
+ type = ppc4xx_reg[i].type;
+ switch (type) {
+ case IDCR1: /* Indirect via SDRAM0_CFGADDR/DDR0_CFGDATA */
+ mtdcr(SDRAM0_CFGADDR, ppc4xx_reg[i].address);
+ value = mfdcr(SDRAM0_CFGDATA);
+ break;
+ case IDCR2: /* Indirect via EBC0_CFGADDR/EBC0_CFGDATA */
+ mtdcr(EBC0_CFGADDR, ppc4xx_reg[i].address);
+ value = mfdcr(EBC0_CFGDATA);
+ break;
+ case IDCR5: /* Indirect via CPR0_CFGADDR/CPR0_CFGDATA */
+ mtdcr(CPR0_CFGADDR, ppc4xx_reg[i].address);
+ value = mfdcr(CPR0_CFGDATA);
+ break;
+ case IDCR6: /* Indirect via SDR0_CFGADDR/SDR0_CFGDATA */
+ mtdcr(SDR0_CFGADDR, ppc4xx_reg[i].address);
+ value = mfdcr(SDR0_CFGDATA);
+ break;
+ case MM: /* Directly Accessed MMIO Register */
+ value = in_be32((const volatile unsigned __iomem *)
+ ppc4xx_reg[i].address);
+ break;
+ default:
+ printf("\nERROR: struct entry %d: unknown register"
+ "type\n", i);
+ break;
+ }
+ printf("0x%08x %-16s: 0x%08x\n",ppc4xx_reg[i].address,
+ ppc4xx_reg[i].name, value);
+ }
+}
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index 988ba97..906face 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -334,7 +334,7 @@ void get_sys_info (sys_info_t *sysInfo)
sysInfo->pllFbkDiv = temp ? temp : 32;
lfdiv = reg & PLLD_LFBDV_MASK;
- mfcpr(CPR0_OPBD, reg);
+ mfcpr(CPR0_OPBD0, reg);
temp = (reg & OPBDDV_MASK) >> 24;
sysInfo->pllOpbDiv = temp ? temp : 4;
@@ -342,7 +342,7 @@ void get_sys_info (sys_info_t *sysInfo)
temp = (reg & PERDV_MASK) >> 24;
sysInfo->pllExtBusDiv = temp ? temp : 8;
- mfcpr(CPR0_PRIMBD, reg);
+ mfcpr(CPR0_PRIMBD0, reg);
temp = (reg & PRBDV_MASK) >> 24;
prbdv0 = temp ? temp : 8;
@@ -1050,7 +1050,7 @@ void get_sys_info (sys_info_t * sysInfo)
/*
* Determine OPBDV0
*/
- mfcpr(CPR0_OPBD, tmp);
+ mfcpr(CPR0_OPBD0, tmp);
tmp = (tmp >> 24) & 0x03;
sysInfo->pllOpbDiv = (tmp == 0) ? 4 : tmp;