📄 denali_spd_ddr2.c
字号:
unsigned long num_dimm_banks, unsigned long *const rows, unsigned long *const banks, unsigned long *const cols, unsigned long *const width){ unsigned long dimm_num; *rows = 0; *banks = 0; *cols = 0; *width = 0; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_ranks[dimm_num]) { unsigned long t; /* Rows */ t = spd_read(iic0_dimm_addr[dimm_num], 3); if (0 == *rows) { *rows = t; } else if (t != *rows) { printf("ERROR: DRAM DIMM modules do not all " "have the same number of rows.\n\n"); spd_ddr_init_hang(); } /* Banks */ t = spd_read(iic0_dimm_addr[dimm_num], 17); if (0 == *banks) { *banks = t; } else if (t != *banks) { printf("ERROR: DRAM DIMM modules do not all " "have the same number of banks.\n\n"); spd_ddr_init_hang(); } /* Columns */ t = spd_read(iic0_dimm_addr[dimm_num], 4); if (0 == *cols) { *cols = t; } else if (t != *cols) { printf("ERROR: DRAM DIMM modules do not all " "have the same number of columns.\n\n"); spd_ddr_init_hang(); } /* Data width */ t = spd_read(iic0_dimm_addr[dimm_num], 6); if (0 == *width) { *width = t; } else if (t != *width) { printf("ERROR: DRAM DIMM modules do not all " "have the same data width.\n\n"); spd_ddr_init_hang(); } } } debug("Number of rows = %d\n", *rows); debug("Number of columns = %d\n", *cols); debug("Number of banks = %d\n", *banks); debug("Data width = %d\n", *width); if (*rows > 14) { printf("ERROR: DRAM DIMM modules have %lu address rows.\n", *rows); printf("Only modules with 14 or fewer rows are supported.\n\n"); spd_ddr_init_hang(); } if (4 != *banks && 8 != *banks) { printf("ERROR: DRAM DIMM modules have %lu banks.\n", *banks); printf("Only modules with 4 or 8 banks are supported.\n\n"); spd_ddr_init_hang(); } if (*cols > 12) { printf("ERROR: DRAM DIMM modules have %lu address columns.\n", *cols); printf("Only modules with 12 or fewer columns are " "supported.\n\n"); spd_ddr_init_hang(); } if (32 != *width && 40 != *width && 64 != *width && 72 != *width) { printf("ERROR: DRAM DIMM modules have a width of %lu bit.\n", *width); printf("Only modules with widths of 32, 40, 64, and 72 bits " "are supported.\n\n"); spd_ddr_init_hang(); }}/*------------------------------------------------------------------ * Only 1.8V modules are supported. This routine verifies this. *-----------------------------------------------------------------*/static void check_voltage_type(unsigned long dimm_ranks[], unsigned char const iic0_dimm_addr[], unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long voltage_type; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_ranks[dimm_num]) { voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8); if (0x05 != voltage_type) { /* 1.8V for DDR2 */ printf("ERROR: Slot %lu provides 1.8V for DDR2 " "DIMMs.\n", dimm_num); switch (voltage_type) { case 0x00: printf("This DIMM is 5.0 Volt/TTL.\n"); break; case 0x01: printf("This DIMM is LVTTL.\n"); break; case 0x02: printf("This DIMM is 1.5 Volt.\n"); break; case 0x03: printf("This DIMM is 3.3 Volt/TTL.\n"); break; case 0x04: printf("This DIMM is 2.5 Volt.\n"); break; default: printf("This DIMM is an unknown " "voltage.\n"); break; } printf("Replace it with a 1.8V DDR2 DIMM.\n\n"); spd_ddr_init_hang(); } } }}static void program_ddr0_03(unsigned long dimm_ranks[], unsigned char const iic0_dimm_addr[], unsigned long num_dimm_banks, unsigned long sdram_freq, unsigned long rows, unsigned long *cas_latency){ unsigned long dimm_num; unsigned long cas_index; unsigned long cycle_2_0_clk; unsigned long cycle_3_0_clk; unsigned long cycle_4_0_clk; unsigned long cycle_5_0_clk; unsigned long max_2_0_tcyc_ps = 100; unsigned long max_3_0_tcyc_ps = 100; unsigned long max_4_0_tcyc_ps = 100; unsigned long max_5_0_tcyc_ps = 100; unsigned char cas_available = 0x3C; /* value for DDR2 */ u32 ddr0_03 = DDR0_03_BSTLEN_ENCODE(0x2) | DDR0_03_INITAREF_ENCODE(0x2); unsigned int const tcyc_addr[3] = { 9, 23, 25 }; /*------------------------------------------------------------------ * Get the board configuration info. *-----------------------------------------------------------------*/ debug("sdram_freq = %d\n", sdram_freq); /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all * the dimm modules installed. *-----------------------------------------------------------------*/ /* loop through all the DIMM slots on the board */ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { /* If a dimm is installed in a particular slot ... */ if (dimm_ranks[dimm_num]) { unsigned char const cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18); unsigned char cas_mask; cas_available &= cas_bit; for (cas_mask = 0x80; cas_mask; cas_mask >>= 1) { if (cas_bit & cas_mask) break; } debug("cas_bit (SPD byte 18) = %02X, cas_mask = %02X\n", cas_bit, cas_mask); for (cas_index = 0; cas_index < 3; cas_mask >>= 1, cas_index++) { unsigned long cycle_time_ps; if (!(cas_available & cas_mask)) { continue; } cycle_time_ps = get_tcyc(spd_read(iic0_dimm_addr[dimm_num], tcyc_addr[cas_index])); debug("cas_index = %d: cycle_time_ps = %d\n", cas_index, cycle_time_ps); /* * DDR2 devices use the following bitmask for CAS latency: * Bit 7 6 5 4 3 2 1 0 * TBD 6.0 5.0 4.0 3.0 2.0 TBD TBD */ switch (cas_mask) { case 0x20: max_5_0_tcyc_ps = max(max_5_0_tcyc_ps, cycle_time_ps); break; case 0x10: max_4_0_tcyc_ps = max(max_4_0_tcyc_ps, cycle_time_ps); break; case 0x08: max_3_0_tcyc_ps = max(max_3_0_tcyc_ps, cycle_time_ps); break; case 0x04: max_2_0_tcyc_ps = max(max_2_0_tcyc_ps, cycle_time_ps); break; } } } } debug("cas_available (bit map) = 0x%02X\n", cas_available); /*------------------------------------------------------------------ * Set the SDRAM mode, SDRAM_MMODE *-----------------------------------------------------------------*/ /* add 10 here because of rounding problems */ cycle_2_0_clk = MULDIV64(ONE_BILLION, 1000, max_2_0_tcyc_ps) + 10; cycle_3_0_clk = MULDIV64(ONE_BILLION, 1000, max_3_0_tcyc_ps) + 10; cycle_4_0_clk = MULDIV64(ONE_BILLION, 1000, max_4_0_tcyc_ps) + 10; cycle_5_0_clk = MULDIV64(ONE_BILLION, 1000, max_5_0_tcyc_ps) + 10; debug("cycle_2_0_clk = %d\n", cycle_2_0_clk); 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 ((cas_available & 0x04) && (sdram_freq <= cycle_2_0_clk)) { *cas_latency = 2; ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x2) | DDR0_03_CASLAT_LIN_ENCODE(0x4); } else if ((cas_available & 0x08) && (sdram_freq <= cycle_3_0_clk)) { *cas_latency = 3; ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x3) | DDR0_03_CASLAT_LIN_ENCODE(0x6); } else if ((cas_available & 0x10) && (sdram_freq <= cycle_4_0_clk)) { *cas_latency = 4; ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x4) | DDR0_03_CASLAT_LIN_ENCODE(0x8); } else if ((cas_available & 0x20) && (sdram_freq <= cycle_5_0_clk)) { *cas_latency = 5; ddr0_03 |= DDR0_03_CASLAT_ENCODE(0x5) | DDR0_03_CASLAT_LIN_ENCODE(0xA); } else { printf("ERROR: Cannot find a supported CAS latency with the " "installed DIMMs.\n"); printf("Only DDR2 DIMMs with CAS latencies of 2.0, 3.0, 4.0, " "and 5.0 are supported.\n"); printf("Make sure the PLB speed is within the supported range " "of the DIMMs.\n"); printf("sdram_freq=%ld cycle2=%ld cycle3=%ld cycle4=%ld " "cycle5=%ld\n\n", sdram_freq, cycle_2_0_clk, cycle_3_0_clk, cycle_4_0_clk, cycle_5_0_clk); spd_ddr_init_hang(); } debug("CAS latency = %d\n", *cas_latency); mtsdram(DDR0_03, ddr0_03);}static void program_ddr0_04(unsigned long dimm_ranks[], unsigned char const iic0_dimm_addr[], unsigned long num_dimm_banks, unsigned long sdram_freq){ unsigned long dimm_num; unsigned long t_rc_ps = 0; unsigned long t_rrd_ps = 0; unsigned long t_rtp_ps = 0; unsigned long t_rc_clk; unsigned long t_rrd_clk; unsigned long t_rtp_clk; /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all * the dimm modules installed. *-----------------------------------------------------------------*/ /* loop through all the DIMM slots on the board */ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { /* If a dimm is installed in a particular slot ... */ if (dimm_ranks[dimm_num]) { unsigned long ps; /* tRC */ ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 41); switch (spd_read(iic0_dimm_addr[dimm_num], 40) >> 4) { case 0x1: ps += 250; break; case 0x2: ps += 333; break; case 0x3: ps += 500; break; case 0x4: ps += 667; break; case 0x5: ps += 750; break; } t_rc_ps = max(t_rc_ps, ps); /* tRRD */ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 28); t_rrd_ps = max(t_rrd_ps, ps); /* tRTP */ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 38); t_rtp_ps = max(t_rtp_ps, ps); } } debug("t_rc_ps = %d\n", t_rc_ps); t_rc_clk = (MULDIV64(sdram_freq, t_rc_ps, ONE_BILLION) + 999) / 1000; debug("t_rrd_ps = %d\n", t_rrd_ps); t_rrd_clk = (MULDIV64(sdram_freq, t_rrd_ps, ONE_BILLION) + 999) / 1000; debug("t_rtp_ps = %d\n", t_rtp_ps); t_rtp_clk = (MULDIV64(sdram_freq, t_rtp_ps, ONE_BILLION) + 999) / 1000; mtsdram(DDR0_04, DDR0_04_TRC_ENCODE(t_rc_clk) | DDR0_04_TRRD_ENCODE(t_rrd_clk) | DDR0_04_TRTP_ENCODE(t_rtp_clk));}static void program_ddr0_05(unsigned long dimm_ranks[], unsigned char const iic0_dimm_addr[], unsigned long num_dimm_banks, unsigned long sdram_freq){ unsigned long dimm_num; unsigned long t_rp_ps = 0; unsigned long t_ras_ps = 0; unsigned long t_rp_clk; unsigned long t_ras_clk; u32 ddr0_05 = DDR0_05_TMRD_ENCODE(0x2) | DDR0_05_TEMRS_ENCODE(0x2); /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all * the dimm modules installed. *-----------------------------------------------------------------*/ /* loop through all the DIMM slots on the board */ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { /* If a dimm is installed in a particular slot ... */ if (dimm_ranks[dimm_num]) { unsigned long ps; /* tRP */ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 27); t_rp_ps = max(t_rp_ps, ps); /* tRAS */ ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 30); t_ras_ps = max(t_ras_ps, ps); } } debug("t_rp_ps = %d\n", t_rp_ps); t_rp_clk = (MULDIV64(sdram_freq, t_rp_ps, ONE_BILLION) + 999) / 1000; debug("t_ras_ps = %d\n", t_ras_ps); t_ras_clk = (MULDIV64(sdram_freq, t_ras_ps, ONE_BILLION) + 999) / 1000; mtsdram(DDR0_05, ddr0_05 | DDR0_05_TRP_ENCODE(t_rp_clk) | DDR0_05_TRAS_MIN_ENCODE(t_ras_clk));}static void program_ddr0_06(unsigned long dimm_ranks[], unsigned char const iic0_dimm_addr[], unsigned long num_dimm_banks, unsigned long sdram_freq){ unsigned long dimm_num; unsigned char spd_40; unsigned long t_wtr_ps = 0; unsigned long t_rfc_ps = 0; unsigned long t_wtr_clk; unsigned long t_rfc_clk; u32 ddr0_06 = DDR0_06_WRITEINTERP_ENCODE(0x1) | DDR0_06_TDLL_ENCODE(200); /*------------------------------------------------------------------ * Handle the timing. We need to find the worst case timing of all * the dimm modules installed. *-----------------------------------------------------------------*/ /* loop through all the DIMM slots on the board */ for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { /* If a dimm is installed in a particular slot ... */ if (dimm_ranks[dimm_num]) { unsigned long ps; /* tWTR */ ps = 250 * spd_read(iic0_dimm_addr[dimm_num], 37); t_wtr_ps = max(t_wtr_ps, ps); /* tRFC */ ps = 1000 * spd_read(iic0_dimm_addr[dimm_num], 42); spd_40 = spd_read(iic0_dimm_addr[dimm_num], 40); ps += 256000 * (spd_40 & 0x01); switch ((spd_40 & 0x0E) >> 1) { case 0x1: ps += 250; break; case 0x2: ps += 333; break; case 0x3: ps += 500; break; case 0x4: ps += 667; break; case 0x5: ps += 750; break; } t_rfc_ps = max(t_rfc_ps, ps); } } debug("t_wtr_ps = %d\n", t_wtr_ps); t_wtr_clk = (MULDIV64(sdram_freq, t_wtr_ps, ONE_BILLION) + 999) / 1000; debug("t_rfc_ps = %d\n", t_rfc_ps); t_rfc_clk = (MULDIV64(sdram_freq, t_rfc_ps, ONE_BILLION) + 999) / 1000; mtsdram(DDR0_06, ddr0_06 | DDR0_06_TWTR_ENCODE(t_wtr_clk) | DDR0_06_TRFC_ENCODE(t_rfc_clk));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -