/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <device/pci_ops.h>
#include <device/smbus_host.h>
#include <cbmem.h>
#include <cf9_reset.h>
#include <console/console.h>
#include <arch/cpu.h>
#include <spd.h>
#include <string.h>
#include <device/dram/ddr2.h>
#include <device/dram/ddr3.h>
#include <mrc_cache.h>
#include <timestamp.h>
#include <types.h>

#include "raminit.h"
#include "x4x.h"

#define MRC_CACHE_VERSION 0

static u16 ddr2_get_crc(u8 device, u8 len)
{
	u8 raw_spd[128] = {};
	i2c_eeprom_read(device, 64, 9, &raw_spd[64]);
	i2c_eeprom_read(device, 93, 6, &raw_spd[93]);
	return spd_ddr2_calc_unique_crc(raw_spd, len);
}

static u16 ddr3_get_crc(u8 device, u8 len)
{
	u8 raw_spd[256] = {};
	i2c_eeprom_read(device, 117, 11, &raw_spd[117]);
	return spd_ddr3_calc_unique_crc(raw_spd, len);
}

static enum cb_err verify_spds(const u8 *spd_map,
			const struct sysinfo *ctrl_cached)
{
	int i;
	u16 crc;

	for (i = 0; i < TOTAL_DIMMS; i++) {
		if (!(spd_map[i]))
			continue;
		int len = smbus_read_byte(spd_map[i], 0);
		if (len < 0 && ctrl_cached->dimms[i].card_type
				== RAW_CARD_UNPOPULATED)
			continue;
		if (len > 0 && ctrl_cached->dimms[i].card_type
				== RAW_CARD_UNPOPULATED)
			return CB_ERR;

		if (ctrl_cached->spd_type == DDR2)
			crc = ddr2_get_crc(spd_map[i], len);
		else
			crc = ddr3_get_crc(spd_map[i], len);

		if (crc != ctrl_cached->dimms[i].spd_crc)
			return CB_ERR;
	}
	return CB_SUCCESS;
}

struct abs_timings {
	u32 min_tclk;
	u32 min_tRAS;
	u32 min_tRP;
	u32 min_tRCD;
	u32 min_tWR;
	u32 min_tRFC;
	u32 min_tWTR;
	u32 min_tRRD;
	u32 min_tRTP;
	u32 min_tAA;
	u32 min_tCLK_cas[8];
	u32 cas_supported;
};

#define CTRL_MIN_TCLK_DDR2 TCK_400MHZ

static void select_cas_dramfreq_ddr2(struct sysinfo *s,
				const struct abs_timings *saved_timings)
{
	u8 try_cas;
	/* Currently only these CAS are supported */
	u8 cas_mask = SPD_CAS_LATENCY_DDR2_5 | SPD_CAS_LATENCY_DDR2_6;

	cas_mask &= saved_timings->cas_supported;
	try_cas = spd_get_msbs(cas_mask);

	while (cas_mask & (1 << try_cas) && try_cas > 0) {
		s->selected_timings.CAS = try_cas;
		s->selected_timings.tclk = saved_timings->min_tCLK_cas[try_cas];
		if (s->selected_timings.tclk >= CTRL_MIN_TCLK_DDR2 &&
				saved_timings->min_tCLK_cas[try_cas] !=
				saved_timings->min_tCLK_cas[try_cas - 1])
			break;
		try_cas--;
	}

	if ((s->selected_timings.CAS < 3) || (s->selected_timings.tclk == 0))
		die("Could not find common memory frequency and CAS\n");

	switch (s->selected_timings.tclk) {
	case TCK_200MHZ:
	case TCK_266MHZ:
		/* FIXME: this works on vendor BIOS */
		die("Selected dram frequency not supported\n");
	case TCK_333MHZ:
		s->selected_timings.mem_clk = MEM_CLOCK_667MHz;
		break;
	case TCK_400MHZ:
		s->selected_timings.mem_clk = MEM_CLOCK_800MHz;
		break;
	}
}

