aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/x4x/raminit_ddr2.c
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2017-03-07 20:48:14 +0100
committerArthur Heymans <arthur@aheymans.xyz>2017-08-20 13:36:03 +0000
commit6d7a8c1125d17781fe2354eb316df247c82df741 (patch)
tree4b3522a81a6cc4ad9f11319301023aab80aa282e /src/northbridge/intel/x4x/raminit_ddr2.c
parente464ccd116fe51137d9068c5db2edd7275ae8c9d (diff)
nb/intel/x4x/raminit: Rework receive enable calibration
Moves receive enable calibration to a separate file to lighten raminit.c a bit. Receive enable calibration is quite similar to gm45 so it reuses some of its function names. The functional changes are: * the minimum coarse is now reset for each channel; * on the second fine search for DQS high, TAP overflow is handled by increasing medium; * start coarse at CAS + 1 instead of CAS - 1. Other Intel northbridges do the same and the results are more in line with register dumps from vendor bios. These might improve stability. TESTED on ga-g41m-es2l Change-Id: I0c970455e609d3ce96a262cbf110336a2079da4d Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/18692 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Huber <nico.h@gmx.de>
Diffstat (limited to 'src/northbridge/intel/x4x/raminit_ddr2.c')
-rw-r--r--src/northbridge/intel/x4x/raminit_ddr2.c283
1 files changed, 1 insertions, 282 deletions
diff --git a/src/northbridge/intel/x4x/raminit_ddr2.c b/src/northbridge/intel/x4x/raminit_ddr2.c
index bc012d259b..9c13fc1995 100644
--- a/src/northbridge/intel/x4x/raminit_ddr2.c
+++ b/src/northbridge/intel/x4x/raminit_ddr2.c
@@ -31,11 +31,6 @@
#define ME_UMA_SIZEMB 0
-static inline void barrier(void)
-{
- asm volatile("mfence":::);
-}
-
static u32 fsb2mhz(u32 speed)
{
return (speed * 267) + 800;
@@ -1161,282 +1156,6 @@ static void jedec_ddr2(struct sysinfo *s)
printk(BIOS_DEBUG, "MRS done\n");
}
-static u8 sampledqs(u16 mchloc, u32 addr, u8 hilow, u8 repeat)
-{
- u8 dqsmatch = 1;
- volatile u32 strobe;
-
- while (repeat-- > 0) {
- MCHBAR8(0x5d8) = MCHBAR8(0x5d8) & ~0x2;
- udelay(2);
- MCHBAR8(0x5d8) = MCHBAR8(0x5d8) | 0x2;
- udelay(2);
- MCHBAR8(0x9d8) = MCHBAR8(0x9d8) & ~0x2;
- udelay(2);
- MCHBAR8(0x9d8) = MCHBAR8(0x9d8) | 0x2;
- udelay(2);
- barrier();
- strobe = read32((u32 *)addr);
- barrier();
- if (((MCHBAR32(mchloc) & 0x40) >> 6) != hilow)
- dqsmatch = 0;
- }
- return dqsmatch;
-}
-
-static void rcven_ddr2(struct sysinfo *s)
-{
- u8 i, reg8, ch, lane;
- u32 addr;
- u8 tap = 0;
- u8 savecc, savemedium, savetap, coarsecommon, medium;
- u8 lanecoarse[8] = {0};
- u8 mincoarse = 0xff;
- u8 pitap[2][8];
- u16 coarsectrl[2];
- u16 coarsedelay[2];
- u16 mediumphase[2];
- u16 readdelay[2];
- u16 mchbar;
- MCHBAR8(0x5d8) = MCHBAR8(0x5d8) & ~0xc;
- MCHBAR8(0x9d8) = MCHBAR8(0x9d8) & ~0xc;
- MCHBAR8(0x5dc) = MCHBAR8(0x5dc) & ~0x80;
-
- FOR_EACH_POPULATED_CHANNEL(s->dimms, ch) {
- addr = (ch << 29);
- for (i = 0; !RANK_IS_POPULATED(s->dimms, ch, i); i++)
- addr += 128*1024*1024;
-
- for (lane = 0; lane < 8; lane++) {
- printk(BIOS_DEBUG, "Channel %d, Lane %d addr=0x%08x\n", ch, lane, addr);
- coarsecommon = (s->selected_timings.CAS - 1);
- switch (lane) {
- case 0: case 1:
- medium = 0;
- break;
- case 2: case 3:
- medium = 1;
- break;
- case 4: case 5:
- medium = 2;
- break;
- case 6: case 7:
- medium = 3;
- break;
- default:
- medium = 0;
- break;
- }
- mchbar = 0x400*ch + 0x561 + (lane << 2);
- tap = 0;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) |
- (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & ~(3 << (lane*2))) |
- (medium << (lane*2));
- MCHBAR8(0x400*ch + 0x560 + lane*4) = MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf;
- MCHBAR8(0x400*ch + 0x560 + lane*4) = MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0x70;
- savecc = coarsecommon;
- savemedium = medium;
- savetap = 0;
-
- MCHBAR16(0x400*ch + 0x588) = (MCHBAR16(0x400*ch + 0x588) & ~(3 << (lane*2))) |
- (1 << (lane*2));
-
- printk(BIOS_DEBUG, "rcven 0.1 coarse=%d\n", coarsecommon);
- while (sampledqs(mchbar, addr, 1, 1) == 1) {
- if (medium < 3) {
- medium++;
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- } else {
- medium = 0;
- coarsecommon++;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
- ~0xf0000) | (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- }
- if (coarsecommon > 16) {
- die("Coarse > 16: DQS tuning failed, halt\n");
- break;
- }
- }
- printk(BIOS_DEBUG, " GOT IT (high -> low transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
- savemedium = medium;
- savecc = coarsecommon;
- if (medium < 3) {
- medium++;
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- } else {
- medium = 0;
- coarsecommon++;
-
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) |
- (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) & ~(3 << (lane*2))) |
- (medium << (lane*2));
- }
-
- printk(BIOS_DEBUG, "rcven 0.2\n");
- while (sampledqs(mchbar, addr, 0, 1) == 1) {
- savemedium = medium;
- savecc = coarsecommon;
- if (medium < 3) {
- medium++;
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- } else {
- medium = 0;
- coarsecommon++;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
- ~0xf0000) | (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- }
- if (coarsecommon > 16) {
- die("Coarse DQS tuning 2 failed, halt\n");
- break;
- }
- }
- printk(BIOS_DEBUG, " GOT IT (low -> high transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
-
- coarsecommon = savecc;
- medium = savemedium;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
- ~0xf0000) | (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
-
- printk(BIOS_DEBUG, "rcven 0.3\n");
- tap = 0;
- while (sampledqs(mchbar, addr, 1, 1) == 0) {
- savetap = tap;
- tap++;
- if (tap > 14)
- break;
- MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
- (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | tap;
- }
-
- tap = savetap;
- MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
- (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | tap;
- MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
- (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0x70) | 0x30;
- if (medium < 3) {
- medium++;
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- } else {
- medium = 0;
- coarsecommon++;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
- ~0xf0000) | (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- }
- if (sampledqs(mchbar, addr, 1, 1) == 0)
- die("Not at DQS high, doh\n");
-
- printk(BIOS_DEBUG, "rcven 0.4\n");
- while (sampledqs(mchbar, addr, 1, 1) == 1) {
- coarsecommon--;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
- ~0xf0000) | (coarsecommon << 16);
- if (coarsecommon == 0) {
- die("Couldn't find DQS-high 0 indicator, halt\n");
- break;
- }
- }
- printk(BIOS_DEBUG, " GOT IT (high -> low transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
- printk(BIOS_DEBUG, "rcven 0.5\n");
- while (sampledqs(mchbar, addr, 0, 1) == 1) {
- savemedium = medium;
- savecc = coarsecommon;
- if (medium < 3) {
- medium++;
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- } else {
- medium = 0;
- coarsecommon++;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
- ~0xf0000) | (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- }
- if (coarsecommon > 16) {
- die("Coarse DQS tuning 5 failed, halt\n");
- break;
- }
- }
- printk(BIOS_DEBUG, " GOT IT (low -> high transition) coarse=%d medium=%d\n", coarsecommon, medium);
-
- printk(BIOS_DEBUG, "rcven 0.6\n");
- coarsecommon = savecc;
- medium = savemedium;
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) &
- ~0xf0000) | (coarsecommon << 16);
- MCHBAR16(0x400*ch + 0x58c) = (MCHBAR16(0x400*ch + 0x58c) &
- ~(3 << (lane*2))) | (medium << (lane*2));
- while (sampledqs(mchbar, addr, 1, 1) == 0) {
- savetap = tap;
- tap++;
- if (tap > 14)
- break;
- MCHBAR8(0x400*ch + 0x560 + lane*4) =
- (MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf) | tap;
- }
- tap = savetap;
- MCHBAR8(0x400*ch + 0x560 + lane*4) =
- (MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0xf) | tap;
- MCHBAR8(0x400*ch + 0x560 + lane*4) =
- (MCHBAR8(0x400*ch + 0x560 + lane*4) & ~0x70) | 0x70;
-
- pitap[ch][lane] = 0x70 | tap;
-
- MCHBAR16(0x400*ch + 0x588) = MCHBAR16(0x400*ch + 0x588) & ~(3 << (lane*2));
- lanecoarse[lane] = coarsecommon;
- printk(BIOS_DEBUG, "rcven 0.7\n");
- } // END EACH LANE
-
- // Find minimum coarse value
- for (lane = 0; lane < 8; lane++) {
- if (mincoarse > lanecoarse[lane])
- mincoarse = lanecoarse[lane];
- }
-
- printk(BIOS_DEBUG, "Found min coarse value = %d\n", mincoarse);
-
- for (lane = 0; lane < 8; lane++) {
- reg8 = (lanecoarse[lane] == 0) ? 0 : lanecoarse[lane] - mincoarse;
- MCHBAR16(0x400*ch + 0x5fa) = (MCHBAR16(0x400*ch + 0x5fa) & ~(3 << (lane*2))) |
- (reg8 << (lane*2));
- }
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) | (mincoarse << 16);
- coarsectrl[ch] = mincoarse;
- coarsedelay[ch] = MCHBAR16(0x400*ch + 0x5fa);
- mediumphase[ch] = MCHBAR16(0x400*ch + 0x58c);
- readdelay[ch] = MCHBAR16(0x400*ch + 0x588);
- } // END EACH POPULATED CHANNEL
-
- FOR_EACH_CHANNEL(ch) {
- for (lane = 0; lane < 8; lane++) {
- MCHBAR8(0x400*ch + 0x560 + (lane*4)) =
- (MCHBAR8(0x400*ch + 0x560 + (lane*4)) & ~0xf) | pitap[ch][lane];
- }
- MCHBAR32(0x400*ch + 0x248) = (MCHBAR32(0x400*ch + 0x248) & ~0xf0000) |
- (coarsectrl[ch] << 16);
- MCHBAR16(0x400*ch + 0x5fa) = coarsedelay[ch];
- MCHBAR16(0x400*ch + 0x58c) = mediumphase[ch];
- }
- printk(BIOS_DEBUG, "End rcven\n");
-}
-
static void sdram_save_receive_enable(void)
{
int i = 0;
@@ -1505,7 +1224,7 @@ static void sdram_program_receive_enable(struct sysinfo *s)
|| (s->boot_path == BOOT_PATH_RESUME)) {
sdram_recover_receive_enable();
} else {
- rcven_ddr2(s);
+ rcven(s);
sdram_save_receive_enable();
}
}