[coreboot-gerrit] Change in coreboot[master]: nb/intel/x4x: Add DDR3 JEDEC init
Arthur Heymans (Code Review)
gerrit at coreboot.org
Wed Dec 27 00:21:37 CET 2017
Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/22994
Change subject: nb/intel/x4x: Add DDR3 JEDEC init
......................................................................
nb/intel/x4x: Add DDR3 JEDEC init
Add DDR3 JEDEC init (Power up and Initialization by setting emrs regs)
the ddr3_emrs1_config array is placed externally since it is needed
for write leveling.
Change-Id: I510b8669aaa48ba99fb4dcf1ece716aef26741bb
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/northbridge/intel/x4x/raminit_ddr23.c
M src/northbridge/intel/x4x/raminit_tables.c
M src/northbridge/intel/x4x/spd_ddr3_decode.c
M src/northbridge/intel/x4x/x4x.h
4 files changed, 100 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/94/22994/1
diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c
index ddb1e01..2835890 100644
--- a/src/northbridge/intel/x4x/raminit_ddr23.c
+++ b/src/northbridge/intel/x4x/raminit_ddr23.c
@@ -1360,14 +1360,34 @@
return channel * 512 * MiB + rank * 128 * MiB;
}
-static void dojedec_ddr2(u8 r, u8 ch, u8 cmd, u16 val)
+static void send_jedec_cmd(const struct sysinfo *s, u8 r,
+ u8 ch, u8 cmd, u32 val)
{
u32 addr = test_address(ch, r);
volatile u32 rubbish;
+ u8 data8 = cmd;
+ u32 data32;
- MCHBAR8(0x271) = (MCHBAR8(0x271) & ~0x3e) | cmd;
- MCHBAR8(0x671) = (MCHBAR8(0x671) & ~0x3e) | cmd;
- rubbish = read32((void *)((val<<3) | addr));
+ if (s->spd_type == DDR3 && (r & 1)
+ && s->dimms[ch * 2 + (r >> 1)].mirrorred) {
+ data8 &= ~(1 << 4);
+ data8 |= ((1 << 4) & (cmd >> 1));
+ data8 &= ~(1 << 5);
+ data8 |= ((1 << 5) & (cmd << 1));
+ }
+
+ MCHBAR8(0x271) = (MCHBAR8(0x271) & ~0x3e) | data8;
+ MCHBAR8(0x671) = (MCHBAR8(0x671) & ~0x3e) | data8;
+ data32 = val;
+ if (s->spd_type == DDR3 && (r & 1)
+ && s->dimms[ch * 2 + (r >> 1)].mirrorred) {
+ data32 &= ~(0x1f8);
+ data32 |= (val & 0xa0) << 1;
+ data32 |= (val & 0x160) >> 1;
+ }
+ data32 <<= 3;
+
+ rubbish = read32((void *)((data32 | addr)));
udelay(10);
MCHBAR8(0x271) = (MCHBAR8(0x271) & ~0x3e) | NORMALOP_CMD;
MCHBAR8(0x671) = (MCHBAR8(0x671) & ~0x3e) | NORMALOP_CMD;
@@ -1432,7 +1452,7 @@
default:
break;
}
- dojedec_ddr2(r, ch, jedec[i][0], v);
+ send_jedec_cmd(s, r, ch, jedec[i][0], v);
udelay(1);
printk(RAM_SPEW, "Jedec step %d\n", i);
}
@@ -1440,6 +1460,52 @@
printk(BIOS_DEBUG, "MRS done\n");
}
+static void jedec_ddr3(struct sysinfo *s)
+{
+ int ch, r, dimmconfig, cmd, ddr3_freq;
+
+ u8 ddr3_emrs2_config[16][4] = { /* [config][Rank] */
+ {0, 0, 0, 0}, /* NC_NC */
+ {0, 0, 0, 0}, /* x8ss_NC */
+ {0, 0, 0, 0}, /* x8ds_NC */
+ {0, 0, 0, 0}, /* x16ss_NC */
+ {0, 0, 0, 0}, /* NC_x8ss */
+ {2, 0, 2, 0}, /* x8ss_x8ss */
+ {2, 2, 2, 0}, /* x8ds_x8ss */
+ {2, 0, 2, 0}, /* x16ss_x8ss */
+ {0, 0, 0, 0}, /* NC_x8ss */
+ {2, 0, 2, 2}, /* x8ss_x8ds */
+ {2, 2, 2, 2}, /* x8ds_x8ds */
+ {2, 0, 2, 2}, /* x16ss_x8ds */
+ {0, 0, 0, 0}, /* NC_x16ss */
+ {2, 0, 2, 0}, /* x8ss_x16ss */
+ {2, 2, 2, 0}, /* x8ds_x16ss */
+ {2, 0, 2, 0}, /* x16ss_x16ss */
+ };
+
+ printk(BIOS_DEBUG, "MRS...\n");
+
+ ddr3_freq = s->selected_timings.mem_clk - MEM_CLOCK_800MHz;
+ FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
+ printk(BIOS_DEBUG, "CH%d: Found Rank %d\n", ch, r);
+ send_jedec_cmd(s, r, ch, NOP_CMD, 0);
+ udelay(200);
+ dimmconfig = s->dimm_config[ch];
+ cmd = ddr3_freq << 3; /* actually twl - 5 which is same */
+ cmd |= ddr3_emrs2_config[dimmconfig][r] << 9;
+ send_jedec_cmd(s, r, ch, EMRS2_CMD, cmd);
+ send_jedec_cmd(s, r, ch, EMRS3_CMD, 0);
+ cmd = ddr3_emrs1_config[dimmconfig][r] << 2;
+ cmd |= (1 << 1);
+ send_jedec_cmd(s, r, ch, EMRS1_CMD, cmd);
+ send_jedec_cmd(s, r, ch, MRS_CMD, (1 << 3) | (1 << 8)
+ | (1 << 12) | ((s->selected_timings.CAS - 4) << 4)
+ | ((s->selected_timings.tWR - 4) << 9));
+ send_jedec_cmd(s, r, ch, ZQCAL_CMD, (1 << 10));
+ }
+ printk(BIOS_DEBUG, "MRS done\n");
+}
+
static void sdram_recover_receive_enable(const struct sysinfo *s)
{
u32 reg32;
@@ -1956,8 +2022,12 @@
printk(BIOS_DEBUG, "Done pre-jedec\n");
// JEDEC reset
- if (s->boot_path != BOOT_PATH_RESUME)
- jedec_ddr2(s);
+ if (s->boot_path != BOOT_PATH_RESUME) {
+ if (s->spd_type == DDR2)
+ jedec_ddr2(s);
+ else /* DDR3 */
+ jedec_ddr3(s);
+ }
printk(BIOS_DEBUG, "Done jedec steps\n");
diff --git a/src/northbridge/intel/x4x/raminit_tables.c b/src/northbridge/intel/x4x/raminit_tables.c
index f386b6b..ee64967 100644
--- a/src/northbridge/intel/x4x/raminit_tables.c
+++ b/src/northbridge/intel/x4x/raminit_tables.c
@@ -269,3 +269,22 @@
{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/spd_ddr3_decode.c b/src/northbridge/intel/x4x/spd_ddr3_decode.c
index b1ac3ea..a57b14c 100644
--- a/src/northbridge/intel/x4x/spd_ddr3_decode.c
+++ b/src/northbridge/intel/x4x/spd_ddr3_decode.c
@@ -160,6 +160,8 @@
s->dimms[dimm_idx].rows = decoded_dimm.row_bits;
s->dimms[dimm_idx].cols = decoded_dimm.col_bits;
+ s->dimms[dimm_idx].mirrorred = decoded_dimm.flags.pins_mirrored;
+
saved_timings->min_tRAS =
MAX(saved_timings->min_tRAS, decoded_dimm.tRAS);
saved_timings->min_tRP =
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
index f374725..37215b1 100644
--- a/src/northbridge/intel/x4x/x4x.h
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -308,6 +308,7 @@
unsigned int ranks;
unsigned int rows;
unsigned int cols;
+ u8 mirrorred;
u16 checksum;
};
@@ -412,6 +413,7 @@
extern const struct dll_setting default_ddr3_800_dq[2][8];
extern const struct dll_setting default_ddr3_1067_dq[2][8];
extern const struct dll_setting default_ddr3_1333_dq[2][8];
+extern const u8 ddr3_emrs1_config[16][4];
struct acpi_rsdp;
#ifndef __SIMPLE_DEVICE__
--
To view, visit https://review.coreboot.org/22994
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I510b8669aaa48ba99fb4dcf1ece716aef26741bb
Gerrit-Change-Number: 22994
Gerrit-PatchSet: 1
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171226/ef95251c/attachment-0001.html>
More information about the coreboot-gerrit
mailing list