?? 44x_spd_ddr2.c
字號:
if (dimm_rank > MAXRANKS) { printf("ERROR: DRAM DIMM detected with %d ranks in " "slot %d is not supported.\n", dimm_rank, dimm_num); printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS); printf("Replace the DIMM module with a supported DIMM.\n\n"); spd_ddr_init_hang (); } else total_rank += dimm_rank; } if (total_rank > MAXRANKS) { printf("ERROR: DRAM DIMM detected with a total of %d ranks " "for all slots.\n", (unsigned int)total_rank); printf("Only %d ranks are supported for all DIMM.\n", MAXRANKS); printf("Remove one of the DIMM modules.\n\n"); spd_ddr_init_hang (); } }}/*------------------------------------------------------------------ * only support 2.5V modules. * This routine verifies this. *-----------------------------------------------------------------*/static void check_voltage_type(unsigned long *dimm_populated, unsigned char *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_populated[dimm_num] != SDRAM_NONE) { voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8); switch (voltage_type) { case 0x00: printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); printf("This DIMM is 5.0 Volt/TTL.\n"); printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", (unsigned int)dimm_num); spd_ddr_init_hang (); break; case 0x01: printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); printf("This DIMM is LVTTL.\n"); printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", (unsigned int)dimm_num); spd_ddr_init_hang (); break; case 0x02: printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); printf("This DIMM is 1.5 Volt.\n"); printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", (unsigned int)dimm_num); spd_ddr_init_hang (); break; case 0x03: printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); printf("This DIMM is 3.3 Volt/TTL.\n"); printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", (unsigned int)dimm_num); spd_ddr_init_hang (); break; case 0x04: /* 2.5 Voltage only for DDR1 */ break; case 0x05: /* 1.8 Voltage only for DDR2 */ break; default: printf("ERROR: Only DIMMs DDR 2.5V or DDR2 1.8V are supported.\n"); printf("Replace the DIMM module in slot %d with a supported DIMM.\n\n", (unsigned int)dimm_num); spd_ddr_init_hang (); break; } } }}/*-----------------------------------------------------------------------------+ * program_copt1. *-----------------------------------------------------------------------------*/static void program_copt1(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long dimm_num; unsigned long mcopt1; unsigned long ecc_enabled; unsigned long ecc = 0; unsigned long data_width = 0; unsigned long dimm_32bit; unsigned long dimm_64bit; unsigned long registered = 0; unsigned long attribute = 0; unsigned long buf0, buf1; /* TODO: code to be changed for IOP1.6 to support 4 DIMMs */ unsigned long bankcount; unsigned long ddrtype; unsigned long val;#ifdef CONFIG_DDR_ECC ecc_enabled = TRUE;#else ecc_enabled = FALSE;#endif dimm_32bit = FALSE; dimm_64bit = FALSE; buf0 = FALSE; buf1 = FALSE; /*------------------------------------------------------------------ * Set memory controller options reg 1, SDRAM_MCOPT1. *-----------------------------------------------------------------*/ mfsdram(SDRAM_MCOPT1, val); mcopt1 = val & ~(SDRAM_MCOPT1_MCHK_MASK | SDRAM_MCOPT1_RDEN_MASK | SDRAM_MCOPT1_PMU_MASK | SDRAM_MCOPT1_DMWD_MASK | SDRAM_MCOPT1_UIOS_MASK | SDRAM_MCOPT1_BCNT_MASK | SDRAM_MCOPT1_DDR_TYPE_MASK | SDRAM_MCOPT1_RWOO_MASK | SDRAM_MCOPT1_WOOO_MASK | SDRAM_MCOPT1_DCOO_MASK | SDRAM_MCOPT1_DREF_MASK); mcopt1 |= SDRAM_MCOPT1_QDEP; mcopt1 |= SDRAM_MCOPT1_PMU_OPEN; mcopt1 |= SDRAM_MCOPT1_RWOO_DISABLED; mcopt1 |= SDRAM_MCOPT1_WOOO_DISABLED; mcopt1 |= SDRAM_MCOPT1_DCOO_DISABLED; mcopt1 |= SDRAM_MCOPT1_DREF_NORMAL; for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] != SDRAM_NONE) { /* test ecc support */ ecc = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 11); if (ecc != 0x02) /* ecc not supported */ ecc_enabled = FALSE; /* test bank count */ bankcount = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 17); if (bankcount == 0x04) /* bank count = 4 */ mcopt1 |= SDRAM_MCOPT1_4_BANKS; else /* bank count = 8 */ mcopt1 |= SDRAM_MCOPT1_8_BANKS; /* test DDR type */ ddrtype = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 2); /* test for buffered/unbuffered, registered, differential clocks */ registered = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 20); attribute = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 21); /* TODO: code to be changed for IOP1.6 to support 4 DIMMs */ if (dimm_num == 0) { if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */ mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE; if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */ mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE; if (registered == 1) { /* DDR2 always buffered */ /* TODO: what about above comments ? */ mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } else { /* TODO: the mask 0x02 doesn't match Samsung def for byte 21. */ if ((attribute & 0x02) == 0x00) { /* buffered not supported */ buf0 = FALSE; } else { mcopt1 |= SDRAM_MCOPT1_RDEN; buf0 = TRUE; } } } else if (dimm_num == 1) { if (dimm_populated[dimm_num] == SDRAM_DDR1) /* DDR1 type */ mcopt1 |= SDRAM_MCOPT1_DDR1_TYPE; if (dimm_populated[dimm_num] == SDRAM_DDR2) /* DDR2 type */ mcopt1 |= SDRAM_MCOPT1_DDR2_TYPE; if (registered == 1) { /* DDR2 always buffered */ mcopt1 |= SDRAM_MCOPT1_RDEN; buf1 = TRUE; } else { if ((attribute & 0x02) == 0x00) { /* buffered not supported */ buf1 = FALSE; } else { mcopt1 |= SDRAM_MCOPT1_RDEN; buf1 = TRUE; } } } /* Note that for DDR2 the byte 7 is reserved, but OK to keep code as is. */ data_width = (unsigned long)spd_read(iic0_dimm_addr[dimm_num], 6) + (((unsigned long)spd_read(iic0_dimm_addr[dimm_num], 7)) << 8); switch (data_width) { case 72: case 64: dimm_64bit = TRUE; break; case 40: case 32: dimm_32bit = TRUE; break; default: printf("WARNING: Detected a DIMM with a data width of %d bits.\n", data_width); printf("Only DIMMs with 32 or 64 bit DDR-SDRAM widths are supported.\n"); break; } } } /* verify matching properties */ if ((dimm_populated[0] != SDRAM_NONE) && (dimm_populated[1] != SDRAM_NONE)) { if (buf0 != buf1) { printf("ERROR: DIMM's buffered/unbuffered, registered, clocking don't match.\n"); spd_ddr_init_hang (); } } if ((dimm_64bit == TRUE) && (dimm_32bit == TRUE)) { printf("ERROR: Cannot mix 32 bit and 64 bit DDR-SDRAM DIMMs together.\n"); spd_ddr_init_hang (); } else if ((dimm_64bit == TRUE) && (dimm_32bit == FALSE)) { mcopt1 |= SDRAM_MCOPT1_DMWD_64; } else if ((dimm_64bit == FALSE) && (dimm_32bit == TRUE)) { mcopt1 |= SDRAM_MCOPT1_DMWD_32; } else { printf("ERROR: Please install only 32 or 64 bit DDR-SDRAM DIMMs.\n\n"); spd_ddr_init_hang (); } if (ecc_enabled == TRUE) mcopt1 |= SDRAM_MCOPT1_MCHK_GEN; else mcopt1 |= SDRAM_MCOPT1_MCHK_NON; mtsdram(SDRAM_MCOPT1, mcopt1);}/*-----------------------------------------------------------------------------+ * program_codt. *-----------------------------------------------------------------------------*/static void program_codt(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks){ unsigned long codt; unsigned long modt0 = 0; unsigned long modt1 = 0; unsigned long modt2 = 0; unsigned long modt3 = 0; unsigned char dimm_num; unsigned char dimm_rank; unsigned char total_rank = 0; unsigned char total_dimm = 0; unsigned char dimm_type = 0; unsigned char firstSlot = 0; /*------------------------------------------------------------------ * Set the SDRAM Controller On Die Termination Register *-----------------------------------------------------------------*/ mfsdram(SDRAM_CODT, codt); codt |= (SDRAM_CODT_IO_NMODE & (~SDRAM_CODT_DQS_SINGLE_END & ~SDRAM_CODT_CKSE_SINGLE_END & ~SDRAM_CODT_FEEBBACK_RCV_SINGLE_END & ~SDRAM_CODT_FEEBBACK_DRV_SINGLE_END)); for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) { if (dimm_populated[dimm_num] != SDRAM_NONE) { dimm_rank = (unsigned long)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; dimm_type = SDRAM_DDR2; } else { dimm_rank = dimm_rank & 0x0F; dimm_type = SDRAM_DDR1; } total_rank += dimm_rank; total_dimm++; if ((dimm_num == 0) && (total_dimm == 1)) firstSlot = TRUE; else firstSlot = FALSE; } } if (dimm_type == SDRAM_DDR2) { codt |= SDRAM_CODT_DQS_1_8_V_DDR2; if ((total_dimm == 1) && (firstSlot == TRUE)) { if (total_rank == 1) { codt |= CALC_ODT_R(0); modt0 = CALC_ODT_W(0); modt1 = 0x00000000; modt2 = 0x00000000; modt3 = 0x00000000; } if (total_rank == 2) { codt |= CALC_ODT_R(0) | CALC_ODT_R(1); modt0 = CALC_ODT_W(0); modt1 = CALC_ODT_W(0); modt2 = 0x00000000; modt3 = 0x00000000; } } else if ((total_dimm == 1) && (firstSlot != TRUE)) { if (total_rank == 1) { codt |= CALC_ODT_R(2); modt0 = 0x00000000; modt1 = 0x00000000; modt2 = CALC_ODT_W(2); modt3 = 0x00000000; } if (total_rank == 2) { codt |= CALC_ODT_R(2) | CALC_ODT_R(3); modt0 = 0x00000000; modt1 = 0x00000000; modt2 = CALC_ODT_W(2); modt3 = CALC_ODT_W(2); } } if (total_dimm == 2) { if (total_rank == 2) { 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) { codt |= CALC_ODT_R(0) | CALC_ODT_R(1) | CALC_ODT_R(2) | CALC_ODT_R(3); modt0 = CALC_ODT_RW(2); modt1 = 0x00000000; modt2 = CALC_ODT_RW(0); modt3 = 0x00000000; } } } else { codt |= SDRAM_CODT_DQS_2_5_V_DDR1; modt0 = 0x00000000; modt1 = 0x00000000; modt2 = 0x00000000; modt3 = 0x00000000; if (total_dimm == 1) { if (total_rank == 1) codt |= 0x00800000; if (total_rank == 2) codt |= 0x02800000; } if (total_dimm == 2) { if (total_rank == 2) codt |= 0x08800000; if (total_rank == 4) codt |= 0x2a800000; } } debug("nb of dimm %d\n", total_dimm); debug("nb of rank %d\n", total_rank); if (total_dimm == 1) debug("dimm in slot %d\n", firstSlot); mtsdram(SDRAM_CODT, codt); mtsdram(SDRAM_MODT0, modt0); mtsdram(SDRAM_MODT1, modt1); mtsdram(SDRAM_MODT2, modt2); mtsdram(SDRAM_MODT3, modt3);}/*-----------------------------------------------------------------------------+ * program_initplr. *-----------------------------------------------------------------------------*/static void program_initplr(unsigned long *dimm_populated, unsigned char *iic0_dimm_addr, unsigned long num_dimm_banks, ddr_cas_id_t selected_cas, int write_recovery){ u32 cas = 0; u32 odt = 0; u32 ods = 0; u32 mr; u32 wr; u32 emr; u32 emr2; u32 emr3; int dimm_num; int total_dimm = 0; /****************************************************** ** Assumption: if more than one DIMM, all DIMMs are the same ** as already checked in check_memory_type ******************************************************/ if ((dimm_populated[0] == SDRAM_DDR1) || (dimm_populated[1] == SDRAM_DDR1)) { mtsdram(SDRAM_INITPLR0, 0x81B80000); mtsdram(SDRAM_INITPLR1, 0x81900400); mtsdram(SDRAM_INITPLR2, 0x81810000); mtsdram(SDRAM_INITPLR3, 0xff800162); mtsdram(SDRAM_INITPLR4, 0x81900400); mtsdram(SDRAM_INITPLR5, 0x86080000); mtsdram(SDRAM_INITPLR6, 0x86080000); mtsdram(SDRAM_INITPLR7, 0x81000062); } else if ((dimm_populated[0] == SDRAM_DDR2) || (dimm_populated[1] == SDRAM_DDR2)) { switch (selected_cas) { case DDR_CAS_3: cas = 3 << 4; break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -