?? 44x_spd_ddr2.c
字號:
* Make sure I2C controller is initialized * before continuing. */ /* switch to correct I2C bus */ I2C_SET_BUS(CFG_SPD_BUS_NUM); i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE); /*------------------------------------------------------------------ * Clear out the serial presence detect buffers. * Perform IIC reads from the dimm. Fill in the spds. * Check to see if the dimm slots are populated *-----------------------------------------------------------------*/ get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Check the memory type for the dimms plugged. *-----------------------------------------------------------------*/ check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Check the frequency supported for the dimms plugged. *-----------------------------------------------------------------*/ check_frequency(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Check the total rank number. *-----------------------------------------------------------------*/ check_rank_number(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Check the voltage type for the dimms plugged. *-----------------------------------------------------------------*/ check_voltage_type(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Program SDRAM controller options 2 register * Except Enabling of the memory controller. *-----------------------------------------------------------------*/ mfsdram(SDRAM_MCOPT2, val); mtsdram(SDRAM_MCOPT2, (val & ~(SDRAM_MCOPT2_SREN_MASK | SDRAM_MCOPT2_PMEN_MASK | SDRAM_MCOPT2_IPTR_MASK | SDRAM_MCOPT2_XSRP_MASK | SDRAM_MCOPT2_ISIE_MASK)) | (SDRAM_MCOPT2_SREN_ENTER | SDRAM_MCOPT2_PMEN_DISABLE | SDRAM_MCOPT2_IPTR_IDLE | SDRAM_MCOPT2_XSRP_ALLOW | SDRAM_MCOPT2_ISIE_ENABLE)); /*------------------------------------------------------------------ * Program SDRAM controller options 1 register * Note: Does not enable the memory controller. *-----------------------------------------------------------------*/ program_copt1(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Set the SDRAM Controller On Die Termination Register *-----------------------------------------------------------------*/ program_codt(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Program SDRAM refresh register. *-----------------------------------------------------------------*/ program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Program SDRAM mode register. *-----------------------------------------------------------------*/ program_mode(dimm_populated, iic0_dimm_addr, num_dimm_banks, &selected_cas, &write_recovery); /*------------------------------------------------------------------ * Set the SDRAM Write Data/DM/DQS Clock Timing Reg *-----------------------------------------------------------------*/ mfsdram(SDRAM_WRDTR, val); mtsdram(SDRAM_WRDTR, (val & ~(SDRAM_WRDTR_LLWP_MASK | SDRAM_WRDTR_WTR_MASK)) | ddr_wrdtr(SDRAM_WRDTR_LLWP_1_CYC | SDRAM_WRDTR_WTR_90_DEG_ADV)); /*------------------------------------------------------------------ * Set the SDRAM Clock Timing Register *-----------------------------------------------------------------*/ mfsdram(SDRAM_CLKTR, val); mtsdram(SDRAM_CLKTR, (val & ~SDRAM_CLKTR_CLKP_MASK) | ddr_clktr(SDRAM_CLKTR_CLKP_0_DEG)); /*------------------------------------------------------------------ * Program the BxCF registers. *-----------------------------------------------------------------*/ program_bxcf(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Program SDRAM timing registers. *-----------------------------------------------------------------*/ program_tr(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Set the Extended Mode register *-----------------------------------------------------------------*/ mfsdram(SDRAM_MEMODE, val); mtsdram(SDRAM_MEMODE, (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_150OHM | SDRAM_MEMODE_DQS_ENABLE)); /*------------------------------------------------------------------ * Program Initialization preload registers. *-----------------------------------------------------------------*/ program_initplr(dimm_populated, iic0_dimm_addr, num_dimm_banks, selected_cas, write_recovery); /*------------------------------------------------------------------ * Delay to ensure 200usec have elapsed since reset. *-----------------------------------------------------------------*/ udelay(400); /*------------------------------------------------------------------ * Set the memory queue core base addr. *-----------------------------------------------------------------*/ program_memory_queue(dimm_populated, iic0_dimm_addr, num_dimm_banks); /*------------------------------------------------------------------ * Program SDRAM controller options 2 register * Enable the memory controller. *-----------------------------------------------------------------*/ mfsdram(SDRAM_MCOPT2, val); 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)); /*------------------------------------------------------------------ * Wait for SDRAM_CFG0_DC_EN to complete. *-----------------------------------------------------------------*/ do { mfsdram(SDRAM_MCSTAT, val); } while ((val & SDRAM_MCSTAT_MIC_MASK) == SDRAM_MCSTAT_MIC_NOTCOMP); /* get installed memory size */ dram_size = sdram_memsize(); /* and program tlb entries for this size (dynamic) */ /* * Program TLB entries with caches enabled, for best performace * while auto-calibrating and ECC generation */ program_tlb(0, 0, dram_size, 0); /*------------------------------------------------------------------ * DQS calibration. *-----------------------------------------------------------------*/ 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, 0);#endif /* * Now after initialization (auto-calibration and ECC generation) * remove the TLB entries with caches enabled and program again with * desired cache functionality */ remove_tlb(0, dram_size); program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE); ppc440sp_sdram_register_dump(); return dram_size;}static void get_spd_info(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long dimm_found; unsigned char num_of_bytes; unsigned char total_size; dimm_found = FALSE; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { num_of_bytes = 0; total_size = 0; num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0); debug("\nspd_read(0x%x) returned %d\n", iic0_dimm_addr[dimm_num], num_of_bytes); total_size = spd_read(iic0_dimm_addr[dimm_num], 1); debug("spd_read(0x%x) returned %d\n", iic0_dimm_addr[dimm_num], total_size); if ((num_of_bytes != 0) && (total_size != 0)) { dimm_populated[dimm_num] = TRUE; dimm_found = TRUE; debug("DIMM slot %lu: populated\n", dimm_num); } else { dimm_populated[dimm_num] = FALSE; debug("DIMM slot %lu: Not populated\n", dimm_num); } } if (dimm_found == FALSE) { printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n"); spd_ddr_init_hang (); }}void board_add_ram_info(int use_default){ PPC440_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 * really are DDR specific DIMMs. *-----------------------------------------------------------------*/static void check_mem_type(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long dimm_type; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] == TRUE) { dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2); switch (dimm_type) { case 1: printf("ERROR: Standard Fast Page Mode DRAM DIMM detected in " "slot %d.\n", (unsigned int)dimm_num); printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); break; case 2: printf("ERROR: EDO DIMM detected in slot %d.\n", (unsigned int)dimm_num); printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); break; case 3: printf("ERROR: Pipelined Nibble DIMM detected in slot %d.\n", (unsigned int)dimm_num); printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); break; case 4: printf("ERROR: SDRAM DIMM detected in slot %d.\n", (unsigned int)dimm_num); printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); break; case 5: printf("ERROR: Multiplexed ROM DIMM detected in slot %d.\n", (unsigned int)dimm_num); printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); break; case 6: printf("ERROR: SGRAM DIMM detected in slot %d.\n", (unsigned int)dimm_num); printf("Only DDR and DDR2 SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); break; case 7: debug("DIMM slot %d: 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); dimm_populated[dimm_num] = SDRAM_DDR2; break; default: printf("ERROR: Unknown DIMM detected in slot %d.\n", (unsigned int)dimm_num); printf("Only DDR1 and DDR2 SDRAM DIMMs are supported.\n"); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); break; } } } for (dimm_num = 1; dimm_num < num_dimm_banks; dimm_num++) { if ((dimm_populated[dimm_num-1] != SDRAM_NONE) && (dimm_populated[dimm_num] != SDRAM_NONE) && (dimm_populated[dimm_num-1] != dimm_populated[dimm_num])) { printf("ERROR: DIMM's DDR1 and DDR2 type can not be mixed.\n"); spd_ddr_init_hang (); } }}/*------------------------------------------------------------------ * For the memory DIMMs installed, this routine verifies that * frequency previously calculated is supported. *-----------------------------------------------------------------*/static void check_frequency(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long tcyc_reg; unsigned long cycle_time; unsigned long calc_cycle_time; unsigned long sdram_freq; unsigned long sdr_ddrpll; PPC440_SYS_INFO board_cfg; /*------------------------------------------------------------------ * Get the board configuration info. *-----------------------------------------------------------------*/ get_sys_info(&board_cfg); mfsdr(SDR0_DDR0, sdr_ddrpll); sdram_freq = ((board_cfg.freqPLB) * SDR0_DDR0_DDRM_DECODE(sdr_ddrpll)); /* * calc_cycle_time is calculated from DDR frequency set by board/chip * and is expressed in multiple of 10 picoseconds * to match the way DIMM cycle time is calculated below. */ calc_cycle_time = MULDIV64(ONE_BILLION, 100, sdram_freq); for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] != SDRAM_NONE) { tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9); /* * Byte 9, Cycle time for CAS Latency=X, is split into two nibbles: * the higher order nibble (bits 4-7) designates the cycle time * to a granularity of 1ns; * the value presented by the lower order nibble (bits 0-3) * has a granularity of .1ns and is added to the value designated * by the higher nibble. In addition, four lines of the lower order * nibble are assigned to support +.25,+.33, +.66 and +.75. */ /* Convert from hex to decimal */ if ((tcyc_reg & 0x0F) == 0x0D) cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 75; else if ((tcyc_reg & 0x0F) == 0x0C) cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 66; else if ((tcyc_reg & 0x0F) == 0x0B) cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 33; else if ((tcyc_reg & 0x0F) == 0x0A) cycle_time = (((tcyc_reg & 0xF0) >> 4) * 100) + 25; 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)) { /* * the provided sdram cycle_time is too small * for the available DIMM cycle_time. * The additionnal 100ps is here to accept a small incertainty. */ printf("ERROR: DRAM DIMM detected with cycle_time %d ps in " "slot %d \n while calculated cycle time is %d ps.\n", (unsigned int)(cycle_time*10), (unsigned int)dimm_num, (unsigned int)(calc_cycle_time*10)); printf("Replace the DIMM, or change DDR frequency via " "strapping bits.\n\n"); spd_ddr_init_hang (); } } }}/*------------------------------------------------------------------ * For the memory DIMMs installed, this routine verifies two * ranks/banks maximum are availables. *-----------------------------------------------------------------*/static void check_rank_number(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long dimm_rank; unsigned long total_rank = 0; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] != SDRAM_NONE) { dimm_rank = spd_read(iic0_dimm_addr[dimm_num], 5); if (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2)) == 0x08) dimm_rank = (dimm_rank & 0x0F) +1; else dimm_rank = dimm_rank & 0x0F;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -