📄 spd_sdram.c.svn-base
字号:
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; }#if 0 printf("tr0: %x\n", tr0);#endif mtsdram(mem_tr0, tr0);}void program_tr1 (void){ unsigned long tr0; unsigned long tr1; unsigned long cfg0; unsigned long ecc_temp; unsigned long dlycal; unsigned long dly_val; unsigned long i, j, k; unsigned long bxcr_num; unsigned long max_pass_length; unsigned long current_pass_length; unsigned long current_fail_length; unsigned long current_start; unsigned long rdclt; unsigned long rdclt_offset; long max_start; long max_end; long rdclt_average; unsigned char window_found; unsigned char fail_found; unsigned char pass_found; unsigned long * membase; PPC440_SYS_INFO sys_info; /* * get the board info */ get_sys_info(&sys_info); /* * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits */ mfsdram(mem_tr1, tr1); tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK | SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK); mfsdram(mem_tr0, tr0); if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) && (sys_info.freqPLB > 100000000)) { tr1 |= SDRAM_TR1_RDSS_TR2; tr1 |= SDRAM_TR1_RDSL_STAGE3; tr1 |= SDRAM_TR1_RDCD_RCD_1_2; } else { tr1 |= SDRAM_TR1_RDSS_TR1; tr1 |= SDRAM_TR1_RDSL_STAGE2; tr1 |= SDRAM_TR1_RDCD_RCD_0_0; } /* * save CFG0 ECC setting to a temporary variable and turn ECC off */ mfsdram(mem_cfg0, cfg0); ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK; mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON); /* * get the delay line calibration register value */ mfsdram(mem_dlycal, dlycal); dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2; max_pass_length = 0; max_start = 0; max_end = 0; current_pass_length = 0; current_fail_length = 0; current_start = 0; rdclt_offset = 0; window_found = FALSE; fail_found = FALSE; pass_found = FALSE;#ifdef DEBUG printf("Starting memory test ");#endif for (k = 0; k < NUMHALFCYCLES; k++) { for (rdclt = 0; rdclt < dly_val; rdclt++) { /* * Set the timing reg for the test. */ mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt))); for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { mtdcr(memcfga, mem_b0cr + (bxcr_num<<2)); if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) { /* Bank is enabled */ membase = (unsigned long*) (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK); /* * Run the short memory test */ for (i = 0; i < NUMMEMTESTS; i++) { for (j = 0; j < NUMMEMWORDS; j++) { membase[j] = test[i][j]; ppcDcbf((unsigned long)&(membase[j])); } for (j = 0; j < NUMMEMWORDS; j++) { if (membase[j] != test[i][j]) { ppcDcbf((unsigned long)&(membase[j])); break; } ppcDcbf((unsigned long)&(membase[j])); } if (j < NUMMEMWORDS) { break; } } /* * see if the rdclt value passed */ if (i < NUMMEMTESTS) { break; } } } if (bxcr_num == MAXBXCR) { if (fail_found == TRUE) { pass_found = TRUE; if (current_pass_length == 0) { current_start = rdclt_offset + rdclt; } current_fail_length = 0; current_pass_length++; if (current_pass_length > max_pass_length) { max_pass_length = current_pass_length; max_start = current_start; max_end = rdclt_offset + rdclt; } } } else { current_pass_length = 0; current_fail_length++; if (current_fail_length >= (dly_val>>2)) { if (fail_found == FALSE) { fail_found = TRUE; } else if (pass_found == TRUE) { window_found = TRUE; break; } } } }#ifdef DEBUG printf(".");#endif if (window_found == TRUE) { break; } tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; rdclt_offset += dly_val; }#ifdef DEBUG printf("\n");#endif /* * make sure we find the window */ if (window_found == FALSE) { printf("ERROR: Cannot determine a common read delay.\n"); hang(); } /* * restore the orignal ECC setting */ mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp); /* * set the SDRAM TR1 RDCD value */ tr1 &= ~SDRAM_TR1_RDCD_MASK; if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) { tr1 |= SDRAM_TR1_RDCD_RCD_1_2; } else { tr1 |= SDRAM_TR1_RDCD_RCD_0_0; } /* * set the SDRAM TR1 RDCLT value */ tr1 &= ~SDRAM_TR1_RDCT_MASK; while (max_end >= (dly_val<<1)) { max_end -= (dly_val<<1); max_start -= (dly_val<<1); } rdclt_average = ((max_start + max_end) >> 1); if (rdclt_average >= 0x60) while(1); if (rdclt_average < 0) { rdclt_average = 0; } if (rdclt_average >= dly_val) { rdclt_average -= dly_val; tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK; } tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);#if 0 printf("tr1: %x\n", tr1);#endif /* * program SDRAM Timing Register 1 TR1 */ mtsdram(mem_tr1, tr1);}unsigned long program_bxcr(unsigned long* dimm_populated, unsigned char* iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long bxcr_num; unsigned long bank_base_addr; unsigned long bank_size_bytes; unsigned long cr; unsigned long i; unsigned long temp; unsigned char num_row_addr; unsigned char num_col_addr; unsigned char num_banks; unsigned char bank_size_id; /* * Set the BxCR regs. First, wipe out the bank config registers. */ for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) { mtdcr(memcfga, mem_b0cr + (bxcr_num << 2)); mtdcr(memcfgd, 0x00000000); } /* * reset the bank_base address */ bank_base_addr = CFG_SDRAM_BASE; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] == TRUE) { num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3); num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4); num_banks = spd_read(iic0_dimm_addr[dimm_num], 5); bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31); /* * Set the SDRAM0_BxCR regs */ cr = 0; bank_size_bytes = 4 * 1024 * 1024 * bank_size_id; switch (bank_size_id) { case 0x02: cr |= SDRAM_BXCR_SDSZ_8; break; case 0x04: cr |= SDRAM_BXCR_SDSZ_16; break; case 0x08: cr |= SDRAM_BXCR_SDSZ_32; break; case 0x10: cr |= SDRAM_BXCR_SDSZ_64; break; case 0x20: cr |= SDRAM_BXCR_SDSZ_128; break; case 0x40: cr |= SDRAM_BXCR_SDSZ_256; break; case 0x80: cr |= SDRAM_BXCR_SDSZ_512; break; default: printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", dimm_num); printf("ERROR: Unsupported value for the banksize: %d.\n", bank_size_id); printf("Replace the DIMM module with a supported DIMM.\n\n"); hang(); } switch (num_col_addr) { case 0x08: cr |= SDRAM_BXCR_SDAM_1; break; case 0x09: cr |= SDRAM_BXCR_SDAM_2; break; case 0x0A: cr |= SDRAM_BXCR_SDAM_3; break; case 0x0B: cr |= SDRAM_BXCR_SDAM_4; break; default: printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n", dimm_num); printf("ERROR: Unsupported value for number of " "column addresses: %d.\n", num_col_addr); printf("Replace the DIMM module with a supported DIMM.\n\n"); hang(); } /* * enable the bank */ cr |= SDRAM_BXCR_SDBE; /*------------------------------------------------------------------ | This next section is hardware dependent and must be programmed | to match the hardware. +-----------------------------------------------------------------*/ if (dimm_num == 0) { for (i = 0; i < num_banks; i++) { mtdcr(memcfga, mem_b0cr + (i << 2)); temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK | SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE); cr |= temp; cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; mtdcr(memcfgd, cr); bank_base_addr += bank_size_bytes; } } else { for (i = 0; i < num_banks; i++) { mtdcr(memcfga, mem_b2cr + (i << 2)); temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK | SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE); cr |= temp; cr |= bank_base_addr & SDRAM_BXCR_SDBA_MASK; mtdcr(memcfgd, cr); bank_base_addr += bank_size_bytes; } } } } return(bank_base_addr);}void program_ecc (unsigned long num_bytes){ unsigned long bank_base_addr; unsigned long current_address; unsigned long end_address; unsigned long address_increment; unsigned long cfg0; /* * get Memory Controller Options 0 data */ mfsdram(mem_cfg0, cfg0); /* * reset the bank_base address */ bank_base_addr = CFG_SDRAM_BASE; if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) { mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_GEN); if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) { address_increment = 4; } else { address_increment = 8; } current_address = (unsigned long)(bank_base_addr); end_address = (unsigned long)(bank_base_addr) + num_bytes; while (current_address < end_address) { *((unsigned long*)current_address) = 0x00000000; current_address += address_increment; } mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_CHK); }}#endif /* CONFIG_440 */#endif /* CONFIG_SPD_EEPROM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -