summaryrefslogtreecommitdiff
path: root/cpu/ppc4xx
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/ppc4xx')
-rw-r--r--cpu/ppc4xx/44x_spd_ddr.c31
-rw-r--r--cpu/ppc4xx/44x_spd_ddr2.c72
-rw-r--r--cpu/ppc4xx/i2c.c2
-rw-r--r--cpu/ppc4xx/start.S64
4 files changed, 103 insertions, 66 deletions
diff --git a/cpu/ppc4xx/44x_spd_ddr.c b/cpu/ppc4xx/44x_spd_ddr.c
index 32d44db..10b4c18 100644
--- a/cpu/ppc4xx/44x_spd_ddr.c
+++ b/cpu/ppc4xx/44x_spd_ddr.c
@@ -46,6 +46,7 @@
#include <asm/processor.h>
#include <i2c.h>
#include <ppc4xx.h>
+#include <asm/mmu.h>
#if defined(CONFIG_SPD_EEPROM) && \
(defined(CONFIG_440GP) || defined(CONFIG_440GX) || \
@@ -229,6 +230,22 @@
#define TRUE 1
#define FALSE 0
+/*
+ * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
+ * region. Right now the cache should still be disabled in U-Boot because of the
+ * EMAC driver, that need it's buffer descriptor to be located in non cached
+ * memory.
+ *
+ * If at some time this restriction doesn't apply anymore, just define
+ * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
+ * everything correctly.
+ */
+#ifdef CFG_ENABLE_SDRAM_CACHE
+#define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */
+#else
+#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
+#endif
+
const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
{0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF},
@@ -259,6 +276,7 @@ typedef struct bank_param BANKPARMS;
#ifdef CFG_SIMULATE_SPD_EEPROM
extern unsigned char cfg_simulate_spd_eeprom[128];
#endif
+void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
unsigned char spd_read(uchar chip, uint addr);
@@ -377,6 +395,11 @@ long int spd_sdram(void) {
total_size = program_bxcr(dimm_populated, iic0_dimm_addr,
num_dimm_banks);
+#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
+ /* and program tlb entries for this size (dynamic) */
+ program_tlb(0, total_size, MY_TLB_WORD2_I_ENABLE);
+#endif
+
/*
* program SDRAM Clock Timing Register (SDRAM0_CLKTR)
*/
@@ -1330,11 +1353,11 @@ unsigned long program_bxcr(unsigned long* dimm_populated,
*/
cr |= SDRAM_BXCR_SDBE;
- for (i = 0; i < num_banks; i++) {
- bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
+ for (i = 0; i < num_banks; i++) {
+ bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].bank_size_bytes =
(4 * 1024 * 1024) * bank_size_id;
- bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
- }
+ bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].cr = cr;
+ }
}
}
diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c
index 35b2315..83c9911 100644
--- a/cpu/ppc4xx/44x_spd_ddr2.c
+++ b/cpu/ppc4xx/44x_spd_ddr2.c
@@ -168,8 +168,8 @@ static void program_codt(unsigned long *dimm_populated,
static void program_mode(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks,
- ddr_cas_id_t *selected_cas,
- int *write_recovery);
+ ddr_cas_id_t *selected_cas,
+ int *write_recovery);
static void program_tr(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks);
@@ -185,9 +185,10 @@ static void program_copt1(unsigned long *dimm_populated,
static void program_initplr(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks,
- ddr_cas_id_t selected_cas,
+ 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,
@@ -195,6 +196,7 @@ static void program_ecc(unsigned long *dimm_populated,
static void program_ecc_addr(unsigned long start_address,
unsigned long num_bytes,
unsigned long tlb_word2_i_value);
+#endif
static void program_DQS_calibration(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks);
@@ -255,15 +257,6 @@ static void mtdcr_any(u32 dcr, u32 val)
}
}
-static void wait_ddr_idle(void)
-{
- u32 val;
-
- do {
- mfsdram(SDRAM_MCSTAT, val);
- } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT);
-}
-
static unsigned char spd_read(uchar chip, uint addr)
{
unsigned char data[2];
@@ -491,7 +484,7 @@ long int initdram(int board_type)
(val & ~(SDRAM_MEMODE_DIC_MASK | SDRAM_MEMODE_DLL_MASK |
SDRAM_MEMODE_RTT_MASK | SDRAM_MEMODE_DQS_MASK)) |
(SDRAM_MEMODE_DIC_NORMAL | SDRAM_MEMODE_DLL_ENABLE
- | SDRAM_MEMODE_RTT_75OHM | SDRAM_MEMODE_DQS_ENABLE));
+ | SDRAM_MEMODE_RTT_150OHM | SDRAM_MEMODE_DQS_ENABLE));
/*------------------------------------------------------------------
* Program Initialization preload registers.
@@ -537,10 +530,12 @@ long int initdram(int board_type)
*-----------------------------------------------------------------*/
program_DQS_calibration(dimm_populated, iic0_dimm_addr, num_dimm_banks);
+#ifdef CONFIG_DDR_ECC
/*------------------------------------------------------------------
* If ecc is enabled, initialize the parity bits.
*-----------------------------------------------------------------*/
program_ecc(dimm_populated, iic0_dimm_addr, num_dimm_banks, MY_TLB_WORD2_I_ENABLE);
+#endif
#ifdef DEBUG
ppc440sp_sdram_register_dump();
@@ -702,7 +697,7 @@ static void check_frequency(unsigned long *dimm_populated,
*-----------------------------------------------------------------*/
get_sys_info(&board_cfg);
- mfsdr(sdr_ddr0, sdr_ddrpll);
+ mfsdr(SDR0_DDR0, sdr_ddrpll);
sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
/*
@@ -877,7 +872,11 @@ static void program_copt1(unsigned long *dimm_populated,
unsigned long ddrtype;
unsigned long val;
+#ifdef CONFIG_DDR_ECC
ecc_enabled = TRUE;
+#else
+ ecc_enabled = FALSE;
+#endif
dimm_32bit = FALSE;
dimm_64bit = FALSE;
buf0 = FALSE;
@@ -1149,7 +1148,7 @@ static void program_codt(unsigned long *dimm_populated,
static void program_initplr(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks,
- ddr_cas_id_t selected_cas,
+ ddr_cas_id_t selected_cas,
int write_recovery)
{
u32 cas = 0;
@@ -1314,7 +1313,7 @@ static void program_mode(unsigned long *dimm_populated,
*-----------------------------------------------------------------*/
get_sys_info(&board_cfg);
- mfsdr(sdr_ddr0, sdr_ddrpll);
+ mfsdr(SDR0_DDR0, sdr_ddrpll);
sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1);
/*------------------------------------------------------------------
@@ -1463,11 +1462,12 @@ static void program_mode(unsigned long *dimm_populated,
mfsdram(SDRAM_MMODE, mmode);
mmode = mmode & ~(SDRAM_MMODE_WR_MASK | SDRAM_MMODE_DCL_MASK);
- cycle_2_0_clk = MULDIV64(ONE_BILLION, 100, max_2_0_tcyc_ns_x_100);
- cycle_2_5_clk = MULDIV64(ONE_BILLION, 100, max_2_5_tcyc_ns_x_100);
- cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100);
- cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100);
- cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100);
+ /* add 10 here because of rounding problems */
+ cycle_2_0_clk = MULDIV64(ONE_BILLION, 100, max_2_0_tcyc_ns_x_100) + 10;
+ cycle_2_5_clk = MULDIV64(ONE_BILLION, 100, max_2_5_tcyc_ns_x_100) + 10;
+ cycle_3_0_clk = MULDIV64(ONE_BILLION, 100, max_3_0_tcyc_ns_x_100) + 10;
+ cycle_4_0_clk = MULDIV64(ONE_BILLION, 100, max_4_0_tcyc_ns_x_100) + 10;
+ cycle_5_0_clk = MULDIV64(ONE_BILLION, 100, max_5_0_tcyc_ns_x_100) + 10;
if (sdram_ddr1 == TRUE) { /* DDR1 */
if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) {
@@ -1498,7 +1498,11 @@ static void program_mode(unsigned long *dimm_populated,
} else {
printf("ERROR: Cannot find a supported CAS latency with the installed DIMMs.\n");
printf("Only DIMMs DDR2 with CAS latencies of 3.0, 4.0, and 5.0 are supported.\n");
- printf("Make sure the PLB speed is within the supported range of the DIMMs.\n\n");
+ printf("Make sure the PLB speed is within the supported range of the DIMMs.\n");
+ printf("cas3=%d cas4=%d cas5=%d\n",
+ cas_3_0_available, cas_4_0_available, cas_5_0_available);
+ printf("sdram_freq=%d cycle3=%d cycle4=%d cycle5=%d\n\n",
+ sdram_freq, cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk);
hang();
}
}
@@ -1575,7 +1579,7 @@ static void program_rtr(unsigned long *dimm_populated,
/*------------------------------------------------------------------
* Set the SDRAM Refresh Timing Register, SDRAM_RTR
*-----------------------------------------------------------------*/
- mfsdr(sdr_ddr0, sdr_ddrpll);
+ mfsdr(SDR0_DDR0, sdr_ddrpll);
sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
max_refresh_rate = 0;
@@ -1661,7 +1665,7 @@ static void program_tr(unsigned long *dimm_populated,
*-----------------------------------------------------------------*/
get_sys_info(&board_cfg);
- mfsdr(sdr_ddr0, sdr_ddrpll);
+ mfsdr(SDR0_DDR0, sdr_ddrpll);
sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll));
/*------------------------------------------------------------------
@@ -2069,7 +2073,7 @@ static void program_memory_queue(unsigned long *dimm_populated,
* Set the sizes
*-----------------------------------------------------------------*/
baseadd_size = 0;
- rank_size_bytes = 1024 * 1024 * rank_size_id;
+ rank_size_bytes = 4 * 1024 * 1024 * rank_size_id;
switch (rank_size_id) {
case 0x02:
baseadd_size |= SDRAM_RXBAS_SDSZ_8;
@@ -2106,8 +2110,8 @@ static void program_memory_queue(unsigned long *dimm_populated,
for (i = 0; i < num_ranks; i++) {
mtdcr_any(rank_reg+i+dimm_num+bank_0_populated,
- (rank_base_addr & SDRAM_RXBAS_SDBA_MASK) |
- baseadd_size);
+ (SDRAM_RXBAS_SDBA_ENCODE(rank_base_addr) |
+ baseadd_size));
rank_base_addr += rank_size_bytes;
}
}
@@ -2130,9 +2134,10 @@ static unsigned long is_ecc_enabled(void)
ecc = max(ecc, SDRAM_MCOPT1_MCHK_CHK_DECODE(val));
}
- return(ecc);
+ return ecc;
}
+#ifdef CONFIG_DDR_ECC
/*-----------------------------------------------------------------------------+
* program_ecc.
*-----------------------------------------------------------------------------*/
@@ -2208,6 +2213,15 @@ static void check_ecc(void)
}
#endif
+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.
*-----------------------------------------------------------------------------*/
@@ -2276,6 +2290,7 @@ static void program_ecc_addr(unsigned long start_address,
#endif
}
}
+#endif
/*-----------------------------------------------------------------------------+
* program_DQS_calibration.
@@ -2531,7 +2546,6 @@ static void DQS_calibration_process(void)
}
} /* for rffd */
-
/*------------------------------------------------------------------
* Set the average RFFD value
*-----------------------------------------------------------------*/
diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c
index 0b056a1..8f4da86 100644
--- a/cpu/ppc4xx/i2c.c
+++ b/cpu/ppc4xx/i2c.c
@@ -460,6 +460,7 @@ int i2c_set_bus_num(unsigned int bus)
return 0;
}
+#endif /* CONFIG_I2C_MULTI_BUS */
/* TODO: add 100/400k switching */
unsigned int i2c_get_bus_speed(void)
@@ -474,5 +475,4 @@ int i2c_set_bus_speed(unsigned int speed)
return 0;
}
-#endif /* CONFIG_I2C_MULTI_BUS */
#endif /* CONFIG_HARD_I2C */
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index de45ba7..3b1586c 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -1395,7 +1395,7 @@ ppcSync:
relocate_code:
#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
- defined(CONFIG_440SPE)
+ defined(CONFIG_440SP) || defined(CONFIG_440SPE)
/*
* On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
* to speed up the boot process. Now this cache needs to be disabled.
@@ -1950,43 +1950,43 @@ pll_wait:
/*----------------------------------------------------------------------------+
| dcbz_area.
+----------------------------------------------------------------------------*/
- function_prolog(dcbz_area)
- rlwinm. r5,r4,0,27,31
- rlwinm r5,r4,27,5,31
- beq ..d_ra2
- addi r5,r5,0x0001
+ function_prolog(dcbz_area)
+ rlwinm. r5,r4,0,27,31
+ rlwinm r5,r4,27,5,31
+ beq ..d_ra2
+ addi r5,r5,0x0001
..d_ra2:mtctr r5
..d_ag2:dcbz r0,r3
- addi r3,r3,32
- bdnz ..d_ag2
- sync
- blr
- function_epilog(dcbz_area)
+ addi r3,r3,32
+ bdnz ..d_ag2
+ sync
+ blr
+ function_epilog(dcbz_area)
/*----------------------------------------------------------------------------+
| dflush. Assume 32K at vector address is cachable.
+----------------------------------------------------------------------------*/
- function_prolog(dflush)
- mfmsr r9
- rlwinm r8,r9,0,15,13
- rlwinm r8,r8,0,17,15
- mtmsr r8
- addi r3,r0,0x0000
- mtspr dvlim,r3
- mfspr r3,ivpr
- addi r4,r0,1024
- mtctr r4
+ function_prolog(dflush)
+ mfmsr r9
+ rlwinm r8,r9,0,15,13
+ rlwinm r8,r8,0,17,15
+ mtmsr r8
+ addi r3,r0,0x0000
+ mtspr dvlim,r3
+ mfspr r3,ivpr
+ addi r4,r0,1024
+ mtctr r4
..dflush_loop:
- lwz r6,0x0(r3)
- addi r3,r3,32
- bdnz ..dflush_loop
- addi r3,r3,-32
- mtctr r4
+ lwz r6,0x0(r3)
+ addi r3,r3,32
+ bdnz ..dflush_loop
+ addi r3,r3,-32
+ mtctr r4
..ag: dcbf r0,r3
- addi r3,r3,-32
- bdnz ..ag
- sync
- mtmsr r9
- blr
- function_epilog(dflush)
+ addi r3,r3,-32
+ bdnz ..ag
+ sync
+ mtmsr r9
+ blr
+ function_epilog(dflush)
#endif /* CONFIG_440 */