X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=cpu%2Fppc4xx%2F44x_spd_ddr2.c;h=995d5fec747822fa8872f7dce2e93f46b1c01d9b;hb=ec081c2c190148b374e86a795fb6b1c49caeb549;hp=ec1765e171c39f0ea8fcdd2d123567495c44ea6d;hpb=4b326101d6cfaeab8250988bc4c7f51e6c92d719;p=u-boot diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index ec1765e171..995d5fec74 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -60,8 +60,6 @@ "SDRAM_" #mnemonic, SDRAM_##mnemonic, data); \ } while (0) -static inline void ppc4xx_ibm_ddr2_register_dump(void); - #if defined(CONFIG_SPD_EEPROM) /*-----------------------------------------------------------------------------+ @@ -118,6 +116,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) @@ -259,62 +258,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]; @@ -570,15 +526,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 +564,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 /*------------------------------------------------------------------ @@ -1159,50 +1128,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 +1312,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 (); @@ -2249,17 +2246,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 +2290,6 @@ static unsigned long is_ecc_enabled(void) return ecc; } -static void blank_string(int size) -{ - int i; - - for (i=0; i