static void mchinfo_ddr2(struct sysinfo *s)
{
	const u32 eax = cpuid_ext(0x04, 0).eax;
	printk(BIOS_WARNING, "%d CPU cores\n", ((eax >> 26) & 0x3f) + 1);

	u32 capid = pci_read_config16(HOST_BRIDGE, 0xe8);
	if (!(capid & (1<<(79-64))))
		printk(BIOS_WARNING, "iTPM enabled\n");

	capid = pci_read_config32(HOST_BRIDGE, 0xe4);
	if (!(capid & (1<<(57-32))))
		printk(BIOS_WARNING, "ME enabled\n");

	if (!(capid & (1<<(56-32))))
		printk(BIOS_WARNING, "AMT enabled\n");

	if (!(capid & (1<<(48-32))))
		printk(BIOS_WARNING, "VT-d enabled\n");
}

static int ddr2_save_dimminfo(u8 dimm_idx, u8 *raw_spd,
		struct abs_timings *saved_timings, struct sysinfo *s)
{
	struct dimm_attr_ddr2_st decoded_dimm;
	int i;

	if (spd_decode_ddr2(&decoded_dimm, raw_spd) != SPD_STATUS_OK) {
		printk(BIOS_DEBUG, "Problems decoding SPD\n");
		return CB_ERR;
	}

	if (CONFIG(DEBUG_RAM_SETUP))
		dram_print_spd_ddr2(&decoded_dimm);

	if (!(decoded_dimm.width & (0x08 | 0x10))) {

		printk(BIOS_ERR,
			"DIMM%d Unsupported width: x%d. Disabling dimm\n",
			dimm_idx, s->dimms[dimm_idx].width);
		return CB_ERR;
	}
	s->dimms[dimm_idx].width = (decoded_dimm.width >> 3) - 1;
	/*
	 * This boils down to:
	 * "Except for the x16 configuration, all DDR2 devices have a
	 * 1KB page size. For the x16 configuration, the page size is 2KB
	 * for all densities except the 256Mb device, which has a 1KB page
	 * size." Micron, 'TN-47-16 Designing for High-Density DDR2 Memory'
	 * The formula is pagesize in KiB = width * 2^col_bits / 8.
	 */
	s->dimms[dimm_idx].page_size = decoded_dimm.width *
		 (1 << decoded_dimm.col_bits) / 8;

	switch (decoded_dimm.banks) {
	case 4:
		s->dimms[dimm_idx].n_banks = N_BANKS_4;
		break;
	case 8:
		s->dimms[dimm_idx].n_banks = N_BANKS_8;
		break;
	default:
		printk(BIOS_ERR,
			"DIMM%d Unsupported #banks: x%d. Disabling dimm\n",
			 dimm_idx, decoded_dimm.banks);
		return CB_ERR;
	}

	s->dimms[dimm_idx].ranks = decoded_dimm.ranks;
	s->dimms[dimm_idx].rows = decoded_dimm.row_bits;
	s->dimms[dimm_idx].cols = decoded_dimm.col_bits;

	saved_timings->cas_supported &= decoded_dimm.cas_supported;

	saved_timings->min_tRAS =
		MAX(saved_timings->min_tRAS, decoded_dimm.tRAS);
	saved_timings->min_tRP =
		MAX(saved_timings->min_tRP, decoded_dimm.tRP);
	saved_timings->min_tRCD =
		MAX(saved_timings->min_tRCD, decoded_dimm.tRCD);
	saved_timings->min_tWR =
		MAX(saved_timings->min_tWR, decoded_dimm.tWR);
	saved_timings->min_tRFC =
		MAX(saved_timings->min_tRFC, decoded_dimm.tRFC);
	saved_timings->min_tWTR =
		MAX(saved_timings->min_tWTR, decoded_dimm.tWTR);
	saved_timings->min_tRRD =
		MAX(saved_timings->min_tRRD, decoded_dimm.tRRD);
	saved_timings->min_tRTP =
		MAX(saved_timings->min_tRTP, decoded_dimm.tRTP);
	for (i = 0; i < 8; i++) {
		if (!(saved_timings->cas_supported & (1 << i)))
			saved_timings->min_tCLK_cas[i] = 0;
		else
			saved_timings->min_tCLK_cas[i] =
				MAX(saved_timings->min_tCLK_cas[i],
					decoded_dimm.cycle_time[i]);
	}

