35 #define NORTHBRIDGE PCI_DEV(0, 0, 0)
36 #define SOUTHBRIDGE PCI_DEV(0, 0x1f, 0)
37 #define GMA PCI_DEV (0, 0x2, 0x0)
39 #define FOR_ALL_RANKS \
40 for (channel = 0; channel < NUM_CHANNELS; channel++) \
41 for (slot = 0; slot < NUM_SLOTS; slot++) \
42 for (rank = 0; rank < NUM_RANKS; rank++)
44 #define FOR_POPULATED_RANKS \
45 for (channel = 0; channel < NUM_CHANNELS; channel++) \
46 for (slot = 0; slot < NUM_SLOTS; slot++) \
47 for (rank = 0; rank < NUM_RANKS; rank++) \
48 if (info->populated_ranks[channel][slot][rank])
50 #define FOR_POPULATED_RANKS_BACKWARDS \
51 for (channel = NUM_CHANNELS - 1; channel >= 0; channel--) \
52 for (slot = 0; slot < NUM_SLOTS; slot++) \
53 for (rank = 0; rank < NUM_RANKS; rank++) \
54 if (info->populated_ranks[channel][slot][rank])
67 asm volatile (
"movdqu %%xmm0, %0\n"
68 "movdqa (%2), %%xmm0\n"
70 "movdqu %0, %%xmm0":
"+m" (stor),
"=m"(ret):
"r"(
addr));
109 val &= ((1 << split) - 1);
116 asm volatile (
"sfence");
121 return 0x124 * lane + ((lane & 4) ? 0x23e : 0) + 11 * rank + 22 * slot -
127 const u16 offs[] = { 0x1d, 0xa8, 0xe6, 0x5c };
137 #define gav(x) gav_real (__LINE__, (x))
147 info->last_500_command[channel] = 1 << 31;
152 1 << 31 | (((
mchbar_read8(0x246 + (channel << 10)) >> 2) & 3) + 0xb88 -
addr));
156 return val & ((1 << split) - 1);
164 if (
info->last_500_command[channel] == 1 << 31) {
165 info->last_500_command[channel] = 1 << 30;
172 (
val & ((1 << bits) - 1)) | 2 << bits | flag << bits);
189 for (i = 0; i < 64; i++)
190 write32p((rank << 28) | (i << 2), 0);
192 for (i = 0; i < 64; i++)
195 for (i = 0; i < 32; i++) {
196 u32 pat = (((
mask >> i) & 1) ? 0xffffffff : 0);
197 write32p((rank << 28) | (i << 3), pat);
198 write32p((rank << 28) | (i << 3) | 4, pat);
201 for (i = 0; i < 32; i++) {
202 u8 pat = (((
mask >> i) & 1) ? 0xff : 0);
206 for (j = 0; j < 4; j++)
207 if (((
val >> (j * 8)) & 0xff) != pat)
210 for (j = 0; j < 4; j++)
211 if (((
val >> (j * 8)) & 0xff) != pat)
215 for (i = 0; i < 64; i++)
216 write32p((rank << 28) | (i << 2), 0);
218 for (i = 0; i < 64; i++)
228 for (lane = 0; lane < 8; lane++) {
232 lane_timings[2][channel][slot][rank][lane],
237 lane_timings[3][channel][slot][rank][lane],
252 if (reg32 & (1 << 1))
257 if (reg32 & (1 << 1))
267 while (!((ret =
mchbar_read32(0x580 + (channel << 10))) & (1 << 16)))
273 #define RANK_SHIFT 28
274 #define CHANNEL_SHIFT 10
280 for (i = 0; i < 2; i++)
281 for (lane = 0; lane < 8; lane++)
283 info->training.lane_timings[i +
292 for (lane = 0; lane < 8; lane++)
295 lane_timings[0][channel][slot][rank][lane],
298 for (i = 0; i < 2; i++) {
299 for (lane = 0; lane < 8; lane++)
301 info->training.lane_timings[i +
308 gav(
get_580(channel, ((i + 1) << 2) | (rank << 5)));
314 for (lane = 0; lane < 8; lane++) {
316 info->training.lane_timings[2][channel][slot][rank][lane] =
320 info->training.lane_timings[3][channel][slot][rank][lane] =
321 info->training.lane_timings[2][channel][slot][rank][lane] +
332 res +=
info->populated_ranks[channel][slot][rank];
368 const u16 regtable[] = { 0x4cf, 0x659, 0x697 };
371 for (
int i = 0; i <
ARRAY_SIZE(regtable); i++)
378 const u32 val3[] = { 0x2a2b2a2b, 0x26272627, 0x2e2f2e2f, 0x2a2b };
382 for (j = 0; j < 4; j++) {
383 u32 a = (j == 1) ? 0x29292929 : 0x31313131;
384 u32 lmask = (j == 3) ? 0xffff : 0xffffffff;
386 if ((j == 0 || j == 3) && zero)
393 for (k = 0; k < 2; k++) {
395 gav(vd8[1][(channel << 3) | (j << 1) | k] =
397 gav(vd8[0][(channel << 3) | (j << 1) | k] =
401 mchbar_write32(0x334 + (channel << 10) + j * 0x44, zero ? 0 : val3[j]);
403 zero ? 0 : 0x18191819 & lmask);
406 zero ? 0 : a & lmask);
408 zero ? 0 : a & lmask);
427 for (i = 15; i >= 0; i--)
436 for (i = 0; i < 32; i++)
462 unsigned int cycletime;
463 unsigned int cas_latency_time;
464 unsigned int supported_cas_latencies;
465 unsigned int channel, slot;
466 unsigned int clock_speed_index;
467 unsigned int min_cas_latency;
468 unsigned int cas_latency;
469 unsigned int max_clock_index;
472 supported_cas_latencies = 0x3fe;
475 if (
info->populated_ranks[channel][slot][0])
476 supported_cas_latencies &=
484 max_clock_index =
MIN(3,
info->max_supported_clock_speed_index);
491 if (
info->populated_ranks[channel][slot][0]) {
492 unsigned int timebase;
503 MAX(cas_latency_time,
509 die(
"RAM init: Decoded SPD DRAM freq is slower than the controller minimum!");
510 for (clock_speed_index = 0; clock_speed_index < 3; clock_speed_index++) {
519 min_cas_latency =
DIV_ROUND_UP(cas_latency_time, cycletime);
521 while (supported_cas_latencies) {
523 if (cas_latency <= min_cas_latency)
525 supported_cas_latencies &=
529 if (cas_latency != min_cas_latency && clock_speed_index)
533 die(
"Couldn't configure DRAM");
534 info->clock_speed_index = clock_speed_index;
535 info->cas_latency = cas_latency;
540 unsigned int channel;
541 unsigned int slot, rank, lane;
542 unsigned int extended_silicon_revision;
545 extended_silicon_revision =
info->silicon_revision;
546 if (
info->silicon_revision == 0)
552 extended_silicon_revision = 4;
556 for (rank = 0; rank <
NUM_SLOTS; rank++) {
558 if (!
info->populated_ranks[channel][slot][rank])
561 for (lane = 0; lane < 9; lane++) {
575 if (reference_card == 3)
580 if (reference_card == 5)
588 lane_timings[0][channel][slot][rank]
593 lane_timings[1][channel][slot][rank]
596 for (tm_reg = 2; tm_reg < 4; tm_reg++)
599 [channel][slot][rank][lane]
602 [extended_silicon_revision]
606 +
info->max4048[channel]
609 [extended_silicon_revision]
611 mode4030[channel]][slot]
615 for (tm_reg = 0; tm_reg < 4; tm_reg++)
619 [channel][slot][rank]
627 if (!(extended_silicon_revision != 4
629 populated_ranks_mask[channel] & 5) ==
647 for (i = 0; i < 3; i++)
650 info->max4048[channel]
653 [extended_silicon_revision]
655 mode4030[channel]][
info->
660 (
info->max4048[channel] +
662 [extended_silicon_revision][
info->
669 if (!
info->populated_ranks_mask[channel])
671 for (i = 0; i < 3; i++)
673 (
info->max4048[channel] +
674 info->avg4044[channel]
677 [extended_silicon_revision][
info->
709 unsigned int channel, slot, rank;
710 int extended_silicon_revision;
713 int some_delay_2_halfcycles_ceil;
714 int some_delay_2_halfcycles_floor;
716 int some_delay_3_ps_rounded;
717 int some_delay_1_cycle_ceil;
718 int some_delay_1_cycle_floor;
720 some_delay_3_ps_rounded = 0;
721 extended_silicon_revision =
info->silicon_revision;
722 if (!
info->silicon_revision)
728 extended_silicon_revision = 4;
729 if (
info->board_lane_delay[7] < 5)
730 info->board_lane_delay[7] = 5;
731 info->revision_flag_1 = 2;
732 if (
info->silicon_revision == 2 ||
info->silicon_revision == 3)
733 info->revision_flag_1 = 0;
734 if (
info->revision < 16)
735 info->revision_flag_1 = 0;
737 if (
info->revision < 8)
738 info->revision_flag_1 = 0;
739 if (
info->revision >= 8 && (
info->silicon_revision == 0
740 ||
info->silicon_revision == 1))
741 some_delay_2_ps = 735;
743 some_delay_2_ps = 750;
745 if (
info->revision >= 0x10 && (
info->silicon_revision == 0
746 ||
info->silicon_revision == 1))
747 some_delay_1_ps = 3929;
749 some_delay_1_ps = 3490;
751 some_delay_1_cycle_floor = some_delay_1_ps /
cycle_ps(
info);
752 some_delay_1_cycle_ceil = some_delay_1_ps /
cycle_ps(
info);
754 some_delay_1_cycle_ceil++;
756 some_delay_1_cycle_floor--;
757 info->some_delay_1_cycle_floor = some_delay_1_cycle_floor;
758 if (
info->revision_flag_1)
761 MAX(some_delay_1_ps - 30,
766 if (
info->revision_flag_1) {
767 if (some_delay_3_ps >= 150) {
768 const int some_delay_3_halfcycles =
770 some_delay_3_ps_rounded =
774 some_delay_2_halfcycles_ceil =
776 2 * (some_delay_1_cycle_ceil - 1);
777 if (
info->revision_flag_1 && some_delay_3_ps < 150)
778 some_delay_2_halfcycles_ceil++;
779 some_delay_2_halfcycles_floor = some_delay_2_halfcycles_ceil;
780 if (
info->revision < 0x10)
781 some_delay_2_halfcycles_floor =
782 some_delay_2_halfcycles_ceil - 1;
783 if (!
info->revision_flag_1)
784 some_delay_2_halfcycles_floor++;
785 info->some_delay_2_halfcycles_ceil = some_delay_2_halfcycles_ceil;
786 info->some_delay_3_ps_rounded = some_delay_3_ps_rounded;
787 if ((
info->populated_ranks[0][0][0] &&
info->populated_ranks[0][1][0])
788 || (
info->populated_ranks[1][0][0]
789 &&
info->populated_ranks[1][1][0]))
790 info->max_slots_used_in_channel = 2;
792 info->max_slots_used_in_channel = 1;
795 ((
info->revision < 8) ? 1 : 0x200) |
796 ((2 -
info->max_slots_used_in_channel) << 17) |
798 (
info->some_delay_1_cycle_floor << 18) | 0x9510);
799 if (
info->max_slots_used_in_channel == 1) {
815 if (!
info->populated_ranks_mask[channel])
819 min_of_unk_2 = 32767;
823 for (i = 0; i < 3; i++) {
825 if (
info->revision < 8)
831 (
info->revision >= 0x10
832 ||
info->revision_flag_1))
840 for (rank = 0; rank <
NUM_RANKS; rank++) {
845 populated_ranks[channel][slot]
848 if (extended_silicon_revision == 4
850 populated_ranks_mask[channel] &
873 min_of_unk_2 =
MIN(min_of_unk_2, a);
874 min_of_unk_2 =
MIN(min_of_unk_2, b);
883 [extended_silicon_revision]
885 mode4030[channel]][
info->
896 [extended_silicon_revision][
info->
899 [
info->clock_speed_index] + min_of_unk_2;
901 max_of_unk =
MAX(max_of_unk, unk1 - t);
906 die(
"No memory ranks found for channel %u\n", channel);
909 info->max4048[channel] = max_of_unk;
914 int channel,
int slot,
int rank,
915 int total_rank,
u8 addr3,
unsigned int value)
919 addr3 = (addr3 & 0xCF) | ((addr3 & 0x10) << 1) | ((addr3 >> 1) & 0x10);
954 int channel, slot, rank;
957 int self_refresh_temperature;
958 int auto_self_refresh;
960 auto_self_refresh = 1;
961 self_refresh_temperature = 1;
962 if (
info->board_lane_delay[3] <= 10) {
963 if (
info->board_lane_delay[3] <= 8)
964 write_recovery =
info->board_lane_delay[3] - 4;
973 self_refresh_temperature &=
976 if (auto_self_refresh == 1)
977 self_refresh_temperature = 0;
979 dll_on = ((
info->silicon_revision != 2 &&
info->silicon_revision != 3)
980 || (
info->populated_ranks[0][0][0]
981 &&
info->populated_ranks[0][1][0])
982 || (
info->populated_ranks[1][0][0]
983 &&
info->populated_ranks[1][1][0]));
987 for (channel =
NUM_CHANNELS - 1; channel >= 0; channel--) {
991 if (
info->silicon_revision == 2 ||
info->silicon_revision == 3) {
994 if (
info->clock_speed_index != 0) {
996 if (
info->populated_ranks_mask[channel] == 3)
1000 if ((
info->populated_ranks_mask[channel] & 5) == 5) {
1016 for (slot = 0; slot <
NUM_SLOTS; slot++)
1017 for (rank = 0; rank <
NUM_RANKS; rank++)
1018 if (
info->populated_ranks[channel][slot][rank]) {
1024 | (auto_self_refresh << 6) |
1025 (self_refresh_temperature <<
1028 total_rank, 0x38, 0);
1035 (write_recovery << 9)
1036 | ((
info->cas_latency - 4) <<
1046 unsigned int channel, slot, rank;
1047 unsigned int total_mb[2] = { 0, 0 };
1048 unsigned int channel_0_non_interleaved;
1051 if (
info->populated_ranks[channel][slot][rank]) {
1052 total_mb[channel] +=
1053 pre_jedec ? 256 : (256 <<
info->
1054 density[channel][slot] >>
info->
1055 is_x16_module[channel][slot]);
1057 (pre_jedec ? (1 | ((1 + 1) << 1)) :
1058 (
info->is_x16_module[channel][slot] |
1059 ((
info->density[channel][slot] + 1) << 1))) |
1063 total_mb[channel] >> 6);
1066 info->total_memory_mb = total_mb[0] + total_mb[1];
1068 info->interleaved_part_mb =
1069 pre_jedec ? 0 : 2 *
MIN(total_mb[0], total_mb[1]);
1070 info->non_interleaved_part_mb =
1071 total_mb[0] + total_mb[1] -
info->interleaved_part_mb;
1072 channel_0_non_interleaved = total_mb[0] -
info->interleaved_part_mb / 2;
1073 mchbar_write32(0x100, channel_0_non_interleaved |
info->non_interleaved_part_mb << 16);
1080 int cas_latency_shift;
1082 int some_delay_3_half_cycles;
1084 unsigned int channel, i;
1085 int high_multiplier;
1087 int cas_latency_derived;
1089 high_multiplier = 0;
1090 some_delay_ns = 200;
1091 some_delay_3_half_cycles = 4;
1092 cas_latency_shift =
info->silicon_revision == 0
1093 ||
info->silicon_revision == 1 ? 1 : 0;
1094 if (
info->revision < 8) {
1095 some_delay_ns = 600;
1096 cas_latency_shift = 0;
1101 ((
info->clock_speed_index > 1
1102 || (
info->silicon_revision != 2
1103 &&
info->silicon_revision != 3))) ^ (
info->revision >=
1109 if (
info->revision >= 0x10 &&
info->clock_speed_index <= 1
1110 && (
info->silicon_revision == 2
1111 ||
info->silicon_revision == 3))
1120 unsigned int some_delay_2_half_cycles;
1121 high_multiplier = 1;
1135 some_delay_3_half_cycles =
1136 MIN((some_delay_2_half_cycles +
1138 some_delay_2_half_cycles) /
1140 4 * (
info->fsb_frequency))) >> 3, 7);
1143 some_delay_3_half_cycles = 3;
1147 (
info->max_slots_used_in_channel - 1) |
1148 (
info->cas_latency - 5 -
info->clock_speed_index)
1149 << 21 | (
info->max_slots_used_in_channel +
1150 info->cas_latency - cas_latency_shift - 4) << 16 |
1151 (
info->cas_latency - cas_latency_shift - 4) << 26 |
1152 (
info->cas_latency -
info->clock_speed_index +
1153 info->max_slots_used_in_channel - 6) << 8);
1157 some_delay_3_half_cycles << 25 | 0x840000);
1161 (!!
info->clock_speed_index) << 17 |
1162 ((2 +
info->clock_speed_index -
1163 (!!
info->clock_speed_index))) << 12 | 0x10200);
1170 ((!
info->populated_ranks[channel][1][1])
1171 | (!
info->populated_ranks[channel][1][0] << 1)
1172 | (!
info->populated_ranks[channel][0][1] << 2)
1173 | (!
info->populated_ranks[channel][0][0] << 3)),
1179 u8 freq_divisor = 2;
1189 if (
info->board_lane_delay[3] <= 10) {
1190 if (
info->board_lane_delay[3] <= 8)
1191 lane_3_delay =
info->board_lane_delay[3];
1197 cas_latency_derived =
info->cas_latency -
info->clock_speed_index + 2;
1198 if (
info->clock_speed_index > 1)
1199 cas_latency_derived++;
1202 ((
info->clock_speed_index == 0) * 0x11000) |
1203 0x1002100 | (2 +
info->clock_speed_index) << 4 |
1204 (
info->cas_latency - 3));
1208 info->clock_speed_index + 2 *
info->cas_latency - 7,
1212 (lane_3_delay +
info->clock_speed_index + 9) << 6 |
1213 info->board_lane_delay[7] << 2 |
1214 info->board_lane_delay[4] << 16 |
1215 info->board_lane_delay[1] << 25 |
1216 info->board_lane_delay[1] << 29 | 1);
1218 info->board_lane_delay[1] >> 3 |
1219 (
info->board_lane_delay[8] + 4 *
info->use_ecc) << 6 |
1220 0x80 |
info->board_lane_delay[6] << 1 |
1221 info->board_lane_delay[2] << 28 |
1222 cas_latency_derived << 16 | 0x4700000);
1224 (
info->board_lane_delay[5] +
info->clock_speed_index + 9) << 12 |
1225 (
info->clock_speed_index -
info->cas_latency + 12) << 8 |
1226 info->board_lane_delay[2] << 17 |
1227 info->board_lane_delay[4] << 24 | 0x47);
1229 info->board_lane_delay[1] << 1 |
1230 info->board_lane_delay[0] << 8 | 0x1da50000);
1241 for (i = 0; i < 8; i++) {
1243 (
info->total_memory_mb - 64) | !i | 2);
1248 #define DEFAULT_PCI_MMIO_SIZE 2048
1252 unsigned int tom, tolud, touud;
1253 unsigned int quickpath_reserved;
1254 unsigned int remap_base;
1255 unsigned int uma_base_igd;
1256 unsigned int uma_base_gtt;
1257 unsigned int mmio_size;
1261 unsigned int current_limit;
1262 unsigned int tseg_base;
1263 int uma_size_igd = 0, uma_size_gtt = 0;
1267 if (
info->uma_enabled) {
1270 const int uma_sizes_gtt[16] =
1271 { 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 3, 4, 42, 42, 42, 42 };
1273 const int uma_sizes_igd[16] = {
1274 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352,
1278 uma_size_igd = uma_sizes_igd[(t >> 4) & 0xF];
1279 uma_size_gtt = uma_sizes_gtt[(t >> 8) & 0xF];
1284 tom =
info->total_memory_mb;
1291 if (touud - tolud > 64) {
1293 remap_base =
MAX(4096, touud);
1294 touud = touud - tolud + 4096;
1298 quickpath_reserved = 0;
1305 u32 shift = t >> 20;
1307 die(
"Quickpath value is 0\n");
1312 touud -= quickpath_reserved;
1314 uma_base_igd = tolud - uma_size_igd;
1315 uma_base_gtt = uma_base_igd - uma_size_gtt;
1316 tseg_base =
ALIGN_DOWN(uma_base_gtt, 64) - (CONFIG_SMM_TSEG_SIZE >> 20);
1318 tseg_base -= quickpath_reserved;
1329 if (
info->uma_enabled) {
1351 unsigned int channel;
1353 for (i = 0; i < 3; i++) {
1361 info->max_supported_clock_speed_index = (~capid0[1] & 7);
1363 if ((capid0[1] >> 11) & 1)
1364 info->uma_enabled = 0;
1369 info->silicon_revision = 0;
1371 if (capid0[2] & 2) {
1372 info->silicon_revision = 0;
1373 info->max_supported_clock_speed_index = 2;
1375 if (
info->populated_ranks[channel][0][0]
1378 info->silicon_revision = 2;
1379 info->max_supported_clock_speed_index = 1;
1382 switch (((capid0[2] >> 18) & 1) + 2 * ((capid0[1] >> 3) & 1)) {
1385 info->silicon_revision = 3;
1388 info->silicon_revision = 0;
1391 info->silicon_revision = 2;
1396 info->silicon_revision = 0;
1399 info->silicon_revision = 1;
1407 int tm, channel, slot, rank, lane;
1408 if (
info->revision < 8)
1411 for (tm = 0; tm < 4; tm++)
1413 for (slot = 0; slot <
NUM_SLOTS; slot++)
1414 for (rank = 0; rank <
NUM_RANKS; rank++)
1415 for (lane = 0; lane < 9; lane++)
1420 [channel][slot][rank]
1431 int channel, slot, rank, lane, i;
1436 for (lane = 0; lane < 9; lane++) {
1438 for (i = 0; i < 4; i++) {
1442 (lane, i, slot, rank),
1445 lane_timings[i][channel][slot][rank]
1452 info->training.reg_178);
1454 info->training.reg_10b);
1463 int channel, slot, rank, lane, i;
1465 train =
info->training;
1467 for (i = 0; i < 4; i++)
1478 train.
reg274265[channel][0] = reg32 >> 16;
1479 train.
reg274265[channel][1] = reg32 & 0xffff;
1491 &train,
sizeof(train));
1503 int ranks_in_channel;
1504 ranks_in_channel =
info->populated_ranks[channel][0][0]
1505 +
info->populated_ranks[channel][0][1]
1506 +
info->populated_ranks[channel][1][0]
1507 +
info->populated_ranks[channel][1][1];
1510 if (ranks_in_channel == 0)
1513 if (ranks_in_channel != ranks)
1516 if (
info->populated_ranks[channel][0][0] !=
1517 info->populated_ranks[channel][1][0])
1519 if (
info->populated_ranks[channel][0][1] !=
1520 info->populated_ranks[channel][1][1])
1522 if (
info->is_x16_module[channel][0] !=
info->is_x16_module[channel][1])
1524 if (
info->density[channel][0] !=
info->density[channel][1])
1531 int i, channel, slot, rank, lane;
1532 for (i = 0; i < 2; i++)
1533 for (slot = 0; slot <
NUM_SLOTS; slot++)
1534 for (rank = 0; rank <
NUM_RANKS; rank++)
1535 for (lane = 0; lane < 9; lane++)
1540 for (i = 1; i < 4; i++)
1542 for (slot = 0; slot <
NUM_SLOTS; slot++)
1543 for (rank = 0; rank <
NUM_RANKS; rank++)
1544 for (lane = 0; lane < 9; lane++) {
1547 [slot][rank][lane] =
1559 const u16 invmask[] = {
1560 0xaaaa, 0x6db6, 0x4924, 0xeeee, 0xcccc, 0x8888, 0x7bde, 0x739c,
1561 0x6318, 0x4210, 0xefbe, 0xcf3c, 0x8e38, 0x0c30, 0x0820
1571 ret = 0x1010101 << (comp4 - 1);
1574 if (flip ^ (((invmask[comp3] >> comp1) ^ comp2) & 1))
1582 msr_t msr = {.
lo = 0, .hi = 0 };
1596 msr.
hi = 0x0000000f;
1605 end = start + (
ALIGN_DOWN(size + 4096, 4096));
1629 if (nwrites >= 320) {
1640 int comp1, comp2, comp3;
1641 u32 failxor[2] = { 0, 0 };
1645 for (comp3 = 0; comp3 < 9 && failmask != 0xff; comp3++) {
1646 for (comp1 = 0; comp1 < 4; comp1++)
1647 for (comp2 = 0; comp2 < 60; comp2++) {
1650 comp3 * 8 * 60 + 2 * comp1 + 8 * comp2;
1651 read128((total_rank << 28) | (curroffset << 3),
1662 for (i = 0; i < 8; i++)
1663 if ((0xff << (8 * (i % 4))) & failxor[i / 4])
1672 0x3a9d5ab5, 0x576cb65b, 0x555773b6, 0x2ab772ee,
1673 0x555556ee, 0x3a9d5ab5, 0x576cb65b, 0x555773b6,
1674 0x2ab772ee, 0x555556ee, 0x5155a555, 0x5155a555,
1675 0x5155a555, 0x5155a555, 0x3a9d5ab5, 0x576cb65b,
1676 0x555773b6, 0x2ab772ee, 0x555556ee, 0x55d6b4a5,
1677 0x366d6b3a, 0x2ae5ddbb, 0x3b9ddbb7, 0x55d6b4a5,
1682 const u32 seed2[5] = {
1683 0x55555555, 0x33333333, 0x2e555a55, 0x55555555,
1687 r = seed2[(a + (a >= 10)) / 5];
1693 const u8 seed3[32] = {
1694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1695 0x00, 0x00, 0x38, 0x1c, 0x3c, 0x18, 0x38, 0x38,
1696 0x38, 0x38, 0x38, 0x38, 0x0f, 0x0f, 0x0f, 0x0f,
1697 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
1700 return (comp2 - ((seed3[comp5] >> (
x & 7)) & 1)) & 0x1f;
1706 int comp1 = (
addr >> 1) & 1;
1707 int comp2 = (
addr >> 3) & 0x1f;
1708 int comp3 = (
addr >> 8) & 0xf;
1709 int comp4 = (
addr >> 12) & 0xf;
1710 int comp5 = (
addr >> 16) & 0x1f;
1711 u32 mask_bit = ~(0x10001 << comp3);
1719 (comp3 >> 3) | (comp1 << 2) | 2)) & 1) ^ flip;
1723 (comp3 >> 3) | (comp1 << 2) | 0)) & 1) ^ flip;
1725 for (
byte = 0;
byte < 4;
byte++)
1727 make_shift(comp2, comp5, (
byte | (comp1 << 2)))) & 1)
1728 mask_byte |= 0xff << (8 * byte);
1730 return (mask_bit & mask_byte) | (part1 << comp3) | (part2 <<
1739 for (i = 0; i < 2048; i++)
1741 (i << 2),
get_etalon(flip, (block << 16) | (i << 2)));
1751 int comp1, comp2, comp3;
1757 for (comp3 = 0; comp3 < 2 && failmask != 0xff; comp3++) {
1758 for (comp1 = 0; comp1 < 16; comp1++)
1759 for (comp2 = 0; comp2 < 64; comp2++) {
1761 (totalrank << 28) | (
region << 25) | (block
1763 | (comp3 << 12) | (comp2 << 6) | (comp1 <<
1765 failxor[comp1 & 1] |=
1768 for (i = 0; i < 8; i++)
1769 if ((0xff << (8 * (i % 4))) & failxor[i / 4])
1781 for (i = 0; i < 8; i++)
1782 if (vals[i] < bound)
1794 for (i = 0; i < 8; i++)
1802 u8 fail_mask,
int margin,
int uplimit,
1807 for (lane = 0; lane < 8; lane++) {
1808 int is_fail = (fail_mask >> lane) & 1;
1809 switch (
state[lane]) {
1822 if (counter[lane] >= margin) {
1824 res_low[lane] =
val - margin + 1;
1836 res_high[lane] =
val - 1;
1840 if (
val == uplimit) {
1842 res_high[lane] = uplimit;
1854 u8 total_rank,
u8 reg_178,
int first_run,
int niter,
1862 unsigned short num_successfully_checked[8];
1866 for (i = 0; i < 8; i++)
1871 for (lane = 0; lane < 8; lane++)
1883 for (i = 0; i < 8; i++)
1895 upper_usable, reg1b3);
1901 for (lane = 0; lane < 8; lane++) {
1905 lower_usable[lane] +
1911 upper_usable[lane] +
1920 for (lane = 0; lane < 8; lane++)
1942 num_successfully_checked[lane] = 0;
1944 num_successfully_checked[lane] = -1;
1948 for (i = 0; i < niter; i++) {
1949 if (failmask == 0xFF)
1959 for (lane = 0; lane < 8; lane++)
1960 if (num_successfully_checked[lane] != 0xffff) {
1961 if ((1 << lane) & failmask) {
1966 [slot][rank][lane].smallest)
1967 num_successfully_checked
1970 num_successfully_checked
2013 num_successfully_checked[lane]
2020 for (lane = 0; lane < 8; lane++)
2042 num_successfully_checked[lane] = 0;
2044 num_successfully_checked[lane] = -1;
2048 for (i = 0; i < niter; i++) {
2049 if (failmask == 0xFF)
2060 for (lane = 0; lane < 8; lane++) {
2061 if (num_successfully_checked[lane] != 0xffff) {
2062 if ((1 << lane) & failmask) {
2069 num_successfully_checked
2072 num_successfully_checked
2115 num_successfully_checked[lane]
2123 for (lane = 0; lane < 8; lane++) {
2164 if (
lut16[
info->clock_speed_index] <= reg_500)
2165 reg_500 -=
lut16[
info->clock_speed_index];
2169 reg_500 +=
lut16[
info->clock_speed_index];
2206 for (lane = 0; lane < 8; lane++)
2216 int slot,
int rank,
int totalrank)
2220 u8 lower_usable[8], upper_usable[8];
2226 for (i = 0; i < 8; i++)
2231 for (lane = 0; lane < 8; lane++)
2242 for (i = 0; i < 2 && failmask != 0xff; i++) {
2253 die(
"Couldn't discover DRAM timings (1)\n");
2255 for (lane = 0; lane < 8; lane++) {
2258 if (
info->silicon_revision) {
2261 usable_length = upper_usable[lane] - lower_usable[lane];
2262 if (usable_length >= 20) {
2263 bias = usable_length / 2 - 10;
2271 (upper_usable[lane] + lower_usable[lane]) / 2 - bias,
2273 info->training.timing2_bounds[channel][slot][rank][lane][0] =
2274 info->training.lane_timings[2][channel][slot][rank][lane] +
2276 info->training.timing2_bounds[channel][slot][rank][lane][1] =
2277 info->training.lane_timings[2][channel][slot][rank][lane] +
2279 info->training.timing2_offset[channel][slot][rank][lane] =
2280 info->training.lane_timings[2][channel][slot][rank][lane];
2290 unsigned int sum = 0,
count = 0;
2292 u8 lower_margin, upper_margin;
2297 central_weight = 20;
2299 if (
info->silicon_revision == 1 && channel == 1) {
2303 populated_ranks_mask[1] ^ (
info->
2304 populated_ranks_mask[1] >> 2)) &
2308 if ((
info->populated_ranks_mask[0] & 5) == 5) {
2309 central_weight = 20;
2312 if (
info->clock_speed_index >= 2
2313 && (
info->populated_ranks_mask[0] & 5) == 5 && slot == 1) {
2314 if (
info->silicon_revision == 1) {
2318 central_weight = 10;
2325 central_weight = 20;
2330 if (
info->silicon_revision == 0 && channel == 0 && lane == 0) {
2332 central_weight = 20;
2341 if (largest - smallest + 1 >= 5) {
2342 unsigned int weight;
2344 weight = central_weight;
2346 weight = side_weight;
2347 sum += weight * (largest + smallest);
2353 die(
"Couldn't discover DRAM timings (2)\n");
2356 result -
timings[center_178][channel][slot][rank][lane].smallest;
2358 timings[center_178][channel][slot][rank][lane].largest -
result;
2359 if (upper_margin < 10 && lower_margin > 10)
2360 result -=
MIN(lower_margin - 10, 10 - upper_margin);
2361 if (upper_margin > 10 && lower_margin < 10)
2362 result +=
MIN(upper_margin - 10, 10 - lower_margin);
2366 #define STANDARD_MIN_MARGIN 5
2371 int lane, rank, slot, channel;
2373 int count = 0, sum = 0;
2378 margin[reg178] = -1;
2381 timings[reg178][channel][slot][rank][lane].largest -
2382 timings[reg178][channel][slot][rank][lane].
2384 if (curmargin < margin[reg178])
2385 margin[reg178] = curmargin;
2390 sum += weight * reg178;
2396 die(
"Couldn't discover DRAM timings (3)\n");
2400 for (threshold = 30; threshold >= 5; threshold--) {
2401 int usable_length = 0;
2402 int smallest_fount = 0;
2406 if (margin[reg178] >= threshold) {
2409 info->training.reg178_largest =
2413 if (!smallest_fount) {
2415 info->training.reg178_smallest =
2421 if (usable_length >= 0x21)
2434 if (!
info->cached_training)
2438 for (slot = 0; slot <
NUM_SLOTS; slot++)
2439 for (rank = 0; rank <
NUM_RANKS; rank++)
2440 for (lane = 0; lane < 8 +
info->use_ecc; lane++) {
2441 u16 cached_value, estimation_value;
2443 info->cached_training->
2446 if (cached_value >= 0x18
2447 && cached_value <= 0x1E7) {
2452 if (estimation_value <
2455 if (estimation_value >
2468 int channel, slot, rank, lane;
2475 info->training.reg178_center =
info->cached_training->reg178_center;
2476 info->training.reg178_smallest =
info->cached_training->reg178_smallest;
2477 info->training.reg178_largest =
info->cached_training->reg178_largest;
2479 &
info->cached_training->timing_bounds,
2480 sizeof(
info->training.timing_bounds));
2482 &
info->cached_training->timing_offset,
2483 sizeof(
info->training.timing_offset));
2494 for (tm = 0; tm < 2; tm++) {
2498 cached_training->reg178_smallest);
2507 for (i = 0; i < 2; i++) {
2508 for (lane = 0; lane < 8; lane++) {
2510 info->cached_training->
2524 [channel][slot][rank]
2527 (lane, 2, slot, rank),
2530 i ?
info->cached_training->
2543 info->cached_training->
2546 (i ?
info->cached_training->
2560 for (j = 0; j < 2; j++) {
2562 u8 expected_failmask;
2565 reg1b3 = (j == 1) + 4;
2567 j == i ? reg1b3 : (-reg1b3) & 0x3f;
2578 j == 0 ? 0x00 : 0xff;
2579 if (failmask != expected_failmask)
2592 info->training = *
info->cached_training;
2626 int lane, rank, slot, channel;
2634 switch (
info->clock_speed_index) {
2653 for (i = 0; i < niter; i++) {
2672 for (channel =
NUM_CHANNELS - 1; channel >= 0; channel--)
2673 for (slot = 0; slot <
NUM_SLOTS; slot++)
2674 for (rank = 0; rank <
NUM_RANKS; rank++) {
2676 [rank][0].smallest, 0, 16);
2678 populated_ranks[channel][slot]
2694 info->training.timing_bounds[0][channel][slot][rank][lane].
2699 info->training.timing_bounds[0][channel][slot][rank][lane].
2703 info->training.timing_bounds[1][channel][slot][rank][lane].
2707 info->training.timing_bounds[1][channel][slot][rank][lane].
2711 info->training.timing_offset[channel][slot][rank][lane] =
2712 info->training.lane_timings[1][channel][slot][rank][lane]
2714 info->training.lane_timings[0][channel][slot][rank][lane] +
2718 if (
info->silicon_revision == 1
2720 populated_ranks_mask[1] ^ (
info->
2721 populated_ranks_mask[1] >> 2)) & 1) {
2722 int ranks_after_channel1;
2729 for (slot = 0; slot <
NUM_SLOTS; slot++)
2730 for (rank = 0; rank <
NUM_RANKS; rank++) {
2732 populated_ranks[1][slot][rank]) {
2743 ranks_after_channel1 = totalrank;
2747 totalrank = ranks_after_channel1;
2749 for (slot = 0; slot <
NUM_SLOTS; slot++)
2750 for (rank = 0; rank <
NUM_RANKS; rank++)
2752 populated_ranks[0][slot][rank]) {
2813 if (
info->revision >= 8)
2818 if ((
info->silicon_revision == 2 ||
info->silicon_revision == 3)
2819 &&
info->clock_speed_index < 2)
2826 int slot, rank, lane;
2832 if (
info->revision < 8)
2835 for (slot = 0; slot <
NUM_SLOTS; slot++)
2836 for (rank = 0; rank <
NUM_RANKS; rank++)
2837 if (
info->populated_ranks[channel][slot][rank])
2838 for (lane = 0; lane < 8 +
info->use_ecc; lane++)
2867 if ((x2ca8 & 1) || (x2ca8 == 8 && !s3resume)) {
2882 ggc = 0xb00 | ((gfxsize + 5) << 4);
2898 RCBA8(0x2318) = 0x47;
2900 RCBA8(0x2320) = 0xfc;
2913 val |= (reg32 >> 4) & (1 << 0);
2914 val |= (reg32 >> 2) & (1 << 1);
2915 val |= (reg32 >> 0) & (1 << 2);
2921 unsigned int channel, slot, lane, rank;
2924 int cbmem_wasnot_inited;
2932 info.last_500_command[0] = 0;
2933 info.last_500_command[1] = 0;
2935 info.board_lane_delay[0] = 0x14;
2936 info.board_lane_delay[1] = 0x07;
2937 info.board_lane_delay[2] = 0x07;
2938 info.board_lane_delay[3] = 0x08;
2939 info.board_lane_delay[4] = 0x56;
2940 info.board_lane_delay[5] = 0x04;
2941 info.board_lane_delay[6] = 0x04;
2942 info.board_lane_delay[7] = 0x05;
2943 info.board_lane_delay[8] = 0x10;
2945 info.training.reg_178 = 0;
2946 info.training.reg_10b = 0;
2949 while (!(
read8((
u8 *)0xfed40000) & (1 << 7)))
2959 if (!s3resume || 1) {
2964 for (slot = 0; slot <
NUM_SLOTS; slot++) {
2968 const u8 useful_addresses[] = {
2980 0x11, 0x12, 0x13, 0x14, 0x15,
2981 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
2987 0x75, 0x76, 0x77, 0x78,
2988 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
2989 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84,
2990 0x85, 0x86, 0x87, 0x88,
2991 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
2992 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
2995 if (!spd_addrmap[2 * channel + slot])
2997 for (
try = 0;
try < 5;
try++) {
3009 spd[channel][0][useful_addresses
3015 die(
"Only DDR3 is supported");
3018 info.populated_ranks[channel][0][0] = 1;
3019 info.populated_ranks[channel][0][1] =
3021 if (((v >> 3) & 7) > 1)
3022 die(
"At most 2 ranks are supported");
3023 if ((v & 7) == 0 || (v & 7) > 2)
3024 die(
"Only x8 and x16 modules are supported");
3030 die(
"Registered memory is not supported");
3031 info.is_x16_module[channel][0] = (v & 7) - 1;
3032 info.density[channel][slot] =
3045 for (slot = 0; slot <
NUM_SLOTS; slot++)
3046 for (rank = 0; rank <
NUM_RANKS; rank++)
3049 << (2 * slot + rank);
3050 info.populated_ranks_mask[channel] = v;
3068 if (x2ca8 == 0 && (reg8 & 0x80)) {
3077 (reg8 & ~(1 << 7)));
3080 "Interrupted RAM init, reset required.\n");
3085 if (!s3resume && x2ca8 == 0)
3127 if (x2c20 == 0 && (x2c10 & 0x300) == 0)
3143 (
info.populated_ranks[0][0][0] * 0xa0));
3151 (
info.populated_ranks_mask[channel] & 3) << 20);
3198 if (
info.populated_ranks[channel][0][1] &&
info.clock_speed_index > 1)
3200 if (
info.silicon_revision == 0 ||
info.silicon_revision == 1)
3203 for (lane = 0; lane < 9; lane++) {
3210 if (
info.cached_training ==
NULL) {
3213 "Couldn't find training data. Rebooting\n");
3219 info.training = *
info.cached_training;
3220 for (tm = 0; tm < 4; tm++)
3222 for (slot = 0; slot <
NUM_SLOTS; slot++)
3223 for (rank = 0; rank <
NUM_RANKS; rank++)
3224 for (lane = 0; lane < 9; lane++)
3256 rmw_1d0(0x14b, 0x47, 0x30, 7);
3280 rmw_1d0(0x320, 0x38, val_2f3, 6);
3281 rmw_1d0(0x14b, 0x78, val_xa1, 7);
3282 rmw_1d0(0xce, 0x38, val_xa1, 6);
3309 info.populated_ranks[0][0][0] << 29);
3317 rmw_1d0(0x14b, 0x78, val_xa1, 7);
3329 0x3 & ~(
info.populated_ranks_mask[channel]), 0x6b7, 2,
3350 (
info.populated_ranks_mask[channel] & 3) << 16);
3355 (
info.populated_ranks_mask[channel] & 3) << 20);
3362 for (slot = 0; slot <
NUM_SLOTS; slot++)
3363 for (rank = 0; rank <
NUM_RANKS; rank++)
3364 if (
info.populated_ranks[channel][slot][rank]) {
3366 totalrank, 0xa, 0x400);
3378 (
info.populated_ranks_mask[channel] & 3) << 16);
3380 info.populated_ranks[channel][0][0] |
3381 info.populated_ranks[channel][0][1] << 5);
3403 for (slot = 0; slot <
NUM_SLOTS; slot++)
3404 for (rank = 0; rank <
NUM_RANKS; rank++)
3426 (
info.populated_ranks_mask[channel] & 3) << 16);
3428 info.populated_ranks[channel][0][0] |
3429 info.populated_ranks[channel][0][1] << 5);
3452 if (
info.non_interleaved_part_mb != 0 &&
info.interleaved_part_mb != 0)
3487 eax =
info.fsb_frequency / 9;
3489 (eax * 0x280) | (eax * 0x5000) | eax | 0x40000);
3495 if (
info.max_slots_used_in_channel == 1)
3502 if (
info.clock_speed_index <= 1 && (
info.silicon_revision == 2
3503 ||
info.silicon_revision == 3))
3514 if (!(
info.silicon_revision == 0 ||
info.silicon_revision == 1))
3516 al |= ((1 << (
info.max_slots_used_in_channel - 1)) - 1) << 4;
3524 (
info.max_slots_used_in_channel - 1) << 0x16);
3539 if (
info.revision == 0x10 ||
info.revision == 0x11) {
3557 if (
info.uma_enabled)
3572 if (reg_1020 != 0) {
3575 ebpb = reg_1020 & 0xff;
3585 mchbar_write32(0x1010, ((((ebpb + 0x7d) << 7) / bl) & 0xff) * !!reg_1020);
3590 if (reg_1020 != 0) {
3595 const u64 heci_uma_addr =
3598 info.memory_reserved_for_heci_mb)) << 20;
3602 if (
info.uma_enabled) {
3615 for (ecx = 0xffff; ecx && (
mchbar_read16(0x1170) & (1 << 12)); ecx--)
3631 if (s3resume && cbmem_wasnot_inited) {
static void write32(void *addr, uint32_t val)
static uint8_t read8(const void *addr)
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dstpp, int c, size_t len)
int intel_early_me_init(void)
int intel_early_me_uma_size(void)
#define DIV_ROUND_UP(x, y)
int cbmem_recovery(int s3resume)
#define printk(level,...)
void __noreturn die(const char *fmt,...)
void outl(u32 val, u16 port)
void raminit(struct romstage_params *params)
static struct smmstore_params_info info
static __always_inline uint8_t mchbar_read8(const uintptr_t offset)
#define mchbar_setbits32(addr, set)
static __always_inline void dmibar_write8(const uintptr_t offset, const uint8_t value)
static __always_inline void mchbar_write16(const uintptr_t offset, const uint16_t value)
static __always_inline void mchbar_write8(const uintptr_t offset, const uint8_t value)
static __always_inline uint32_t epbar_read32(const uintptr_t offset)
static __always_inline void mchbar_clrsetbits8(uintptr_t offset, uint8_t clear, uint8_t set)
static __always_inline void mchbar_write32(const uintptr_t offset, const uint32_t value)
#define mchbar_clrbits8(addr, clear)
#define mchbar_clrbits16(addr, clear)
#define mchbar_setbits8(addr, set)
#define dmibar_setbits32(addr, set)
static __always_inline void mchbar_clrsetbits32(uintptr_t offset, uint32_t clear, uint32_t set)
static __always_inline uint32_t mchbar_read32(const uintptr_t offset)
#define mchbar_clrbits32(addr, clear)
static __always_inline void mchbar_clrsetbits16(uintptr_t offset, uint16_t clear, uint16_t set)
static __always_inline uint16_t mchbar_read16(const uintptr_t offset)
static __always_inline uint8_t dmibar_read8(const uintptr_t offset)
#define mchbar_setbits16(addr, set)
static __always_inline void dmibar_write16(const uintptr_t offset, const uint16_t value)
static __always_inline void epbar_write32(const uintptr_t offset, const uint32_t value)
void __noreturn halt(void)
halt the system reliably
static void clflush(void *addr)
static __always_inline msr_t rdmsr(unsigned int index)
static __always_inline void wrmsr(unsigned int index, msr_t msr)
static __always_inline uint32_t read32p(const uintptr_t addr)
static __always_inline void write32p(const uintptr_t addr, const uint32_t value)
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
static int smbus_read_byte(struct device *const dev, u8 addr)
static unsigned int halfcycle_ps(struct raminfo *info)
static unsigned int frequency_11(struct raminfo *info)
static unsigned int fsbcycle_ps(struct raminfo *info)
const u16 u16_fffd0c70[2][2]
const u16 u16_fffd0c50[3][2][2]
const u8 u8_FFFD1891[2][2][4][12]
const u16 min_cas_latency_time[4]
const u16 u16_FFFE0EB8[2][4]
const u16 min_cycletime[4]
const u16 u16_fe0eb8[2][4]
const u16 u16_ffd1188[2][9][4]
const u8 u8_FFFD0C78[2][5][4][2][2][4]
const u16 u16_ffd1178[2][4]
const u16 u16_fffd0c68[3]
const u8 u8_FFFD1240[2][5][9][4][4]
const u8 u8_FFFD17E0[2][5][4][4]
const u8 u8_FFFD0EF8[2][5][4][4]
#define SAD_INTERLEAVE_LIST(x)
void timestamp_add_now(enum timestamp_id id)
int ram_check_nodie(uintptr_t start)
#define BIOS_INFO
BIOS_INFO - Expected events.
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
int mrc_cache_stash_data(int type, uint32_t version, const void *data, size_t size)
Returns < 0 on error, 0 on success.
void * mrc_cache_current_mmap_leak(int type, uint32_t version, size_t *data_size)
mrc_cache_mmap_leak
#define MRC_CACHE_VERSION
static struct map_entry memory_map[NUM_MAP_ENTRIES]
static u32 get_580(int channel, u8 addr)
static u32 get_etalon2(int flip, u32 addr)
static void dmi_setup(void)
static void calculate_timings(struct raminfo *info)
static void set_ecc(int onoff)
static const struct ram_training * get_cached_training(void)
static void write_training_data(struct raminfo *info)
static u32 get_seed2(int a, int b)
static void set_10b(struct raminfo *info, u8 val)
static void dump_timings(struct raminfo *info)
static void seq9(struct raminfo *info, int channel, int slot, int rank)
static int count_ranks_in_channel(struct raminfo *info, int channel)
static int rw_test(int rank)
static void enable_cache_region(unsigned int base, unsigned int size)
static void config_rank(struct raminfo *info, int s3resume, int channel, int slot, int rank)
static int check_bounded(unsigned short *vals, u16 bound)
static void compute_derived_timings(struct raminfo *info)
static void rmw_1d0(u16 addr, u32 and, u32 or, int split)
static unsigned int frequency_01(struct raminfo *info)
static unsigned int ps_to_halfcycles(struct raminfo *info, unsigned int ps)
static void program_timings(struct raminfo *info, u16 base, int channel, int slot, int rank)
static void train_ram_at_178(struct raminfo *info, u8 channel, int slot, int rank, u8 total_rank, u8 reg_178, int first_run, int niter, timing_bounds_t *timings)
static void read128(u32 addr, u64 *out)
static void write_testing_type2(struct raminfo *info, u8 totalrank, u8 region, u8 block, char flip)
static unsigned int ns_to_cycles(struct raminfo *info, unsigned int ns)
#define DEFAULT_PCI_MMIO_SIZE
static u32 gav_real(int line, u32 in)
static void clear_errors(void)
static void rmw_500(struct raminfo *info, int channel, u16 addr, int bits, u32 and, u32 or)
static u8 get_bits_420(const u32 reg32)
static u8 choose_training(struct raminfo *info, int channel, int slot, int rank, int lane, timing_bounds_t *timings, u8 center_178)
static void collect_system_info(struct raminfo *info)
static u8 choose_reg178(struct raminfo *info, timing_bounds_t *timings)
static void disable_cache_region(void)
static void write_testing(struct raminfo *info, int totalrank, int flip)
static void do_ram_training(struct raminfo *info)
timing_bounds_t timings_car[64]
static void toggle_1d0_142_5ff(void)
static u8 check_testing(struct raminfo *info, u8 total_rank, int flip)
@ REFERENCE_RAW_CARD_USED
u16 get_max_timing(struct raminfo *info, int channel)
static void set_178(u8 val)
static void save_timings(struct raminfo *info)
static int validate_state(enum state *in)
static void ram_training(struct raminfo *info)
static int find_highest_bit_set(u16 val)
static void write_26c(int channel, u16 si)
static int make_shift(int comp2, int comp5, int x)
static u16 get_timing_register_addr(int lane, int tm, int slot, int rank)
static void write_1d0(u32 val, u16 addr, int bits, int flag)
static unsigned int cycle_ps(struct raminfo *info)
static void program_base_timings(struct raminfo *info)
static void program_total_memory_map(struct raminfo *info)
#define FOR_POPULATED_RANKS_BACKWARDS
static void program_board_delay(struct raminfo *info)
static u32 get_etalon(int flip, u32 addr)
static void read_4090(struct raminfo *info)
static u8 check_testing_type2(struct raminfo *info, u8 totalrank, u8 region, u8 block, char flip)
static void do_fsm(enum state *state, u16 *counter, u8 fail_mask, int margin, int uplimit, u8 *res_low, u8 *res_high, u8 val)
static void set_334(int zero)
static void write_500_timings_type(struct raminfo *info, int channel, int slot, int rank, int type)
static u16 get_lane_offset(int slot, int rank, int lane)
#define STANDARD_MIN_MARGIN
static void write_500(struct raminfo *info, int channel, u32 val, u16 addr, int bits, int flag)
static int have_match_ranks(struct raminfo *info, int channel, int ranks)
void chipset_init(const int s3resume)
static int check_cached_sanity(struct raminfo *info)
static void flush_cache(u32 start, u32 size)
static int find_lowest_bit_set32(u32 val)
static u16 read_500(struct raminfo *info, int channel, u16 addr, int split)
static void jedec_init(struct raminfo *info)
static void program_modules_memory_map(struct raminfo *info, int pre_jedec)
static u16 read_1d0(u16 addr, int split)
static int try_cached_training(struct raminfo *info)
static void set_4cf(struct raminfo *info, int channel, u8 bit, u8 val)
static void jedec_read(struct raminfo *info, int channel, int slot, int rank, int total_rank, u8 addr3, unsigned int value)
static void try_timing_offsets(struct raminfo *info, int channel, int slot, int rank, int totalrank)
#define FOR_POPULATED_RANKS
unsigned int get_uint_option(const char *name, const unsigned int fallback)
u32 read_pmbase32(const u8 addr)
void write_pmbase32(const u8 addr, const u32 val)
void late_quickpath_init(struct raminfo *info, const int s3resume)
void early_quickpath_init(struct raminfo *info, const u8 x2ca8)
void setup_heci_uma(u64 heci_uma_addr, unsigned int heci_uma_size)
u16 timing_offset[2][2][2][9]
u16 timing2_offset[2][2][2][9]
timing_bounds_t timing_bounds[2]
u16 timing2_bounds[2][2][2][9][2]
u16 lane_timings[4][2][2][2][9]
u8 populated_ranks[2][2][2]
#define c(value, pmcreg, dst_bits)
#define MTRR_PHYS_BASE(reg)
#define MTRR_PHYS_MASK(reg)