[coreboot-gerrit] Change in coreboot[master]: nb/intel/x4x/raminit: Support programming initials DD3 DLL s...
Arthur Heymans (Code Review)
gerrit at coreboot.org
Wed May 24 22:10:36 CEST 2017
Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/19874 )
Change subject: nb/intel/x4x/raminit: Support programming initials DD3 DLL setting
......................................................................
nb/intel/x4x/raminit: Support programming initials DD3 DLL setting
Due to shear amount of tables for default DLL settings used, they are
mostly pushed to a new file to avoid cluttering up the raminit.
Change-Id: Ia79b216ad69a02d4706ffc74f867a85db3eb2d6c
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/northbridge/intel/x4x/Makefile.inc
M src/northbridge/intel/x4x/raminit_ddr23.c
A src/northbridge/intel/x4x/raminit_tables.c
M src/northbridge/intel/x4x/x4x.h
4 files changed, 470 insertions(+), 136 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/74/19874/1
diff --git a/src/northbridge/intel/x4x/Makefile.inc b/src/northbridge/intel/x4x/Makefile.inc
index ae8d388..8b59dbf 100644
--- a/src/northbridge/intel/x4x/Makefile.inc
+++ b/src/northbridge/intel/x4x/Makefile.inc
@@ -22,6 +22,7 @@
romstage-y += ram_calc.c
romstage-y += spd_ddr2_decode.c
romstage-y += spd_ddr3_decode.c
+romstage-y += raminit_tables.c
ramstage-y += acpi.c
ramstage-y += ram_calc.c
diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c
index 4db29f5..673ebad 100644
--- a/src/northbridge/intel/x4x/raminit_ddr23.c
+++ b/src/northbridge/intel/x4x/raminit_ddr23.c
@@ -367,9 +367,10 @@
setting->tap;
}
-static void dqsset(u8 ch, u8 lane, const struct dll_setting *setting)
+void dqsset(u8 ch, u8 lane, const struct dll_setting *setting)
{
- MCHBAR32(0x400*ch + 0x5fc) = MCHBAR32(0x400*ch + 0x5fc) & ~(2 << (lane*4));
+ MCHBAR32(0x400*ch + 0x5fc) = (MCHBAR32(0x400*ch + 0x5fc) & ~(2 << (lane*4)))
+ | (setting->coarse << ((lane * 4) + 1));
MCHBAR32(0x400*ch + 0x5b4) = (MCHBAR32(0x400*ch + 0x5b4) & ~(0x201 << lane)) |
(setting->db_en << (9 + lane)) |
@@ -411,10 +412,10 @@
setting->tap;
}
-static void dqset(u8 ch, u8 lane, const struct dll_setting *setting)
+void dqset(u8 ch, u8 lane, const struct dll_setting *setting)
{
- MCHBAR32(0x400*ch + 0x5fc) = MCHBAR32(0x400*ch + 0x5fc) & ~(1 << (lane*4));
-
+ MCHBAR32(0x400*ch + 0x5fc) = (MCHBAR32(0x400*ch + 0x5fc) & ~(1 << (lane*4))) |
+ (setting->coarse << (lane * 4));
MCHBAR32(0x400*ch + 0x5a4) = (MCHBAR32(0x400*ch + 0x5a4) & ~(0x201 << lane)) |
(setting->db_en << (9 + lane)) |
(setting->db_sel << lane);
@@ -615,7 +616,12 @@
MCHBAR16(0x400*i + 0x25b) = ((s->selected_timings.tRP + trpmod) << 9) |
s->selected_timings.tRFC;
- MCHBAR16(0x400*i + 0x260) = (MCHBAR16(0x400*i + 0x260) & ~0x3fe) | (100 << 1);
+ if (s->spd_type == DDR2)
+ MCHBAR16(0x400*i + 0x260) =
+ (MCHBAR16(0x400*i + 0x260) & ~0x3fe) | (100 << 1);
+ else
+ MCHBAR16(0x400*i + 0x260) =
+ (MCHBAR16(0x400*i + 0x260) & ~0x3fe) | (256 << 1);
MCHBAR8(0x400*i + 0x264) = 0xff;
MCHBAR8(0x400*i + 0x25d) = (MCHBAR8(0x400*i + 0x25d) & ~0x3f) |
s->selected_timings.tRAS;
@@ -668,17 +674,30 @@
MCHBAR8(0x400*i + 0x24c) = MCHBAR8(0x400*i + 0x24c) & ~0x3;
reg16 = 0;
- switch (s->selected_timings.mem_clk) {
- default:
- case MEM_CLOCK_667MHz:
- reg16 = 0x99;
- break;
- case MEM_CLOCK_800MHz:
- if (s->selected_timings.CAS == 5)
- reg16 = 0x19a;
- else if (s->selected_timings.CAS == 6)
- reg16 = 0x9a;
- break;
+ if (s->spd_type == DDR2) {
+ switch (s->selected_timings.mem_clk) {
+ default:
+ case MEM_CLOCK_667MHz:
+ reg16 = 0x99;
+ break;
+ case MEM_CLOCK_800MHz:
+ if (s->selected_timings.CAS == 5)
+ reg16 = 0x19a;
+ else if (s->selected_timings.CAS == 6)
+ reg16 = 0x9a;
+ break;
+ }
+ } else { /* DDR3 */
+ switch (s->selected_timings.mem_clk) {
+ default:
+ case MEM_CLOCK_800MHz:
+ case MEM_CLOCK_1066MHz:
+ reg16 = 1;
+ break;
+ case MEM_CLOCK_1333MHz:
+ reg16 = 2;
+ break;
+ }
}
reg16 &= 0x7;
reg16 += twl + 9;
@@ -715,8 +734,37 @@
MCHBAR8(0x12d) = (MCHBAR8(0x12d) & ~0xf) | reg8;
MCHBAR8(0x12f) = 0x4c;
reg32 = (1 << 31) | (0x80 << 14) | (1 << 13) | (0xa << 9);
+ if (s->spd_type == DDR3) {
+ MCHBAR8(0x114) = 0x42;
+ reg16 = (512 - MAX(5, s->selected_timings.tRFC +
+ 10000 / ddr2ps[s->selected_timings.mem_clk])) / 2;
+ reg16 &= 0x1ff;
+ reg32 = (reg16 << 22) | (0x80 << 14) | (0xa << 9);
+ }
MCHBAR32(0x6c0) = (MCHBAR32(0x6c0) & ~0xffffff00) | reg32;
MCHBAR8(0x6c4) = (MCHBAR8(0x6c4) & ~0x7) | 0x2;
+}
+
+static void program_dll_clk_ctrl(int channel, const struct dll_setting *dll_settings)
+{
+ clkset0(channel, &dll_settings[CLKSET0]);
+ clkset1(channel, &dll_settings[CLKSET1]);
+ ctrlset0(channel, &dll_settings[CTRL0]);
+ ctrlset1(channel, &dll_settings[CTRL1]);
+ ctrlset2(channel, &dll_settings[CTRL2]);
+ ctrlset3(channel, &dll_settings[CTRL3]);
+ cmdset(channel, &dll_settings[CMD]);
+}
+
+static void program_dq_dqs(u8 channel, const struct dll_setting dll_setting[23])
+{
+ int lane;
+ for (lane = 0; lane < 8; lane++) {
+ dqsset(channel, lane, &dll_setting[DQS1 + lane]);
+ }
+ for (lane = 0; lane < 8; lane++) {
+ dqset(channel, lane, &dll_setting[DQ1 + lane]);
+ }
}
static void program_dll(struct sysinfo *s)
@@ -726,6 +774,9 @@
u32 reg32 = 0;
u8 lane;
+ const u8 rank2clken[8] = { 0x04, 0x01, 0x20, 0x08, 0x01, 0x04,
+ 0x08, 0x10 };
+
MCHBAR16(0x180) = (MCHBAR16(0x180) & ~0x7e06) | 0xc04;
MCHBAR16(0x182) = (MCHBAR16(0x182) & ~0x3ff) | 0xc8;
MCHBAR16(0x18a) = (MCHBAR16(0x18a) & ~0x1f1f) | 0x0f0f;
@@ -734,10 +785,14 @@
switch (s->selected_timings.mem_clk) {
default:
case MEM_CLOCK_667MHz:
+ case MEM_CLOCK_1333MHz:
reg16 = (0xa << 9) | 0xa;
break;
case MEM_CLOCK_800MHz:
reg16 = (0x9 << 9) | 0x9;
+ break;
+ case MEM_CLOCK_1066MHz:
+ reg16 = (0x7 << 9) | 0x7;
break;
}
MCHBAR16(0x19c) = (MCHBAR16(0x19c) & ~0x1e0f) | reg16;
@@ -762,14 +817,29 @@
udelay(1); // 533ns
// ME related
- MCHBAR32(0x1a0) = (MCHBAR32(0x1a0) & ~0x7ffffff) | 0x551803;
+ if (s->spd_type == DDR2)
+ MCHBAR32(0x1a0) = (MCHBAR32(0x1a0) & ~0x7ffffff) | 0x551803;
+ else /* DDR3 */
+ MCHBAR32(0x1a0) = (MCHBAR32(0x1a0) & ~0x7ffffff) | 0x555801;
MCHBAR16(0x1b4) = MCHBAR16(0x1b4) & ~0x800;
- MCHBAR8(0x1a8) = MCHBAR8(0x1a8) | 0xf0;
+ if (s->spd_type == DDR2) {
+ MCHBAR8(0x1a8) = MCHBAR8(0x1a8) | 0xf0;
+ } else { /* DDR3 */
+ reg8 = 0x9; /* 0x9 << 4 ?? */
+ if (s->dimms[0].ranks == 2)
+ reg8 &= ~0x80;
+ if (s->dimms[3].ranks == 2)
+ reg8 &= ~0x10;
+ MCHBAR8(0x1a8) = (MCHBAR8(0x1a8) & ~0xf0) | reg8;
+ }
+
FOR_EACH_CHANNEL(i) {
reg16 = 0;
- MCHBAR16(0x400*i + 0x59c) = MCHBAR16(0x400*i + 0x59c) & ~0x3000;
+ if ((s->spd_type == DDR3) && (i == 0))
+ reg16 = (0x3 << 12);
+ MCHBAR16(0x400*i + 0x59c) = (MCHBAR16(0x400*i + 0x59c) & ~0x3000) | reg16;
reg32 = 0;
FOR_EACH_RANK_IN_CHANNEL(r) {
@@ -780,114 +850,82 @@
MCHBAR32(0x400*i + 0x59c) = (MCHBAR32(0x400*i + 0x59c) & ~0xfff) | reg32;
MCHBAR8(0x400*i + 0x594) = MCHBAR8(0x400*i + 0x594) & ~1;
- if (!CHANNEL_IS_POPULATED(s->dimms, i)) {
- printk(BIOS_DEBUG, "No dimms in channel %d\n", i);
- reg8 = 0x3f;
- } else if (ONLY_DIMMA_IS_POPULATED(s->dimms, i)) {
- printk(BIOS_DEBUG, "DimmA populated only in channel %d\n", i);
- reg8 = 0x38;
- } else if (ONLY_DIMMB_IS_POPULATED(s->dimms, i)) {
- printk(BIOS_DEBUG, "DimmB populated only in channel %d\n", i);
- reg8 = 0x7;
- } else if (BOTH_DIMMS_ARE_POPULATED(s->dimms, i)) {
- printk(BIOS_DEBUG, "Both dimms populated in channel %d\n", i);
- reg8 = 0;
- } else {
- die("Unhandled case\n");
- }
-
- //reg8 = 0x00; // FIXME don't switch on all clocks anyway
-
- MCHBAR32(0x400*i + 0x5a0) = (MCHBAR32(0x400*i + 0x5a0) & ~0x3f000000) |
+ if (s->spd_type == DDR2) {
+ if (!CHANNEL_IS_POPULATED(s->dimms, i)) {
+ printk(BIOS_DEBUG, "No dimms in channel %d\n", i);
+ reg8 = 0x3f;
+ } else if (ONLY_DIMMA_IS_POPULATED(s->dimms, i)) {
+ printk(BIOS_DEBUG, "DimmA populated only in channel %d\n", i);
+ reg8 = 0x38;
+ } else if (ONLY_DIMMB_IS_POPULATED(s->dimms, i)) {
+ printk(BIOS_DEBUG, "DimmB populated only in channel %d\n", i);
+ reg8 = 0x7;
+ } else if (BOTH_DIMMS_ARE_POPULATED(s->dimms, i)) {
+ printk(BIOS_DEBUG, "Both dimms populated in channel %d\n", i);
+ reg8 = 0;
+ } else {
+ die("Unhandled case\n");
+ }
+ MCHBAR32(0x400*i + 0x5a0) = (MCHBAR32(0x400*i + 0x5a0) & ~0x3f000000) |
((u32)(reg8 << 24));
+ } else { /* DDR3 */
+ FOR_EACH_RANK_IN_CHANNEL(r) {
+ if (RANK_IS_POPULATED(s->dimms, i, r)) {
+ MCHBAR8(0x400 * i + 0x5a0 + 3) = MCHBAR8(0x400 * i + 0x5a0 + 3)
+ & ~rank2clken[r + i * 4];
+ }
+ }
+ }
} // END EACH CHANNEL
- MCHBAR8(0x1a8) = MCHBAR8(0x1a8) | 1;
- MCHBAR8(0x1a8) = MCHBAR8(0x1a8) & ~0x4;
+ if (s->spd_type == DDR2) {
+ MCHBAR8(0x1a8) = MCHBAR8(0x1a8) | 1;
+ MCHBAR8(0x1a8) = MCHBAR8(0x1a8) & ~0x4;
+ } else { /* DDR3 */
+ MCHBAR8(0x1a8) = MCHBAR8(0x1a8) & ~1;
+ MCHBAR8(0x1a8) = MCHBAR8(0x1a8) | 0x4;
+ }
// Update DLL timing
MCHBAR8(0x1a4) = MCHBAR8(0x1a4) & ~0x80;
MCHBAR8(0x1a4) = MCHBAR8(0x1a4) | 0x40;
MCHBAR16(0x5f0) = (MCHBAR16(0x5f0) & ~0x400) | 0x400;
- const struct dll_setting dll_setting_667[23] = {
- // tap pi db delay
- {13, 0, 1, 0, 0},
- {4, 1, 0, 0, 0},
- {13, 0, 1, 0, 0},
- {4, 5, 0, 0, 0},
- {4, 1, 0, 0, 0},
- {4, 1, 0, 0, 0},
- {4, 1, 0, 0, 0},
- {1, 5, 1, 1, 1},
- {1, 6, 1, 1, 1},
- {2, 0, 1, 1, 1},
- {2, 1, 1, 1, 1},
- {2, 1, 1, 1, 1},
- {14, 6, 1, 0, 0},
- {14, 3, 1, 0, 0},
- {14, 0, 1, 0, 0},
- {9, 0, 0, 0, 1},
- {9, 1, 0, 0, 1},
- {9, 2, 0, 0, 1},
- {9, 2, 0, 0, 1},
- {9, 1, 0, 0, 1},
- {6, 4, 0, 0, 1},
- {6, 2, 0, 0, 1},
- {5, 4, 0, 0, 1}
- };
-
- const struct dll_setting dll_setting_800[23] = {
- // tap pi db delay
- {11, 5, 1, 0, 0},
- {0, 5, 1, 1, 0},
- {11, 5, 1, 0, 0},
- {1, 4, 1, 1, 0},
- {0, 5, 1, 1, 0},
- {0, 5, 1, 1, 0},
- {0, 5, 1, 1, 0},
- {2, 5, 1, 1, 1},
- {2, 6, 1, 1, 1},
- {3, 0, 1, 1, 1},
- {3, 0, 1, 1, 1},
- {3, 3, 1, 1, 1},
- {2, 0, 1, 1, 1},
- {1, 3, 1, 1, 1},
- {0, 3, 1, 1, 1},
- {9, 3, 0, 0, 1},
- {9, 4, 0, 0, 1},
- {9, 5, 0, 0, 1},
- {9, 6, 0, 0, 1},
- {10, 0, 0, 0, 1},
- {8, 1, 0, 0, 1},
- {7, 5, 0, 0, 1},
- {6, 2, 0, 0, 1}
- };
-
FOR_EACH_POPULATED_CHANNEL(s->dimms, i) {
MCHBAR16(0x400*i + 0x5f0) = (MCHBAR16(0x400*i + 0x5f0) & ~0x3fc) | 0x3fc;
MCHBAR32(0x400*i + 0x5fc) = MCHBAR32(0x400*i + 0x5fc) & ~0xcccccccc;
- MCHBAR8(0x400*i + 0x5d9) = (MCHBAR8(0x400*i + 0x5d9) & ~0xf0) | 0x70;
- MCHBAR16(0x400*i + 0x590) = (MCHBAR16(0x400*i + 0x590) & ~0xffff) | 0x5555;
+ if (s->spd_type == DDR2) {
+ MCHBAR8(0x400*i + 0x5d9) = (MCHBAR8(0x400*i + 0x5d9)
+ & ~0xf0) | 0x70;
+ MCHBAR16(0x400*i + 0x590) = (MCHBAR16(0x400*i + 0x590)
+ & ~0xffff) | 0x5555;
+ } else {
+ MCHBAR8(0x400*i + 0x5d9) = (MCHBAR8(0x400*i + 0x5d9)
+ & ~0xf0) | 0x60;
+ MCHBAR16(0x400*i + 0x590) = (MCHBAR16(0x400*i + 0x590)
+ & ~0xffff) | 0xa955;
+ }
}
FOR_EACH_POPULATED_CHANNEL(s->dimms, i) {
- if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz) {
- clkset0(i, &dll_setting_667[CLKSET0]);
- clkset1(i, &dll_setting_667[CLKSET1]);
- ctrlset0(i, &dll_setting_667[CTRL0]);
- ctrlset1(i, &dll_setting_667[CTRL1]);
- ctrlset2(i, &dll_setting_667[CTRL2]);
- ctrlset3(i, &dll_setting_667[CTRL3]);
- cmdset(i, &dll_setting_667[CMD]);
- } else {
- clkset0(i, &dll_setting_800[CLKSET0]);
- clkset1(i, &dll_setting_800[CLKSET1]);
- ctrlset0(i, &dll_setting_800[CTRL0]);
- ctrlset1(i, &dll_setting_800[CTRL1]);
- ctrlset2(i, &dll_setting_800[CTRL2]);
- ctrlset3(i, &dll_setting_800[CTRL3]);
- cmdset(i, &dll_setting_800[CMD]);
+ if (s->spd_type == DDR2) {
+ if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz)
+ program_dll_clk_ctrl(i, ddr2_dll_setting_667);
+ else
+ program_dll_clk_ctrl(i, ddr2_dll_setting_800);
+ } else { /* DDR3 */
+ switch (s->selected_timings.mem_clk) {
+ default:
+ case MEM_CLOCK_800MHz:
+ program_dll_clk_ctrl(i, ddr3_dll_setting_800[s->nmode - 1]);
+ break;
+ case MEM_CLOCK_1066MHz:
+ program_dll_clk_ctrl(i, ddr3_dll_setting_1066[s->nmode - 1]);
+ break;
+ case MEM_CLOCK_1333MHz:
+ program_dll_clk_ctrl(i, ddr3_dll_setting_1333[s->nmode - 1]);
+ break;
+ }
}
}
@@ -954,23 +992,38 @@
}
clk = 0x1a;
+ if (s->selected_timings.mem_clk == MEM_CLOCK_1333MHz)
+ clk = 0x18;
if (async != 1) {
reg8 = MCHBAR8(0x188) & 0x1e;
- if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz &&
- s->selected_timings.fsb_clk == FSB_CLOCK_800MHz) {
- clk = 0x10;
- } else if (s->selected_timings.mem_clk == MEM_CLOCK_800MHz) {
- clk = 0x10;
- } else {
+ switch (s->selected_timings.mem_clk) {
+ case MEM_CLOCK_667MHz:
clk = 0x1a;
+ if (s->selected_timings.fsb_clk == FSB_CLOCK_800MHz)
+ clk = 0x10;
+ break;
+ case MEM_CLOCK_800MHz:
+ case MEM_CLOCK_1066MHz:
+ clk = 0x10;
+ break;
+ case MEM_CLOCK_1333MHz:
+ clk = 0x18;
+ break;
+ default:
+ clk = 0x1a;
+ break;
}
}
MCHBAR8(0x180) = MCHBAR8(0x180) & ~0x80;
- if ((s->selected_timings.fsb_clk == FSB_CLOCK_800MHz) &&
- (s->selected_timings.mem_clk == MEM_CLOCK_667MHz)) {
+ if ((s->spd_type == DDR3 && s->selected_timings.mem_clk == MEM_CLOCK_1066MHz)
+ || (s->spd_type == DDR2 && s->selected_timings.fsb_clk == FSB_CLOCK_800MHz
+ && s->selected_timings.mem_clk == MEM_CLOCK_667MHz)) {
i = MCHBAR8(0x180) & 0xf;
- i = (i + 10) % 14;
+ if (s->spd_type == DDR2)
+ i = (i + 10) % 14;
+ else /* DDR3 */
+ i = (i + 3) % 12;
MCHBAR8(0x1c8) = (MCHBAR8(0x1c8) & ~0x1f) | i;
MCHBAR8(0x180) = MCHBAR8(0x180) | 0x10;
while (MCHBAR8(0x180) & 0x10)
@@ -991,11 +1044,26 @@
// Program DQ/DQS dll settings
reg32 = 0;
FOR_EACH_POPULATED_CHANNEL(s->dimms, i) {
- for (lane = 0; lane < 8; lane++) {
- if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz)
- reg32 = 0x06db7777;
- else if (s->selected_timings.mem_clk == MEM_CLOCK_800MHz)
+ switch (s->selected_timings.mem_clk) {
+ default: /* Should not happen */
+ break;
+ case MEM_CLOCK_667MHz:
+ reg32 = 0x06db7777;
+ break;
+ case MEM_CLOCK_800MHz:
+ if (s->spd_type == DDR2)
reg32 = 0x00007777;
+ else /* DDR3 */
+ reg32 = 0x06db6666;
+ break;
+ case MEM_CLOCK_1066MHz:
+ reg32 = 0x06db5555;
+ break;
+ case MEM_CLOCK_1333MHz:
+ reg32 = 0x00007777;
+ break;
+ }
+ for (lane = 0; lane < 8; lane++) {
MCHBAR32(0x400*i + 0x540 + lane*4) =
(MCHBAR32(0x400*i + 0x540 + lane*4) & 0x0fffffff) |
reg32;
@@ -1003,16 +1071,24 @@
}
FOR_EACH_POPULATED_CHANNEL(s->dimms, i) {
- if (s->selected_timings.mem_clk == MEM_CLOCK_667MHz) {
- for (lane = 0; lane < 8; lane++)
- dqsset(i, lane, &dll_setting_667[DQS1+lane]);
- for (lane = 0; lane < 8; lane++)
- dqset(i, lane, &dll_setting_667[DQ1+lane]);
- } else {
- for (lane = 0; lane < 8; lane++)
- dqsset(i, lane, &dll_setting_800[DQS1+lane]);
- for (lane = 0; lane < 8; lane++)
- dqset(i, lane, &dll_setting_800[DQ1+lane]);
+ switch (s->selected_timings.mem_clk) {
+ default: /* Should not happen */
+ break;
+ case MEM_CLOCK_667MHz:
+ program_dq_dqs(i, ddr2_dll_setting_667);
+ break;
+ case MEM_CLOCK_800MHz:
+ if (s->spd_type == DDR2)
+ program_dq_dqs(i, ddr2_dll_setting_800);
+ else /* DDR3 */
+ program_dq_dqs(i, ddr3_dll_setting_800[s->nmode - 1]);
+ break;
+ case MEM_CLOCK_1066MHz:
+ program_dq_dqs(i, ddr3_dll_setting_1066[s->nmode - 1]);
+ break;
+ case MEM_CLOCK_1333MHz:
+ program_dq_dqs(i, ddr3_dll_setting_1333[s->nmode - 1]);
+ break;
}
}
}
diff --git a/src/northbridge/intel/x4x/raminit_tables.c b/src/northbridge/intel/x4x/raminit_tables.c
new file mode 100644
index 0000000..3349f62
--- /dev/null
+++ b/src/northbridge/intel/x4x/raminit_tables.c
@@ -0,0 +1,248 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Arthur Heymans <arthur at aheymans.xyz>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <stdint.h>
+#include "x4x.h"
+
+const struct dll_setting ddr2_dll_setting_667[23] = {
+ /* tap pi db delay */
+ {13, 0, 1, 0, 0, 0},
+ {4, 1, 0, 0, 0, 0},
+ {13, 0, 1, 0, 0, 0},
+ {4, 5, 0, 0, 0, 0},
+ {4, 1, 0, 0, 0, 0},
+ {4, 1, 0, 0, 0, 0},
+ {4, 1, 0, 0, 0, 0},
+ {1, 5, 1, 1, 1, 0},
+ {1, 6, 1, 1, 1, 0},
+ {2, 0, 1, 1, 1, 0},
+ {2, 1, 1, 1, 1, 0},
+ {2, 1, 1, 1, 1, 0},
+ {14, 6, 1, 0, 0, 0},
+ {14, 3, 1, 0, 0, 0},
+ {14, 0, 1, 0, 0, 0},
+ {9, 0, 0, 0, 1, 0},
+ {9, 1, 0, 0, 1, 0},
+ {9, 2, 0, 0, 1, 0},
+ {9, 2, 0, 0, 1, 0},
+ {9, 1, 0, 0, 1, 0},
+ {6, 4, 0, 0, 1, 0},
+ {6, 2, 0, 0, 1, 0},
+ {5, 4, 0, 0, 1, 0}
+};
+
+const struct dll_setting ddr2_dll_setting_800[23] = {
+ /* tap pi db delay */
+ {11, 5, 1, 0, 0, 0},
+ {0, 5, 1, 1, 0, 0},
+ {11, 5, 1, 0, 0, 0},
+ {1, 4, 1, 1, 0, 0},
+ {0, 5, 1, 1, 0, 0},
+ {0, 5, 1, 1, 0, 0},
+ {0, 5, 1, 1, 0, 0},
+ {2, 5, 1, 1, 1, 0},
+ {2, 6, 1, 1, 1, 0},
+ {3, 0, 1, 1, 1, 0},
+ {3, 0, 1, 1, 1, 0},
+ {3, 3, 1, 1, 1, 0},
+ {2, 0, 1, 1, 1, 0},
+ {1, 3, 1, 1, 1, 0},
+ {0, 3, 1, 1, 1, 0},
+ {9, 3, 0, 0, 1, 0},
+ {9, 4, 0, 0, 1, 0},
+ {9, 5, 0, 0, 1, 0},
+ {9, 6, 0, 0, 1, 0},
+ {10, 0, 0, 0, 1, 0},
+ {8, 1, 0, 0, 1, 0},
+ {7, 5, 0, 0, 1, 0},
+ {6, 2, 0, 0, 1, 0}
+};
+
+const struct dll_setting ddr3_dll_setting_800[2][23] = {
+ { /* 1N */
+ /* tap pi db(2) delay coarse */
+ {8, 2, 0, 0, 0, 0},
+ {8, 4, 0, 0, 0, 0},
+ {9, 5, 0, 0, 0, 0},
+ {6, 1, 0, 0, 0, 0},
+ {8, 4, 0, 0, 0, 0},
+ {10, 0, 0, 0, 0, 0},
+ {10, 0, 0, 0, 0, 0},
+ {12, 0, 1, 0, 0, 0},
+ {1, 1, 1, 1, 1, 0},
+ {2, 4, 1, 1, 1, 0},
+ {3, 5, 0, 0, 1, 0},
+ {4, 3, 0, 0, 1, 0},
+ {5, 2, 0, 0, 1, 0},
+ {6, 1, 0, 0, 1, 0},
+ {6, 4, 0, 0, 1, 0},
+ {4, 1, 0, 0, 1, 0},
+ {6, 4, 0, 0, 1, 0},
+ {8, 1, 0, 0, 1, 0},
+ {8, 6, 0, 0, 1, 0},
+ {9, 5, 0, 0, 1, 0},
+ {10, 2, 0, 0, 1, 0},
+ {10, 6, 1, 0, 1, 0},
+ {11, 4, 1, 0, 1, 0} },
+ { /* 2N */
+ {2, 2, 1, 1, 0, 0},
+ {2, 4, 1, 1, 0, 0},
+ {3, 5, 0, 0, 0, 0},
+ {3, 2, 1, 1, 0, 0},
+ {2, 4, 1, 1, 0, 0},
+ {3, 6, 0, 0, 0, 0},
+ {3, 6, 0, 0, 0, 0},
+ {5, 6, 0, 0, 0, 0},
+ {8, 0, 0, 0, 0, 0},
+ {9, 4, 0, 0, 0, 0},
+ {10, 4, 1, 0, 0, 0},
+ {11, 3, 1, 0, 0, 0},
+ {12, 1, 1, 0, 0, 0},
+ {0, 1, 1, 1, 1, 0},
+ {0, 3, 1, 1, 1, 0},
+ {11, 0, 1, 0, 0, 0},
+ {0, 3, 1, 1, 1, 0},
+ {2, 1, 1, 1, 1, 0},
+ {2, 5, 1, 1, 1, 0},
+ {3, 5, 0, 0, 1, 0},
+ {4, 2, 0, 0, 1, 0},
+ {4, 6, 0, 0, 1, 0},
+ {5, 4, 0, 0, 1, 0}
+ }
+};
+
+const struct dll_setting ddr3_dll_setting_1066[2][23] = {
+ { /* 1N */
+ {8, 5, 0, 0, 0, 0},
+ {7, 6, 0, 0, 0, 0},
+ {10, 2, 1, 0, 0, 0},
+ {0, 4, 4, 0, 0, 0},
+ {7, 6, 0, 0, 0, 0},
+ {9, 2, 1, 0, 0, 0},
+ {9, 2, 1, 0, 0, 0},
+ {2, 5, 1, 1, 1, 0},
+ {5, 1, 0, 0, 1, 0},
+ {6, 6, 0, 0, 1, 0},
+ {8, 0, 0, 0, 1, 0},
+ {8, 6, 0, 0, 1, 0},
+ {9, 6, 1, 0, 1, 0},
+ {10, 6, 1, 0, 1, 0},
+ {0, 1, 1, 1, 0, 0},
+ {6, 5, 0, 0, 1, 0},
+ {9, 3, 1, 0, 1, 0},
+ {0, 2, 1, 1, 0, 1},
+ {1, 0, 1, 1, 0, 1},
+ {2, 0, 1, 1, 0, 1},
+ {2, 5, 1, 1, 0, 1},
+ {3, 2, 0, 0, 0, 1},
+ {4, 1, 0, 0, 0, 1}, },
+ { /* 2N */
+ {1, 5, 1, 1, 0, 0},
+ {0, 6, 1, 1, 0, 0},
+ {3, 2, 0, 0, 0, 0},
+ {2, 6, 1, 1, 0, 0},
+ {0, 6, 1, 1, 0, 0},
+ {2, 2, 1, 1, 0, 0},
+ {2, 2, 1, 1, 0, 0},
+ {6, 4, 0, 0, 0, 0},
+ {9, 1, 1, 0, 0, 0},
+ {10, 6, 1, 0, 0, 0},
+ {1, 0, 1, 1, 1, 0},
+ {1, 6, 1, 1, 1, 0},
+ {2, 5, 1, 1, 1, 0},
+ {3, 5, 0, 0, 1, 0},
+ {4, 1, 0, 0, 1, 0},
+ {10, 5, 1, 0, 0, 0},
+ {2, 3, 1, 1, 1, 0},
+ {4, 1, 0, 0, 1, 0},
+ {5, 0, 0, 0, 1, 0},
+ {6, 0, 0, 0, 1, 0},
+ {6, 5, 0, 0, 1, 0},
+ {7, 2, 0, 0, 1, 0},
+ {8, 1, 0, 0, 1, 0},
+ }
+};
+const struct dll_setting ddr3_dll_setting_1333[2][23] = {
+ { /* 1N */
+ {8, 5, 0, 0, 0, 0},
+ {9, 0, 1, 0, 0, 0},
+ {10, 2, 1, 0, 0, 0},
+ {0, 0, 1, 1, 0, 0},
+ {9, 0, 1, 0, 0, 0},
+ {10, 4, 1, 0, 0, 0},
+ {10, 4, 1, 0, 0, 0},
+ {2, 4, 1, 1, 1, 0},
+ {5, 1, 0, 0, 1, 0},
+ {6, 6, 0, 0, 1, 0},
+ {8, 0, 0, 0, 1, 0},
+ {8, 6, 0, 0, 1, 0},
+ {9, 5, 1, 0, 1, 0},
+ {10, 6, 1, 0, 1, 0},
+ {0, 1, 1, 1, 0, 1},
+ {6, 5, 0, 0, 1, 0},
+ {9, 3, 1, 0, 1, 0},
+ {0, 2, 1, 1, 0, 1},
+ {1, 0, 1, 1, 0, 1},
+ {2, 0, 1, 1, 0, 1},
+ {2, 5, 1, 1, 0, 1},
+ {3, 2, 0, 0, 0, 1},
+ {4, 1, 0, 0, 0, 1}, },
+ { /* 2N */
+ {1, 6, 1, 1, 0, 0},
+ {2, 2, 1, 1, 0, 0},
+ {4, 2, 0, 0, 0, 0},
+ {3, 1, 1, 1, 0, 0},
+ {2, 2, 1, 1, 0, 0},
+ {4, 5, 0, 0, 0, 0},
+ {4, 5, 0, 0, 0, 0},
+ {10, 4, 0, 0, 0, 0},
+ {0, 3, 1, 1, 1, 0},
+ {3, 2, 1, 1, 1, 0},
+ {5, 0, 0, 0, 1, 0},
+ {6, 1, 0, 0, 1, 0},
+ {7, 4, 0, 0, 1, 0},
+ {9, 2, 0, 0, 1, 0},
+ {9, 6, 0, 0, 1, 0},
+ {1, 3, 1, 1, 1, 0},
+ {5, 6, 0, 0, 1, 0},
+ {8, 5, 0, 0, 1, 0},
+ {10, 2, 0, 0, 1, 0},
+ {11, 1, 0, 0, 1, 0},
+ {12, 3, 1, 0, 1, 0},
+ {13, 6, 1, 0, 1, 0},
+ {0, 3, 1, 1, 0, 1}
+ }
+};
+
+const u8 ddr3_emrs1_config[16][4] = { /* [Config][Rank] */
+ {0x00, 0x00, 0x00, 0x00}, /* NC_NC */
+ {0x11, 0x00, 0x00, 0x00}, /* 8S_NC */
+ {0x11, 0x11, 0x00, 0x00}, /* 8D_NC */
+ {0x11, 0x00, 0x00, 0x00}, /* 16S_NC */
+ {0x00, 0x00, 0x11, 0x00}, /* NC_8S */
+ {0x81, 0x00, 0x81, 0x00}, /* 8S_8S */
+ {0x81, 0x81, 0x81, 0x00}, /* 8D_8S */
+ {0x81, 0x00, 0x81, 0x00}, /* 16S_8S */
+ {0x00, 0x00, 0x11, 0x11}, /* NC_8D */
+ {0x81, 0x00, 0x81, 0x81}, /* 8S_8D */
+ {0x81, 0x81, 0x81, 0x81}, /* 8D_8D */
+ {0x81, 0x00, 0x81, 0x81}, /* 16S_8D */
+ {0x00, 0x00, 0x11, 0x00}, /* NC_16S */
+ {0x81, 0x00, 0x81, 0x00}, /* 8S_16S */
+ {0x81, 0x81, 0x81, 0x00}, /* 8D_16S */
+ {0x81, 0x00, 0x81, 0x00}, /* 16S_16S */
+};
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
index 34fef93..9ef07b3 100644
--- a/src/northbridge/intel/x4x/x4x.h
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -355,6 +355,15 @@
struct abs_timings *saved_timings);
int ddr3_save_dimminfo(u8 dimm_idx, u8 *raw_spd,
struct abs_timings *saved_timings, struct sysinfo *s);
+void dqsset(u8 ch, u8 lane, const struct dll_setting *setting);
+void dqset(u8 ch, u8 lane, const struct dll_setting *setting);
+
+/* Look up tables Tables */
+extern const struct dll_setting ddr2_dll_setting_667[23];
+extern const struct dll_setting ddr2_dll_setting_800[23];
+extern const struct dll_setting ddr3_dll_setting_800[2][23];
+extern const struct dll_setting ddr3_dll_setting_1066[2][23];
+extern const struct dll_setting ddr3_dll_setting_1333[2][23];
struct acpi_rsdp;
--
To view, visit https://review.coreboot.org/19874
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia79b216ad69a02d4706ffc74f867a85db3eb2d6c
Gerrit-PatchSet: 1
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>
More information about the coreboot-gerrit
mailing list