	s->dimms[dimm_idx].spd_crc = spd_ddr2_calc_unique_crc(raw_spd,
					spd_decode_spd_size_ddr2(raw_spd[0]));
	return CB_SUCCESS;
}

static void normalize_tCLK(u32 *tCLK)
{
	if (*tCLK <= TCK_666MHZ)
		*tCLK = TCK_666MHZ;
	else if (*tCLK <= TCK_533MHZ)
		*tCLK = TCK_533MHZ;
	else if (*tCLK <= TCK_400MHZ)
		*tCLK = TCK_400MHZ;
	else
		*tCLK = 0;
}

static void select_cas_dramfreq_ddr3(struct sysinfo *s,
			struct abs_timings *saved_timings)
{
	/*
	 * various constraints must be fulfilled:
	 *  CAS * tCK < 20ns == 160MTB
	 * tCK_max >= tCK >= tCK_min
	 * CAS >= roundup(tAA_min/tCK)
	 * CAS supported
	 * AND BTW: Clock(MT) = 2000 / tCK(ns) - intel uses MTs but calls them MHz
	 */

	u32 min_tCLK;
	u8 try_CAS;
	u16 capid = (pci_read_config16(HOST_BRIDGE, 0xea) >> 4) & 0x3f;

	switch (s->max_fsb) {
	default:
	case FSB_CLOCK_800MHz:
		min_tCLK = TCK_400MHZ;
		break;
	case FSB_CLOCK_1066MHz:
		min_tCLK = TCK_533MHZ;
		break;
	case FSB_CLOCK_1333MHz:
		min_tCLK = TCK_666MHZ;
		break;
	}

	switch (capid >> 3) {
	default: /* Should not happen */
		min_tCLK = TCK_400MHZ;
		break;
	case 1:
		min_tCLK = MAX(min_tCLK, TCK_400MHZ);
		break;
	case 2:
		min_tCLK = MAX(min_tCLK, TCK_533MHZ);
		break;
	case 3: /* Only on P45 */
	case 0:
		min_tCLK = MAX(min_tCLK, TCK_666MHZ);
		break;
	}

	min_tCLK = MAX(min_tCLK, saved_timings->min_tclk);
	if (min_tCLK == 0) {
		printk(BIOS_ERR, "DRAM frequency is under lowest supported "
			"frequency (400 MHz). Increasing to 400 MHz "
			"as last resort");
		min_tCLK = TCK_400MHZ;
	}

	while (1) {
		normalize_tCLK(&min_tCLK);
		if (min_tCLK == 0)
			die("Couldn't find compatible clock / CAS settings.\n");
		try_CAS = DIV_ROUND_UP(saved_timings->min_tAA, min_tCLK);
		printk(BIOS_SPEW, "Trying CAS %u, tCK %u.\n", try_CAS, min_tCLK);
		for (; try_CAS <= DDR3_MAX_CAS; try_CAS++) {
			/*
			 * cas_supported is encoded like the SPD which starts
			 * at CAS=4.
			 */
			if ((saved_timings->cas_supported << 4) & (1 << try_CAS))
				break;
		}
		if ((try_CAS <= DDR3_MAX_CAS) && (try_CAS * min_tCLK < 20 * 256)) {
			/* Found good CAS. */
			printk(BIOS_SPEW, "Found compatible tCLK / CAS pair: %u / %u.\n",
				min_tCLK, try_CAS);
			break;
		}
		/*
		 * If no valid tCLK / CAS pair could be found for a tCLK
		 * increase it after which it gets normalised. This means
		 * that a lower frequency gets tried.
		 */
		min_tCLK++;
	}

