diff options
author | Patrick Rudolph <siro@das-labor.org> | 2016-03-26 10:59:02 +0100 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-03-30 16:22:44 +0200 |
commit | 27e085a8eea7f34ed4987b83c513d2f1818b33a1 (patch) | |
tree | a17f2bdabae937e1b0171d752ab9e6f9f577583b /src/northbridge/intel/sandybridge/raminit.c | |
parent | e9e7b20f43617880d1d0300257bb88595bea4e35 (diff) | |
download | coreboot-27e085a8eea7f34ed4987b83c513d2f1818b33a1.tar.xz |
nb/intel/sandybridge/raminit: move ram training into seperate function
In order to add a fallback mechanism, move the ram training code
into a new function. This function will be called multiple times
and must return error or success to the calling function.
Change-Id: I5ee1b3a528290d8252d236b9152b81291736958a
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/14169
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/northbridge/intel/sandybridge/raminit.c')
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit.c | 172 |
1 files changed, 90 insertions, 82 deletions
diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 7d946af049..dbec9fb8c8 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -3946,88 +3946,32 @@ static void restore_timings(ramctr_timing * ctrl) write32(DEFAULT_MCHBAR + 0x4ea8, 0); } -void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck, - int s3resume) +static int try_init_dram_ddr3(ramctr_timing *ctrl, int s3resume, + int me_uma_size) { - int me_uma_size; - int cbmem_was_inited; - ramctr_timing ctrl; - - MCHBAR32(0x5f00) |= 1; - - report_platform_info(); - - /* Wait for ME to be ready */ - intel_early_me_init(); - me_uma_size = intel_early_me_uma_size(); - - printk(BIOS_DEBUG, "Starting native Platform init\n"); - - u32 reg_5d10; - - wait_txt_clear(); - - wrmsr(0x000002e6, (msr_t) { .lo = 0, .hi = 0 }); - - reg_5d10 = read32(DEFAULT_MCHBAR + 0x5d10); // !!! = 0x00000000 - if ((pcie_read_config16(SOUTHBRIDGE, 0xa2) & 0xa0) == 0x20 /* 0x0004 */ - && reg_5d10 && !s3resume) { - write32(DEFAULT_MCHBAR + 0x5d10, 0); - /* Need reset. */ - outb(0x6, 0xcf9); - - halt(); - } - - memset(&ctrl, 0, sizeof (ctrl)); - - early_pch_init_native(); - early_thermal_init(); - - ctrl.mobile = mobile; - ctrl.tCK = min_tck; - - /* FIXME: for non-S3 we should be able to use timing caching with - proper verification. Right now we use timings only for S3 case. - */ - if (s3resume) { - struct mrc_data_container *mrc_cache; - - mrc_cache = find_current_mrc_cache(); - if (!mrc_cache || mrc_cache->mrc_data_size < sizeof (ctrl)) { - /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); - } - memcpy(&ctrl, mrc_cache->mrc_data, sizeof (ctrl)); - } - if (!s3resume) { - /* Get DDR3 SPD data */ - dram_find_spds_ddr3(spds, &ctrl); - /* Find fastest common supported parameters */ - dram_find_common_params(&ctrl); + dram_find_common_params(ctrl); - dram_dimm_mapping(&ctrl); + dram_dimm_mapping(ctrl); } /* Set MCU frequency */ - dram_freq(&ctrl); + dram_freq(ctrl); if (!s3resume) { /* Calculate timings */ - dram_timing(&ctrl); + dram_timing(ctrl); } /* Set version register */ MCHBAR32(0x5034) = 0xC04EB002; /* Enable crossover */ - dram_xover(&ctrl); + dram_xover(ctrl); /* Set timing and refresh registers */ - dram_timing_regs(&ctrl); + dram_timing_regs(ctrl); /* Power mode preset */ MCHBAR32(0x4e80) = 0x5500; @@ -4042,64 +3986,128 @@ void init_dram_ddr3(spd_raw_data * spds, int mobile, int min_tck, MCHBAR32(0x5030) &= ~0x20; /* Set MAD-DIMM registers */ - dram_dimm_set_mapping(&ctrl); + dram_dimm_set_mapping(ctrl); printk(BIOS_DEBUG, "Done dimm mapping\n"); /* Zone config */ - dram_zones(&ctrl, 1); + dram_zones(ctrl, 1); /* Set memory map */ - dram_memorymap(&ctrl, me_uma_size); + dram_memorymap(ctrl, me_uma_size); printk(BIOS_DEBUG, "Done memory map\n"); /* Set IO registers */ - dram_ioregs(&ctrl); + dram_ioregs(ctrl); printk(BIOS_DEBUG, "Done io registers\n"); udelay(1); if (s3resume) { - restore_timings(&ctrl); + restore_timings(ctrl); } else { /* Do jedec ddr3 reset sequence */ - dram_jedecreset(&ctrl); + dram_jedecreset(ctrl); printk(BIOS_DEBUG, "Done jedec reset\n"); /* MRS commands */ - dram_mrscommands(&ctrl); + dram_mrscommands(ctrl); printk(BIOS_DEBUG, "Done MRS commands\n"); /* Prepare for memory training */ - prepare_training(&ctrl); + prepare_training(ctrl); - read_training(&ctrl); - write_training(&ctrl); + read_training(ctrl); + write_training(ctrl); printram("CP5a\n"); - discover_edges(&ctrl); + discover_edges(ctrl); printram("CP5b\n"); - command_training(&ctrl); + command_training(ctrl); printram("CP5c\n"); - discover_edges_write(&ctrl); + discover_edges_write(ctrl); - discover_timC_write(&ctrl); + discover_timC_write(ctrl); - normalize_training(&ctrl); + normalize_training(ctrl); } - set_4008c(&ctrl); + set_4008c(ctrl); - write_controller_mr(&ctrl); + write_controller_mr(ctrl); if (!s3resume) { - channel_test(&ctrl); + channel_test(ctrl); + } + + return 0; +} + +void init_dram_ddr3(spd_raw_data *spds, int mobile, int min_tck, + int s3resume) +{ + int me_uma_size; + int cbmem_was_inited; + ramctr_timing ctrl; + + MCHBAR32(0x5f00) |= 1; + + report_platform_info(); + + /* Wait for ME to be ready */ + intel_early_me_init(); + me_uma_size = intel_early_me_uma_size(); + + printk(BIOS_DEBUG, "Starting native Platform init\n"); + + u32 reg_5d10; + + wait_txt_clear(); + + wrmsr(0x000002e6, (msr_t) { .lo = 0, .hi = 0 }); + + reg_5d10 = read32(DEFAULT_MCHBAR + 0x5d10); // !!! = 0x00000000 + if ((pcie_read_config16(SOUTHBRIDGE, 0xa2) & 0xa0) == 0x20 /* 0x0004 */ + && reg_5d10 && !s3resume) { + write32(DEFAULT_MCHBAR + 0x5d10, 0); + /* Need reset. */ + outb(0x6, 0xcf9); + + halt(); + } + + memset(&ctrl, 0, sizeof (ctrl)); + + early_pch_init_native(); + early_thermal_init(); + + ctrl.mobile = mobile; + ctrl.tCK = min_tck; + + /* FIXME: for non-S3 we should be able to use timing caching with + proper verification. Right now we use timings only for S3 case. + */ + if (s3resume) { + struct mrc_data_container *mrc_cache; + + mrc_cache = find_current_mrc_cache(); + if (!mrc_cache || (mrc_cache->mrc_data_size < sizeof(ctrl))) { + /* Failed S3 resume, reset to come up cleanly */ + outb(0x6, 0xcf9); + halt(); + } + memcpy(&ctrl, mrc_cache->mrc_data, sizeof(ctrl)); + } else { + /* Get DDR3 SPD data */ + dram_find_spds_ddr3(spds, &ctrl); } + try_init_dram_ddr3(&ctrl, s3resume, me_uma_size); + /* FIXME: should be hardware revision-dependent. */ write32(DEFAULT_MCHBAR + 0x5024, 0x00a030ce); |