X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cpu%2Fppc4xx%2F44x_spd_ddr2.c;h=2ecd3e4b61011cc553675580d99ab530e879fa56;hb=2be1bab6a7dc1d1c9ee1e3ca53ff9f011136f1fe;hp=83c991116f81a843f6eb4ea214ed06ab194221c6;hpb=37896293bc991bddb75ccac887b54e9a61f36320;p=oweals%2Fu-boot.git diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index 83c991116f..2ecd3e4b61 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -107,10 +107,11 @@ #define CALC_ODT_RW(n) (CALC_ODT_R(n) | CALC_ODT_W(n)) /* Defines for the Read Cycle Delay test */ -#define NUMMEMTESTS 8 -#define NUMMEMWORDS 8 +#define NUMMEMTESTS 8 +#define NUMMEMWORDS 8 +#define NUMLOOPS 256 /* memory test loops */ -#define CONFIG_ECC_ERROR_RESET /* test-only: see description below, at check_ecc() */ +#undef CONFIG_ECC_ERROR_RESET /* test-only: see description below, at check_ecc() */ /* * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory @@ -584,10 +585,23 @@ static void get_spd_info(unsigned long *dimm_populated, #ifdef CONFIG_ADD_RAM_INFO void board_add_ram_info(int use_default) { + PPC440_SYS_INFO board_cfg; + u32 val; + if (is_ecc_enabled()) - puts(" (ECC enabled)"); + puts(" (ECC"); else - puts(" (ECC not enabled)"); + 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); } #endif @@ -731,6 +745,7 @@ static void check_frequency(unsigned long *dimm_populated, else cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + ((tcyc_reg & 0x0F)*10); + debug("cycle_time=%d [10 picoseconds]\n", cycle_time); if (cycle_time > (calc_cycle_time + 10)) { /* @@ -1109,7 +1124,7 @@ static void program_codt(unsigned long *dimm_populated, modt3 = 0x00000000; } } - } else { + } else { codt |= SDRAM_CODT_DQS_2_5_V_DDR1; modt0 = 0x00000000; modt1 = 0x00000000; @@ -1315,6 +1330,7 @@ static void program_mode(unsigned long *dimm_populated, mfsdr(SDR0_DDR0, sdr_ddrpll); sdram_freq = MULDIV64((board_cfg.freqPLB), SDR0_DDR0_DDRM_DECODE(sdr_ddrpll), 1); + debug("sdram_freq=%d\n", sdram_freq); /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all @@ -1344,6 +1360,7 @@ static void program_mode(unsigned long *dimm_populated, /* t_wr_ns = max(t_wr_ns, (unsigned long)dimm_spd[dimm_num][36] >> 2); */ /* not used in this loop. */ cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); + debug("cas_bit[SPD byte 18]=%02x\n", cas_bit); /* For a particular DIMM, grab the three CAS values it supports */ for (cas_index = 0; cas_index < 3; cas_index++) { @@ -1362,7 +1379,8 @@ static void program_mode(unsigned long *dimm_populated, if ((tcyc_reg & 0x0F) >= 10) { if ((tcyc_reg & 0x0F) == 0x0D) { /* Convert from hex to decimal */ - cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + 75; + cycle_time_ns_x_100[cas_index] = + (((tcyc_reg & 0xF0) >> 4) * 100) + 75; } else { printf("ERROR: SPD reported Tcyc is incorrect for DIMM " "in slot %d\n", (unsigned int)dimm_num); @@ -1370,9 +1388,12 @@ static void program_mode(unsigned long *dimm_populated, } } else { /* Convert from hex to decimal */ - cycle_time_ns_x_100[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 100) + + cycle_time_ns_x_100[cas_index] = + (((tcyc_reg & 0xF0) >> 4) * 100) + ((tcyc_reg & 0x0F)*10); } + debug("cas_index=%d: cycle_time_ns_x_100=%d\n", cas_index, + cycle_time_ns_x_100[cas_index]); } /* The rest of this routine determines if CAS 2.0, 2.5, 3.0, 4.0 and 5.0 are */ @@ -1385,8 +1406,10 @@ static void program_mode(unsigned long *dimm_populated, * Bit 7 6 5 4 3 2 1 0 * TBD 4.0 3.5 3.0 2.5 2.0 1.5 1.0 */ - if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x40) == 0x40) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1394,8 +1417,10 @@ static void program_mode(unsigned long *dimm_populated, cas_4_0_available = FALSE; } - if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1403,8 +1428,10 @@ static void program_mode(unsigned long *dimm_populated, cas_3_0_available = FALSE; } - if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_2_5_tcyc_ns_x_100 = max(max_2_5_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1412,8 +1439,10 @@ static void program_mode(unsigned long *dimm_populated, cas_2_5_available = FALSE; } - if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x04) == 0x04) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_2_0_tcyc_ns_x_100 = max(max_2_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1426,8 +1455,10 @@ static void program_mode(unsigned long *dimm_populated, * Bit 7 6 5 4 3 2 1 0 * TBD 6.0 5.0 4.0 3.0 2.0 TBD TBD */ - if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x20) == 0x20) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_5_0_tcyc_ns_x_100 = max(max_5_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1435,8 +1466,10 @@ static void program_mode(unsigned long *dimm_populated, cas_5_0_available = FALSE; } - if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x10) == 0x10) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_4_0_tcyc_ns_x_100 = max(max_4_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1444,8 +1477,10 @@ static void program_mode(unsigned long *dimm_populated, cas_4_0_available = FALSE; } - if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && (cycle_time_ns_x_100[cas_index] != 0)) { - max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, cycle_time_ns_x_100[cas_index]); + if (((cas_bit & 0x08) == 0x08) && (cas_index < 3) && + (cycle_time_ns_x_100[cas_index] != 0)) { + max_3_0_tcyc_ns_x_100 = max(max_3_0_tcyc_ns_x_100, + cycle_time_ns_x_100[cas_index]); cas_index++; } else { if (cas_index != 0) @@ -1468,6 +1503,9 @@ static void program_mode(unsigned long *dimm_populated, 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; + debug("cycle_3_0_clk=%d\n", cycle_3_0_clk); + debug("cycle_4_0_clk=%d\n", cycle_4_0_clk); + debug("cycle_5_0_clk=%d\n", cycle_5_0_clk); if (sdram_ddr1 == TRUE) { /* DDR1 */ if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) { @@ -1486,6 +1524,9 @@ static void program_mode(unsigned long *dimm_populated, hang(); } } else { /* DDR2 */ + debug("cas_3_0_available=%d\n", cas_3_0_available); + debug("cas_4_0_available=%d\n", cas_4_0_available); + debug("cas_5_0_available=%d\n", cas_5_0_available); if ((cas_3_0_available == TRUE) && (sdram_freq <= cycle_3_0_clk)) { mmode |= SDRAM_MMODE_DCL_DDR2_3_0_CLK; *selected_cas = DDR_CAS_3; @@ -2137,6 +2178,18 @@ static unsigned long is_ecc_enabled(void) return ecc; } +static void blank_string(int size) +{ + int i; + + for (i=0; i> 1); + /*------------------------------------------------------------------ * Make sure we found the valid read passing window. Halt if not *-----------------------------------------------------------------*/ if (window_found == FALSE) { - printf("ERROR: Cannot determine a common read delay for the " + if (rqfd_start < SDRAM_RQDC_RQFD_MAX) { + putc('\b'); + putc(slash[loopi++ % 8]); + + /* try again from with a different RQFD start value */ + rqfd_start++; + goto calibration_loop; + } + + printf("\nERROR: Cannot determine a common read delay for the " "DIMM(s) installed.\n"); debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__); hang(); } - rqfd_average = ((max_start + max_end) >> 1); + blank_string(strlen(str)); if (rqfd_average < 0) rqfd_average = 0; @@ -2630,12 +2699,6 @@ static void DQS_calibration_process(void) if (rqfd_average > SDRAM_RQDC_RQFD_MAX) rqfd_average = SDRAM_RQDC_RQFD_MAX; - /*------------------------------------------------------------------ - * Restore the ECC variable to what it originally was - *-----------------------------------------------------------------*/ - mfsdram(SDRAM_MCOPT1, val); - mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | ecc_temp); - mtsdram(SDRAM_RQDC, (rqdc_reg & ~SDRAM_RQDC_RQFD_MASK) | SDRAM_RQDC_RQFD_ENCODE(rqfd_average));