Tobias Diedrich has uploaded this change for review. ( https://review.coreboot.org/22806
Change subject: intel/sandybridge: Add RAM voltage hooks ......................................................................
intel/sandybridge: Add RAM voltage hooks
Some boards support low-voltage DDR3.
This adds a hook for native raminit that is called before ram training and allows the romstage to set the RAM voltage first.
Tested: - Measured voltage on Intel NUC DCP847SKE changes from 1.5V to 1.35V when the RAM SPD claims support
Known issues: - Native raminit fails timC calibration with the RAM I have - Non-native raminit will continue to use the default voltage
Change-Id: Ic714c0717a66089dad4423d4eca5a0a29b7af817 Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de --- M src/mainboard/intel/dcp847ske/romstage.c M src/northbridge/intel/sandybridge/raminit_common.c M src/northbridge/intel/sandybridge/raminit_common.h M src/northbridge/intel/sandybridge/raminit_ivy.c M src/northbridge/intel/sandybridge/raminit_native.h M src/northbridge/intel/sandybridge/raminit_sandy.c 6 files changed, 32 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/22806/1
diff --git a/src/mainboard/intel/dcp847ske/romstage.c b/src/mainboard/intel/dcp847ske/romstage.c index ad31bba..cef6094 100644 --- a/src/mainboard/intel/dcp847ske/romstage.c +++ b/src/mainboard/intel/dcp847ske/romstage.c @@ -16,7 +16,9 @@ * GNU General Public License for more details. */
+#include <console/console.h> #include <stdint.h> +#include <southbridge/intel/common/gpio.h> #include <northbridge/intel/sandybridge/sandybridge.h> #if IS_ENABLED(CONFIG_USE_NATIVE_RAMINIT) #include <northbridge/intel/sandybridge/raminit_native.h> @@ -24,7 +26,20 @@ #include <northbridge/intel/sandybridge/raminit.h> #endif
-#if !IS_ENABLED(CONFIG_USE_NATIVE_RAMINIT) +#if IS_ENABLED(CONFIG_USE_NATIVE_RAMINIT) +void mainboard_set_dram_voltage(dimm_flags_t flags) +{ + if (flags.operable_1_35V) { + // GPIO8 default from gpio.c is LOW (1.5V). + // Set to HIGH to lower ram voltage to 1.35V. + set_gpio(8, 1); + } else if (!flags.operable_1_50V) { + // 1.50V _should_ be supported by any DDR3 ram that fits + // the connector... + printk(BIOS_ERR, "RAM does not support 1.35V or 1.5V!\n"); + } +} +#else void mainboard_fill_pei_data(struct pei_data *pei_data) { struct pei_data pei_data_template = { diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index eaef5f7..92bd9c5 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -138,12 +138,16 @@ dimm_info *dimms = &ctrl->info;
ctrl->cas_supported = (1 << (MAX_CAS - MIN_CAS + 1)) - 1; + ctrl->flags.raw = 0xffffffff; valid_dimms = 0; FOR_ALL_CHANNELS for (slot = 0; slot < 2; slot++) { const dimm_attr *dimm = &dimms->dimm[channel][slot]; if (dimm->dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3) continue; valid_dimms++; + + /* Find common flags */ + ctrl->flags.raw &= dimm->flags.raw;
/* Find all possible CAS combinations */ ctrl->cas_supported &= dimm->cas_supported; @@ -3363,3 +3367,7 @@
write32(DEFAULT_MCHBAR + 0x4ea8, 0); } + +void __attribute__((weak)) mainboard_set_dram_voltage(dimm_flags_t flags) +{ +} diff --git a/src/northbridge/intel/sandybridge/raminit_common.h b/src/northbridge/intel/sandybridge/raminit_common.h index ab6e592..c9f5c25 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.h +++ b/src/northbridge/intel/sandybridge/raminit_common.h @@ -81,6 +81,7 @@ /* DDR base_freq = 100 Mhz / 133 Mhz */ u8 base_freq;
+ dimm_flags_t flags; u16 cas_supported; /* tLatencies are in units of ns, scaled by x256 */ u32 tCK; diff --git a/src/northbridge/intel/sandybridge/raminit_ivy.c b/src/northbridge/intel/sandybridge/raminit_ivy.c index 675ac71..3df68c5 100644 --- a/src/northbridge/intel/sandybridge/raminit_ivy.c +++ b/src/northbridge/intel/sandybridge/raminit_ivy.c @@ -646,6 +646,9 @@ dram_dimm_mapping(ctrl); }
+ /* Set DRAM voltage */ + mainboard_set_dram_voltage(ctrl->flags); + /* Set MCU frequency */ dram_freq(ctrl);
diff --git a/src/northbridge/intel/sandybridge/raminit_native.h b/src/northbridge/intel/sandybridge/raminit_native.h index 2a91772..4744edd 100644 --- a/src/northbridge/intel/sandybridge/raminit_native.h +++ b/src/northbridge/intel/sandybridge/raminit_native.h @@ -22,5 +22,6 @@ /* The order is ch0dimmA, ch0dimmB, ch1dimmA, ch1dimmB. */ void read_spd(spd_raw_data *spd, u8 addr, bool id_only); void mainboard_get_spd(spd_raw_data *spd, bool id_only); +void mainboard_set_dram_voltage(dimm_flags_t flags);
#endif /* RAMINIT_H */ diff --git a/src/northbridge/intel/sandybridge/raminit_sandy.c b/src/northbridge/intel/sandybridge/raminit_sandy.c index 3acc563..231159f 100644 --- a/src/northbridge/intel/sandybridge/raminit_sandy.c +++ b/src/northbridge/intel/sandybridge/raminit_sandy.c @@ -416,6 +416,9 @@ dram_dimm_mapping(ctrl); }
+ /* Set DRAM voltage */ + mainboard_set_dram_voltage(ctrl->flags); + /* Set MCU frequency */ dram_freq(ctrl);