X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cpu%2Fppc4xx%2F44x_spd_ddr2.c;h=2ab23365a537e8c53702313fcd43eca6322613f2;hb=9b1b8c8a1bf52e9b65e1958e5205838576066cbc;hp=ec1765e171c39f0ea8fcdd2d123567495c44ea6d;hpb=4b326101d6cfaeab8250988bc4c7f51e6c92d719;p=oweals%2Fu-boot.git diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index ec1765e171..2ab23365a5 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -60,7 +60,33 @@ "SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \ } while (0) -static inline void ppc4xx_ibm_ddr2_register_dump(void); +#define PPC4xx_IBM_DDR2_DUMP_MQ_REGISTER(mnemonic) \ + do { \ + u32 data; \ + data = mfdcr(SDRAM_##mnemonic); \ + printf("%20s[%02x] = 0x%08X\n", \ + "SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \ + } while (0) + +#if defined(CONFIG_440) +/* + * 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 its buffer descriptor to be located + * in non cached memory. + * + * If at some time this restriction doesn't apply anymore, just define + * CONFIG_4xx_DCACHE in the board config file and this code should setup + * everything correctly. + */ +#ifdef CONFIG_4xx_DCACHE +/* enable caching on SDRAM */ +#define MY_TLB_WORD2_I_ENABLE 0 +#else +/* disable caching on SDRAM */ +#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE +#endif /* CONFIG_4xx_DCACHE */ +#endif /* CONFIG_440 */ #if defined(CONFIG_SPD_EEPROM) @@ -118,6 +144,7 @@ static inline void ppc4xx_ibm_ddr2_register_dump(void); #define ODS_FULL 0x00000000 #define ODS_REDUCED 0x00000002 +#define OCD_CALIB_DEF 0x00000380 /* defines for ODT (On Die Termination) of the 440SP(e) DDR2 controller */ #define ODT_EB0R (0x80000000 >> 8) @@ -131,22 +158,6 @@ static inline void ppc4xx_ibm_ddr2_register_dump(void); #define NUMMEMWORDS 8 #define NUMLOOPS 64 /* memory test loops */ -/* - * 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 - * CONFIG_4xx_DCACHE in the board config file and this code should setup - * everything correctly. - */ -#ifdef CONFIG_4xx_DCACHE -#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 - /* * Newer PPC's like 440SPe, 460EX/GT can be equipped with more than 2GB of SDRAM. * To support such configurations, we "only" map the first 2GB via the TLB's. We @@ -157,9 +168,6 @@ static inline void ppc4xx_ibm_ddr2_register_dump(void); * SDRAM. This is because we only map the first 2GB on such systems, and therefore * the ECC parity byte of the remaining area can't be written. */ -#ifndef CONFIG_MAX_MEM_MAPPED -#define CONFIG_MAX_MEM_MAPPED ((phys_size_t)2 << 30) -#endif /* * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed @@ -259,62 +267,19 @@ 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, - unsigned char *iic0_dimm_addr, - unsigned long num_dimm_banks); + unsigned char *iic0_dimm_addr, + unsigned long num_dimm_banks); #ifdef HARD_CODED_DQS /* calibration test with hardvalues */ static void test(void); #else 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 u32 mfdcr_any(u32 dcr) -{ - u32 val; - - switch (dcr) { - case SDRAM_R0BAS + 0: - val = mfdcr(SDRAM_R0BAS + 0); - break; - case SDRAM_R0BAS + 1: - val = mfdcr(SDRAM_R0BAS + 1); - break; - case SDRAM_R0BAS + 2: - val = mfdcr(SDRAM_R0BAS + 2); - break; - case SDRAM_R0BAS + 3: - val = mfdcr(SDRAM_R0BAS + 3); - break; - default: - printf("DCR %d not defined in case statement!!!\n", dcr); - val = 0; /* just to satisfy the compiler */ - } - - return val; -} - -static void mtdcr_any(u32 dcr, u32 val) -{ - switch (dcr) { - case SDRAM_R0BAS + 0: - mtdcr(SDRAM_R0BAS + 0, val); - break; - case SDRAM_R0BAS + 1: - mtdcr(SDRAM_R0BAS + 1, val); - break; - case SDRAM_R0BAS + 2: - mtdcr(SDRAM_R0BAS + 2, val); - break; - case SDRAM_R0BAS + 3: - mtdcr(SDRAM_R0BAS + 3, val); - break; - default: - printf("DCR %d not defined in case statement!!!\n", dcr); - } -} - static unsigned char spd_read(uchar chip, uint addr) { unsigned char data[2]; @@ -446,8 +411,8 @@ phys_size_t initdram(int board_type) */ /* switch to correct I2C bus */ - I2C_SET_BUS(CFG_SPD_BUS_NUM); - i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); + I2C_SET_BUS(CONFIG_SYS_SPD_BUS_NUM); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); /*------------------------------------------------------------------ * Clear out the serial presence detect buffers. @@ -570,15 +535,24 @@ phys_size_t initdram(int board_type) mtsdram(SDRAM_MCOPT2, (val & ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_DCEN_MASK | SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_ISIE_MASK)) | - (SDRAM_MCOPT2_DCEN_ENABLE | SDRAM_MCOPT2_IPTR_EXECUTE)); + SDRAM_MCOPT2_IPTR_EXECUTE); /*------------------------------------------------------------------ - * Wait for SDRAM_CFG0_DC_EN to complete. + * Wait for IPTR_EXECUTE init sequence to complete. *-----------------------------------------------------------------*/ do { mfsdram(SDRAM_MCSTAT, val); } while ((val & SDRAM_MCSTAT_MIC_MASK) == SDRAM_MCSTAT_MIC_NOTCOMP); + /* enable the controller only after init sequence completes */ + mfsdram(SDRAM_MCOPT2, val); + mtsdram(SDRAM_MCOPT2, (val | SDRAM_MCOPT2_DCEN_ENABLE)); + + /* Make sure delay-line calibration is done before proceeding */ + do { + mfsdram(SDRAM_DLCR, val); + } while (!(val & SDRAM_DLCR_DLCS_COMPLETE)); + /* get installed memory size */ dram_size = sdram_memsize(); @@ -599,7 +573,11 @@ phys_size_t initdram(int board_type) /*------------------------------------------------------------------ * DQS calibration. *-----------------------------------------------------------------*/ +#if defined(CONFIG_PPC4xx_DDR_AUTOCALIBRATION) + DQS_autocalibration(); +#else program_DQS_calibration(dimm_populated, iic0_dimm_addr, num_dimm_banks); +#endif #ifdef CONFIG_DDR_ECC /*------------------------------------------------------------------ @@ -744,11 +722,11 @@ static void check_mem_type(unsigned long *dimm_populated, spd_ddr_init_hang (); break; case 7: - debug("DIMM slot %d: DDR1 SDRAM detected\n", dimm_num); + debug("DIMM slot %lu: DDR1 SDRAM detected\n", dimm_num); dimm_populated[dimm_num] = SDRAM_DDR1; break; case 8: - debug("DIMM slot %d: DDR2 SDRAM detected\n", dimm_num); + debug("DIMM slot %lu: DDR2 SDRAM detected\n", dimm_num); dimm_populated[dimm_num] = SDRAM_DDR2; break; default: @@ -826,7 +804,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); + debug("cycle_time=%lu [10 picoseconds]\n", cycle_time); if (cycle_time > (calc_cycle_time + 10)) { /* @@ -1131,11 +1109,8 @@ static void program_codt(unsigned long *dimm_populated, * Set the SDRAM Controller On Die Termination Register *-----------------------------------------------------------------*/ mfsdram(SDRAM_CODT, codt); - codt |= (SDRAM_CODT_IO_NMODE - & (~SDRAM_CODT_DQS_SINGLE_END - & ~SDRAM_CODT_CKSE_SINGLE_END - & ~SDRAM_CODT_FEEBBACK_RCV_SINGLE_END - & ~SDRAM_CODT_FEEBBACK_DRV_SINGLE_END)); + codt &= ~(SDRAM_CODT_DQS_SINGLE_END | SDRAM_CODT_CKSE_SINGLE_END); + codt |= SDRAM_CODT_IO_NMODE; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] != SDRAM_NONE) { @@ -1159,50 +1134,50 @@ static void program_codt(unsigned long *dimm_populated, if (dimm_type == SDRAM_DDR2) { codt |= SDRAM_CODT_DQS_1_8_V_DDR2; if ((total_dimm == 1) && (firstSlot == TRUE)) { - if (total_rank == 1) { + if (total_rank == 1) { /* PUUU */ codt |= CALC_ODT_R(0); modt0 = CALC_ODT_W(0); modt1 = 0x00000000; modt2 = 0x00000000; modt3 = 0x00000000; } - if (total_rank == 2) { + if (total_rank == 2) { /* PPUU */ codt |= CALC_ODT_R(0) | CALC_ODT_R(1); - modt0 = CALC_ODT_W(0); - modt1 = CALC_ODT_W(0); + modt0 = CALC_ODT_W(0) | CALC_ODT_W(1); + modt1 = 0x00000000; modt2 = 0x00000000; modt3 = 0x00000000; } } else if ((total_dimm == 1) && (firstSlot != TRUE)) { - if (total_rank == 1) { + if (total_rank == 1) { /* UUPU */ codt |= CALC_ODT_R(2); modt0 = 0x00000000; modt1 = 0x00000000; modt2 = CALC_ODT_W(2); modt3 = 0x00000000; } - if (total_rank == 2) { + if (total_rank == 2) { /* UUPP */ codt |= CALC_ODT_R(2) | CALC_ODT_R(3); modt0 = 0x00000000; modt1 = 0x00000000; - modt2 = CALC_ODT_W(2); - modt3 = CALC_ODT_W(2); + modt2 = CALC_ODT_W(2) | CALC_ODT_W(3); + modt3 = 0x00000000; } } if (total_dimm == 2) { - if (total_rank == 2) { + if (total_rank == 2) { /* PUPU */ codt |= CALC_ODT_R(0) | CALC_ODT_R(2); modt0 = CALC_ODT_RW(2); modt1 = 0x00000000; modt2 = CALC_ODT_RW(0); modt3 = 0x00000000; } - if (total_rank == 4) { + if (total_rank == 4) { /* PPPP */ codt |= CALC_ODT_R(0) | CALC_ODT_R(1) | CALC_ODT_R(2) | CALC_ODT_R(3); - modt0 = CALC_ODT_RW(2); + modt0 = CALC_ODT_RW(2) | CALC_ODT_RW(3); modt1 = 0x00000000; - modt2 = CALC_ODT_RW(0); + modt2 = CALC_ODT_RW(0) | CALC_ODT_RW(1); modt3 = 0x00000000; } } @@ -1343,22 +1318,50 @@ static void program_initplr(unsigned long *dimm_populated, emr = CMD_EMR | SELECT_EMR | odt | ods; emr2 = CMD_EMR | SELECT_EMR2; emr3 = CMD_EMR | SELECT_EMR3; - mtsdram(SDRAM_INITPLR0, 0xB5000000 | CMD_NOP); /* NOP */ + /* NOP - Wait 106 MemClk cycles */ + mtsdram(SDRAM_INITPLR0, SDRAM_INITPLR_ENABLE | CMD_NOP | + SDRAM_INITPLR_IMWT_ENCODE(106)); udelay(1000); - mtsdram(SDRAM_INITPLR1, 0x82000400 | CMD_PRECHARGE); /* precharge 8 DDR clock cycle */ - mtsdram(SDRAM_INITPLR2, 0x80800000 | emr2); /* EMR2 */ - mtsdram(SDRAM_INITPLR3, 0x80800000 | emr3); /* EMR3 */ - mtsdram(SDRAM_INITPLR4, 0x80800000 | emr); /* EMR DLL ENABLE */ - mtsdram(SDRAM_INITPLR5, 0x80800000 | mr | DLL_RESET); /* MR w/ DLL reset */ + /* precharge 4 MemClk cycles */ + mtsdram(SDRAM_INITPLR1, SDRAM_INITPLR_ENABLE | CMD_PRECHARGE | + SDRAM_INITPLR_IMWT_ENCODE(4)); + /* EMR2 - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR2, SDRAM_INITPLR_ENABLE | emr2 | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* EMR3 - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR3, SDRAM_INITPLR_ENABLE | emr3 | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* EMR DLL ENABLE - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR4, SDRAM_INITPLR_ENABLE | emr | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* MR w/ DLL reset - 200 cycle wait for DLL reset */ + mtsdram(SDRAM_INITPLR5, SDRAM_INITPLR_ENABLE | mr | DLL_RESET | + SDRAM_INITPLR_IMWT_ENCODE(200)); udelay(1000); - mtsdram(SDRAM_INITPLR6, 0x82000400 | CMD_PRECHARGE); /* precharge 8 DDR clock cycle */ - mtsdram(SDRAM_INITPLR7, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR8, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR9, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR10, 0x8a000000 | CMD_REFRESH); /* Refresh 50 DDR clock cycle */ - mtsdram(SDRAM_INITPLR11, 0x80000000 | mr); /* MR w/o DLL reset */ - mtsdram(SDRAM_INITPLR12, 0x80800380 | emr); /* EMR OCD Default */ - mtsdram(SDRAM_INITPLR13, 0x80800000 | emr); /* EMR OCD Exit */ + /* precharge 4 MemClk cycles */ + mtsdram(SDRAM_INITPLR6, SDRAM_INITPLR_ENABLE | CMD_PRECHARGE | + SDRAM_INITPLR_IMWT_ENCODE(4)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR7, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR8, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR9, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* Refresh 25 MemClk cycles */ + mtsdram(SDRAM_INITPLR10, SDRAM_INITPLR_ENABLE | CMD_REFRESH | + SDRAM_INITPLR_IMWT_ENCODE(25)); + /* MR w/o DLL reset - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR11, SDRAM_INITPLR_ENABLE | mr | + SDRAM_INITPLR_IMWT_ENCODE(2)); + /* EMR OCD Default - Wait tMRD (2 MemClk cycles) */ + mtsdram(SDRAM_INITPLR12, SDRAM_INITPLR_ENABLE | OCD_CALIB_DEF | + SDRAM_INITPLR_IMWT_ENCODE(2) | emr); + /* EMR OCD Exit */ + mtsdram(SDRAM_INITPLR13, SDRAM_INITPLR_ENABLE | emr | + SDRAM_INITPLR_IMWT_ENCODE(2)); } else { printf("ERROR: ucode error as unknown DDR type in program_initplr"); spd_ddr_init_hang (); @@ -1412,7 +1415,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); + debug("sdram_freq=%lu\n", sdram_freq); /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all @@ -1442,7 +1445,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); + debug("cas_bit[SPD byte 18]=%02lx\n", cas_bit); /* For a particular DIMM, grab the three CAS values it supports */ for (cas_index = 0; cas_index < 3; cas_index++) { @@ -1474,7 +1477,7 @@ static void program_mode(unsigned long *dimm_populated, (((tcyc_reg & 0xF0) >> 4) * 100) + ((tcyc_reg & 0x0F)*10); } - debug("cas_index=%d: cycle_time_ns_x_100=%d\n", cas_index, + debug("cas_index=%lu: cycle_time_ns_x_100=%lu\n", cas_index, cycle_time_ns_x_100[cas_index]); } @@ -1585,9 +1588,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); + debug("cycle_3_0_clk=%lu\n", cycle_3_0_clk); + debug("cycle_4_0_clk=%lu\n", cycle_4_0_clk); + debug("cycle_5_0_clk=%lu\n", cycle_5_0_clk); if (sdram_ddr1 == TRUE) { /* DDR1 */ if ((cas_2_0_available == TRUE) && (sdram_freq <= cycle_2_0_clk)) { @@ -2249,17 +2252,28 @@ static void program_memory_queue(unsigned long *dimm_populated, } } -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ + defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ + defined(CONFIG_460SX) /* - * Enable high bandwidth access on 460EX/GT. - * This should/could probably be done on other - * PPC's too, like 440SPe. + * Enable high bandwidth access * This is currently not used, but with this setup * it is possible to use it later on in e.g. the Linux * EMAC driver for performance gain. */ mtdcr(SDRAM_PLBADDULL, 0x00000000); /* MQ0_BAUL */ mtdcr(SDRAM_PLBADDUHB, 0x00000008); /* MQ0_BAUH */ + + /* + * Set optimal value for Memory Queue HB/LL Configuration registers + */ + mtdcr(SDRAM_CONF1HB, (mfdcr(SDRAM_CONF1HB) & ~SDRAM_CONF1HB_MASK) | + SDRAM_CONF1HB_AAFR | SDRAM_CONF1HB_RPEN | SDRAM_CONF1HB_RFTE | + SDRAM_CONF1HB_RPLM | SDRAM_CONF1HB_WRCL); + mtdcr(SDRAM_CONF1LL, (mfdcr(SDRAM_CONF1LL) & ~SDRAM_CONF1LL_MASK) | + SDRAM_CONF1LL_AAFR | SDRAM_CONF1LL_RPEN | SDRAM_CONF1LL_RFTE | + SDRAM_CONF1LL_RPLM); + mtdcr(SDRAM_CONFPATHB, mfdcr(SDRAM_CONFPATHB) | SDRAM_CONFPATHB_TPEN); #endif } @@ -2282,18 +2296,6 @@ static unsigned long is_ecc_enabled(void) return ecc; } -static void blank_string(int size) -{ - int i; - - for (i=0; i