Newer
Older
{0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
{0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
{0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55}};
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++) {
/* printf("bank enabled base:%x\n", &membase[j]); */
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
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]));
return 0;
}
ppcDcbf((unsigned long)&(membase[j]));
}
if (j < NUMMEMWORDS)
return 0;
}
/*
* see if the rdclt value passed
*/
if (i < NUMMEMTESTS)
return 0;
}
}
return 1;
}
static 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 k;
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
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;
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;
debug("Starting memory test ");
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)));
if (short_mem_test()) {
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
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;
}
}
debug(".");
if (window_found == TRUE) {
tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
rdclt_offset += dly_val;
debug("\n");
/*
* make sure we find the window
*/
if (window_found == FALSE) {
printf("ERROR: Cannot determine a common read delay.\n");
spd_ddr_init_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;
}
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
/*
* 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);
debug("tr1: %x\n", tr1);
/*
* program SDRAM Timing Register 1 TR1
*/
mtsdram(mem_tr1, tr1);
static unsigned long program_bxcr(unsigned long *dimm_populated,
unsigned char *iic0_dimm_addr,
unsigned long num_dimm_banks)
unsigned long dimm_num;
unsigned long bank_base_addr;
unsigned long cr;
unsigned long i;
unsigned long j;
unsigned long temp;
unsigned char num_row_addr;
unsigned char num_col_addr;
unsigned char num_banks;
unsigned char bank_size_id;
unsigned long ctrl_bank_num[MAXBANKS];
unsigned long bx_cr_num;
unsigned long largest_size_index;
unsigned long largest_size;
unsigned long current_size_index;
BANKPARMS bank_parms[MAXBXCR];
unsigned long sorted_bank_num[MAXBXCR]; /* DDR Controller bank number table (sorted by size) */
unsigned long sorted_bank_size[MAXBXCR]; /* DDR Controller bank size table (sorted by size)*/
/*
* Set the BxCR regs. First, wipe out the bank config registers.
*/
for (bx_cr_num = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
mtdcr(memcfga, mem_b0cr + (bx_cr_num << 2));
mtdcr(memcfgd, 0x00000000);
bank_parms[bx_cr_num].bank_size_bytes = 0;
}
#ifdef CONFIG_BAMBOO
/*
* This next section is hardware dependent and must be programmed
* to match the hardware. For bamboo, the following holds...
* 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 (soldered onboard)
* 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1
* 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1
* 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3
* ctrl_bank_num corresponds to the first usable DDR controller bank number by DIMM
*/
ctrl_bank_num[0] = 0;
ctrl_bank_num[1] = 1;
ctrl_bank_num[2] = 3;
#else
/*
* Ocotea, Ebony and the other IBM/AMCC eval boards have
* 2 DIMM slots with each max 2 banks
*/
ctrl_bank_num[0] = 0;
ctrl_bank_num[1] = 2;
/*
* 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);
debug("DIMM%d: row=%d col=%d banks=%d\n", dimm_num,
num_row_addr, num_col_addr, num_banks);
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
/*
* Set the SDRAM0_BxCR regs
*/
cr = 0;
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");
spd_ddr_init_hang ();
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
}
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");
spd_ddr_init_hang ();
}
/*
* enable the bank
*/
cr |= SDRAM_BXCR_SDBE;
for (i = 0; i < num_banks; i++) {
bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
(4 << 20) * bank_size_id;
bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
debug("DIMM%d-bank %d (SDRAM0_B%dCR): bank_size_bytes=%d\n",
dimm_num, i, ctrl_bank_num[dimm_num]+i,
bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes);
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
/* Initialize sort tables */
for (i = 0; i < MAXBXCR; i++) {
sorted_bank_num[i] = i;
sorted_bank_size[i] = bank_parms[i].bank_size_bytes;
}
for (i = 0; i < MAXBXCR-1; i++) {
largest_size = sorted_bank_size[i];
largest_size_index = 255;
/* Find the largest remaining value */
for (j = i + 1; j < MAXBXCR; j++) {
if (sorted_bank_size[j] > largest_size) {
/* Save largest remaining value and its index */
largest_size = sorted_bank_size[j];
largest_size_index = j;
}
}
if (largest_size_index != 255) {
/* Swap the current and largest values */
current_size_index = sorted_bank_num[largest_size_index];
sorted_bank_size[largest_size_index] = sorted_bank_size[i];
sorted_bank_size[i] = largest_size;
sorted_bank_num[largest_size_index] = sorted_bank_num[i];
sorted_bank_num[i] = current_size_index;
}
}
/* Set the SDRAM0_BxCR regs thanks to sort tables */
for (bx_cr_num = 0, bank_base_addr = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
if (bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes) {
mtdcr(memcfga, mem_b0cr + (sorted_bank_num[bx_cr_num] << 2));
temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK |
SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE);
temp = temp | (bank_base_addr & SDRAM_BXCR_SDBA_MASK) |
bank_parms[sorted_bank_num[bx_cr_num]].cr;
mtdcr(memcfgd, temp);
bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes;
debug("SDRAM0_B%dCR=0x%08lx\n", sorted_bank_num[bx_cr_num], temp);
}
}
return(bank_base_addr);
#ifdef CONFIG_DDR_ECC
static 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;
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_DDR_ECC */