	s->selected_timings.tclk = min_tCLK;
	s->selected_timings.CAS = try_CAS;

	switch (s->selected_timings.tclk) {
	case TCK_400MHZ:
		s->selected_timings.mem_clk = MEM_CLOCK_800MHz;
		break;
	case TCK_533MHZ:
		s->selected_timings.mem_clk = MEM_CLOCK_1066MHz;
		break;
	case TCK_666MHZ:
		s->selected_timings.mem_clk = MEM_CLOCK_1333MHz;
		break;
	}
}

/* With DDR3 and 533MHz mem clock and an enabled internal gfx device the display
   is not usable in non stacked mode, so select stacked mode accordingly */
static void workaround_stacked_mode(struct sysinfo *s)
{
	u32 deven;
	/* Only a problem on DDR3 */
	if (s->spd_type == DDR2)
		return;
	/* Does not matter if only one channel is populated */
	if (!CHANNEL_IS_POPULATED(s->dimms, 0)
		|| !CHANNEL_IS_POPULATED(s->dimms, 1))
		return;
	if (s->selected_timings.mem_clk != MEM_CLOCK_1066MHz)
		return;
	/* IGD0EN gets disabled if not present before this code runs */
	deven = pci_read_config32(HOST_BRIDGE, D0F0_DEVEN);
	if (deven & IGD0EN)
		s->stacked_mode = 1;
}

static int ddr3_save_dimminfo(u8 dimm_idx, u8 *raw_spd,
		struct abs_timings *saved_timings, struct sysinfo *s)
{
	struct dimm_attr_ddr3_st decoded_dimm;

	if (spd_decode_ddr3(&decoded_dimm, raw_spd) != SPD_STATUS_OK)
		return CB_ERR;

	if (CONFIG(DEBUG_RAM_SETUP))
		dram_print_spd_ddr3(&decoded_dimm);

	/* x4 DIMMs are not supported (true for both ddr2 and ddr3) */
	if (!(decoded_dimm.width & (0x8 | 0x10))) {
		printk(BIOS_ERR, "DIMM%d Unsupported width: x%d. Disabling dimm\n",
			dimm_idx, s->dimms[dimm_idx].width);
		return CB_ERR;
	}
	s->dimms[dimm_idx].width = (decoded_dimm.width >> 3) - 1;
	/*
	 * This boils down to:
	 * "Except for the x16 configuration, all DDR3 devices have a
	 * 1KB page size. For the x16 configuration, the page size is 2KB
	 * for all densities except the 256Mb device, which has a 1KB page size."
	 * Micron, 'TN-47-16 Designing for High-Density DDR2 Memory'
	*/
	s->dimms[dimm_idx].page_size = decoded_dimm.width *
		(1 << decoded_dimm.col_bits) / 8;

	s->dimms[dimm_idx].n_banks = N_BANKS_8; /* Always 8 banks on ddr3?? */

	s->dimms[dimm_idx].ranks = decoded_dimm.ranks;
	s->dimms[dimm_idx].rows = decoded_dimm.row_bits;
	s->dimms[dimm_idx].cols = decoded_dimm.col_bits;

	saved_timings->min_tRAS =
		MAX(saved_timings->min_tRAS, decoded_dimm.tRAS);
	saved_timings->min_tRP =
		MAX(saved_timings->min_tRP, decoded_dimm.tRP);
	saved_timings->min_tRCD =
		MAX(saved_timings->min_tRCD, decoded_dimm.tRCD);
	saved_timings->min_tWR =
		MAX(saved_timings->min_tWR, decoded_dimm.tWR);
	saved_timings->min_tRFC =
		MAX(saved_timings->min_tRFC, decoded_dimm.tRFC);
	saved_timings->min_tWTR =
		MAX(saved_timings->min_tWTR, decoded_dimm.tWTR);
	saved_timings->min_tRRD =
		MAX(saved_timings->min_tRRD, decoded_dimm.tRRD);
	saved_timings->min_tRTP =
		MAX(saved_timings->min_tRTP, decoded_dimm.tRTP);
	saved_timings->min_tAA =
		MAX(saved_timings->min_tAA, decoded_dimm.tAA);
	saved_timings->cas_supported &= decoded_dimm.cas_supported;

