📄 44x_spd_ddr.c
字号:
if ((attributes & 0x02) != 0x00) { cfg0 |= SDRAM_CFG0_RDEN; } /* * program DDR SDRAM Data Width */ data_width = (unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) + (((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8); if (data_width == 64 || data_width == 72) { dimm_64bit = TRUE; cfg0 |= SDRAM_CFG0_DMWD_64; } else if (data_width == 32 || data_width == 40) { dimm_32bit = TRUE; cfg0 |= SDRAM_CFG0_DMWD_32; } else { printf("WARNING: DIMM with datawidth of %lu bits.\n", data_width); printf("Only DIMMs with 32 or 64 bit datawidths supported.\n"); spd_ddr_init_hang (); } break; } } /* * program Memory Data Error Checking */ if (ecc_enabled == TRUE) { cfg0 |= SDRAM_CFG0_MCHK_GEN; } else { cfg0 |= SDRAM_CFG0_MCHK_NON; } /* * program Page Management Unit (0 == enabled) */ cfg0 &= ~SDRAM_CFG0_PMUD; /* * program Memory Controller Options 0 * Note: DCEN must be enabled after all DDR SDRAM controller * configuration registers get initialized. */ mtsdram(mem_cfg0, cfg0);}static void program_cfg1(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long cfg1; mfsdram(mem_cfg1, cfg1); /* * Self-refresh exit, disable PM */ cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN); /* * program Memory Controller Options 1 */ mtsdram(mem_cfg1, cfg1);}static void program_rtr(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long bus_period_x_10; unsigned long refresh_rate = 0; unsigned char refresh_rate_type; unsigned long refresh_interval; unsigned long sdram_rtr; PPC4xx_SYS_INFO sys_info; /* * get the board info */ get_sys_info(&sys_info); bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] == TRUE) { refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12); switch (refresh_rate_type) { case 0x00: refresh_rate = 15625; break; case 0x01: refresh_rate = 15625/4; break; case 0x02: refresh_rate = 15625/2; break; case 0x03: refresh_rate = 15626*2; break; case 0x04: refresh_rate = 15625*4; break; case 0x05: refresh_rate = 15625*8; break; default: printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n", dimm_num); printf("Replace the DIMM module with a supported DIMM.\n"); break; } break; } } refresh_interval = refresh_rate * 10 / bus_period_x_10; sdram_rtr = (refresh_interval & 0x3ff8) << 16; /* * program Refresh Timer Register (SDRAM0_RTR) */ mtsdram(mem_rtr, sdram_rtr);}static void program_tr0(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long tr0; unsigned char wcsbc; unsigned char t_rp_ns; unsigned char t_rcd_ns; unsigned char t_ras_ns; unsigned long t_rp_clk; unsigned long t_ras_rcd_clk; unsigned long t_rcd_clk; unsigned long t_rfc_clk; unsigned long plb_check; unsigned char cas_bit; unsigned long cas_index; unsigned char cas_2_0_available; unsigned char cas_2_5_available; unsigned char cas_3_0_available; unsigned long cycle_time_ns_x_10[3]; unsigned long tcyc_3_0_ns_x_10; unsigned long tcyc_2_5_ns_x_10; unsigned long tcyc_2_0_ns_x_10; unsigned long tcyc_reg; unsigned long bus_period_x_10; PPC4xx_SYS_INFO sys_info; unsigned long residue; /* * get the board info */ get_sys_info(&sys_info); bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10); /* * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits */ mfsdram(mem_tr0, tr0); tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK | SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK | SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK | SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK); /* * initialization */ wcsbc = 0; t_rp_ns = 0; t_rcd_ns = 0; t_ras_ns = 0; cas_2_0_available = TRUE; cas_2_5_available = TRUE; cas_3_0_available = TRUE; tcyc_2_0_ns_x_10 = 0; tcyc_2_5_ns_x_10 = 0; tcyc_3_0_ns_x_10 = 0; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] == TRUE) { wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15); t_rp_ns = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2; t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2; t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30); cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); for (cas_index = 0; cas_index < 3; cas_index++) { switch (cas_index) { case 0: tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9); break; case 1: tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23); break; default: tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25); break; } if ((tcyc_reg & 0x0F) >= 10) { printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n", dimm_num); spd_ddr_init_hang (); } cycle_time_ns_x_10[cas_index] = (((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F); } cas_index = 0; if ((cas_bit & 0x80) != 0) { cas_index += 3; } else if ((cas_bit & 0x40) != 0) { cas_index += 2; } else if ((cas_bit & 0x20) != 0) { cas_index += 1; } if (((cas_bit & 0x10) != 0) && (cas_index < 3)) { tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; cas_index++; } else { if (cas_index != 0) { cas_index++; } cas_3_0_available = FALSE; } if (((cas_bit & 0x08) != 0) || (cas_index < 3)) { tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index]; cas_index++; } else { if (cas_index != 0) { cas_index++; } cas_2_5_available = FALSE; } if (((cas_bit & 0x04) != 0) || (cas_index < 3)) { tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index]; cas_index++; } else { if (cas_index != 0) { cas_index++; } cas_2_0_available = FALSE; } break; } } /* * Program SD_WR and SD_WCSBC fields */ tr0 |= SDRAM_TR0_SDWR_2_CLK; /* Write Recovery: 2 CLK */ switch (wcsbc) { case 0: tr0 |= SDRAM_TR0_SDWD_0_CLK; break; default: tr0 |= SDRAM_TR0_SDWD_1_CLK; break; } /* * Program SD_CASL field */ if ((cas_2_0_available == TRUE) && (bus_period_x_10 >= tcyc_2_0_ns_x_10)) { tr0 |= SDRAM_TR0_SDCL_2_0_CLK; } else if ((cas_2_5_available == TRUE) && (bus_period_x_10 >= tcyc_2_5_ns_x_10)) { tr0 |= SDRAM_TR0_SDCL_2_5_CLK; } else if ((cas_3_0_available == TRUE) && (bus_period_x_10 >= tcyc_3_0_ns_x_10)) { tr0 |= SDRAM_TR0_SDCL_3_0_CLK; } else { printf("ERROR: No supported CAS latency with the installed DIMMs.\n"); printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n"); printf("Make sure the PLB speed is within the supported range.\n"); spd_ddr_init_hang (); } /* * Calculate Trp in clock cycles and round up if necessary * Program SD_PTA field */ t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION; plb_check = ONE_BILLION * t_rp_clk / t_rp_ns; if (sys_info.freqPLB != plb_check) { t_rp_clk++; } switch ((unsigned long)t_rp_clk) { case 0: case 1: case 2: tr0 |= SDRAM_TR0_SDPA_2_CLK; break; case 3: tr0 |= SDRAM_TR0_SDPA_3_CLK; break; default: tr0 |= SDRAM_TR0_SDPA_4_CLK; break; } /* * Program SD_CTP field */ t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION; plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns); if (sys_info.freqPLB != plb_check) { t_ras_rcd_clk++; } switch (t_ras_rcd_clk) { case 0: case 1: case 2: tr0 |= SDRAM_TR0_SDCP_2_CLK; break; case 3: tr0 |= SDRAM_TR0_SDCP_3_CLK; break; case 4: tr0 |= SDRAM_TR0_SDCP_4_CLK; break; default: tr0 |= SDRAM_TR0_SDCP_5_CLK; break; } /* * Program SD_LDF field */ tr0 |= SDRAM_TR0_SDLD_2_CLK; /* * Program SD_RFTA field * FIXME tRFC hardcoded as 75 nanoseconds */ t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75); residue = sys_info.freqPLB % (ONE_BILLION / 75); if (residue >= (ONE_BILLION / 150)) { t_rfc_clk++; } switch (t_rfc_clk) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: tr0 |= SDRAM_TR0_SDRA_6_CLK; break; case 7: tr0 |= SDRAM_TR0_SDRA_7_CLK; break; case 8: tr0 |= SDRAM_TR0_SDRA_8_CLK; break; case 9: tr0 |= SDRAM_TR0_SDRA_9_CLK; break; case 10: tr0 |= SDRAM_TR0_SDRA_10_CLK; break; case 11: tr0 |= SDRAM_TR0_SDRA_11_CLK; break; case 12: tr0 |= SDRAM_TR0_SDRA_12_CLK; break; default: tr0 |= SDRAM_TR0_SDRA_13_CLK; break; } /* * Program SD_RCD field */ t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION; plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns; if (sys_info.freqPLB != plb_check) { t_rcd_clk++; } switch (t_rcd_clk) { case 0: case 1: case 2: tr0 |= SDRAM_TR0_SDRD_2_CLK; break; case 3: tr0 |= SDRAM_TR0_SDRD_3_CLK; break; default: tr0 |= SDRAM_TR0_SDRD_4_CLK; break; } debug("tr0: %x\n", tr0); mtsdram(mem_tr0, tr0);}static int short_mem_test(void){ unsigned long i, j; unsigned long bxcr_num; unsigned long *membase; const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -