summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/intel/sandybridge/raminit.c172
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);