	s->dimms[dimm_idx].spd_crc = spd_ddr3_calc_unique_crc(raw_spd,
							raw_spd[0]);

	s->dimms[dimm_idx].mirrored = decoded_dimm.flags.pins_mirrored;

	return CB_SUCCESS;
}

static void select_discrete_timings(struct sysinfo *s,
				const struct abs_timings *timings)
{
	s->selected_timings.tRAS = DIV_ROUND_UP(timings->min_tRAS,
						s->selected_timings.tclk);
	s->selected_timings.tRP = DIV_ROUND_UP(timings->min_tRP,
						s->selected_timings.tclk);
	s->selected_timings.tRCD = DIV_ROUND_UP(timings->min_tRCD,
						s->selected_timings.tclk);
	s->selected_timings.tWR = DIV_ROUND_UP(timings->min_tWR,
						s->selected_timings.tclk);
	s->selected_timings.tRFC = DIV_ROUND_UP(timings->min_tRFC,
						s->selected_timings.tclk);
	s->selected_timings.tWTR = DIV_ROUND_UP(timings->min_tWTR,
						s->selected_timings.tclk);
	s->selected_timings.tRRD = DIV_ROUND_UP(timings->min_tRRD,
						s->selected_timings.tclk);
	s->selected_timings.tRTP = DIV_ROUND_UP(timings->min_tRTP,
						s->selected_timings.tclk);
}
static void print_selected_timings(struct sysinfo *s)
{
	printk(BIOS_DEBUG, "Selected timings:\n");
	printk(BIOS_DEBUG, "\tFSB:  %dMHz\n",
		fsb_to_mhz(s->selected_timings.fsb_clk));
	printk(BIOS_DEBUG, "\tDDR:  %dMHz\n",
		ddr_to_mhz(s->selected_timings.mem_clk));

	printk(BIOS_DEBUG, "\tCAS:  %d\n", s->selected_timings.CAS);
	printk(BIOS_DEBUG, "\ttRAS: %d\n", s->selected_timings.tRAS);
	printk(BIOS_DEBUG, "\ttRP:  %d\n", s->selected_timings.tRP);
	printk(BIOS_DEBUG, "\ttRCD: %d\n", s->selected_timings.tRCD);
	printk(BIOS_DEBUG, "\ttWR:  %d\n", s->selected_timings.tWR);
	printk(BIOS_DEBUG, "\ttRFC: %d\n", s->selected_timings.tRFC);
	printk(BIOS_DEBUG, "\ttWTR: %d\n", s->selected_timings.tWTR);
	printk(BIOS_DEBUG, "\ttRRD: %d\n", s->selected_timings.tRRD);
	printk(BIOS_DEBUG, "\ttRTP: %d\n", s->selected_timings.tRTP);
}

static void find_fsb_speed(struct sysinfo *s)
{
	switch (MCHBAR32(0xc00) & 0x7) {
	case 0x0:
		s->max_fsb = FSB_CLOCK_1066MHz;
		break;
	case 0x2:
		s->max_fsb = FSB_CLOCK_800MHz;
		break;
	case 0x4:
		s->max_fsb = FSB_CLOCK_1333MHz;
		break;
	default:
		s->max_fsb = FSB_CLOCK_800MHz;
		printk(BIOS_WARNING, "Can't detect FSB, setting 800MHz\n");
		break;
	}
	s->selected_timings.fsb_clk = s->max_fsb;
}

