diff options
| author | Leah Rowe <leah@libreboot.org> | 2025-04-21 02:22:40 +0100 | 
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2025-04-21 03:26:54 +0100 | 
| commit | 762c7ff43ebd065de62f26fbe5729d221110c5a0 (patch) | |
| tree | e61a91b987761e52cca04f3a2b6dc0d0c26c2d47 /config/coreboot/default/patches/0044-haswell-NRI-Add-final-raminit-steps.patch | |
| parent | 86e7aa80c51979767208b858dac5f38d7e83914e (diff) | |
coreboot/default: Update, c247f62749b (8 Feb 2025)
This is currently the latest revision of coreboot.
Other coreboot trees to follow. The "next" tree will
also be merged with coreboot/default, in a follow-up
commit.
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'config/coreboot/default/patches/0044-haswell-NRI-Add-final-raminit-steps.patch')
| -rw-r--r-- | config/coreboot/default/patches/0044-haswell-NRI-Add-final-raminit-steps.patch | 570 | 
1 files changed, 0 insertions, 570 deletions
diff --git a/config/coreboot/default/patches/0044-haswell-NRI-Add-final-raminit-steps.patch b/config/coreboot/default/patches/0044-haswell-NRI-Add-final-raminit-steps.patch deleted file mode 100644 index 62cae936..00000000 --- a/config/coreboot/default/patches/0044-haswell-NRI-Add-final-raminit-steps.patch +++ /dev/null @@ -1,570 +0,0 @@ -From 9d1b945702006db5678c5dc81699699bf6e6741a Mon Sep 17 00:00:00 2001 -From: Angel Pons <th3fanbus@gmail.com> -Date: Sun, 8 May 2022 14:29:05 +0200 -Subject: [PATCH 44/51] haswell NRI: Add final raminit steps - -Implement the remaining raminit steps. Although many training steps are -missing, this is enough to boot on the Asrock B85M Pro4. - -Change-Id: I94f3b65f0218d4da4fda4d84592dfd91f77f8f21 -Signed-off-by: Angel Pons <th3fanbus@gmail.com> ---- - src/northbridge/intel/haswell/Kconfig         |   4 +- - .../intel/haswell/native_raminit/Makefile.mk  |   1 + - .../haswell/native_raminit/activate_mc.c      | 388 ++++++++++++++++++ - .../haswell/native_raminit/raminit_main.c     |   5 +- - .../haswell/native_raminit/raminit_native.c   |   5 +- - .../haswell/native_raminit/raminit_native.h   |   2 + - .../haswell/native_raminit/reg_structs.h      |  12 + - .../intel/haswell/registers/mchbar.h          |   7 + - 8 files changed, 416 insertions(+), 8 deletions(-) - create mode 100644 src/northbridge/intel/haswell/native_raminit/activate_mc.c - -diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig -index 4b83a25bc1..c6ab27184e 100644 ---- a/src/northbridge/intel/haswell/Kconfig -+++ b/src/northbridge/intel/haswell/Kconfig -@@ -11,12 +11,12 @@ config NORTHBRIDGE_INTEL_HASWELL - if NORTHBRIDGE_INTEL_HASWELL -  - config USE_NATIVE_RAMINIT --	bool "[NOT WORKING] Use native raminit" -+	bool "[NOT COMPLETE] Use native raminit" - 	default n - 	select HAVE_DEBUG_RAM_SETUP - 	help - 	  Select if you want to use coreboot implementation of raminit rather than --	  MRC.bin. Currently incomplete and does not boot. -+	  MRC.bin. Currently incomplete and does not support S3 resume. -  - config HASWELL_VBOOT_IN_BOOTBLOCK - 	depends on VBOOT -diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk -index 40c2f5e014..d97da72890 100644 ---- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk -+++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk -@@ -1,5 +1,6 @@ - ## SPDX-License-Identifier: GPL-2.0-or-later -  -+romstage-y += activate_mc.c - romstage-y += change_margin.c - romstage-y += configure_mc.c - romstage-y += ddr3.c -diff --git a/src/northbridge/intel/haswell/native_raminit/activate_mc.c b/src/northbridge/intel/haswell/native_raminit/activate_mc.c -new file mode 100644 -index 0000000000..78a7ad27ef ---- /dev/null -+++ b/src/northbridge/intel/haswell/native_raminit/activate_mc.c -@@ -0,0 +1,388 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+ -+#include <console/console.h> -+#include <delay.h> -+#include <device/pci_ops.h> -+#include <northbridge/intel/haswell/haswell.h> -+#include <timer.h> -+#include <types.h> -+ -+#include "raminit_native.h" -+ -+static void update_internal_clocks_on(struct sysinfo *ctrl) -+{ -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		if (!does_ch_exist(ctrl, channel)) -+			continue; -+ -+		bool clocks_on = false; -+		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { -+			const union ddr_data_control_1_reg data_control_1 = { -+				.raw = ctrl->dq_control_1[channel][byte], -+			}; -+			const int8_t o_on = data_control_1.odt_delay; -+			const int8_t s_on = data_control_1.sense_amp_delay; -+			const int8_t o_off = data_control_1.odt_duration; -+			const int8_t s_off = data_control_1.sense_amp_duration; -+			if (o_on + o_off >= 7 || s_on + s_off >= 7) { -+				clocks_on = true; -+				break; -+			} -+		} -+		union ddr_data_control_0_reg data_control_0 = { -+			.raw = ctrl->dq_control_0[channel], -+		}; -+		data_control_0.internal_clocks_on = clocks_on; -+		ctrl->dq_control_0[channel] = data_control_0.raw; -+		mchbar_write32(DDR_DATA_ch_CONTROL_0(channel), data_control_0.raw); -+	} -+} -+ -+/* Switch off unused segments of the SDLL to save power */ -+static void update_sdll_length(struct sysinfo *ctrl) -+{ -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		if (!does_ch_exist(ctrl, channel)) -+			continue; -+ -+		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { -+			uint8_t max_pi = 0; -+			for (uint8_t rank = 0; rank < NUM_SLOTRANKS; rank++) { -+				if (!rank_in_ch(ctrl, rank, channel)) -+					continue; -+ -+				const uint8_t rx_dqs_p = ctrl->rxdqsp[channel][rank][byte]; -+				const uint8_t rx_dqs_n = ctrl->rxdqsn[channel][rank][byte]; -+				max_pi = MAX(max_pi, MAX(rx_dqs_p, rx_dqs_n)); -+			} -+			/* Update SDLL length for power savings */ -+			union ddr_data_control_1_reg data_control_1 = { -+				.raw = ctrl->dq_control_1[channel][byte], -+			}; -+			/* Calculate which segments to turn off */ -+			data_control_1.sdll_segment_disable = (7 - (max_pi >> 3)) & ~1; -+			ctrl->dq_control_1[channel][byte] = data_control_1.raw; -+			mchbar_write32(DQ_CONTROL_1(channel, byte), data_control_1.raw); -+		} -+	} -+} -+ -+static void set_rx_clk_stg_num(struct sysinfo *ctrl, const uint8_t channel) -+{ -+	const uint8_t rcven_drift = ctrl->lpddr ? DIV_ROUND_UP(tDQSCK_DRIFT, ctrl->qclkps) : 1; -+	uint8_t max_rcven = 0; -+	for (uint8_t rank = 0; rank < NUM_SLOTRANKS; rank++) { -+		if (!rank_in_ch(ctrl, rank, channel)) -+			continue; -+ -+		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) -+			max_rcven = MAX(max_rcven, ctrl->rcven[channel][rank][byte] / 64); -+	} -+	const union ddr_data_control_1_reg ddr_data_control_1 = { -+		.raw = ctrl->dq_control_1[channel][0], -+	}; -+	const bool lpddr_long_odt = ddr_data_control_1.lpddr_long_odt_en; -+	const uint8_t rcven_turnoff = max_rcven + 18 + 2 * rcven_drift + lpddr_long_odt; -+	const union ddr_data_control_0_reg ddr_data_control_0 = { -+		.raw = ctrl->dq_control_0[channel], -+	}; -+	for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { -+		union ddr_data_control_2_reg ddr_data_control_2 = { -+			.raw = ctrl->dq_control_2[channel][byte], -+		}; -+		if (ddr_data_control_0.odt_samp_extend_en) { -+			if (ddr_data_control_2.rx_clk_stg_num < rcven_turnoff) -+				ddr_data_control_2.rx_clk_stg_num = rcven_turnoff; -+		} else { -+			const int8_t o_on = ddr_data_control_1.odt_delay; -+			const int8_t o_off = ddr_data_control_1.odt_duration; -+			ddr_data_control_2.rx_clk_stg_num = MAX(17, o_on + o_off + 14); -+		} -+		ctrl->dq_control_2[channel][byte] = ddr_data_control_2.raw; -+		mchbar_write32(DQ_CONTROL_2(channel, byte), ddr_data_control_2.raw); -+	} -+} -+ -+#define SELF_REFRESH_IDLE_COUNT 0x200 -+ -+static void enter_sr(void) -+{ -+	mchbar_write32(PM_SREF_CONFIG, SELF_REFRESH_IDLE_COUNT | BIT(16)); -+	udelay(1); -+} -+ -+enum power_down_mode { -+	PDM_NO_PD	= 0, -+	PDM_APD		= 1, -+	PDM_PPD		= 2, -+	PDM_PPD_DLL_OFF	= 6, -+}; -+ -+static void power_down_config(struct sysinfo *ctrl) -+{ -+	const enum power_down_mode pd_mode = ctrl->lpddr ? PDM_PPD : PDM_PPD_DLL_OFF; -+	mchbar_write32(PM_PDWN_CONFIG, pd_mode << 12 | 0x40); -+} -+ -+static void train_power_modes_post(struct sysinfo *ctrl) -+{ -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		if (!does_ch_exist(ctrl, channel)) -+			continue; -+ -+		/* Adjust tCPDED and tPRPDEN */ -+		if (ctrl->mem_clock_mhz >= 933) -+			ctrl->tc_bankrank_d[channel].tCPDED = 2; -+ -+		if (ctrl->mem_clock_mhz >= 1066) -+			ctrl->tc_bankrank_d[channel].tPRPDEN = 2; -+ -+		mchbar_write32(TC_BANK_RANK_D_ch(channel), ctrl->tc_bankrank_d[channel].raw); -+	} -+	power_down_config(ctrl); -+	mchbar_write32(MCDECS_CBIT, BIT(30));	/* dis_msg_clk_gate */ -+} -+ -+static uint8_t compute_burst_end_odt_delay(const struct sysinfo *const ctrl) -+{ -+	/* Must be disabled for LPDDR */ -+	if (ctrl->lpddr) -+		return 0; -+ -+	const uint8_t beod = MIN(7, DIV_ROUND_CLOSEST(14300 * 20 / 100, ctrl->qclkps)); -+	if (beod < 3) -+		return 0; -+ -+	if (beod < 4) -+		return 4; -+ -+	return beod; -+} -+ -+static void program_burst_end_odt_delay(struct sysinfo *ctrl) -+{ -+	/* Program burst_end_odt_delay - it should be zero during training steps */ -+	const uint8_t beod = compute_burst_end_odt_delay(ctrl); -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		if (!does_ch_exist(ctrl, channel)) -+			continue; -+ -+		for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { -+			union ddr_data_control_1_reg ddr_data_control_1 = { -+				.raw = ctrl->dq_control_1[channel][byte], -+			}; -+			ddr_data_control_1.burst_end_odt_delay = beod; -+			ctrl->dq_control_1[channel][byte] = ddr_data_control_1.raw; -+			mchbar_write32(DQ_CONTROL_1(channel, byte), ddr_data_control_1.raw); -+		} -+	} -+} -+ -+/* -+ * Return a random value to use for scrambler seeds. Try to use RDRAND -+ * first and fall back to hardcoded values if RDRAND does not succeed. -+ */ -+static uint16_t get_random_number(const uint8_t channel) -+{ -+	/* The RDRAND instruction is only available 100k cycles after reset */ -+	for (size_t i = 0; i < 100000; i++) { -+		uint32_t status; -+		uint32_t random; -+		/** TODO: Clean up asm **/ -+		__asm__ __volatile__( -+			"\n\t .byte 0x0F, 0xC7, 0xF0" -+			"\n\t movl %%eax, %0" -+			"\n\t pushf" -+			"\n\t pop %%eax" -+			"\n\t movl %%eax, %1" -+			: "=m"(random), -+			  "=m"(status) -+			: /* No inputs */ -+			: "eax", "cc"); -+ -+		/* Only consider non-zero random values as valid */ -+		if (status & 1 && random) -+			return random; -+	} -+ -+	/* https://xkcd.com/221 */ -+	if (channel) -+		return 0x28f4; -+	else -+		return 0x893e; -+} -+ -+/* Work around "error: 'typeof' applied to a bit-field" */ -+static inline uint32_t max(const uint32_t a, const uint32_t b) -+{ -+	return MAX(a, b); -+} -+ -+enum raminit_status activate_mc(struct sysinfo *ctrl) -+{ -+	const bool enable_scrambling = true; -+	const bool enable_cmd_tristate = true; -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		if (!does_ch_exist(ctrl, channel)) -+			continue; -+ -+		if (enable_scrambling && ctrl->stepping < STEPPING_C0) { -+			/* Make sure tRDRD_(sr, dr, dd) are at least 6 for scrambler W/A */ -+			union tc_bank_rank_a_reg tc_bank_rank_a = { -+				.raw = mchbar_read32(TC_BANK_RANK_A_ch(channel)), -+			}; -+			tc_bank_rank_a.tRDRD_sr = max(tc_bank_rank_a.tRDRD_sr, 6); -+			tc_bank_rank_a.tRDRD_dr = max(tc_bank_rank_a.tRDRD_dr, 6); -+			tc_bank_rank_a.tRDRD_dd = max(tc_bank_rank_a.tRDRD_dd, 6); -+			mchbar_write32(TC_BANK_RANK_A_ch(channel), tc_bank_rank_a.raw); -+		} -+		if (enable_scrambling) { -+			const union ddr_scramble_reg ddr_scramble = { -+				.scram_key = get_random_number(channel), -+				.scram_en  = 1, -+			}; -+			mchbar_write32(DDR_SCRAMBLE_ch(channel), ddr_scramble.raw); -+		} -+		if (ctrl->tCMD == 1) { -+			/* If we are in 1N mode, enable and set command rate limit to 3 */ -+			union mcmain_command_rate_limit_reg cmd_rate_limit = { -+				.raw = mchbar_read32(COMMAND_RATE_LIMIT_ch(channel)), -+			}; -+			cmd_rate_limit.enable_cmd_limit = 1; -+			cmd_rate_limit.cmd_rate_limit   = 3; -+			mchbar_write32(COMMAND_RATE_LIMIT_ch(channel), cmd_rate_limit.raw); -+		} -+		if (enable_cmd_tristate) { -+			/* Enable command tri-state at the end of training */ -+			union tc_bank_rank_a_reg tc_bank_rank_a = { -+				.raw = mchbar_read32(TC_BANK_RANK_A_ch(channel)), -+			}; -+			tc_bank_rank_a.cmd_3st_dis = 0; -+			mchbar_write32(TC_BANK_RANK_A_ch(channel), tc_bank_rank_a.raw); -+		} -+		/* Set MC to normal mode and clean the ODT and CKE */ -+		mchbar_write32(REUT_ch_SEQ_CFG(channel), REUT_MODE_NOP << 12); -+		/* Set again the rank occupancy */ -+		mchbar_write8(MC_INIT_STATE_ch(channel), ctrl->rankmap[channel]); -+		if (ctrl->is_ecc) { -+			/* Enable ECC I/O and logic */ -+			union mad_dimm_reg mad_dimm = { -+				.raw = mchbar_read32(MAD_DIMM(channel)), -+			}; -+			mad_dimm.ecc_mode = 3; -+			mchbar_write32(MAD_DIMM(channel), mad_dimm.raw); -+		} -+	} -+ -+	if (!is_hsw_ult()) -+		update_internal_clocks_on(ctrl); -+ -+	update_sdll_length(ctrl); -+ -+	program_burst_end_odt_delay(ctrl); -+ -+	if (is_hsw_ult()) { -+		for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+			if (!does_ch_exist(ctrl, channel)) -+				continue; -+ -+			set_rx_clk_stg_num(ctrl, channel); -+		} -+		/** TODO: Program DDRPL_CR_DDR_TX_DELAY if Memory Trace is enabled **/ -+	} -+ -+	/* Enable periodic COMP */ -+	mchbar_write32(M_COMP, (union pcu_comp_reg) { -+		.comp_interval = COMP_INT, -+	}.raw); -+ -+	/* Enable the power mode before PCU starts working */ -+	train_power_modes_post(ctrl); -+ -+	/* Set idle timer and self refresh enable bits */ -+	enter_sr(); -+ -+	/** FIXME: Do not hardcode power weights and RAPL settings **/ -+	mchbar_write32(0x5888, 0x00000d0d); -+	mchbar_write32(0x5884, 0x00000004);	/* 58.2 pJ */ -+ -+	mchbar_write32(0x58e0, 0); -+	mchbar_write32(0x58e4, 0); -+ -+	mchbar_write32(0x5890, 0xffff); -+	mchbar_write32(0x5894, 0xffff); -+	mchbar_write32(0x5898, 0xffff); -+	mchbar_write32(0x589c, 0xffff); -+	mchbar_write32(0x58d0, 0xffff); -+	mchbar_write32(0x58d4, 0xffff); -+	mchbar_write32(0x58d8, 0xffff); -+	mchbar_write32(0x58dc, 0xffff); -+ -+	/* Overwrite thermal parameters */ -+	for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { -+		mchbar_write32(_MCMAIN_C(0x42ec, channel), 0x0000000f); -+		mchbar_write32(_MCMAIN_C(0x42f0, channel), 0x00000009); -+		mchbar_write32(_MCMAIN_C(0x42f4, channel), 0x00000093); -+		mchbar_write32(_MCMAIN_C(0x42f8, channel), 0x00000087); -+		mchbar_write32(_MCMAIN_C(0x42fc, channel), 0x000000de); -+ -+		/** TODO: Differs for LPDDR **/ -+		mchbar_write32(PM_THRT_CKE_MIN_ch(channel), 0x30); -+	} -+	mchbar_write32(PCU_DDR_PTM_CTL, 0x40); -+	return RAMINIT_STATUS_SUCCESS; -+} -+ -+static void mc_lockdown(void) -+{ -+	/* Lock memory controller registers */ -+	mchbar_write32(MC_LOCK, 0x8f); -+ -+	/* MPCOHTRK_GDXC_OCLA_ADDRESS_HI_LOCK is set when programming the memory map */ -+ -+	/* Lock memory map registers */ -+	pci_or_config16(HOST_BRIDGE, GGC,         1 <<  0); -+	pci_or_config32(HOST_BRIDGE, DPR,         1 <<  0); -+	pci_or_config32(HOST_BRIDGE, MESEG_LIMIT, 1 << 10); -+	pci_or_config32(HOST_BRIDGE, REMAPBASE,   1 <<  0); -+	pci_or_config32(HOST_BRIDGE, REMAPLIMIT,  1 <<  0); -+	pci_or_config32(HOST_BRIDGE, TOM,         1 <<  0); -+	pci_or_config32(HOST_BRIDGE, TOUUD,       1 <<  0); -+	pci_or_config32(HOST_BRIDGE, BDSM,        1 <<  0); -+	pci_or_config32(HOST_BRIDGE, BGSM,        1 <<  0); -+	pci_or_config32(HOST_BRIDGE, TOLUD,       1 <<  0); -+} -+ -+enum raminit_status raminit_done(struct sysinfo *ctrl) -+{ -+	union mc_init_state_g_reg mc_init_state_g = { -+		.raw = mchbar_read32(MC_INIT_STATE_G), -+	}; -+	mc_init_state_g.refresh_enable = 1; -+	mc_init_state_g.pu_mrc_done    = 1; -+	mc_init_state_g.mrc_done       = 1; -+	mchbar_write32(MC_INIT_STATE_G, mc_init_state_g.raw); -+ -+	/* Lock the memory controller to enable normal operation */ -+	mc_lockdown(); -+ -+	/* Poll for mc_init_done_ack to make sure memory initialization is complete */ -+	printk(BIOS_DEBUG, "Waiting for mc_init_done acknowledgement... "); -+ -+	struct stopwatch timer; -+	stopwatch_init_msecs_expire(&timer, 2000); -+	do { -+		mc_init_state_g.raw = mchbar_read32(MC_INIT_STATE_G); -+ -+		/* DRAM will NOT work without the acknowledgement. There is no hope. */ -+		if (stopwatch_expired(&timer)) -+			die("\nTimed out waiting for mc_init_done acknowledgement\n"); -+ -+	} while (mc_init_state_g.mc_init_done_ack == 0); -+	printk(BIOS_DEBUG, "DONE!\n"); -+ -+	/* Provide some data for the graphics driver. Yes, it's hardcoded. */ -+	mchbar_write32(SSKPD + 0, 0x05a2404f); -+	mchbar_write32(SSKPD + 4, 0x140000a0); -+	return RAMINIT_STATUS_SUCCESS; -+} -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -index 1ff23be615..3a65fb01fb 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c -@@ -63,6 +63,8 @@ static const struct task_entry cold_boot[] = { - 	{ train_receive_enable,                                   true, "RCVET",      }, - 	{ train_read_mpr,                                         true, "RDMPRT",     }, - 	{ train_jedec_write_leveling,                             true, "JWRL",       }, -+	{ activate_mc,                                            true, "ACTIVATE",   }, -+	{ raminit_done,                                           true, "RAMINITEND", }, - }; -  - /* Return a generic stepping value to make stepping checks simpler */ -@@ -143,7 +145,4 @@ void raminit_main(const enum raminit_boot_mode bootmode) -  - 	if (status != RAMINIT_STATUS_SUCCESS) - 		die("Memory initialization was met with utmost failure and misery\n"); -- --	/** TODO: Implement the required magic **/ --	die("NATIVE RAMINIT: More Magic (tm) required.\n"); - } -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -index 2fed93de5b..5f7ceec222 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c -@@ -199,8 +199,6 @@ void perform_raminit(const int s3resume) - 		else - 			me_status = ME_INIT_STATUS_SUCCESS; -  --		/** TODO: Remove this once raminit is implemented **/ --		me_status = ME_INIT_STATUS_ERROR; - 		intel_early_me_init_done(me_status); - 	} -  -@@ -214,7 +212,8 @@ void perform_raminit(const int s3resume) - 	} -  - 	/* Save training data on non-S3 resumes */ --	if (!s3resume) -+	/** TODO: Enable this once training data is populated **/ -+	if (0 && !s3resume) - 		save_mrc_data(&md); -  - 	/** TODO: setup_sdram_meminfo **/ -diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -index d6b11b9d3c..a0a913f926 100644 ---- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h -+++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h -@@ -448,6 +448,8 @@ enum raminit_status do_jedec_init(struct sysinfo *ctrl); - enum raminit_status train_receive_enable(struct sysinfo *ctrl); - enum raminit_status train_read_mpr(struct sysinfo *ctrl); - enum raminit_status train_jedec_write_leveling(struct sysinfo *ctrl); -+enum raminit_status activate_mc(struct sysinfo *ctrl); -+enum raminit_status raminit_done(struct sysinfo *ctrl); -  - void configure_timings(struct sysinfo *ctrl); - void configure_refresh(struct sysinfo *ctrl); -diff --git a/src/northbridge/intel/haswell/native_raminit/reg_structs.h b/src/northbridge/intel/haswell/native_raminit/reg_structs.h -index a0e36ed082..0d9aaa1f7c 100644 ---- a/src/northbridge/intel/haswell/native_raminit/reg_structs.h -+++ b/src/northbridge/intel/haswell/native_raminit/reg_structs.h -@@ -294,6 +294,18 @@ union ddr_cke_ctl_controls_reg { - 	uint32_t raw; - }; -  -+union ddr_scramble_reg { -+	struct __packed { -+		uint32_t scram_en    :  1; // Bits  0:0 -+		uint32_t scram_key   : 16; // Bits 16:1 -+		uint32_t clk_gate_ab :  2; // Bits 18:17 -+		uint32_t clk_gate_c  :  2; // Bits 20:19 -+		uint32_t en_dbi_ab   :  1; // Bits 21:21 -+		uint32_t             : 10; // Bits 31:17 -+	}; -+	uint32_t raw; -+}; -+ - union ddr_scram_misc_control_reg { - 	struct __packed { - 		uint32_t wl_wake_cycles       :  2; // Bits  1:0 -diff --git a/src/northbridge/intel/haswell/registers/mchbar.h b/src/northbridge/intel/haswell/registers/mchbar.h -index 7c0b5a49de..49a215aa71 100644 ---- a/src/northbridge/intel/haswell/registers/mchbar.h -+++ b/src/northbridge/intel/haswell/registers/mchbar.h -@@ -20,6 +20,7 @@ -  - #define DDR_DATA_TRAIN_FEEDBACK(ch, byte)	_DDRIO_C_R_B(0x0054, ch, 0, byte) -  -+#define DQ_CONTROL_1(ch, byte)			_DDRIO_C_R_B(0x0060, ch, 0, byte) - #define DQ_CONTROL_2(ch, byte)			_DDRIO_C_R_B(0x0064, ch, 0, byte) - #define DDR_DATA_OFFSET_TRAIN_ch_b(ch, byte)	_DDRIO_C_R_B(0x0070, ch, 0, byte) - #define DQ_CONTROL_0(ch, byte)			_DDRIO_C_R_B(0x0074, ch, 0, byte) -@@ -147,6 +148,8 @@ - #define QCLK_ch_LDAT_SDAT(ch)			_MCMAIN_C(0x42d4, ch) - #define QCLK_ch_LDAT_DATA_IN_x(ch, x)		_MCMAIN_C_X(0x42dc, ch, x) /* x in 0 .. 1 */ -  -+#define PM_THRT_CKE_MIN_ch(ch)			_MCMAIN_C(0x4328, ch) -+ - #define REUT_GLOBAL_CTL				0x4800 - #define REUT_GLOBAL_ERR				0x4804 -  -@@ -175,6 +178,8 @@ -  - #define MCSCHEDS_DFT_MISC	0x4c30 -  -+#define PM_PDWN_CONFIG		0x4cb0 -+ - #define REUT_ERR_DATA_STATUS	0x4ce0 -  - #define REUT_MISC_CKE_CTRL	0x4d90 -@@ -186,8 +191,10 @@ - #define MAD_CHNL		0x5000 /* Address Decoder Channel Configuration */ - #define MAD_DIMM(ch)		(0x5004 + (ch) * 4) - #define MAD_ZR			0x5014 -+#define MCDECS_CBIT		0x501c - #define MC_INIT_STATE_G		0x5030 - #define MRC_REVISION		0x5034 /* MRC Revision */ -+#define PM_SREF_CONFIG		0x5060 -  - #define RCOMP_TIMER		0x5084 -  ---  -2.39.5 -  | 
