18 #if CONFIG(DEBUG_RAM_SETUP)
19 #define PRINTK_DEBUG(x...) printk(BIOS_DEBUG, x)
21 #define PRINTK_DEBUG(x...)
24 #define MAX_TCLK_667 0x30
25 #define MAX_TCLK_800 0x25
26 #define MAX_TAC_667 0x45
27 #define MAX_TAC_800 0x40
29 #define NOP_CMD (1 << 1)
30 #define PRE_CHARGE_CMD (1 << 2)
31 #define MRS_CMD ((1 << 2) | (1 << 1))
32 #define EMRS_CMD (1 << 3)
33 #define EMRS1_CMD (EMRS_CMD | (1 << 4))
34 #define EMRS2_CMD (EMRS_CMD | (1 << 5))
35 #define EMRS3_CMD (EMRS_CMD | (1 << 5) | (1 << 4))
36 #define ZQCAL_CMD ((1 << 3) | (1 << 1))
37 #define CBR_CMD ((1 << 3) | (1 << 2))
38 #define NORMAL_OP_CMD ((1 << 3) | (1 << 2) | (1 << 1))
43 #define TOTAL_CHANNELS 1
46 #define DIMM_IS_POPULATED(dimms, idx) (dimms[idx].card_type != 0)
47 #define IF_DIMM_POPULATED(dimms, idx) if (dimms[idx].card_type != 0)
48 #define ONLY_DIMMA_IS_POPULATED(dimms, ch) (\
49 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
50 !DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3)))
51 #define ONLY_DIMMB_IS_POPULATED(dimms, ch) (\
52 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3) && \
53 !DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2)))
54 #define BOTH_DIMMS_ARE_POPULATED(dimms, ch) (\
55 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
56 (DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3))))
57 #define FOR_EACH_DIMM(idx) \
58 for (idx = 0; idx < TOTAL_DIMMS; ++idx)
59 #define FOR_EACH_POPULATED_DIMM(dimms, idx) \
60 FOR_EACH_DIMM(idx) IF_DIMM_POPULATED(dimms, idx)
61 #define CHANNEL_IS_POPULATED(dimms, idx) ((dimms[idx<<1].card_type != 0) || (dimms[(idx<<1) + 1].card_type != 0))
62 #define CHANNEL_IS_CARDF(dimms, idx) ((dimms[idx<<1].card_type == 0xf) || (dimms[(idx<<1) + 1].card_type == 0xf))
63 #define IF_CHANNEL_POPULATED(dimms, idx) if ((dimms[idx<<1].card_type != 0) || (dimms[(idx<<1) + 1].card_type != 0))
64 #define FOR_EACH_CHANNEL(idx) \
65 for (idx = 0; idx < TOTAL_CHANNELS; ++idx)
66 #define FOR_EACH_POPULATED_CHANNEL(dimms, idx) \
67 FOR_EACH_CHANNEL(idx) IF_CHANNEL_POPULATED(dimms, idx)
69 #define RANKS_PER_CHANNEL 4
71 #define FOR_EACH_RANK_IN_CHANNEL(r) \
72 for (r = 0; r < RANKS_PER_CHANNEL; ++r)
73 #define FOR_EACH_POPULATED_RANK_IN_CHANNEL(dimms, ch, r) \
74 FOR_EACH_RANK_IN_CHANNEL(r) if (rank_is_populated(dimms, ch, r))
75 #define FOR_EACH_RANK(ch, r) \
76 FOR_EACH_CHANNEL(ch) FOR_EACH_RANK_IN_CHANNEL(r)
77 #define FOR_EACH_POPULATED_RANK(dimms, ch, r) \
78 FOR_EACH_RANK(ch, r) if (rank_is_populated(dimms, ch, r))
82 return ((dimms[
ch<<1].card_type && ((r) < dimms[
ch<<1].ranks))
83 || (dimms[(
ch<<1) + 1].card_type
85 && ((r) < (dimms[(
ch<<1) + 1].ranks + 2))));
90 __asm__ __volatile__(
"": : :
"memory");
119 #if CONFIG(DEBUG_RAM_SETUP)
120 const char *ubso[2] = {
"UB",
"SO" };
146 if (
s->dimms[chan>>1].sides == 0) {
148 if (
s->dimms[(chan>>1) + 1].sides == 0) {
150 s->dimm_config[chan] = 0;
151 }
else if (
s->dimms[(chan>>1) + 1].sides == 1) {
153 if (
s->dimms[(chan>>1) + 1].width == 0) {
155 s->dimm_config[chan] = 1;
158 s->dimm_config[chan] = 1;
162 if (
s->dimms[(chan>>1) + 1].width == 0) {
164 s->dimm_config[chan] = 5;
167 s->dimm_config[chan] = 2;
170 }
else if (
s->dimms[chan>>1].sides == 1) {
172 if (
s->dimms[(chan>>1) + 1].sides == 0) {
174 if (
s->dimms[chan>>1].width == 0) {
176 s->dimm_config[chan] = 1;
179 s->dimm_config[chan] = 1;
181 }
else if (
s->dimms[(chan>>1) + 1].sides == 1) {
183 if (
s->dimms[chan>>1].width == 0) {
184 if (
s->dimms[(chan>>1) + 1].width == 0) {
186 s->dimm_config[chan] = 3;
189 die(
"Mixed Not supported\n");
192 if (
s->dimms[(chan>>1) + 1].width == 0) {
194 die(
"Mixed Not supported\n");
197 s->dimm_config[chan] = 3;
202 if (
s->dimms[chan>>1].width == 0) {
203 if (
s->dimms[(chan>>1) + 1].width == 0) {
205 die(
"Mixed Not supported\n");
207 die(
"Mixed Not supported\n");
210 if (
s->dimms[(chan>>1) + 1].width == 0) {
212 die(
"Mixed Not supported\n");
214 die(
"Mixed Not supported\n");
220 if (
s->dimms[(chan>>1) + 1].sides == 0) {
222 if (
s->dimms[chan>>1].width == 0) {
224 s->dimm_config[chan] = 5;
226 s->dimm_config[chan] = 4;
228 }
else if (
s->dimms[(chan>>1) + 1].sides == 1) {
230 if (
s->dimms[chan>>1].width == 0) {
231 if (
s->dimms[(chan>>1) + 1].width == 0) {
233 die(
"Mixed Not supported\n");
236 die(
"Mixed Not supported\n");
239 if (
s->dimms[(chan>>1) + 1].width == 0) {
240 die(
"Mixed Not supported\n");
243 s->dimm_config[chan] = 4;
248 if (
s->dimms[chan>>1].width == 0 &&
s->dimms[(chan>>1)+1].width == 0) {
250 s->dimm_config[chan] = 6;
261 if (i2c_eeprom_read(
s->spd_map[i], 0, 64,
s->dimms[i].spd_data) != 64)
262 s->dimms[i].card_type = 0;
264 s->dimms[i].card_type =
s->dimms[i].spd_data[62] & 0x1f;
270 switch (
s->dimms[i].spd_data[2]) {
276 die(
"DIMM type mismatch\n");
284 s->dt0mode |= (
s->dimms[i].spd_data[49] & 0x2) >> 1;
287 die(
"No memory dimms, halt\n");
292 PRINTK_DEBUG(
" Config[CH%d] : %d\n", chan,
s->dimm_config[chan]);
296 #if CONFIG(DEBUG_RAM_SETUP)
297 static u32 fsb_reg_to_mhz(
u32 speed)
299 return (speed * 133) + 667;
302 static u32 ddr_reg_to_mhz(
u32 speed)
304 return (speed == 0) ? 667 : (speed == 1) ? 800 : 0;
312 for (
int i = 0; i < 8; i++)
322 for (
int i = 7; i >= 0; i--)
330 static const u16 mult[6] = {
346 maxtras =
MAX(maxtras, (
s->dimms[i].spd_data[30] * 1000));
347 maxtrp =
MAX(maxtrp, (
s->dimms[i].spd_data[27] * 1000) >> 2);
348 maxtrcd =
MAX(maxtrcd, (
s->dimms[i].spd_data[29] * 1000) >> 2);
349 maxtwr =
MAX(maxtwr, (
s->dimms[i].spd_data[36] * 1000) >> 2);
350 maxtrfc =
MAX(maxtrfc, (
s->dimms[i].spd_data[42] * 1000) +
351 (
s->dimms[i].spd_data[40] & 0xf));
352 maxtwtr =
MAX(maxtwtr, (
s->dimms[i].spd_data[37] * 1000) >> 2);
353 maxtrrd =
MAX(maxtrrd, (
s->dimms[i].spd_data[28] * 1000) >> 2);
354 maxtrtp =
MAX(maxtrtp, (
s->dimms[i].spd_data[38] * 1000) >> 2);
362 mult[
s->selected_timings.mem_clock]));
364 mult[
s->selected_timings.mem_clock]));
366 mult[
s->selected_timings.mem_clock]));
368 mult[
s->selected_timings.mem_clock]));
371 mult[
s->selected_timings.mem_clock])) + 1);
373 mult[
s->selected_timings.mem_clock]));
375 mult[
s->selected_timings.mem_clock]));
377 mult[
s->selected_timings.mem_clock]));
380 PRINTK_DEBUG(
"\tFSB: %dMHz\n", fsb_reg_to_mhz(
s->selected_timings.fsb_clock));
381 PRINTK_DEBUG(
"\tDDR: %dMHz\n", ddr_reg_to_mhz(
s->selected_timings.mem_clock));
425 commoncas &=
s->dimms[i].spd_data[18];
427 if (commoncas == 0) {
428 die(
"No common CAS among dimms\n");
438 lowcas =
MAX(lsbp, 5);
440 while (cas == 0 && highcas >= lowcas) {
444 if ((
s->dimms[i].spd_data[9] > 0x25) ||
445 (
s->dimms[i].spd_data[10] > 0x40)) {
455 if ((
s->dimms[i].spd_data[9] > 0x30) ||
456 (
s->dimms[i].spd_data[10] > 0x45)) {
467 if (highcas < lowcas) {
471 PRINTK_DEBUG(
"Run DDR clock speed reduced due to timings\n");
473 die(
"Timings not supported by MCH\n");
478 while (cas == 0 && highcas >= lowcas) {
480 if ((
s->dimms[i].spd_data[9] > 0x30) ||
481 (
s->dimms[i].spd_data[10] > 0x45)) {
490 die(
"Unsupported dimms\n");
494 s->selected_timings.CAS = cas;
495 s->selected_timings.mem_clock =
freq;
496 s->selected_timings.fsb_clock = fsb;
498 PRINTK_DEBUG(
"Drive Memory at %dMHz with CAS = %d clocks\n",
499 ddr_reg_to_mhz(
s->selected_timings.mem_clock),
s->selected_timings.CAS);
529 (
uint8_t)
s->selected_timings.mem_clock & 0xff);
535 u8 ddr_freq, fsb_freq;
536 static const u32 clkcross[2][2][4] = {
538 {0xffffffff, 0x05030305, 0x0000ffff, 0x00000000},
539 {0x1f1f1f1f, 0x2a1f1fa5, 0x00000000, 0x05000002},
542 {0x1f1f1f1f, 0x0d07070b, 0x00000000, 0x00000000},
543 {0xffffffff, 0x05030305, 0x0000ffff, 0x00000000},
547 ddr_freq =
s->selected_timings.mem_clock;
548 fsb_freq =
s->selected_timings.fsb_clock;
558 if ((fsb_freq == 0) && (ddr_freq == 1)) {
564 static const u32 clkcross2[2][2][8] = {
567 0x00000000, 0x08010204, 0x00000000, 0x08010204,
568 0x00000000, 0x00000000, 0x00000000, 0x04080102,
571 0x04080000, 0x10010002, 0x10000000, 0x20010208,
572 0x00000000, 0x00000004, 0x02040000, 0x08100102,
577 0x10000000, 0x20010208, 0x04080000, 0x10010002,
578 0x00000000, 0x00000000, 0x08000000, 0x10200204,
581 0x00000000, 0x08010204, 0x00000000, 0x08010204,
582 0x00000000, 0x00000000, 0x00000000, 0x04080102,
614 mpll_ctl = (1 << 8) | (1 << 5);
622 const u32 cas_to_reg[2][4] = {
623 {0x00000000, 0x00030100, 0x0c240201, 0x00000000},
624 {0x00000000, 0x00030100, 0x0c240201, 0x10450302}
632 u8 i, j,
ch, r, ta1, ta2, ta3, ta4, trp, bank, page, flag;
637 static const u8 pagetab[2][2] = {
643 wl =
s->selected_timings.CAS - 1;
645 ta3 =
s->selected_timings.CAS;
647 s->selected_timings.tRFC = (
s->selected_timings.tRFC + 1) & 0xfe;
656 if (
s->dimms[i].banks == 1) {
660 if (
s->dimms[i].page_size == 2048) {
664 PRINTK_DEBUG(
"trp=%d bank=%d page=%d\n",trp, bank, page);
674 (2 +
MAX(
s->selected_timings.tRTP, 2)) << 2 | 1);
676 reg32 = (bank << 21) | (
s->selected_timings.tRRD << 17) |
677 (
s->selected_timings.tRP << 13) | ((
s->selected_timings.tRP + trp) << 9) |
678 s->selected_timings.tRFC;
681 reg32 |= (pagetab[flag][page] << 22);
691 reg16 = (
s->selected_timings.tRCD << 12) | (4 << 8) | (ta2 << 4) | ta4;
694 reg32 = (
s->selected_timings.tRCD << 17) | ((wl + 4 +
s->selected_timings.tWTR) << 12) |
695 (ta3 << 8) | (4 << 4) | ta1;
698 reg16 = ((
s->selected_timings.tRP + trp) << 9) |
s->selected_timings.tRFC;
719 reg16 = (
u16)((((
s->selected_timings.CAS + 7) * (reg32)) / reg2) << 8);
726 reg16 = (
u8) (wl - 1 - flag);
754 i =
s->selected_timings.mem_clock;
755 j =
s->selected_timings.fsb_clock;
765 reg16 |= (0x6 << 12);
768 reg32 = (0x6 << 27) | (1 << 25);
775 reg32 = ((6 & 3) << 30) | (4 << 25) | (1 << 20) | (8 << 15) | (6 << 10) | (4 << 5) | 1;
786 reg8 |= (
s->dt0mode << 4);
794 reg32 = (2 << 29) | (1 << 28) | (1 << 23);
811 for (i = 0; i < 8; i++) {
819 for (i = 0; i < 8; i++) {
836 (
pll->clkdelay[f][i] << 14) |
837 (
pll->dben[f][i] << 10) |
838 (
pll->dbsel[f][i] << 6));
847 (
pll->clkdelay[f][i] << 16) |
848 (
pll->dben[f][i] << 11) |
849 (
pll->dbsel[f][i] << 7));
859 reg8 =
pll->dbsel[f][i] << 5;
860 reg8 |=
pll->dben[f][i] << 6;
863 reg8 =
pll->clkdelay[f][i] << 4;
866 reg8 =
pll->pi[f][i];
878 reg32 = ((
u32)
pll->dbsel[f][i]) << 20;
879 reg32 |= ((
u32)
pll->dben[f][i]) << 21;
880 reg32 |= ((
u32)
pll->dbsel[f][i]) << 22;
881 reg32 |= ((
u32)
pll->dben[f][i]) << 23;
882 reg32 |= ((
u32)
pll->clkdelay[f][i]) << 24;
883 reg32 |= ((
u32)
pll->clkdelay[f][i]) << 27;
886 reg8 =
pll->pi[f][i];
891 reg32 = ((
u32)
pll->dbsel[f][i]) << 12;
892 reg32 |= ((
u32)
pll->dben[f][i]) << 13;
893 reg32 |= ((
u32)
pll->dbsel[f][i]) << 8;
894 reg32 |= ((
u32)
pll->dben[f][i]) << 9;
895 reg32 |= ((
u32)
pll->clkdelay[f][i]) << 14;
896 reg32 |= ((
u32)
pll->clkdelay[f][i]) << 10;
899 reg8 =
pll->pi[f][i];
906 u8 rank, dqs, reg8, j;
915 reg32 |= ((
u32)
pll->dben[f][clk]) << (dqs + 9);
916 reg32 |= ((
u32)
pll->dbsel[f][clk]) << dqs;
920 reg32 = ((
u32)
pll->clkdelay[f][clk]) << ((dqs * 2) + 16);
924 reg8 =
pll->pi[f][clk];
930 u8 rank, dq, reg8, j;
939 reg32 |= ((
u32)
pll->dben[f][clk]) << (dq + 9);
940 reg32 |= ((
u32)
pll->dbsel[f][clk]) << dq;
944 reg32 = ((
u32)
pll->clkdelay[f][clk]) << (dq*2);
947 reg8 =
pll->pi[f][clk];
957 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
958 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4,
959 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
960 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3,
961 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
962 0, 0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 3,
965 53, 53, 10, 10, 5, 5, 5, 5, 27, 27, 27, 27,
966 34, 34, 34, 34, 34, 34, 34, 34, 39, 39, 39, 39,
967 47, 47, 47, 47, 44, 44, 44, 44, 47, 47, 47, 47,
968 47, 47, 47, 47, 59, 59, 59, 59, 2, 2, 2, 2,
969 2, 2, 2, 2, 7, 7, 7, 7, 15, 15, 15, 15,
970 12, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15,
975 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
976 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
977 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
978 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
979 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
980 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
983 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
984 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
985 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
986 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
987 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
988 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
993 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
994 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
995 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
996 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
997 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
998 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1001 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
1002 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1003 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1004 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1005 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
1006 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1011 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
1012 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1013 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1014 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1015 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1016 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1019 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1020 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1021 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1022 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
1023 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1024 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1034 for (i = 0; i < 72; i++) {
1035 pll.pi[f][i] += pidelay;
1047 for (i = 0; i < 32; i++) {
1050 for (i = 0; i < 32; i++) {
1132 for (i = 0; i < 8; i++) {
1182 reg16 |= (1 << 8) | (1 << 4) | (1 << 0);
1185 reg16 |= (1 << 9) | (1 << 5) | (1 << 1);
1188 reg16 |= (1 << 10) | (1 << 6) | (1 << 2);
1191 reg16 |= (1 << 11) | (1 << 7) | (1 << 3);
1197 #define TABLE static const
1200 #define FOR_EACH_RCOMP_GROUP(idx) for (idx = 0; idx < 7; idx++) if (idx != 1)
1203 #define C0RCOMPCTRLx(x) (rcompctl[(x)] + 0x00)
1204 #define C0RCOMPMULTx(x) (rcompctl[(x)] + 0x04)
1205 #define C0RCOMPOVRx(x) (rcompctl[(x)] + 0x06)
1206 #define C0RCOMPOSVx(x) (rcompctl[(x)] + 0x0a)
1207 #define C0SCOMPVREFx(x) (rcompctl[(x)] + 0x0e)
1208 #define C0SCOMPOVRx(x) (rcompctl[(x)] + 0x10)
1209 #define C0SCOMPOFFx(x) (rcompctl[(x)] + 0x12)
1210 #define C0DCOMPx(x) (rcompctl[(x)] + 0x14)
1211 #define C0SLEWBASEx(x) (rcompctl[(x)] + 0x16)
1212 #define C0SLEWPULUTx(x) (rcompctl[(x)] + 0x18)
1213 #define C0SLEWPDLUTx(x) (rcompctl[(x)] + 0x1c)
1214 #define C0DCOMPOVRx(x) (rcompctl[(x)] + 0x20)
1215 #define C0DCOMPOFFx(x) (rcompctl[(x)] + 0x24)
1220 u8 i, j, reg8, rcompp, rcompn, srup, srun;
1222 u32 reg32, rcomp1, rcomp2;
1224 static const u8 rcompslew = 0x0a;
1225 static const u16 rcompctl[7] = {
1236 TABLE u8 rcompupdate[7] = { 0, 0, 0, 1, 1, 0, 0};
1237 TABLE u8 rcompstr[7] = { 0x66, 0x00, 0xaa, 0x55, 0x55, 0x77, 0x77};
1238 TABLE u16 rcompscomp[7] = {0xa22a, 0x0000, 0xe22e, 0xe22e, 0xe22e, 0xa22a, 0xa22a};
1239 TABLE u8 rcompdelay[7] = { 1, 0, 0, 0, 0, 1, 1};
1240 TABLE u16 rcompf[7] = {0x1114, 0x0000, 0x0505, 0x0909, 0x0909, 0x0a0a, 0x0a0a};
1241 TABLE u8 rcompstr2[7] = { 0x00, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0xaa};
1242 TABLE u16 rcompscomp2[7] = {0x0000, 0xe22e, 0xe22e, 0xe22e, 0x8228, 0xe22e, 0x8228};
1243 TABLE u8 rcompdelay2[7] = { 0, 0, 0, 0, 2, 0, 2};
1246 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1247 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1248 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1249 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1250 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1251 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1252 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1253 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1254 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1255 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1256 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1257 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1258 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1259 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1260 { 9, 9, 11, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1261 {10, 9, 12, 11, 2, 2, 5, 5, 6, 6, 5, 5},
1262 {10, 9, 12, 11, 2, 2, 6, 5, 7, 6, 6, 5},
1263 {10, 10, 12, 12, 2, 2, 6, 5, 7, 6, 6, 5},
1264 {10, 10, 12, 12, 2, 2, 6, 6, 7, 7, 6, 6},
1265 {10, 10, 12, 12, 3, 2, 6, 6, 7, 7, 6, 6},
1266 {10, 10, 12, 12, 3, 2, 6, 6, 7, 7, 6, 6},
1267 {10, 10, 12, 12, 3, 2, 6, 6, 7, 7, 6, 6},
1268 {10, 10, 12, 12, 3, 3, 6, 6, 7, 7, 6, 6},
1269 {10, 10, 12, 12, 3, 3, 6, 6, 7, 7, 6, 6},
1270 {10, 10, 12, 12, 3, 3, 6, 6, 7, 7, 6, 6},
1271 {10, 10, 12, 12, 3, 3, 6, 6, 7, 7, 6, 6},
1272 {10, 10, 12, 12, 3, 3, 6, 6, 7, 7, 6, 6},
1273 {11, 10, 12, 12, 3, 3, 6, 6, 7, 7, 6, 6},
1274 {11, 10, 14, 13, 3, 3, 6, 6, 7, 7, 6, 6},
1275 {12, 10, 14, 13, 3, 3, 6, 6, 7, 7, 6, 6},
1276 {12, 12, 14, 13, 3, 3, 7, 6, 7, 7, 7, 6},
1277 {13, 12, 16, 15, 3, 3, 7, 6, 8, 7, 7, 6},
1278 {13, 14, 16, 15, 4, 3, 7, 7, 8, 8, 7, 7},
1279 {14, 14, 16, 17, 4, 3, 7, 7, 8, 8, 7, 7},
1280 {14, 16, 18, 17, 4, 4, 8, 7, 8, 8, 8, 7},
1281 {15, 16, 18, 19, 4, 4, 8, 7, 9, 8, 8, 7},
1282 {15, 18, 18, 19, 4, 4, 8, 8, 9, 9, 8, 8},
1283 {16, 18, 20, 21, 4, 4, 8, 8, 9, 9, 8, 8},
1284 {16, 19, 20, 21, 5, 4, 9, 8, 10, 9, 9, 8},
1285 {16, 19, 20, 23, 5, 5, 9, 9, 10, 10, 9, 9},
1286 {17, 19, 22, 23, 5, 5, 9, 9, 10, 10, 9, 9},
1287 {17, 20, 22, 25, 5, 5, 9, 9, 10, 10, 9, 9},
1288 {17, 20, 22, 25, 5, 5, 9, 9, 10, 10, 9, 9},
1289 {18, 20, 22, 25, 5, 5, 9, 9, 10, 10, 9, 9},
1290 {18, 21, 24, 25, 5, 5, 9, 9, 11, 10, 9, 9},
1291 {19, 21, 24, 27, 5, 5, 9, 9, 11, 11, 9, 9},
1292 {19, 22, 24, 27, 5, 5, 10, 9, 11, 11, 10, 9},
1293 {20, 22, 24, 27, 6, 5, 10, 10, 11, 11, 10, 10},
1294 {20, 23, 26, 27, 6, 6, 10, 10, 12, 12, 10, 10},
1295 {20, 23, 26, 29, 6, 6, 10, 10, 12, 12, 10, 10},
1296 {21, 24, 26, 29, 6, 6, 10, 10, 12, 12, 10, 10},
1297 {21, 24, 26, 29, 6, 6, 11, 10, 12, 13, 11, 10},
1298 {22, 25, 28, 29, 6, 6, 11, 11, 13, 13, 11, 11},
1299 {22, 25, 28, 31, 6, 6, 11, 11, 13, 13, 11, 11},
1300 {22, 26, 28, 31, 6, 6, 11, 11, 13, 14, 11, 11},
1301 {23, 26, 30, 31, 7, 6, 12, 11, 14, 14, 12, 11},
1302 {23, 27, 30, 33, 7, 7, 12, 12, 14, 14, 12, 12},
1303 {23, 27, 30, 33, 7, 7, 12, 12, 14, 15, 12, 12},
1304 {24, 28, 32, 33, 7, 7, 12, 12, 15, 15, 12, 12},
1305 {24, 28, 32, 33, 7, 7, 12, 12, 15, 16, 12, 12},
1306 {24, 29, 32, 35, 7, 7, 12, 12, 15, 16, 12, 12},
1307 {25, 29, 32, 35, 7, 7, 12, 12, 15, 17, 12, 12},
1308 {25, 30, 32, 35, 7, 7, 12, 12, 15, 17, 12, 12},
1309 {25, 30, 32, 35, 7, 7, 12, 12, 15, 17, 12, 12},
1316 rcomp1 = 0x00050431;
1318 rcomp1 = 0x00050542;
1321 rcomp2 = 0x14c42827;
1323 rcomp2 = 0x19042827;
1327 reg8 = rcompupdate[i];
1417 rcompp = (
u8) ((reg32 & ~(1 << 31)) >> 24);
1418 rcompn = (
u8) ((reg32 & ~(0xff800000)) >> 16);
1425 reg16 = (
u16)(rcompp - (1 << (srup + 1))) << 8;
1428 reg16 = (
u16)(rcompn - (1 << (srun + 1)));
1432 reg8 = rcompp - (1 << (srup + 1));
1433 for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1437 for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1438 if (
s->dimm_config[0] < 3 ||
s->dimm_config[0] == 5) {
1443 for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1448 for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1453 reg8 = rcompn - (1 << (srun + 1));
1454 for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1458 for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1459 if (
s->dimm_config[0] < 3 ||
s->dimm_config[0] == 5) {
1464 for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1469 for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1482 static const u16 odt_rankctrl[16] = {
1484 0x0000, 0x0000, 0x0000, 0x0000, 0x0044, 0x1111, 0x0000, 0x1111,
1486 0x0000, 0x0000, 0x0000, 0x0000, 0x0044, 0x1111, 0x0000, 0x1111,
1488 static const u16 odt_matrix[16] = {
1490 0x0000, 0x0011, 0x0000, 0x0011, 0x0000, 0x4444, 0x0000, 0x4444,
1492 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4444, 0x0000, 0x4444,
1495 switch (
s->dimms[0].ranks) {
1497 if (
s->dimms[1].ranks == 0) {
1499 }
else if (
s->dimms[1].ranks == 1) {
1501 }
else if (
s->dimms[1].ranks == 2) {
1506 if (
s->dimms[1].ranks == 0) {
1508 }
else if (
s->dimms[1].ranks == 1) {
1510 }
else if (
s->dimms[1].ranks == 2) {
1515 if (
s->dimms[1].ranks == 0) {
1517 }
else if (
s->dimms[1].ranks == 1) {
1519 }
else if (
s->dimms[1].ranks == 2) {
1534 TABLE u32 w260[7] = {0, 0x400001, 0xc00001, 0x500000, 0xf00000, 0xc00001, 0xf00000};
1535 TABLE u32 w208[7] = {0, 0x10000, 0x1010000, 0x10001, 0x1010101, 0x1010000, 0x1010101};
1536 TABLE u32 w200[7] = {0, 0, 0, 0x20002, 0x40002, 0, 0x40002};
1537 TABLE u32 w204[7] = {0, 0x20002, 0x40002, 0x40004, 0x80006, 0x40002, 0x80006};
1539 TABLE u16 tolud[7] = {2048, 2048, 4096, 4096, 8192, 4096, 8192};
1540 TABLE u16 tom[7] = { 2, 2, 4, 4, 8, 4, 8};
1541 TABLE u16 touud[7] = { 128, 128, 256, 256, 512, 256, 512};
1542 TABLE u32 gbsm[7] = {1 << 27, 1 << 27, 1 << 28, 1 << 27, 1 << 29, 1 << 28, 1 << 29};
1543 TABLE u32 bgsm[7] = {1 << 27, 1 << 27, 1 << 28, 1 << 27, 1 << 29, 1 << 28, 1 << 29};
1544 TABLE u32 tsegmb[7] = {1 << 27, 1 << 27, 1 << 28, 1 << 27, 1 << 29, 1 << 28, 1 << 29};
1547 if (
s->dimms[0].sides > 1) {
1582 u8 aa, bb, a, b,
c, d;
1585 a = (
u8)((xcomp & 0x7f000000) >> 24);
1586 b = (
u8)((xcomp & 0x007f0000) >> 16);
1587 c = (
u8)((xcomp & 0x00003f00) >> 8);
1588 d = (
u8)((xcomp & 0x0000003f) >> 0);
1600 if ((aa > 18) || (bb > 7) || (a <= 5) || (b <= 5) || (
c <= 5) || (d <= 5) ||
1601 (a >= 0x7a) || (b >= 0x7a) || (
c >= 0x3a) || (d >= 0x3a)) {
1616 for (i = 0; i < 3; i++) {
1625 reg32b = ((reg32a >> 16) & 0x0000ffff);
1626 reg32a = ((reg32a << 16) & 0xffff0000) | reg32b;
1627 reg32a |= (1 << 31) | (1 << 15);
1636 static void __attribute__((noinline))
1642 reg32 |= rank * (1 << 27);
1662 u16 reg16, mrs, rttnom;
1669 static const struct jedeclist jedec[12] = {
1675 {
" DLL RESET ",
MRS_CMD, (1 << 8) },
1677 {
" AUTOREFRESH",
CBR_CMD, 0 },
1678 {
" AUTOREFRESH",
CBR_CMD, 0 },
1679 {
" INITIALISE ",
MRS_CMD, 0 },
1680 {
" EMRS1 OCD ",
EMRS1_CMD, (1 << 9) | (1 << 8) | (1 << 7) },
1684 mrs = (
s->selected_timings.CAS << 4) |
1685 ((
s->selected_timings.tWR - 1) << 9) | (1 << 3) | (1 << 1) | 3;
1695 for (i = 0; i < 12; i++) {
1696 PRINTK_DEBUG(
"Rank:%d Jedec:%14s...", r, jedec[i].debug);
1697 reg16 = jedec[i].val;
1698 switch (jedec[i].cmd) {
1739 if (pmcon2 & 0x80) {
1748 pmcon3 = (pmcon3 & ~0x30) | 0x30;
1760 u32 reg32, ind, c0dra, c0drb, dra;
1763 static const u8 dratab[2][2][2][4] =
1766 {0xff, 0xff, 0xff, 0xff},
1767 {0xff, 0x00, 0x02, 0xff}
1770 {0xff, 0x01, 0xff, 0xff},
1771 {0xff, 0x03, 0xff, 0x06}
1776 {0xff, 0xff, 0xff, 0xff},
1777 {0xff, 0x04, 0x06, 0x08}
1780 {0xff, 0xff, 0xff, 0xff},
1781 {0x05, 0x07, 0x09, 0xff}
1785 static const u8 dradrb[10][6] = {
1787 {0x01, 0x01, 0x00, 0x08, 0, 0x04},
1788 {0x01, 0x00, 0x00, 0x10, 0, 0x02},
1789 {0x02, 0x01, 0x00, 0x08, 1, 0x08},
1790 {0x01, 0x01, 0x00, 0x10, 1, 0x04},
1791 {0x01, 0x01, 0x01, 0x08, 1, 0x08},
1792 {0x00, 0x01, 0x01, 0x10, 1, 0x04},
1793 {0x02, 0x01, 0x01, 0x08, 2, 0x10},
1794 {0x01, 0x01, 0x01, 0x10, 2, 0x08},
1795 {0x03, 0x01, 0x01, 0x08, 3, 0x20},
1796 {0x02, 0x01, 0x01, 0x10, 3, 0x10},
1806 [
s->dimms[i].cols - 9]
1807 [
s->dimms[i].rows - 12];
1809 if (
s->dimms[i].banks == 1) {
1812 reg32 |= (dra << (r * 8));
1822 reg8 = (
u8)(reg32 << 4) & 0xf0;
1833 ind = (c0dra >> (8 * r)) & 0x7f;
1834 c0drb = (
u16)(c0drb + dradrb[ind][5]);
1835 s->channel_capacity[0] += dradrb[ind][5] << 6;
1852 read32((
void *)strobeaddr);
1856 if (((
mchbar_read8(dqshighaddr) & (1 << 6)) >> 6) != highlow) {
1879 u8 coarse, savecoarse;
1880 u8 medium, savemedium;
1883 u8 lanecoarse[8] = {0};
1884 u8 minlanecoarse = 0xff;
1896 for (lane = 0; lane < maxlane; lane++) {
1901 coarse =
s->selected_timings.CAS + 1;
1910 savecoarse = coarse;
1911 savemedium = medium;
1919 while (
sampledqs(dqshighaddr, strobeaddr, 0, 3) == 0) {
1930 savecoarse = coarse;
1931 savemedium = medium;
1934 while (
sampledqs(dqshighaddr, strobeaddr, 1, 3) == 0) {
1935 savecoarse = coarse;
1936 savemedium = medium;
1946 coarse = savecoarse;
1947 medium = savemedium;
1951 while (
sampledqs(dqshighaddr, strobeaddr, 1, 3) == 0) {
1954 if (pi >
s->maxpi) {
1956 pi = savepi =
s->maxpi;
1968 if (
sampledqs(dqshighaddr, strobeaddr, 1, 1) == 0) {
1973 while (
sampledqs(dqshighaddr, strobeaddr, 0, 3) == 0) {
1985 lanecoarse[lane] = coarse;
1993 if (minlanecoarse > lanecoarse[lane]) {
1994 minlanecoarse = lanecoarse[lane];
1996 }
while (lane != 0);
2001 offset = lanecoarse[lane] - minlanecoarse;
2003 }
while (lane != 0);
2007 s->coarsectrl = minlanecoarse;
2028 u32 mmiosize, tom, tolud, touud, reclaimbase, reclaimlimit;
2029 u32 gfxbase, gfxsize, gttbase, gttsize, tsegbase, tsegsize;
2031 u16 ggc_to_uma[10] = {0, 1, 4, 8, 16, 32, 48, 64, 128, 256};
2032 u8 ggc_to_gtt[4] = {0, 1, 0, 0};
2040 gfxsize = ggc_to_uma[(ggc & 0x00f0) >> 4];
2042 gttsize = ggc_to_gtt[(ggc & 0x0300) >> 8];
2044 tom =
s->channel_capacity[0];
2052 tolud =
MIN(4096 - mmiosize, tom);
2053 if ((tom - tolud) > 64) {
2057 tolud = tolud & ~0x3f;
2059 reclaimbase =
MAX(4096, tom);
2060 reclaimlimit = reclaimbase + (
MIN(4096, tom) - tolud) - 0x40;
2064 touud = reclaimlimit + 64;
2067 gfxbase = tolud - gfxsize;
2068 gttbase = gfxbase - gttsize;
2069 tsegbase = gttbase - tsegsize;
2085 reg8 |= (0 << 1) | (1 << 0);
2098 u8 reg8,
ch, r, fsb_freq, ddr_freq;
2102 mask32 = (0x1f << 15) | (0x1f << 10) | (0x1f << 5) | 0x1f;
2103 reg32 = (0x1e << 15) | (0x10 << 10) | (0x1e << 5) | 0x10;
2126 u32 nranks, curranksize, maxranksize, dra;
2128 static const u8 drbtab[10] = {0x4, 0x2, 0x8, 0x4, 0x8, 0x4, 0x10, 0x8, 0x20, 0x10};
2138 curranksize = drbtab[dra];
2139 if (maxranksize == 0) {
2140 maxranksize = curranksize;
2142 if (curranksize != maxranksize) {
2168 die(
"Invalid number of ranks found, halt\n");
2180 u32 clkcx[2][2][3] = {
2182 {0x00000000, 0x0c080302, 0x08010204},
2183 {0x02040000, 0x08100102, 0x00000000},
2186 {0x18000000, 0x3021060c, 0x20010208},
2187 {0x00000000, 0x0c090306, 0x00000000},
2191 fsb_freq =
s->selected_timings.fsb_clock;
2192 ddr_freq =
s->selected_timings.mem_clock;
2216 u8 pidelay, i, j, k, cc, trd_perphase[5];
2217 u8 bypass, freqgb, trd, reg8, txfifo;
2218 u32 reg32, datadelay, tio, rcvendelay, maxrcvendelay;
2219 u16 tmclk, thclk, buffertocore, postcalib;
2220 static const u8 txfifo_lut[8] = { 0, 7, 6, 5, 2, 1, 4, 3 };
2221 static const u16 trd_adjust[2][2][5] = {
2223 {3000, 3000, 0,0,0},
2224 {1000,2000,3000,1500,2500}
2227 {2000,1000,3000,0,0},
2232 buffertocore = 5000;
2235 tmclk = tmclk * 100 / freqgb;
2237 switch (
s->selected_timings.mem_clock) {
2258 for (i = 0; i < 8; i++) {
2259 rcvendelay = ((
u32)((
s->coarsedelay >> (i << 1)) & 3) * (
u32)(tmclk));
2260 rcvendelay += ((
u32)((
s->readptrdelay >> (i << 1)) & 3) * (
u32)(tmclk) / 2);
2261 rcvendelay += ((
u32)((
s->mediumphase >> (i << 1)) & 3) * (
u32)(tmclk) / 4);
2262 rcvendelay += (
u32)(pidelay *
s->pi[i]);
2263 maxrcvendelay =
MAX(maxrcvendelay, rcvendelay);
2274 txfifo = txfifo_lut[reg8] & 0x07;
2276 datadelay = tmclk * (2*txfifo + 4*
s->coarsectrl + 4*(bypass-1) + 13) / 4
2277 + tio + maxrcvendelay + pidelay + buffertocore + postcalib;
2279 datadelay += tmclk / 2;
2285 if (j == 0 && k == 0) {
2290 for (i = 0; i < cc; i++) {
2291 reg32 = datadelay - (trd_adjust[k][j][i] * 100 / freqgb);
2292 trd_perphase[i] = (
u8)(reg32 / thclk) - 2;
2293 trd_perphase[i] += 1;
2294 if (trd_perphase[i] > trd) {
2295 trd = trd_perphase[i];
2351 static const u16 ddr2lut[2][4][2] = {
2373 reg32 =
s->nodll ? 0x30000000 : 0;
2447 u16 mdclk, tpi, refclk, dqdqs_out, dqdqs_outdelay, dqdqs_delay;
2448 u32 coretomcp, txdelay, tmaxunmask, tmaxpi;
2449 u8 repeat, halfclk, feature, reg8,
push;
2452 static const u8 txfifotab[8] = {0, 7, 6, 5, 2, 1, 4, 3};
2456 dqdqs_outdelay = 5083;
2472 refclk = 3000 - mdclk;
2485 txfifotab[reg8]*(mdclk / 2) +
2491 txdelay -= mdclk / 2;
2492 reg32 = dqdqs_outdelay + coretomcp - mdclk / 2;
2494 reg32 = dqdqs_outdelay + coretomcp;
2497 tmaxunmask = txdelay - mdclk - dqdqs_out;
2498 tmaxpi = tmaxunmask - tpi;
2500 if ((tmaxunmask >= reg32) && tmaxpi >= dqdqs_delay) {
2529 const char *boot_str[] = {
"Normal",
"Reset",
"Resume"};
2533 memset(&si, 0,
sizeof(si));
2537 si.
spd_map[0] = spd_addresses[0];
2538 si.
spd_map[1] = spd_addresses[1];
2539 si.
spd_map[2] = spd_addresses[2];
2540 si.
spd_map[3] = spd_addresses[3];
static uint32_t read32(const void *addr)
void * memset(void *dstpp, int c, size_t len)
#define DIV_ROUND_UP(x, y)
#define printk(level,...)
void __noreturn die(const char *fmt,...)
static __always_inline uint8_t mchbar_read8(const uintptr_t offset)
#define mchbar_setbits32(addr, set)
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 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)
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)
#define mchbar_setbits16(addr, set)
void hpet_udelay(u32 delay)
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
static __always_inline void pci_and_config8(const struct device *dev, u16 reg, u8 andmask)
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
static __always_inline void pci_or_config8(const struct device *dev, u16 reg, u8 ormask)
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)
void hexdump(const void *memory, size_t length)
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
#define CLKXSSH2MCBYPPHAS
static struct dramc_channel const ch[2]
void sdram_initialize(void)
static void sdram_read_spds(struct sysinfo *s)
static void sdram_calibratepll(struct sysinfo *s, u8 pidelay)
static void sdram_jedecinit(struct sysinfo *s)
static void sdram_calibratehwpll(struct sysinfo *s)
static void sdram_powersettings(struct sysinfo *s)
static void sdram_checkreset(void)
static int decode_spd(struct dimminfo *d, int i)
static void sdram_dradrb(struct sysinfo *s)
#define FOR_EACH_POPULATED_CHANNEL(dimms, idx)
static void sdram_p_clkset0(const struct pllparam *pll, u8 f, u8 i)
static void sdram_odt(struct sysinfo *s)
static void sdram_detect_ram_speed(struct sysinfo *s)
static void sdram_clkmode(struct sysinfo *s)
static void sdram_p_dqs(struct pllparam *pll, u8 f, u8 clk)
static void sdram_detect_smallest_params(struct sysinfo *s)
static void sdram_p_cmd(const struct pllparam *pll, u8 f, u8 i)
static void sdram_mmap_regs(struct sysinfo *s)
static void sdram_programdqdqs(struct sysinfo *s)
#define ONLY_DIMMA_IS_POPULATED(dimms, ch)
static u8 sdram_checkrcompoverride(void)
static void sdram_dlltiming(struct sysinfo *s)
#define FOR_EACH_POPULATED_RANK(dimms, ch, r)
static void sdram_rcven(struct sysinfo *s)
static u8 sampledqs(u32 dqshighaddr, u32 strobeaddr, u8 highlow, u8 count)
static void sdram_misc(struct sysinfo *s)
static int lsbpos(u8 val)
static void sdram_p_clkset1(const struct pllparam *pll, u8 f, u8 i)
#define PRINTK_DEBUG(x...)
static bool rank_is_populated(struct dimminfo dimms[], u8 ch, u8 r)
#define FOR_EACH_DIMM(idx)
static void sdram_programddr(void)
static void barrier(void)
static void sdram_clk_crossing(struct sysinfo *s)
static void sdram_periodic_rcomp(void)
static void find_ramconfig(struct sysinfo *s, u32 chan)
#define FOR_EACH_POPULATED_DIMM(dimms, idx)
static void sdram_mmap(struct sysinfo *s)
static void sdram_jedec(struct sysinfo *s, u8 rank, u8 jmode, u16 jval)
static int msbpos(u8 val)
static void sdram_rcomp(struct sysinfo *s)
static void sdram_enhancedmode(struct sysinfo *s)
static void sdram_new_trd(struct sysinfo *s)
#define ONLY_DIMMB_IS_POPULATED(dimms, ch)
static void sdram_p_ctrl(const struct pllparam *pll, u8 f, u8 i)
static void sdram_timings(struct sysinfo *s)
#define FOR_EACH_RANK(ch, r)
static void sdram_p_dq(struct pllparam *pll, u8 f, u8 clk)
#define FOR_EACH_RCOMP_GROUP(idx)
static void sdram_rcompupdate(struct sysinfo *s)
static void sdram_zqcl(struct sysinfo *s)
static void rcvenclock(u8 *coarse, u8 *medium, u8 lane)
#define PCI_DEV(SEGBUS, DEV, FN)
static void enable_hpet(struct device *dev)
enum chip_cap chip_capacity
unsigned int cas_latencies
static void __noreturn reset(void)
#define s(param, src_bits, pmcreg, dst_bits)
#define c(value, pmcreg, dst_bits)