static void decode_spd_select_timings(struct sysinfo *s)
{
	unsigned int device;
	u8 dram_type_mask = (1 << DDR2) | (1 << DDR3);
	u8 dimm_mask = 0;
	u8 raw_spd[256];
	int i, j;
	struct abs_timings saved_timings;
	memset(&saved_timings, 0, sizeof(saved_timings));
	saved_timings.cas_supported = UINT32_MAX;

	FOR_EACH_DIMM(i) {
		s->dimms[i].card_type = RAW_CARD_POPULATED;
		device = s->spd_map[i];
		if (!device) {
			s->dimms[i].card_type = RAW_CARD_UNPOPULATED;
			continue;
		}
		switch (smbus_read_byte(s->spd_map[i], SPD_MEMORY_TYPE)) {
		case DDR2SPD:
			dram_type_mask &= 1 << DDR2;
			s->spd_type = DDR2;
			break;
		case DDR3SPD:
			dram_type_mask &= 1 << DDR3;
			s->spd_type = DDR3;
			break;
		default:
			s->dimms[i].card_type = RAW_CARD_UNPOPULATED;
			continue;
		}
		if (!dram_type_mask)
			die("Mixing up dimm types is not supported!\n");

		printk(BIOS_DEBUG, "Decoding dimm %d\n", i);
		if (i2c_eeprom_read(device, 0, 128, raw_spd) != 128) {
			printk(BIOS_DEBUG, "i2c block operation failed,"
				" trying smbus byte operation.\n");
			for (j = 0; j < 128; j++)
				raw_spd[j] = smbus_read_byte(device, j);
		}

		if (s->spd_type == DDR2){
			if (ddr2_save_dimminfo(i, raw_spd, &saved_timings, s)) {
				printk(BIOS_WARNING,
					"Encountered problems with SPD, "
					"skipping this DIMM.\n");
				s->dimms[i].card_type = RAW_CARD_UNPOPULATED;
				continue;
			}
		} else { /* DDR3 */
			if (ddr3_save_dimminfo(i, raw_spd, &saved_timings, s)) {
				printk(BIOS_WARNING,
					"Encountered problems with SPD, "
					"skipping this DIMM.\n");
				/* something in decoded SPD was unsupported */
				s->dimms[i].card_type = RAW_CARD_UNPOPULATED;
				continue;
			}
		}
		dimm_mask |= (1 << i);
	}
	if (!dimm_mask)
		die("No memory installed.\n");

	if (s->spd_type == DDR2)
		select_cas_dramfreq_ddr2(s, &saved_timings);
	else
		select_cas_dramfreq_ddr3(s, &saved_timings);
	select_discrete_timings(s, &saved_timings);
	workaround_stacked_mode(s);
}

static void find_dimm_config(struct sysinfo *s)
{
	int chan, i;

	FOR_EACH_POPULATED_CHANNEL(s->dimms, chan) {
		FOR_EACH_POPULATED_DIMM_IN_CHANNEL(s->dimms, chan, i) {
			int dimm_config;
			if (s->dimms[i].ranks == 1) {
				if (s->dimms[i].width == 0)	/* x8 */
					dimm_config = 1;
				else				/* x16 */
					dimm_config = 3;
			} else {
				if (s->dimms[i].width == 0)	/* x8 */
					dimm_config = 2;
				else
					die("Dual-rank x16 not supported\n");
			}
			s->dimm_config[chan] |=
				dimm_config << (i % DIMMS_PER_CHANNEL) * 2;
		}
		printk(BIOS_DEBUG, "  Config[CH%d] : %d\n", chan,
			s->dimm_config[chan]);
	}

}

static void checkreset_ddr2(int boot_path)
{
	u8 pmcon2;
	u32 pmsts;

	if (boot_path >= 1) {
		pmsts = MCHBAR32(PMSTS_MCHBAR);
		if (!(pmsts & 1))
			printk(BIOS_DEBUG,
				"Channel 0 possibly not in self refresh\n");
		if (!(pmsts & 2))
			printk(BIOS_DEBUG,
				"Channel 1 possibly not in self refresh\n");
	}

	pmcon2 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2);

	if (pmcon2 & 0x80) {
		pmcon2 &= ~0x80;
		pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, pmcon2);

		/* do magic 0xf0 thing. */
		pci_and_config8(HOST_BRIDGE, 0xf0, ~(1 << 2));

		pci_or_config8(HOST_BRIDGE, 0xf0, (1 << 2));

		full_reset();
	}
	pmcon2 |= 0x80;
	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, pmcon2);
}

/**
 * @param boot_path: 0 = normal, 1 = reset, 2 = resume from s3
 */
void sdram_initialize(int boot_path, const u8 *spd_map)
{
	struct sysinfo s, *ctrl_cached;
	u8 reg8;
	int fast_boot, cbmem_was_inited;
	size_t mrc_size;

	timestamp_add_now(TS_BEFORE_INITRAM);
	printk(BIOS_DEBUG, "Setting up RAM controller.\n");

	pci_write_config8(HOST_BRIDGE, 0xdf, 0xff);

	memset(&s, 0, sizeof(struct sysinfo));

	ctrl_cached = mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
						  MRC_CACHE_VERSION,
						  &mrc_size);

	if (!ctrl_cached || mrc_size < sizeof(s)) {
		if (boot_path == BOOT_PATH_RESUME) {
			/* Failed S3 resume, reset to come up cleanly */
			system_reset();
		} else if (boot_path == BOOT_PATH_WARM_RESET) {
			/* On warm reset some of dram calibrations fail
			   and therefore requiring valid cached settings */
			full_reset();
		}
	}

	/* verify MRC cache for fast boot */
	if (boot_path != BOOT_PATH_RESUME && ctrl_cached) {
		/* check SPD checksum to make sure the DIMMs haven't been replaced */
		fast_boot = verify_spds(spd_map, ctrl_cached) == CB_SUCCESS;
		if (!fast_boot) {
			printk(BIOS_DEBUG, "SPD checksums don't match,"
				" dimm's have been replaced\n");
		} else {
			find_fsb_speed(&s);
			fast_boot = s.max_fsb == ctrl_cached->max_fsb;
			if (!fast_boot)
				printk(BIOS_DEBUG,
				       "CPU FSB does not match and has been replaced\n");
		}
	} else {
		fast_boot = boot_path == BOOT_PATH_RESUME;
	}

	if (fast_boot) {
		printk(BIOS_DEBUG, "Using cached raminit settings\n");
		memcpy(&s, ctrl_cached, sizeof(s));
		s.boot_path = boot_path;
		mchinfo_ddr2(&s);
		print_selected_timings(&s);
	} else {
		s.boot_path = boot_path;
		s.spd_map[0] = spd_map[0];
		s.spd_map[1] = spd_map[1];
		s.spd_map[2] = spd_map[2];
		s.spd_map[3] = spd_map[3];
		checkreset_ddr2(s.boot_path);

		/* Detect dimms per channel */
		reg8 = pci_read_config8(HOST_BRIDGE, 0xe9);
		printk(BIOS_DEBUG, "Dimms per channel: %d\n",
			(reg8 & 0x10) ? 1 : 2);

		mchinfo_ddr2(&s);

		find_fsb_speed(&s);
		decode_spd_select_timings(&s);
		print_selected_timings(&s);
		find_dimm_config(&s);
	}

	do_raminit(&s, fast_boot);

	pci_and_config8(PCI_DEV(0, 0x1f, 0), 0xa2, (u8)~0x80);

	pci_or_config8(HOST_BRIDGE, 0xf4, 1);

	timestamp_add_now(TS_AFTER_INITRAM);

	printk(BIOS_DEBUG, "RAM initialization finished.\n");

	int s3resume = boot_path == BOOT_PATH_RESUME;

	cbmem_was_inited = !cbmem_recovery(s3resume);
	if (!fast_boot)
		mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION,
					&s, sizeof(s));

	if (s3resume && !cbmem_was_inited) {
		/* Failed S3 resume, reset to come up cleanly */
		system_reset();
	}

	printk(BIOS_DEBUG, "Memory initialized\n");
}
