/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <cpu/intel/model_206ax/model_206ax.h>
#include <device/mmio.h>
#include <device/pci_ops.h>
#include <northbridge/intel/sandybridge/chip.h>
#include <device/pci_def.h>
#include <delay.h>
#include <types.h>

#include "raminit_native.h"
#include "raminit_common.h"
#include "raminit_tables.h"
#include "sandybridge.h"

/* FIXME: no support for 3-channel chipsets */

static void sfence(void)
{
	asm volatile ("sfence");
}

/* Toggle IO reset bit */
static void toggle_io_reset(void)
{
	u32 r32 = mchbar_read32(MC_INIT_STATE_G);
	mchbar_write32(MC_INIT_STATE_G, r32 |  (1 << 5));
	udelay(1);
	mchbar_write32(MC_INIT_STATE_G, r32 & ~(1 << 5));
	udelay(1);
}

static u32 get_XOVER_CLK(u8 rankmap)
{
	return rankmap << 24;
}

static u32 get_XOVER_CMD(u8 rankmap)
{
	u32 reg;

	/* Enable xover cmd */
	reg = 1 << 14;

	/* Enable xover ctl */
	if (rankmap & 0x03)
		reg |= (1 << 17);

	if (rankmap & 0x0c)
		reg |= (1 << 26);

	return reg;
}

void dram_find_common_params(ramctr_timing *ctrl)
{
	size_t valid_dimms;
	int channel, slot;
	dimm_info *dimms = &ctrl->info;

	ctrl->cas_supported = (1 << (MAX_CAS - MIN_CAS + 1)) - 1;
	valid_dimms = 0;

	FOR_ALL_CHANNELS for (slot = 0; slot < 2; slot++) {

		const struct dimm_attr_ddr3_st *dimm = &dimms->dimm[channel][slot];
		if (dimm->dram_type != SPD_MEMORY_TYPE_SDRAM_DDR3)
			continue;

		valid_dimms++;

		/* Find all possible CAS combinations */
		ctrl->cas_supported &= dimm->cas_supported;

		/* Find the smallest common latencies supported by all DIMMs */
		ctrl->tCK  = MAX(ctrl->tCK,  dimm->tCK);
		ctrl->tAA  = MAX(ctrl->tAA,  dimm->tAA);
		ctrl->tWR  = MAX(ctrl->tWR,  dimm->tWR);
		ctrl->tRCD = MAX(ctrl->tRCD, dimm->tRCD);
		ctrl->tRRD = MAX(ctrl->tRRD, dimm->tRRD);
		ctrl->tRP  = MAX(ctrl->tRP,  dimm->tRP);
		ctrl->tRAS = MAX(ctrl->tRAS, dimm->tRAS);
		ctrl->tRFC = MAX(ctrl->tRFC, dimm->tRFC);
		ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
		ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
		ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
		ctrl->tCWL = MAX(ctrl->tCWL, dimm->tCWL);
		ctrl->tCMD = MAX(ctrl->tCMD, dimm->tCMD);
	}

	if (!ctrl->cas_supported)
		die("Unsupported DIMM combination. DIMMS do not support common CAS latency");

	if (!valid_dimms)
		die("No valid DIMMs found");
}

void dram_xover(ramctr_timing *ctrl)
{
	u32 reg;
	int channel;

	FOR_ALL_CHANNELS {
		/* Enable xover clk */
		reg = get_XOVER_CLK(ctrl->rankmap[channel]);
		printram("XOVER CLK [%x] = %x\n", GDCRCKPICODE_ch(channel), reg);
		mchbar_write32(GDCRCKPICODE_ch(channel), reg);

		/* Enable xover ctl & xover cmd */
		reg = get_XOVER_CMD(ctrl->rankmap[channel]);
		printram("XOVER CMD [%x] = %x\n", GDCRCMDPICODING_ch(channel), reg);
		mchbar_write32(GDCRCMDPICODING_ch(channel), reg);
	}
}

static void dram_odt_stretch(ramctr_timing *ctrl, int channel)
{
	u32 addr, stretch;

	stretch = ctrl->ref_card_offset[channel];
	/*
	 * ODT stretch:
	 * Delay ODT signal by stretch value. Useful for multi DIMM setups on the same channel.
	 */
	if (IS_SANDY_CPU(ctrl->cpu) && IS_SANDY_CPU_C(ctrl->cpu)) {
		if (stretch == 2)
			stretch = 3;

		addr = SCHED_SECOND_CBIT_ch(channel);
		mchbar_clrsetbits32(addr, 0xf << 10, stretch << 12 | stretch << 10);
		printk(RAM_DEBUG, "OTHP Workaround [%x] = %x\n", addr, mchbar_read32(addr));
	} else {
		addr = TC_OTHP_ch(channel);
		union tc_othp_reg tc_othp = {
			.raw = mchbar_read32(addr),
		};
		tc_othp.odt_delay_d0 = stretch;
		tc_othp.odt_delay_d1 = stretch;
		mchbar_write32(addr, tc_othp.raw);
		printk(RAM_DEBUG, "OTHP [%x] = %x\n", addr, mchbar_read32(addr));
	}
}

void dram_timing_regs(ramctr_timing *ctrl)
{
	int channel;

	/* BIN parameters */
	const union tc_dbp_reg tc_dbp = {
		.tRCD = ctrl->tRCD,
		.tRP  = ctrl->tRP,
		.tAA  = ctrl->CAS,
		.tCWL = ctrl->CWL,
		.tRAS = ctrl->tRAS,
	};

	/* Regular access parameters */
	const union tc_rap_reg tc_rap = {
		.tRRD = ctrl->tRRD,
		.tRTP = ctrl->tRTP,
		.tCKE = ctrl->tCKE,
		.tWTR = ctrl->tWTR,
		.tFAW = ctrl->tFAW,
		.tWR  = ctrl->tWR,
		.tCMD = 3,
	};

	/* Other parameters */
	const union tc_othp_reg tc_othp = {
		.tXPDLL  = MIN(ctrl->tXPDLL, 31),
		.tXP     = MIN(ctrl->tXP, 7),
		.tAONPD  = ctrl->tAONPD,
		.tCPDED  = 2,
		.tPRPDEN = 1,
	};

	/*
	 * If tXP and tXPDLL are very high, they no longer fit in the bitfields
	 * of the TC_OTHP register. If so, we set bits in TC_DTP to compensate.
	 * This can only happen on Ivy Bridge, and when overclocking the RAM.
	 */
	const union tc_dtp_reg tc_dtp = {
		.overclock_tXP    = ctrl->tXP >= 8,
		.overclock_tXPDLL = ctrl->tXPDLL >= 32,
	};

	/*
	 * TC-Refresh timing parameters:
	 *   The tREFIx9 field should be programmed to minimum of 8.9 * tREFI (to allow
	 *   for possible delays from ZQ or isoc) and tRASmax (70us) divided by 1024.
	 */
	const u32 val32 = MIN((ctrl->tREFI * 89) / 10, (70000 << 8) / ctrl->tCK);

	const union tc_rftp_reg tc_rftp = {
		.tREFI   = ctrl->tREFI,
		.tRFC    = ctrl->tRFC,
		.tREFIx9 = val32 / 1024,
	};

	/* Self-refresh timing parameters */
	const union tc_srftp_reg tc_srftp = {
		.tXSDLL     = tDLLK,
		.tXS_offset = ctrl->tXSOffset,
		.tZQOPER    = tDLLK - ctrl->tXSOffset,
		.tMOD       = ctrl->tMOD - 8,
	};

	FOR_ALL_CHANNELS {
		printram("DBP [%x] = %x\n", TC_DBP_ch(channel), tc_dbp.raw);
		mchbar_write32(TC_DBP_ch(channel), tc_dbp.raw);

		printram("RAP [%x] = %x\n", TC_RAP_ch(channel), tc_rap.raw);
		mchbar_write32(TC_RAP_ch(channel), tc_rap.raw);

		printram("OTHP [%x] = %x\n", TC_OTHP_ch(channel), tc_othp.raw);
		mchbar_write32(TC_OTHP_ch(channel), tc_othp.raw);

		if (IS_IVY_CPU(ctrl->cpu)) {
			/* Debug parameters - only applies to Ivy Bridge */
			mchbar_write32(TC_DTP_ch(channel), tc_dtp.raw);
		}

		dram_odt_stretch(ctrl, channel);

		printram("REFI [%x] = %x\n", TC_RFTP_ch(channel), tc_rftp.raw);
		mchbar_write32(TC_RFTP_ch(channel), tc_rftp.raw);

		union tc_rfp_reg tc_rfp = {
			.raw = mchbar_read32(TC_RFP_ch(channel)),
		};
		tc_rfp.oref_ri = 0xff;
		mchbar_write32(TC_RFP_ch(channel), tc_rfp.raw);

		printram("SRFTP [%x] = %x\n", TC_SRFTP_ch(channel), tc_srftp.raw);
		mchbar_write32(TC_SRFTP_ch(channel), tc_srftp.raw);
	}
}

void dram_dimm_mapping(ramctr_timing *ctrl)
{
	int channel;
	dimm_info *info = &ctrl->info;

	FOR_ALL_CHANNELS {
		struct dimm_attr_ddr3_st *dimmA, *dimmB;
		u32 reg = 0;

		if (info->dimm[channel][0].size_mb >= info->dimm[channel][1].size_mb) {
			dimmA = &info->dimm[channel][0];
			dimmB = &info->dimm[channel][1];
			reg |= (0 << 16);
		} else {
			dimmA = &info->dimm[channel][1];
			dimmB = &info->dimm[channel][0];
			reg |= (1 << 16);
		}

		if (dimmA && (dimmA->ranks > 0)) {
			reg |= (dimmA->size_mb / 256) <<  0;
			reg |= (dimmA->ranks - 1)     << 17;
			reg |= (dimmA->width / 8 - 1) << 19;
		}

		if (dimmB && (dimmB->ranks > 0)) {
			reg |= (dimmB->size_mb / 256) <<  8;
			reg |= (dimmB->ranks - 1)     << 18;
			reg |= (dimmB->width / 8 - 1) << 20;
		}

		/*
		 * Rank interleave: Bit 16 of the physical address space sets
		 * the rank to use in a dual single rank DIMM configuration.
		 * That results in every 64KiB being interleaved between two ranks.
		 */
		reg |= 1 << 21;
		/* Enhanced interleave */
		reg |= 1 << 22;

		if ((dimmA && (dimmA->ranks > 0)) || (dimmB && (dimmB->ranks > 0))) {
			ctrl->mad_dimm[channel] = reg;
		} else {
			ctrl->mad_dimm[channel] = 0;
		}
	}
}

void dram_dimm_set_mapping(ramctr_timing *ctrl, int training)
{
	int channel;
	u32 ecc;

	if (ctrl->ecc_enabled)
		ecc = training ? (1 << 24) : (3 << 24);
	else
		ecc = 0;

	FOR_ALL_CHANNELS {
		mchbar_write32(MAD_DIMM(channel), ctrl->mad_dimm[channel] | ecc);
	}

	if (ctrl->ecc_enabled)
		udelay(10);
}

void dram_zones(ramctr_timing *ctrl, int training)
{
	u32 reg, ch0size, ch1size;
	u8 val;
	reg = 0;
	val = 0;

	if (training) {
		ch0size = ctrl->channel_size_mb[0] ? 256 : 0;
		ch1size = ctrl->channel_size_mb[1] ? 256 : 0;
	} else {
		ch0size = ctrl->channel_size_mb[0];
		ch1size = ctrl->channel_size_mb[1];
	}

	if (ch0size >= ch1size) {
		reg = mchbar_read32(MAD_ZR);
		val = ch1size / 256;
		reg = (reg & ~0xff000000) | val << 24;
		reg = (reg & ~0x00ff0000) | (2 * val) << 16;
		mchbar_write32(MAD_ZR, reg);
		mchbar_write32(MAD_CHNL, 0x24);

	} else {
		reg = mchbar_read32(MAD_ZR);
		val = ch0size / 256;
		reg = (reg & ~0xff000000) | val << 24;
		reg = (reg & ~0x00ff0000) | (2 * val) << 16;
		mchbar_write32(MAD_ZR, reg);
		mchbar_write32(MAD_CHNL, 0x21);
	}
}

/*
 * Returns the ECC mode the NB is running at. It takes precedence over ECC capability.
 * The ME/PCU/.. has the ability to change this.
 * Return 0: ECC is optional
 * Return 1: ECC is forced
 */
bool get_host_ecc_forced(void)
{
	/* read Capabilities A Register */
	const u32 reg32 = pci_read_config32(HOST_BRIDGE, CAPID0_A);
	return !!(reg32 & (1 << 24));
}

/*
 * Returns the ECC capability.
 * The ME/PCU/.. has the ability to change this.
 * Return 0: ECC is disabled
 * Return 1: ECC is possible
 */
bool get_host_ecc_cap(void)
{
	/* read Capabilities A Register */
	const u32 reg32 = pci_read_config32(HOST_BRIDGE, CAPID0_A);
	return !(reg32 & (1 << 25));
}

#define DEFAULT_PCI_MMIO_SIZE 2048

void dram_memorymap(ramctr_timing *ctrl, int me_uma_size)
{
	u32 reg, val, reclaim, tom, gfxstolen, gttsize;
	size_t tsegbase, toludbase, remapbase, gfxstolenbase, mmiosize, gttbase;
	size_t tsegsize, touudbase, remaplimit, mestolenbase, tsegbasedelta;
	uint16_t ggc;

	mmiosize = DEFAULT_PCI_MMIO_SIZE;

	ggc = pci_read_config16(HOST_BRIDGE, GGC);
	if (!(ggc & 2)) {
		gfxstolen = ((ggc >> 3) & 0x1f) * 32;
		gttsize   = ((ggc >> 8) & 0x3);
	} else {
		gfxstolen = 0;
		gttsize   = 0;
	}

	tsegsize = CONFIG_SMM_TSEG_SIZE >> 20;

	tom = ctrl->channel_size_mb[0] + ctrl->channel_size_mb[1];

	mestolenbase = tom - me_uma_size;

	toludbase = MIN(4096 - mmiosize + gfxstolen + gttsize + tsegsize, tom - me_uma_size);

	gfxstolenbase = toludbase - gfxstolen;
	gttbase = gfxstolenbase - gttsize;

	tsegbase = gttbase - tsegsize;

	/* Round tsegbase down to nearest address aligned to tsegsize */
	tsegbasedelta = tsegbase & (tsegsize - 1);
	tsegbase &= ~(tsegsize - 1);

	gttbase -= tsegbasedelta;
	gfxstolenbase -= tsegbasedelta;
	toludbase -= tsegbasedelta;

	/* Test if it is possible to reclaim a hole in the RAM addressing */
	if (tom - me_uma_size > toludbase) {
		/* Reclaim is possible */
		reclaim    = 1;
		remapbase  = MAX(4096, tom - me_uma_size);
		remaplimit = remapbase + MIN(4096, tom - me_uma_size) - toludbase - 1;
		touudbase  = remaplimit + 1;
	} else {
		/* Reclaim not possible */
		reclaim   = 0;
		touudbase = tom - me_uma_size;
	}

	/* Update memory map in PCIe configuration space */
	printk(BIOS_DEBUG, "Update PCI-E configuration space:\n");

	/* TOM (top of memory) */
	reg = pci_read_config32(HOST_BRIDGE, TOM);
	val = tom & 0xfff;
	reg = (reg & ~0xfff00000) | (val << 20);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", TOM, reg);
	pci_write_config32(HOST_BRIDGE, TOM, reg);

	reg = pci_read_config32(HOST_BRIDGE, TOM + 4);
	val = tom & 0xfffff000;
	reg = (reg & ~0x000fffff) | (val >> 12);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", TOM + 4, reg);
	pci_write_config32(HOST_BRIDGE, TOM + 4, reg);

	/* TOLUD (Top Of Low Usable DRAM) */
	reg = pci_read_config32(HOST_BRIDGE, TOLUD);
	val = toludbase & 0xfff;
	reg = (reg & ~0xfff00000) | (val << 20);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", TOLUD, reg);
	pci_write_config32(HOST_BRIDGE, TOLUD, reg);

	/* TOUUD LSB (Top Of Upper Usable DRAM) */
	reg = pci_read_config32(HOST_BRIDGE, TOUUD);
	val = touudbase & 0xfff;
	reg = (reg & ~0xfff00000) | (val << 20);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", TOUUD, reg);
	pci_write_config32(HOST_BRIDGE, TOUUD, reg);

	/* TOUUD MSB */
	reg = pci_read_config32(HOST_BRIDGE, TOUUD + 4);
	val = touudbase & 0xfffff000;
	reg = (reg & ~0x000fffff) | (val >> 12);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", TOUUD + 4, reg);
	pci_write_config32(HOST_BRIDGE, TOUUD + 4, reg);

	if (reclaim) {
		/* REMAP BASE */
		pci_write_config32(HOST_BRIDGE, REMAPBASE,     remapbase << 20);
		pci_write_config32(HOST_BRIDGE, REMAPBASE + 4, remapbase >> 12);

		/* REMAP LIMIT */
		pci_write_config32(HOST_BRIDGE, REMAPLIMIT,     remaplimit << 20);
		pci_write_config32(HOST_BRIDGE, REMAPLIMIT + 4, remaplimit >> 12);
	}
	/* TSEG */
	reg = pci_read_config32(HOST_BRIDGE, TSEGMB);
	val = tsegbase & 0xfff;
	reg = (reg & ~0xfff00000) | (val << 20);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", TSEGMB, reg);
	pci_write_config32(HOST_BRIDGE, TSEGMB, reg);

	/* GFX stolen memory */
	reg = pci_read_config32(HOST_BRIDGE, BDSM);
	val = gfxstolenbase & 0xfff;
	reg = (reg & ~0xfff00000) | (val << 20);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", BDSM, reg);
	pci_write_config32(HOST_BRIDGE, BDSM, reg);

	/* GTT stolen memory */
	reg = pci_read_config32(HOST_BRIDGE, BGSM);
	val = gttbase & 0xfff;
	reg = (reg & ~0xfff00000) | (val << 20);
	printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", BGSM, reg);
	pci_write_config32(HOST_BRIDGE, BGSM, reg);

	if (me_uma_size) {
		reg = pci_read_config32(HOST_BRIDGE, MESEG_MASK + 4);
		val = (0x80000 - me_uma_size) & 0xfffff000;
		reg = (reg & ~0x000fffff) | (val >> 12);
		printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", MESEG_MASK + 4, reg);
		pci_write_config32(HOST_BRIDGE, MESEG_MASK + 4, reg);

		/* ME base */
		reg = pci_read_config32(HOST_BRIDGE, MESEG_BASE);
		val = mestolenbase & 0xfff;
		reg = (reg & ~0xfff00000) | (val << 20);
		printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", MESEG_BASE, reg);
		pci_write_config32(HOST_BRIDGE, MESEG_BASE, reg);

		reg = pci_read_config32(HOST_BRIDGE, MESEG_BASE + 4);
		val = mestolenbase & 0xfffff000;
		reg = (reg & ~0x000fffff) | (val >> 12);
		printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", MESEG_BASE + 4, reg);
		pci_write_config32(HOST_BRIDGE, MESEG_BASE + 4, reg);

		/* ME mask */
		reg = pci_read_config32(HOST_BRIDGE, MESEG_MASK);
		val = (0x80000 - me_uma_size) & 0xfff;
		reg = (reg & ~0xfff00000) | (val << 20);
		reg = reg | ME_STLEN_EN;	/* Set ME memory enable */
		reg = reg | MELCK;		/* Set lock bit on ME mem */
		printk(BIOS_DEBUG, "PCI(0, 0, 0)[%x] = %x\n", MESEG_MASK, reg);
		pci_write_config32(HOST_BRIDGE, MESEG_MASK, reg);
	}
}

static void write_reset(ramctr_timing *ctrl)
{
	int channel, slotrank;

	/* Choose a populated channel */
	channel = (ctrl->rankmap[0]) ? 0 : 1;

	wait_for_iosav(channel);

	/* Choose a populated rank */
	slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;

	iosav_write_zqcs_sequence(channel, slotrank, 3, 8, 0);

	/* This is actually using the IOSAV state machine as a timer */
	iosav_run_queue(channel, 1, 1);

	wait_for_iosav(channel);
}

void dram_jedecreset(ramctr_timing *ctrl)
{
	u32 reg;
	int channel;

	while (!(mchbar_read32(RCOMP_TIMER) & (1 << 16)))
		;
	do {
		reg = mchbar_read32(IOSAV_STATUS_ch(0));
	} while ((reg & 0x14) == 0);

	/* Set state of memory controller */
	reg = 0x112;
	mchbar_write32(MC_INIT_STATE_G, reg);
	mchbar_write32(MC_INIT_STATE, 0);
	reg |= 2;		/* DDR reset */
	mchbar_write32(MC_INIT_STATE_G, reg);

	/* Assert DIMM reset signal */
	mchbar_clrbits32(MC_INIT_STATE_G, 1 << 1);

	/* Wait 200us */
	udelay(200);

	/* Deassert DIMM reset signal */
	mchbar_setbits32(MC_INIT_STATE_G, 1 << 1);

	/* Wait 500us */
	udelay(500);

	/* Enable DCLK */
	mchbar_setbits32(MC_INIT_STATE_G, 1 << 2);

	/* XXX Wait 20ns */
	udelay(1);

	FOR_ALL_CHANNELS {
		/* Set valid rank CKE */
		reg = ctrl->rankmap[channel];
		mchbar_write32(MC_INIT_STATE_ch(channel), reg);

		/* Wait 10ns for ranks to settle */
		// udelay(0.01);

		reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
		mchbar_write32(MC_INIT_STATE_ch(channel), reg);

		/* Write reset using a NOP */
		write_reset(ctrl);
	}
}

/*
 * DDR3 Rank1 Address mirror swap the following pins:
 * A3<->A4, A5<->A6, A7<->A8, BA0<->BA1
 */
static void ddr3_mirror_mrreg(int *bank, u32 *addr)
{
	*bank = ((*bank >> 1) & 1) | ((*bank << 1) & 2);
	*addr = (*addr & ~0x1f8) | ((*addr >> 1) & 0xa8) | ((*addr & 0xa8) << 1);
}

static void write_mrreg(ramctr_timing *ctrl, int channel, int slotrank, int reg, u32 val)
{
	wait_for_iosav(channel);

	if (ctrl->rank_mirror[channel][slotrank])
		ddr3_mirror_mrreg(&reg, &val);

	const struct iosav_ssq sequence[] = {
		/* DRAM command MRS */
		[0] = {
			.sp_cmd_ctrl = {
				.command = IOSAV_MRS,
			},
			.subseq_ctrl = {
				.cmd_executions = 1,
				.cmd_delay_gap  = 4,
				.post_ssq_wait  = 4,
				.data_direction = SSQ_NA,
			},
			.sp_cmd_addr = {
				.address = val,
				.rowbits = 6,
				.bank    = reg,
				.rank    = slotrank,
			},
		},
		/* DRAM command MRS */
		[1] = {
			.sp_cmd_ctrl = {
				.command    = IOSAV_MRS,
				.ranksel_ap = 1,
			},
			.subseq_ctrl = {
				.cmd_executions = 1,
				.cmd_delay_gap  = 4,
				.post_ssq_wait  = 4,
				.data_direction = SSQ_NA,
			},
			.sp_cmd_addr = {
				.address = val,
				.rowbits = 6,
				.bank    = reg,
				.rank    = slotrank,
			},
		},
		/* DRAM command MRS */
		[2] = {
			.sp_cmd_ctrl = {
				.command = IOSAV_MRS,
			},
			.subseq_ctrl = {
				.cmd_executions = 1,
				.cmd_delay_gap  = 4,
				.post_ssq_wait  = ctrl->tMOD,
				.data_direction = SSQ_NA,
			},
			.sp_cmd_addr = {
				.address = val,
				.rowbits = 6,
				.bank    = reg,
				.rank    = slotrank,
			},
		},
	};
	iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));

	iosav_run_once_and_wait(channel);
}

/* Obtain optimal power down mode for current configuration */
static enum power_down_mode get_power_down_mode(ramctr_timing *ctrl)
{
	if (ctrl->tXP > 8)
		return PDM_NONE;

	if (ctrl->tXPDLL > 32)
		return PDM_PPD;

	if (CONFIG(RAMINIT_ALWAYS_ALLOW_DLL_OFF) || get_platform_type() == PLATFORM_MOBILE)
		return PDM_DLL_OFF;

	return PDM_APD_PPD;
}

static u32 make_mr0(ramctr_timing *ctrl, u8 rank)
{
	u16 mr0reg, mch_cas, mch_wr;
	static const u8 mch_wr_t[12] = { 1, 2, 3, 4, 0, 5, 0, 6, 0, 7, 0, 0 };

	const enum power_down_mode power_down = get_power_down_mode(ctrl);

	const bool slow_exit = power_down == PDM_DLL_OFF || power_down == PDM_APD_DLL_OFF;

	/* Convert CAS to MCH register friendly */
	if (ctrl->CAS < 12) {
		mch_cas = (u16)((ctrl->CAS - 4) << 1);
	} else {
		mch_cas = (u16)(ctrl->CAS - 12);
		mch_cas = ((mch_cas << 1) | 0x1);
	}

	/* Convert tWR to MCH register friendly */
	mch_wr = mch_wr_t[ctrl->tWR - 5];

	/* DLL Reset - self clearing - set after CLK frequency has been changed */
	mr0reg = 1 << 8;

	mr0reg |= (mch_cas & 0x1) << 2;
	mr0reg |= (mch_cas & 0xe) << 3;
	mr0reg |= mch_wr << 9;

	/* Precharge PD - Use slow exit when DLL-off is used - mostly power-saving feature */
	mr0reg |= !slow_exit << 12;
	return mr0reg;
}

static void dram_mr0(ramctr_timing *ctrl, u8 rank, int channel)
{
	write_mrreg(ctrl, channel, rank, 0, make_mr0(ctrl, rank));
}

static odtmap get_ODT(ramctr_timing *ctrl, int channel)
{
	/* Get ODT based on rankmap */
	int dimms_per_ch = (ctrl->rankmap[channel] & 1) + ((ctrl->rankmap[channel] >> 2) & 1);

	if (dimms_per_ch == 1) {
		return (const odtmap){60,  60};
	} else {
		return (const odtmap){120, 30};
	}
}

static u32 encode_odt(u32 odt)
{
	switch (odt) {
	case 30:
		return (1 << 9) | (1 << 2);	/* RZQ/8, RZQ/4 */
	case 60:
		return (1 << 2);	/* RZQ/4 */
	case 120:
		return (1 << 6);	/* RZQ/2 */
	default:
	case 0:
		return 0;
	}
}

static u32 make_mr1(ramctr_timing *ctrl, u8 rank, int channel)
{
	odtmap odt;
	u32 mr1reg;

	odt = get_ODT(ctrl, channel);
	mr1reg = 2;

	mr1reg |= encode_odt(odt.rttnom);

	return mr1reg;
}

static void dram_mr1(ramctr_timing *ctrl, u8 rank, int channel)
{
	u16 mr1reg;

	mr1reg = make_mr1(ctrl, rank, channel);

	write_mrreg(ctrl, channel, rank, 1, mr1reg);
}

static void dram_mr2(ramctr_timing *ctrl, u8 rank, int channel)
{
	const u16 pasr = 0;
	const u16 cwl = ctrl->CWL - 5;
	const odtmap odt = get_ODT(ctrl, channel);

	int srt = 0;
	if (IS_IVY_CPU(ctrl->cpu) && ctrl->tCK >= TCK_1066MHZ)
		srt = ctrl->extended_temperature_range && !ctrl->auto_self_refresh;

	u16 mr2reg = 0;
	mr2reg |= pasr;
	mr2reg |= cwl << 3;
	mr2reg |= ctrl->auto_self_refresh << 6;
	mr2reg |= srt << 7;
	mr2reg |= (odt.rttwr / 60) << 9;

	write_mrreg(ctrl, channel, rank, 2, mr2reg);

	/* Program MR2 shadow */
	u32 reg32 = mchbar_read32(TC_MR2_SHADOW_ch(channel));

	reg32 &= 3 << 14 | 3 << 6;

	reg32 |= mr2reg & ~(3 << 6);

	if (srt)
		reg32 |= 1 << (rank / 2 + 6);

	if (ctrl->rank_mirror[channel][rank])
		reg32 |= 1 << (rank / 2 + 14);

	mchbar_write32(TC_MR2_SHADOW_ch(channel), reg32);
}

static void dram_mr3(ramctr_timing *ctrl, u8 rank, int channel)
{
	write_mrreg(ctrl, channel, rank, 3, 0);
}

void dram_mrscommands(ramctr_timing *ctrl)
{
	u8 slotrank;
	int channel;

	FOR_ALL_POPULATED_CHANNELS {
		FOR_ALL_POPULATED_RANKS {
			/* MR2 */
			dram_mr2(ctrl, slotrank, channel);

			/* MR3 */
			dram_mr3(ctrl, slotrank, channel);

			/* MR1 */
			dram_mr1(ctrl, slotrank, channel);

			/* MR0 */
			dram_mr0(ctrl, slotrank, channel);
		}
	}

	const struct iosav_ssq zqcl_sequence[] = {
		/* DRAM command NOP (without ODT nor chip selects) */
		[0] = {
			.sp_cmd_ctrl = {
				.command = IOSAV_NOP & ~(0xff << 8),
			},
			.subseq_ctrl = {
				.cmd_executions = 1,
				.cmd_delay_gap  = 4,
				.post_ssq_wait  = 15,
				.data_direction = SSQ_NA,
			},
			.sp_cmd_addr = {
				.address = 2,
				.rowbits = 6,
				.bank    = 0,
				.rank    = 0,
			},
		},
		/* DRAM command ZQCL */
		[1] = {
			.sp_cmd_ctrl = {
				.command    = IOSAV_ZQCS,
				.ranksel_ap = 1,
			},
			.subseq_ctrl = {
				.cmd_executions = 1,
				.cmd_delay_gap  = 4,
				.post_ssq_wait  = 400,
				.data_direction = SSQ_NA,
			},
			.sp_cmd_addr = {
				.address = 1 << 10,
				.rowbits = 6,
				.bank    = 0,
				.rank    = 0,
			},
			.addr_update = {
				.inc_rank  = 1,
				.addr_wrap = 20,
			},
		},
	};
	iosav_write_sequence(BROADCAST_CH, zqcl_sequence, ARRAY_SIZE(zqcl_sequence));

	iosav_run_queue(BROADCAST_CH, 4, 0);

	FOR_ALL_CHANNELS {
		wait_for_iosav(channel);
	}

	/* Refresh enable */
	mchbar_setbits32(MC_INIT_STATE_G, 1 << 3);

	FOR_ALL_POPULATED_CHANNELS {
		mchbar_clrbits32(SCHED_CBIT_ch(channel), 1 << 21);

		wait_for_iosav(channel);

		slotrank = (ctrl->rankmap[channel] & 1) ? 0 : 2;

		wait_for_iosav(channel);

		iosav_write_zqcs_sequence(channel, slotrank, 4, 101, 31);

		iosav_run_once_and_wait(channel);
	}
}

static const u32 lane_base[] = {
	LANEBASE_B0, LANEBASE_B1, LANEBASE_B2, LANEBASE_B3,
	LANEBASE_B4, LANEBASE_B5, LANEBASE_B6, LANEBASE_B7,
	LANEBASE_ECC
};

/* Maximum delay for command, control, clock */
#define CCC_MAX_PI	(2 * QCLK_PI - 1)

void program_timings(ramctr_timing *ctrl, int channel)
{
	u32 reg_roundtrip_latency, reg_io_latency;
	int lane;
	int slotrank, slot;

	u32 ctl_delay[NUM_SLOTS] = { 0 };
	int cmd_delay = 0;

	/* Enable CLK XOVER */
	u32 clk_pi_coding = get_XOVER_CLK(ctrl->rankmap[channel]);
	u32 clk_logic_dly = 0;

	/*
	 * Compute command timing as abs() of the most negative PI code
	 * across all ranks. Use zero if none of the values is negative.
	 */
	FOR_ALL_POPULATED_RANKS {
		cmd_delay = MAX(cmd_delay, -ctrl->timings[channel][slotrank].pi_coding);
	}
	if (cmd_delay > CCC_MAX_PI) {
		printk(BIOS_ERR, "C%d command delay overflow: %d\n", channel, cmd_delay);
		cmd_delay = CCC_MAX_PI;
	}

	for (slot = 0; slot < NUM_SLOTS; slot++) {
		const int pi_coding_0 = ctrl->timings[channel][2 * slot + 0].pi_coding;
		const int pi_coding_1 = ctrl->timings[channel][2 * slot + 1].pi_coding;

		const u8 slot_map = (ctrl->rankmap[channel] >> (2 * slot)) & 3;

		if (slot_map & 1)
			ctl_delay[slot] += pi_coding_0 + cmd_delay;

		if (slot_map & 2)
			ctl_delay[slot] += pi_coding_1 + cmd_delay;

		/* If both ranks in a slot are populated, use the average */
		if (slot_map == 3)
			ctl_delay[slot] /= 2;

		if (ctl_delay[slot] > CCC_MAX_PI) {
			printk(BIOS_ERR, "C%dS%d control delay overflow: %d\n",
				channel, slot, ctl_delay[slot]);
			ctl_delay[slot] = CCC_MAX_PI;
		}
	}
	FOR_ALL_POPULATED_RANKS {
		int clk_delay = ctrl->timings[channel][slotrank].pi_coding + cmd_delay;

		/*
		 * Clock is a differential signal, whereas command and control are not.
		 * This affects its timing, and it is also why it needs a magic offset.
		 */
		clk_delay += ctrl->pi_code_offset;

		/* Can never happen with valid values */
		if (clk_delay < 0) {
			printk(BIOS_ERR, "C%dR%d clock delay underflow: %d\n",
				channel, slotrank, clk_delay);
			clk_delay = 0;
		}

		/* Clock can safely wrap around because it is a periodic signal */
		clk_delay %= CCC_MAX_PI + 1;

		clk_pi_coding |= (clk_delay % QCLK_PI) << (6 * slotrank);
		clk_logic_dly |= (clk_delay / QCLK_PI) << slotrank;
	}

	/* Enable CMD XOVER */
	union gdcr_cmd_pi_coding_reg cmd_pi_coding = {
		.raw = get_XOVER_CMD(ctrl->rankmap[channel]),
	};
	cmd_pi_coding.cmd_pi_code = cmd_delay % QCLK_PI;
	cmd_pi_coding.cmd_logic_delay = cmd_delay / QCLK_PI;

	cmd_pi_coding.ctl_pi_code_d0 = ctl_delay[0] % QCLK_PI;
	cmd_pi_coding.ctl_pi_code_d1 = ctl_delay[1] % QCLK_PI;
	cmd_pi_coding.ctl_logic_delay_d0 = ctl_delay[0] / QCLK_PI;
	cmd_pi_coding.ctl_logic_delay_d1 = ctl_delay[1] / QCLK_PI;

	mchbar_write32(GDCRCMDPICODING_ch(channel), cmd_pi_coding.raw);

	mchbar_write32(GDCRCKPICODE_ch(channel), clk_pi_coding);
	mchbar_write32(GDCRCKLOGICDELAY_ch(channel), clk_logic_dly);

	reg_io_latency = mchbar_read32(SC_IO_LATENCY_ch(channel));
	reg_io_latency &= ~0xffff;

	reg_roundtrip_latency = 0;

	FOR_ALL_POPULATED_RANKS {
		reg_io_latency |= ctrl->timings[channel][slotrank].io_latency << (4 * slotrank);

		reg_roundtrip_latency |=
		    ctrl->timings[channel][slotrank].roundtrip_latency << (8 * slotrank);

		FOR_ALL_LANES {
			const u16 rcven = ctrl->timings[channel][slotrank].lanes[lane].rcven;
			const u8 dqs_p = ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_p;
			const u8 dqs_n = ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_n;
			const union gdcr_rx_reg gdcr_rx = {
				.rcven_pi_code     = rcven % QCLK_PI,
				.rx_dqs_p_pi_code  = dqs_p,
				.rcven_logic_delay = rcven / QCLK_PI,
				.rx_dqs_n_pi_code  = dqs_n,
			};
			mchbar_write32(lane_base[lane] + GDCRRX(channel, slotrank),
				gdcr_rx.raw);

			const u16 tx_dqs = ctrl->timings[channel][slotrank].lanes[lane].tx_dqs;
			const int tx_dq = ctrl->timings[channel][slotrank].lanes[lane].tx_dq;
			const union gdcr_tx_reg gdcr_tx = {
				.tx_dq_pi_code      = tx_dq % QCLK_PI,
				.tx_dqs_pi_code     = tx_dqs % QCLK_PI,
				.tx_dqs_logic_delay = tx_dqs / QCLK_PI,
				.tx_dq_logic_delay  = tx_dq / QCLK_PI,
			};
			mchbar_write32(lane_base[lane] + GDCRTX(channel, slotrank),
				gdcr_tx.raw);
		}
	}
	mchbar_write32(SC_ROUNDT_LAT_ch(channel), reg_roundtrip_latency);
	mchbar_write32(SC_IO_LATENCY_ch(channel), reg_io_latency);
}

static void test_rcven(ramctr_timing *ctrl, int channel, int slotrank)
{
	wait_for_iosav(channel);

	/* Send a burst of 16 back-to-back read commands (4 DCLK apart) */
	iosav_write_read_mpr_sequence(channel, slotrank, ctrl->tMOD, 1, 3, 15, ctrl->CAS + 36);

	iosav_run_once_and_wait(channel);
}

static int does_lane_work(ramctr_timing *ctrl, int channel, int slotrank, int lane)
{
	u32 rcven = ctrl->timings[channel][slotrank].lanes[lane].rcven;

	return (mchbar_read32(lane_base[lane] +
		GDCRTRAININGRESULT(channel, (rcven / 32) & 1)) >> (rcven % 32)) & 1;
}

struct run {
	int middle;
	int end;
	int start;
	int all;
	int length;
};

static struct run get_longest_zero_run(int *seq, int sz)
{
	int i, ls;
	int bl = 0, bs = 0;
	struct run ret;

	ls = 0;
	for (i = 0; i < 2 * sz; i++)
		if (seq[i % sz]) {
			if (i - ls > bl) {
				bl = i - ls;
				bs = ls;
			}
			ls = i + 1;
		}
	if (bl == 0) {
		ret.middle = sz / 2;
		ret.start  = 0;
		ret.end    = sz;
		ret.length = sz;
		ret.all    = 1;
		return ret;
	}

	ret.start  = bs % sz;
	ret.end    = (bs + bl - 1) % sz;
	ret.middle = (bs + (bl - 1) / 2) % sz;
	ret.length = bl;
	ret.all    = 0;

	return ret;
}

#define RCVEN_COARSE_PI_LENGTH	(2 * QCLK_PI)

static void find_rcven_pi_coarse(ramctr_timing *ctrl, int channel, int slotrank, int *upperA)
{
	int rcven;
	int statistics[NUM_LANES][RCVEN_COARSE_PI_LENGTH];
	int lane;

	for (rcven = 0; rcven < RCVEN_COARSE_PI_LENGTH; rcven++) {
		FOR_ALL_LANES {
			ctrl->timings[channel][slotrank].lanes[lane].rcven = rcven;
		}
		program_timings(ctrl, channel);

		test_rcven(ctrl, channel, slotrank);

		FOR_ALL_LANES {
			statistics[lane][rcven] =
				!does_lane_work(ctrl, channel, slotrank, lane);
		}
	}
	FOR_ALL_LANES {
		struct run rn = get_longest_zero_run(statistics[lane], RCVEN_COARSE_PI_LENGTH);
		ctrl->timings[channel][slotrank].lanes[lane].rcven = rn.middle;
		upperA[lane] = rn.end;
		if (upperA[lane] < rn.middle)
			upperA[lane] += 2 * QCLK_PI;

		printram("rcven: %d, %d, %d: % 4d-% 4d-% 4d\n",
			 channel, slotrank, lane, rn.start, rn.middle, rn.end);
	}
}

static void fine_tune_rcven_pi(ramctr_timing *ctrl, int channel, int slotrank, int *upperA)
{
	int rcven_delta;
	int statistics[NUM_LANES][51] = {0};
	int lane, i;

	for (rcven_delta = -25; rcven_delta <= 25; rcven_delta++) {

		FOR_ALL_LANES {
			ctrl->timings[channel][slotrank].lanes[lane].rcven
				= upperA[lane] + rcven_delta + QCLK_PI;
		}
		program_timings(ctrl, channel);

		for (i = 0; i < 100; i++) {
			test_rcven(ctrl, channel, slotrank);
			FOR_ALL_LANES {
				statistics[lane][rcven_delta + 25] +=
					does_lane_work(ctrl, channel, slotrank, lane);
			}
		}
	}
	FOR_ALL_LANES {
		int last_zero, first_all;

		for (last_zero = -25; last_zero <= 25; last_zero++)
			if (statistics[lane][last_zero + 25])
				break;

		last_zero--;
		for (first_all = -25; first_all <= 25; first_all++)
			if (statistics[lane][first_all + 25] == 100)
				break;

		printram("lane %d: %d, %d\n", lane, last_zero, first_all);

		ctrl->timings[channel][slotrank].lanes[lane].rcven =
			(last_zero + first_all) / 2 + upperA[lane];

		printram("Aval: %d, %d, %d: % 4d\n", channel, slotrank,
			lane, ctrl->timings[channel][slotrank].lanes[lane].rcven);
	}
}

/*
 * Once the DQS high phase has been found (for each DRAM) the next stage
 * is to find out the round trip latency, by locating the preamble cycle.
 * This is achieved by trying smaller and smaller roundtrip values until
 * the strobe sampling is done on the preamble cycle.
 */
static int find_roundtrip_latency(ramctr_timing *ctrl, int channel, int slotrank, int *upperA)
{
	int works[NUM_LANES];
	int lane;

	while (1) {
		int all_works = 1, some_works = 0;

		program_timings(ctrl, channel);
		test_rcven(ctrl, channel, slotrank);

		FOR_ALL_LANES {
			works[lane] = !does_lane_work(ctrl, channel, slotrank, lane);

			if (works[lane])
				some_works = 1;
			else
				all_works = 0;
		}

		/* If every lane is working, exit */
		if (all_works)
			return 0;

		/*
		 * If all bits are one (everyone is failing), decrement
		 * the roundtrip value by two, and do another iteration.
		 */
		if (!some_works) {
			/* Guard against roundtrip latency underflow */
			if (ctrl->timings[channel][slotrank].roundtrip_latency < 2) {
				printk(BIOS_EMERG, "Roundtrip latency underflow: %d, %d\n",
				       channel, slotrank);
				return MAKE_ERR;
			}
			ctrl->timings[channel][slotrank].roundtrip_latency -= 2;
			printram("4024 -= 2;\n");
			continue;
		}

		/*
		 * Else (if some lanes are failing), increase the rank's
		 * I/O latency by 2, and increase rcven logic delay by 2
		 * on the working lanes, then perform another iteration.
		 */
		ctrl->timings[channel][slotrank].io_latency += 2;
		printram("4028 += 2;\n");

		/* Guard against I/O latency overflow */
		if (ctrl->timings[channel][slotrank].io_latency >= 16) {
			printk(BIOS_EMERG, "I/O latency overflow: %d, %d\n",
			       channel, slotrank);
			return MAKE_ERR;
		}
		FOR_ALL_LANES if (works[lane]) {
			ctrl->timings[channel][slotrank].lanes[lane].rcven += 2 * QCLK_PI;
			upperA[lane] += 2 * QCLK_PI;
			printram("increment %d, %d, %d\n", channel, slotrank, lane);
		}
	}
	return 0;
}

static int get_logic_delay_delta(ramctr_timing *ctrl, int channel, int slotrank)
{
	int lane;
	u16 logic_delay_min = 7;
	u16 logic_delay_max = 0;

	FOR_ALL_LANES {
		const u16 logic_delay = ctrl->timings[channel][slotrank].lanes[lane].rcven >> 6;

		logic_delay_min = MIN(logic_delay_min, logic_delay);
		logic_delay_max = MAX(logic_delay_max, logic_delay);
	}

	if (logic_delay_max < logic_delay_min) {
		printk(BIOS_EMERG, "Logic delay max < min (%u < %u): %d, %d\n",
		       logic_delay_max, logic_delay_min, channel, slotrank);
	}

	assert(logic_delay_max >= logic_delay_min);

	return logic_delay_max - logic_delay_min;
}

static int align_rt_io_latency(ramctr_timing *ctrl, int channel, int slotrank, int prev)
{
	int latency_offset = 0;

	/* Get changed maxima */
	const int post = get_logic_delay_delta(ctrl, channel, slotrank);

	if (prev < post)
		latency_offset = +1;

	else if (prev > post)
		latency_offset = -1;

	else
		latency_offset = 0;

	ctrl->timings[channel][slotrank].io_latency += latency_offset;
	ctrl->timings[channel][slotrank].roundtrip_latency += latency_offset;
	printram("4024 += %d;\n", latency_offset);
	printram("4028 += %d;\n", latency_offset);

	return post;
}

static void compute_final_logic_delay(ramctr_timing *ctrl, int channel, int slotrank)
{
	u16 logic_delay_min = 7;
	int lane;

	FOR_ALL_LANES {
		const u16 logic_delay = ctrl->timings[channel][slotrank].lanes[lane].rcven >> 6;

		logic_delay_min = MIN(logic_delay_min, logic_delay);
	}

	if (logic_delay_min >= 2) {
		printk(BIOS_WARNING, "Logic delay %u greater than 1: %d %d\n",
			logic_delay_min, channel, slotrank);
	}

	FOR_ALL_LANES {
		ctrl->timings[channel][slotrank].lanes[lane].rcven -= logic_delay_min << 6;
	}
	ctrl->timings[channel][slotrank].io_latency -= logic_delay_min;
	printram("4028 -= %d;\n", logic_delay_min);
}

int receive_enable_calibration(ramctr_timing *ctrl)
{
	int channel, slotrank, lane;
	int err;

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		int all_high, some_high;
		int upperA[NUM_LANES];
		int prev;

		wait_for_iosav(channel);

		iosav_write_prea_sequence(channel, slotrank, ctrl->tRP, 0);

		iosav_run_once_and_wait(channel);

		const union gdcr_training_mod_reg training_mod = {
			.receive_enable_mode = 1,
			.training_rank_sel   = slotrank,
			.odt_always_on       = 1,
		};
		mchbar_write32(GDCRTRAININGMOD, training_mod.raw);

		ctrl->timings[channel][slotrank].io_latency = 4;
		ctrl->timings[channel][slotrank].roundtrip_latency = 55;
		program_timings(ctrl, channel);

		find_rcven_pi_coarse(ctrl, channel, slotrank, upperA);

		all_high = 1;
		some_high = 0;
		FOR_ALL_LANES {
			if (ctrl->timings[channel][slotrank].lanes[lane].rcven >= QCLK_PI)
				some_high = 1;
			else
				all_high = 0;
		}

		if (all_high) {
			ctrl->timings[channel][slotrank].io_latency--;
			printram("4028--;\n");
			FOR_ALL_LANES {
				ctrl->timings[channel][slotrank].lanes[lane].rcven -= QCLK_PI;
				upperA[lane] -= QCLK_PI;

			}
		} else if (some_high) {
			ctrl->timings[channel][slotrank].roundtrip_latency++;
			ctrl->timings[channel][slotrank].io_latency++;
			printram("4024++;\n");
			printram("4028++;\n");
		}

		program_timings(ctrl, channel);

		prev = get_logic_delay_delta(ctrl, channel, slotrank);

		err = find_roundtrip_latency(ctrl, channel, slotrank, upperA);
		if (err)
			return err;

		prev = align_rt_io_latency(ctrl, channel, slotrank, prev);

		fine_tune_rcven_pi(ctrl, channel, slotrank, upperA);

		prev = align_rt_io_latency(ctrl, channel, slotrank, prev);

		compute_final_logic_delay(ctrl, channel, slotrank);

		align_rt_io_latency(ctrl, channel, slotrank, prev);

		printram("4/8: %d, %d, % 4d, % 4d\n", channel, slotrank,
		       ctrl->timings[channel][slotrank].roundtrip_latency,
		       ctrl->timings[channel][slotrank].io_latency);

		printram("final results:\n");
		FOR_ALL_LANES
			printram("Aval: %d, %d, %d: % 4d\n", channel, slotrank, lane,
			    ctrl->timings[channel][slotrank].lanes[lane].rcven);

		mchbar_write32(GDCRTRAININGMOD, 0);

		toggle_io_reset();
	}

	FOR_ALL_POPULATED_CHANNELS {
		program_timings(ctrl, channel);
	}

	return 0;
}

static void test_tx_dq(ramctr_timing *ctrl, int channel, int slotrank)
{
	int lane;

	FOR_ALL_LANES {
		mchbar_write32(IOSAV_By_ERROR_COUNT_ch(channel, lane), 0);
		mchbar_read32(IOSAV_By_BW_SERROR_C_ch(channel, lane));
	}

	wait_for_iosav(channel);

	iosav_write_misc_write_sequence(ctrl, channel, slotrank,
		MAX(ctrl->tRRD, (ctrl->tFAW >> 2) + 1), 4, 4, 500, 18);

	iosav_run_once_and_wait(channel);

	iosav_write_prea_act_read_sequence(ctrl, channel, slotrank);

	iosav_run_once_and_wait(channel);
}

static void tx_dq_threshold_process(int *data, const int count)
{
	int min = data[0];
	int max = min;
	int i;
	for (i = 1; i < count; i++) {
		if (min > data[i])
			min = data[i];

		if (max < data[i])
			max = data[i];
	}
	int threshold = min / 2 + max / 2;
	for (i = 0; i < count; i++)
		data[i] = data[i] > threshold;

	printram("threshold=%d min=%d max=%d\n", threshold, min, max);
}

static int tx_dq_write_leveling(ramctr_timing *ctrl, int channel, int slotrank)
{
	int tx_dq;
	int stats[NUM_LANES][MAX_TX_DQ + 1];
	int lane;

	wait_for_iosav(channel);

	iosav_write_prea_sequence(channel, slotrank, ctrl->tRP, 18);

	iosav_run_once_and_wait(channel);

	for (tx_dq = 0; tx_dq <= MAX_TX_DQ; tx_dq++) {
		FOR_ALL_LANES ctrl->timings[channel][slotrank].lanes[lane].tx_dq = tx_dq;
		program_timings(ctrl, channel);

		test_tx_dq(ctrl, channel, slotrank);

		FOR_ALL_LANES {
			stats[lane][tx_dq] = mchbar_read32(
				IOSAV_By_ERROR_COUNT_ch(channel, lane));
		}
	}
	FOR_ALL_LANES {
		struct run rn = get_longest_zero_run(stats[lane], ARRAY_SIZE(stats[lane]));

		if (rn.all || rn.length < 8) {
			printk(BIOS_EMERG, "tx_dq write leveling failed: %d, %d, %d\n",
			       channel, slotrank, lane);
			/*
			 * With command training not being done yet, the lane can be erroneous.
			 * Take the average as reference and try again to find a run.
			 */
			tx_dq_threshold_process(stats[lane], ARRAY_SIZE(stats[lane]));
			rn = get_longest_zero_run(stats[lane], ARRAY_SIZE(stats[lane]));

			if (rn.all || rn.length < 8) {
				printk(BIOS_EMERG, "tx_dq recovery failed\n");
				return MAKE_ERR;
			}
		}
		ctrl->timings[channel][slotrank].lanes[lane].tx_dq = rn.middle;
		printram("tx_dq: %d, %d, %d: % 4d-% 4d-% 4d\n",
			channel, slotrank, lane, rn.start, rn.middle, rn.end);
	}
	return 0;
}

static int get_precedening_channels(ramctr_timing *ctrl, int target_channel)
{
	int channel, ret = 0;

	FOR_ALL_POPULATED_CHANNELS if (channel < target_channel)
		 ret++;

	return ret;
}

/* Each cacheline is 64 bits long */
static void program_wdb_pattern_length(int channel, const unsigned int num_cachelines)
{
	mchbar_write8(IOSAV_DATA_CTL_ch(channel), num_cachelines / 8 - 1);
}

static void fill_pattern0(ramctr_timing *ctrl, int channel, u32 a, u32 b)
{
	unsigned int j;
	unsigned int channel_offset = get_precedening_channels(ctrl, channel) * 64;
	uintptr_t addr;

	for (j = 0; j < 16; j++) {
		addr = 0x04000000 + channel_offset + 4 * j;
		write32p(addr, j & 2 ? b : a);
	}

	sfence();

	program_wdb_pattern_length(channel, 8);
}

static int num_of_channels(const ramctr_timing *ctrl)
{
	int ret = 0;
	int channel;
	FOR_ALL_POPULATED_CHANNELS ret++;
	return ret;
}

static void fill_pattern1(ramctr_timing *ctrl, int channel)
{
	unsigned int j;
	unsigned int channel_offset = get_precedening_channels(ctrl, channel) * 64;
	unsigned int channel_step = 64 * num_of_channels(ctrl);
	uintptr_t addr;

	for (j = 0; j < 16; j++) {
		addr = 0x04000000 + channel_offset + j * 4;
		write32p(addr, 0xffffffff);
	}
	for (j = 0; j < 16; j++) {
		addr = 0x04000000 + channel_offset + channel_step + j * 4;
		write32p(addr, 0);
	}
	sfence();

	program_wdb_pattern_length(channel, 16);
}

#define TX_DQS_PI_LENGTH	(2 * QCLK_PI)

static int write_level_rank(ramctr_timing *ctrl, int channel, int slotrank)
{
	int tx_dqs;
	int statistics[NUM_LANES][TX_DQS_PI_LENGTH];
	int lane;

	const union gdcr_training_mod_reg training_mod = {
		.write_leveling_mode = 1,
		.training_rank_sel   = slotrank,
		.enable_dqs_wl       = 5,
		.odt_always_on       = 1,
		.force_drive_enable  = 1,
	};
	mchbar_write32(GDCRTRAININGMOD, training_mod.raw);

	u32 mr1reg = make_mr1(ctrl, slotrank, channel) | 1 << 7;
	int bank = 1;

	if (ctrl->rank_mirror[channel][slotrank])
		ddr3_mirror_mrreg(&bank, &mr1reg);

	wait_for_iosav(channel);

	iosav_write_jedec_write_leveling_sequence(ctrl, channel, slotrank, bank, mr1reg);

	for (tx_dqs = 0; tx_dqs < TX_DQS_PI_LENGTH; tx_dqs++) {
		FOR_ALL_LANES {
			ctrl->timings[channel][slotrank].lanes[lane].tx_dqs = tx_dqs;
		}
		program_timings(ctrl, channel);

		iosav_run_once_and_wait(channel);

		FOR_ALL_LANES {
			statistics[lane][tx_dqs] =  !((mchbar_read32(lane_base[lane] +
				GDCRTRAININGRESULT(channel, (tx_dqs / 32) & 1)) >>
				(tx_dqs % 32)) & 1);
		}
	}
	FOR_ALL_LANES {
		struct run rn = get_longest_zero_run(statistics[lane], TX_DQS_PI_LENGTH);
		/*
		 * tx_dq is a direct function of tx_dqs's 6 LSBs. Some tests increment the value
		 * of tx_dqs by a small value, which might cause the 6-bit value to overflow if
		 * it's close to 0x3f. Increment the value by a small offset if it's likely
		 * to overflow, to make sure it won't overflow while running tests and bricks
		 * the system due to a non matching tx_dq.
		 *
		 * TODO: find out why some tests (edge write discovery) increment tx_dqs.
		 */
		if ((rn.start & 0x3f) == 0x3e)
			rn.start += 2;
		else if ((rn.start & 0x3f) == 0x3f)
			rn.start += 1;

		ctrl->timings[channel][slotrank].lanes[lane].tx_dqs = rn.start;
		if (rn.all) {
			printk(BIOS_EMERG, "JEDEC write leveling failed: %d, %d, %d\n",
			       channel, slotrank, lane);

			return MAKE_ERR;
		}
		printram("tx_dqs: %d, %d, %d: % 4d-% 4d-% 4d\n",
				 channel, slotrank, lane, rn.start, rn.middle, rn.end);
	}
	return 0;
}

static int get_dqs_flyby_adjust(u64 val)
{
	int i;
	/* DQS is good enough */
	if (val == 0xffffffffffffffffLL)
		return 0;
	if (val >= 0xf000000000000000LL) {
		/* DQS is late, needs negative adjustment */
		for (i = 0; i < 8; i++)
			if (val << (8 * (7 - i) + 4))
				return -i;
	} else {
		/* DQS is early, needs positive adjustment */
		for (i = 0; i < 8; i++)
			if (val >> (8 * (7 - i) + 4))
				return i;
	}
	return 8;
}

static void train_write_flyby(ramctr_timing *ctrl)
{
	int channel, slotrank, lane, old;

	const union gdcr_training_mod_reg training_mod = {
		.dq_dqs_training_res = 1,
	};
	mchbar_write32(GDCRTRAININGMOD, training_mod.raw);

	FOR_ALL_POPULATED_CHANNELS {
		fill_pattern1(ctrl, channel);
	}
	FOR_ALL_POPULATED_CHANNELS FOR_ALL_POPULATED_RANKS {

		/* Reset read and write WDB pointers */
		mchbar_write32(IOSAV_DATA_CTL_ch(channel), 0x10001);

		wait_for_iosav(channel);

		iosav_write_misc_write_sequence(ctrl, channel, slotrank, 3, 1, 3, 3, 31);

		iosav_run_once_and_wait(channel);

		const struct iosav_ssq rd_sequence[] = {
			/* DRAM command PREA */
			[0] = {
				.sp_cmd_ctrl = {
					.command    = IOSAV_PRE,
					.ranksel_ap = 1,
				},
				.subseq_ctrl = {
					.cmd_executions = 1,
					.cmd_delay_gap  = 3,
					.post_ssq_wait  = ctrl->tRP,
					.data_direction = SSQ_NA,
				},
				.sp_cmd_addr = {
					.address = 1 << 10,
					.rowbits = 6,
					.bank    = 0,
					.rank    = slotrank,
				},
				.addr_update = {
					.addr_wrap = 18,
				},
			},
			/* DRAM command ACT */
			[1] = {
				.sp_cmd_ctrl = {
					.command    = IOSAV_ACT,
					.ranksel_ap = 1,
				},
				.subseq_ctrl = {
					.cmd_executions = 1,
					.cmd_delay_gap  = 3,
					.post_ssq_wait  = ctrl->tRCD,
					.data_direction = SSQ_NA,
				},
				.sp_cmd_addr = {
					.address = 0,
					.rowbits = 6,
					.bank    = 0,
					.rank    = slotrank,
				},
			},
			/* DRAM command RDA */
			[2] = {
				.sp_cmd_ctrl = {
					.command    = IOSAV_RD,
					.ranksel_ap = 3,
				},
				.subseq_ctrl = {
					.cmd_executions = 1,
					.cmd_delay_gap  = 3,
					.post_ssq_wait  = ctrl->tRP +
				ctrl->timings[channel][slotrank].roundtrip_latency +
				ctrl->timings[channel][slotrank].io_latency,
					.data_direction = SSQ_RD,
				},
				.sp_cmd_addr = {
					.address = 8,
					.rowbits = 6,
					.bank    = 0,
					.rank    = slotrank,
				},
			},
		};
		iosav_write_sequence(channel, rd_sequence, ARRAY_SIZE(rd_sequence));

		iosav_run_once_and_wait(channel);

		FOR_ALL_LANES {
			u64 res = mchbar_read32(lane_base[lane] + GDCRTRAININGRESULT1(channel));
			res |= ((u64)mchbar_read32(lane_base[lane] +
				GDCRTRAININGRESULT2(channel))) << 32;

			old = ctrl->timings[channel][slotrank].lanes[lane].tx_dqs;
			ctrl->timings[channel][slotrank].lanes[lane].tx_dqs +=
				get_dqs_flyby_adjust(res) * QCLK_PI;

			printram("High adjust %d:%016llx\n", lane, res);
			printram("Bval+: %d, %d, %d, % 4d -> % 4d\n", channel, slotrank, lane,
				old, ctrl->timings[channel][slotrank].lanes[lane].tx_dqs);
		}
	}
	mchbar_write32(GDCRTRAININGMOD, 0);
}

static void disable_refresh_machine(ramctr_timing *ctrl)
{
	int channel;

	FOR_ALL_POPULATED_CHANNELS {
		/* choose an existing rank */
		const int slotrank = !(ctrl->rankmap[channel] & 1) ? 2 : 0;

		iosav_write_zqcs_sequence(channel, slotrank, 4, 4, 31);

		iosav_run_once_and_wait(channel);

		mchbar_setbits32(SCHED_CBIT_ch(channel), 1 << 21);
	}

	/* Refresh disable */
	mchbar_clrbits32(MC_INIT_STATE_G, 1 << 3);

	FOR_ALL_POPULATED_CHANNELS {
		/* Execute the same command queue */
		iosav_run_once_and_wait(channel);
	}
}

/*
 * Compensate the skew between CMD/ADDR/CLK and DQ/DQS lanes.
 *
 * Since DDR3 uses a fly-by topology, the data and strobes signals reach the chips at different
 * times with respect to command, address and clock signals. By delaying either all DQ/DQS or
 * all CMD/ADDR/CLK signals, a full phase shift can be introduced. It is assumed that the
 * CLK/ADDR/CMD signals have the same routing delay.
 *
 * To find the required phase shift the DRAM is placed in "write leveling" mode. In this mode,
 * the DRAM-chip samples the CLK on every DQS edge and feeds back the sampled value on the data
 * lanes (DQ).
 */
static int jedec_write_leveling(ramctr_timing *ctrl)
{
	int channel, slotrank;

	disable_refresh_machine(ctrl);

	/* Enable write leveling on all ranks
	   Disable all DQ outputs
	   Only NOP is allowed in this mode */
	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
		write_mrreg(ctrl, channel, slotrank, 1,
				make_mr1(ctrl, slotrank, channel) | 1 << 12 | 1 << 7);

	/* Needs to be programmed before I/O reset below */
	const union gdcr_training_mod_reg training_mod = {
		.write_leveling_mode = 1,
		.enable_dqs_wl       = 5,
		.odt_always_on       = 1,
		.force_drive_enable  = 1,
	};
	mchbar_write32(GDCRTRAININGMOD, training_mod.raw);

	toggle_io_reset();

	/* Set any valid value for tx_dqs, it gets corrected later */
	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		const int err = write_level_rank(ctrl, channel, slotrank);
		if (err)
			return err;
	}

	/* Disable write leveling on all ranks */
	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS
		write_mrreg(ctrl, channel, slotrank, 1, make_mr1(ctrl, slotrank, channel));

	mchbar_write32(GDCRTRAININGMOD, 0);

	FOR_ALL_POPULATED_CHANNELS
		wait_for_iosav(channel);

	/* Refresh enable */
	mchbar_setbits32(MC_INIT_STATE_G, 1 << 3);

	FOR_ALL_POPULATED_CHANNELS {
		mchbar_clrbits32(SCHED_CBIT_ch(channel), 1 << 21);
		mchbar_read32(IOSAV_STATUS_ch(channel));
		wait_for_iosav(channel);

		iosav_write_zqcs_sequence(channel, 0, 4, 101, 31);

		iosav_run_once_and_wait(channel);
	}

	toggle_io_reset();

	return 0;
}

int write_training(ramctr_timing *ctrl)
{
	int channel, slotrank;
	int err;

	/*
	 * Set the DEC_WRD bit, required for the write flyby algorithm.
	 * Needs to be done before starting the write training procedure.
	 */
	FOR_ALL_POPULATED_CHANNELS
		mchbar_setbits32(TC_RWP_ch(channel), 1 << 27);

	printram("CPE\n");

	err = jedec_write_leveling(ctrl);
	if (err)
		return err;

	printram("CPF\n");

	FOR_ALL_POPULATED_CHANNELS {
		fill_pattern0(ctrl, channel, 0xaaaaaaaa, 0x55555555);
	}

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		err = tx_dq_write_leveling(ctrl, channel, slotrank);
		if (err)
			return err;
	}

	FOR_ALL_POPULATED_CHANNELS
		program_timings(ctrl, channel);

	/* measure and adjust tx_dqs timings */
	train_write_flyby(ctrl);

	FOR_ALL_POPULATED_CHANNELS
		program_timings(ctrl, channel);

	return 0;
}

static int test_command_training(ramctr_timing *ctrl, int channel, int slotrank)
{
	struct ram_rank_timings saved_rt = ctrl->timings[channel][slotrank];
	int tx_dq_delta;
	int lanes_ok = 0;
	int ctr = 0;
	int lane;

	for (tx_dq_delta = -5; tx_dq_delta <= 5; tx_dq_delta++) {
		FOR_ALL_LANES {
			ctrl->timings[channel][slotrank].lanes[lane].tx_dq =
			    saved_rt.lanes[lane].tx_dq + tx_dq_delta;
		}
		program_timings(ctrl, channel);
		FOR_ALL_LANES {
			mchbar_write32(IOSAV_By_ERROR_COUNT(lane), 0);
		}

		/* Reset read WDB pointer */
		mchbar_write32(IOSAV_DATA_CTL_ch(channel), 0x1f);

		wait_for_iosav(channel);

		iosav_write_command_training_sequence(ctrl, channel, slotrank, ctr);

		/* Program LFSR for the RD/WR subsequences */
		mchbar_write32(IOSAV_n_ADDRESS_LFSR_ch(channel, 1), 0x389abcd);
		mchbar_write32(IOSAV_n_ADDRESS_LFSR_ch(channel, 2), 0x389abcd);

		iosav_run_once_and_wait(channel);

		FOR_ALL_LANES {
			u32 r32 = mchbar_read32(IOSAV_By_ERROR_COUNT_ch(channel, lane));

			if (r32 == 0)
				lanes_ok |= 1 << lane;
		}
		ctr++;
		if (lanes_ok == ((1 << ctrl->lanes) - 1))
			break;
	}

	ctrl->timings[channel][slotrank] = saved_rt;

	return lanes_ok != ((1 << ctrl->lanes) - 1);
}

static void fill_pattern5(ramctr_timing *ctrl, int channel, int patno)
{
	unsigned int i, j;
	unsigned int offset = get_precedening_channels(ctrl, channel) * 64;
	unsigned int step = 64 * num_of_channels(ctrl);
	uintptr_t addr;

	if (patno) {
		u8 base8 = 0x80 >> ((patno - 1) % 8);
		u32 base = base8 | (base8 << 8) | (base8 << 16) | (base8 << 24);
		for (i = 0; i < 32; i++) {
			for (j = 0; j < 16; j++) {
				u32 val = use_base[patno - 1][i] & (1 << (j / 2)) ? base : 0;

				if (invert[patno - 1][i] & (1 << (j / 2)))
					val = ~val;

				addr = (1 << 26) + offset + i * step + j * 4;
				write32p(addr, val);
			}
		}
	} else {
		for (i = 0; i < ARRAY_SIZE(pattern); i++) {
			for (j = 0; j < 16; j++) {
				const u32 val = pattern[i][j];
				addr = (1 << 26) + offset + i * step + j * 4;
				write32p(addr, val);
			}
		}
		sfence();
	}

	program_wdb_pattern_length(channel, 256);
}

static void reprogram_320c(ramctr_timing *ctrl)
{
	disable_refresh_machine(ctrl);

	/* JEDEC reset */
	dram_jedecreset(ctrl);

	/* MRS commands */
	dram_mrscommands(ctrl);

	toggle_io_reset();
}

#define CT_MIN_PI	(-CCC_MAX_PI)
#define CT_MAX_PI	(+CCC_MAX_PI + 1)
#define CT_PI_LENGTH	(CT_MAX_PI - CT_MIN_PI + 1)

#define MIN_C320C_LEN 13

static int try_cmd_stretch(ramctr_timing *ctrl, int channel, int cmd_stretch)
{
	struct ram_rank_timings saved_timings[NUM_CHANNELS][NUM_SLOTRANKS];
	int slotrank;
	int command_pi;
	int stat[NUM_SLOTRANKS][CT_PI_LENGTH];
	int delta = 0;

	printram("Trying cmd_stretch %d on channel %d\n", cmd_stretch, channel);

	FOR_ALL_POPULATED_RANKS {
		saved_timings[channel][slotrank] = ctrl->timings[channel][slotrank];
	}

	ctrl->cmd_stretch[channel] = cmd_stretch;

	const union tc_rap_reg tc_rap = {
		.tRRD    = ctrl->tRRD,
		.tRTP    = ctrl->tRTP,
		.tCKE    = ctrl->tCKE,
		.tWTR    = ctrl->tWTR,
		.tFAW    = ctrl->tFAW,
		.tWR     = ctrl->tWR,
		.tCMD    = ctrl->cmd_stretch[channel],
	};
	mchbar_write32(TC_RAP_ch(channel), tc_rap.raw);

	if (ctrl->cmd_stretch[channel] == 2)
		delta = 2;
	else if (ctrl->cmd_stretch[channel] == 0)
		delta = 4;

	FOR_ALL_POPULATED_RANKS {
		ctrl->timings[channel][slotrank].roundtrip_latency -= delta;
	}

	for (command_pi = CT_MIN_PI; command_pi < CT_MAX_PI; command_pi++) {
		FOR_ALL_POPULATED_RANKS {
			ctrl->timings[channel][slotrank].pi_coding = command_pi;
		}
		program_timings(ctrl, channel);
		reprogram_320c(ctrl);
		FOR_ALL_POPULATED_RANKS {
			stat[slotrank][command_pi - CT_MIN_PI] =
				test_command_training(ctrl, channel, slotrank);
		}
	}
	FOR_ALL_POPULATED_RANKS {
		struct run rn = get_longest_zero_run(stat[slotrank], CT_PI_LENGTH - 1);

		ctrl->timings[channel][slotrank].pi_coding = rn.middle + CT_MIN_PI;
		printram("cmd_stretch: %d, %d: % 4d-% 4d-% 4d\n",
				 channel, slotrank, rn.start, rn.middle, rn.end);

		if (rn.all || rn.length < MIN_C320C_LEN) {
			FOR_ALL_POPULATED_RANKS {
				ctrl->timings[channel][slotrank] =
					saved_timings[channel][slotrank];
			}
			return MAKE_ERR;
		}
	}

	return 0;
}

/*
 * Adjust CMD phase shift and try multiple command rates.
 * A command rate of 2T doubles the time needed for address and command decode.
 */
int command_training(ramctr_timing *ctrl)
{
	int channel;

	FOR_ALL_POPULATED_CHANNELS {
		fill_pattern5(ctrl, channel, 0);
	}

	FOR_ALL_POPULATED_CHANNELS {
		int cmdrate, err;

		/*
		 * Dual DIMM per channel:
		 * Issue:
		 * While command training seems to succeed, raminit will fail in write training.
		 *
		 * Workaround:
		 * Skip 1T in dual DIMM mode, that's only supported by a few DIMMs.
		 * Only try 1T mode for XMP DIMMs that request it in dual DIMM mode.
		 *
		 * Single DIMM per channel:
		 * Try command rate 1T and 2T
		 */
		cmdrate = ((ctrl->rankmap[channel] & 0x5) == 0x5);
		if (ctrl->tCMD)
			/* XMP gives the CMD rate in clock ticks, not ns */
			cmdrate = MIN(DIV_ROUND_UP(ctrl->tCMD, 256) - 1, 1);

		for (; cmdrate < 2; cmdrate++) {
			err = try_cmd_stretch(ctrl, channel, cmdrate << 1);

			if (!err)
				break;
		}

		if (err) {
			printk(BIOS_EMERG, "Command training failed: %d\n", channel);
			return err;
		}

		printram("Using CMD rate %uT on channel %u\n", cmdrate + 1, channel);
	}

	FOR_ALL_POPULATED_CHANNELS
		program_timings(ctrl, channel);

	reprogram_320c(ctrl);
	return 0;
}

static int find_read_mpr_margin(ramctr_timing *ctrl, int channel, int slotrank, int *edges)
{
	int dqs_pi;
	int stats[NUM_LANES][MAX_EDGE_TIMING + 1];
	int lane;

	for (dqs_pi = 0; dqs_pi <= MAX_EDGE_TIMING; dqs_pi++) {
		FOR_ALL_LANES {
			ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_p = dqs_pi;
			ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_n = dqs_pi;
		}
		program_timings(ctrl, channel);

		FOR_ALL_LANES {
			mchbar_write32(IOSAV_By_ERROR_COUNT_ch(channel, lane), 0);
			mchbar_read32(IOSAV_By_BW_SERROR_C_ch(channel, lane));
		}

		wait_for_iosav(channel);

		iosav_write_read_mpr_sequence(
			channel, slotrank, ctrl->tMOD, 500, 4, 1, ctrl->CAS + 8);

		iosav_run_once_and_wait(channel);

		FOR_ALL_LANES {
			stats[lane][dqs_pi] = mchbar_read32(
				IOSAV_By_ERROR_COUNT_ch(channel, lane));
		}
	}

	FOR_ALL_LANES {
		struct run rn = get_longest_zero_run(stats[lane], MAX_EDGE_TIMING + 1);
		edges[lane] = rn.middle;

		if (rn.all) {
			printk(BIOS_EMERG, "Read MPR training failed: %d, %d, %d\n", channel,
			       slotrank, lane);
			return MAKE_ERR;
		}
		printram("eval %d, %d, %d: % 4d\n", channel, slotrank, lane, edges[lane]);
	}
	return 0;
}

static void find_predefined_pattern(ramctr_timing *ctrl, const int channel)
{
	int slotrank, lane;

	fill_pattern0(ctrl, channel, 0, 0);
	FOR_ALL_LANES {
		mchbar_write32(IOSAV_By_BW_MASK_ch(channel, lane), 0);
		mchbar_read32(IOSAV_By_BW_SERROR_C_ch(channel, lane));
	}

	FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_n = 16;
		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_p = 16;
	}

	program_timings(ctrl, channel);

	FOR_ALL_POPULATED_RANKS {
		wait_for_iosav(channel);

		iosav_write_read_mpr_sequence(
			channel, slotrank, ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);

		iosav_run_once_and_wait(channel);
	}

	/* XXX: check any measured value ? */

	FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_n = 48;
		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_p = 48;
	}

	program_timings(ctrl, channel);

	FOR_ALL_POPULATED_RANKS {
		wait_for_iosav(channel);

		iosav_write_read_mpr_sequence(
			channel, slotrank, ctrl->tMOD, 3, 4, 1, ctrl->CAS + 8);

		iosav_run_once_and_wait(channel);
	}

	/* XXX: check any measured value ? */

	FOR_ALL_LANES {
		mchbar_write32(IOSAV_By_BW_MASK_ch(channel, lane),
			~mchbar_read32(IOSAV_By_BW_SERROR_ch(channel, lane)) & 0xff);
	}
}

int read_mpr_training(ramctr_timing *ctrl)
{
	int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
	int rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
	int channel, slotrank, lane;
	int err;

	mchbar_write32(GDCRTRAININGMOD, 0);

	toggle_io_reset();

	FOR_ALL_POPULATED_CHANNELS {
		find_predefined_pattern(ctrl, channel);

		fill_pattern0(ctrl, channel, 0, 0xffffffff);
	}

	/*
	 * FIXME: Under some conditions, vendor BIOS sets both edges to the same value. It will
	 *        also use a single loop. It would seem that it is a debugging configuration.
	 */
	mchbar_write32(IOSAV_DC_MASK, 3 << 8);
	printram("discover falling edges:\n[%x] = %x\n", IOSAV_DC_MASK, 3 << 8);

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		err = find_read_mpr_margin(ctrl, channel, slotrank,
			falling_edges[channel][slotrank]);
		if (err)
			return err;
	}

	mchbar_write32(IOSAV_DC_MASK, 2 << 8);
	printram("discover rising edges:\n[%x] = %x\n", IOSAV_DC_MASK, 2 << 8);

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		err = find_read_mpr_margin(ctrl, channel, slotrank,
				    rising_edges[channel][slotrank]);
		if (err)
			return err;
	}

	mchbar_write32(IOSAV_DC_MASK, 0);

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_n =
		    falling_edges[channel][slotrank][lane];
		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_p =
		    rising_edges[channel][slotrank][lane];
	}

	FOR_ALL_POPULATED_CHANNELS {
		program_timings(ctrl, channel);
	}

	FOR_ALL_POPULATED_CHANNELS FOR_ALL_LANES {
		mchbar_write32(IOSAV_By_BW_MASK_ch(channel, lane), 0);
	}
	return 0;
}

static int find_agrsv_read_margin(ramctr_timing *ctrl, int channel, int slotrank, int *edges)
{
	const int rd_vref_offsets[] = { 0, 0xc, 0x2c };

	u32 raw_stats[MAX_EDGE_TIMING + 1];
	int lower[NUM_LANES];
	int upper[NUM_LANES];
	int lane, i, read_pi, pat;

	FOR_ALL_LANES {
		lower[lane] = 0;
		upper[lane] = MAX_EDGE_TIMING;
	}

	for (i = 0; i < ARRAY_SIZE(rd_vref_offsets); i++) {
		const union gdcr_training_mod_reg training_mod = {
			.vref_gen_ctl = rd_vref_offsets[i],
		};
		mchbar_write32(GDCRTRAININGMOD_ch(channel), training_mod.raw);
		printram("[%x] = 0x%08x\n", GDCRTRAININGMOD_ch(channel), training_mod.raw);

		for (pat = 0; pat < NUM_PATTERNS; pat++) {
			fill_pattern5(ctrl, channel, pat);
			printram("using pattern %d\n", pat);

			for (read_pi = 0; read_pi <= MAX_EDGE_TIMING; read_pi++) {
				FOR_ALL_LANES {
					ctrl->timings[channel][slotrank].lanes[lane]
						.rx_dqs_p = read_pi;
					ctrl->timings[channel][slotrank].lanes[lane]
						.rx_dqs_n = read_pi;
				}
				program_timings(ctrl, channel);

				FOR_ALL_LANES {
					mchbar_write32(IOSAV_By_ERROR_COUNT_ch(channel, lane),
							0);
					mchbar_read32(IOSAV_By_BW_SERROR_C_ch(channel, lane));
				}
				wait_for_iosav(channel);

				iosav_write_data_write_sequence(ctrl, channel, slotrank);

				iosav_run_once_and_wait(channel);

				FOR_ALL_LANES {
					mchbar_read32(IOSAV_By_ERROR_COUNT_ch(channel, lane));
				}

				/* FIXME: This register only exists on Ivy Bridge */
				raw_stats[read_pi] = mchbar_read32(
					IOSAV_BYTE_SERROR_C_ch(channel));
			}

			FOR_ALL_LANES {
				int stats[MAX_EDGE_TIMING + 1];
				struct run rn;

				for (read_pi = 0; read_pi <= MAX_EDGE_TIMING; read_pi++)
					stats[read_pi] = !!(raw_stats[read_pi] & (1 << lane));

				rn = get_longest_zero_run(stats, MAX_EDGE_TIMING + 1);

				printram("edges: %d, %d, %d: % 4d-% 4d-% 4d, "
					 "% 4d-% 4d\n", channel, slotrank, i, rn.start,
					 rn.middle, rn.end, rn.start + ctrl->edge_offset[i],
					 rn.end - ctrl->edge_offset[i]);

				lower[lane] = MAX(rn.start + ctrl->edge_offset[i], lower[lane]);
				upper[lane] = MIN(rn.end   - ctrl->edge_offset[i], upper[lane]);

				edges[lane] = (lower[lane] + upper[lane]) / 2;
				if (rn.all || (lower[lane] > upper[lane])) {
					printk(BIOS_EMERG, "Aggressive read training failed: "
						"%d, %d, %d\n", channel, slotrank, lane);

					return MAKE_ERR;
				}
			}
		}
	}

	/* Restore nominal Vref after training */
	mchbar_write32(GDCRTRAININGMOD_ch(channel), 0);
	printram("CPA\n");
	return 0;
}

int aggressive_read_training(ramctr_timing *ctrl)
{
	int falling_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
	int  rising_edges[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
	int channel, slotrank, lane, err;

	/*
	 * FIXME: Under some conditions, vendor BIOS sets both edges to the same value. It will
	 *        also use a single loop. It would seem that it is a debugging configuration.
	 */
	mchbar_write32(IOSAV_DC_MASK, 3 << 8);
	printram("discover falling edges aggressive:\n[%x] = %x\n", IOSAV_DC_MASK, 3 << 8);

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		err = find_agrsv_read_margin(ctrl, channel, slotrank,
					falling_edges[channel][slotrank]);
		if (err)
			return err;
	}

	mchbar_write32(IOSAV_DC_MASK, 2 << 8);
	printram("discover rising edges aggressive:\n[%x] = %x\n", IOSAV_DC_MASK, 2 << 8);

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		err = find_agrsv_read_margin(ctrl, channel, slotrank,
					 rising_edges[channel][slotrank]);
		if (err)
			return err;
	}

	mchbar_write32(IOSAV_DC_MASK, 0);

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_n =
				falling_edges[channel][slotrank][lane];

		ctrl->timings[channel][slotrank].lanes[lane].rx_dqs_p =
				rising_edges[channel][slotrank][lane];
	}

	FOR_ALL_POPULATED_CHANNELS
		program_timings(ctrl, channel);

	return 0;
}

static void test_aggressive_write(ramctr_timing *ctrl, int channel, int slotrank)
{
	wait_for_iosav(channel);

	iosav_write_aggressive_write_read_sequence(ctrl, channel, slotrank);

	iosav_run_once_and_wait(channel);
}

static void set_write_vref(const int channel, const u8 wr_vref)
{
	mchbar_clrsetbits32(GDCRCMDDEBUGMUXCFG_Cz_S(channel), 0x3f << 24, wr_vref << 24);
	udelay(2);
}

int aggressive_write_training(ramctr_timing *ctrl)
{
	const u8 wr_vref_offsets[3] = { 0, 0x0f, 0x2f };
	int i, pat;

	int lower[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
	int upper[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES];
	int channel, slotrank, lane;

	/* Changing the write Vref is only supported on some Ivy Bridge SKUs */
	if (!IS_IVY_CPU(ctrl->cpu))
		return 0;

	if (!(pci_read_config32(HOST_BRIDGE, CAPID0_A) & CAPID_WRTVREF))
		return 0;

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
		lower[channel][slotrank][lane] = 0;
		upper[channel][slotrank][lane] = MAX_TX_DQ;
	}

	/* Only enable IOSAV_n_SPECIAL_COMMAND_ADDR optimization on later steppings */
	const bool enable_iosav_opt = IS_IVY_CPU_D(ctrl->cpu) || IS_IVY_CPU_E(ctrl->cpu);

	if (enable_iosav_opt)
		mchbar_write32(MCMNTS_SPARE, 1);

	printram("Aggressive write training:\n");

	for (i = 0; i < ARRAY_SIZE(wr_vref_offsets); i++) {
		FOR_ALL_POPULATED_CHANNELS {
			set_write_vref(channel, wr_vref_offsets[i]);

			for (pat = 0; pat < NUM_PATTERNS; pat++) {
				FOR_ALL_POPULATED_RANKS {
					int tx_dq;
					u32 raw_stats[MAX_TX_DQ + 1];
					int stats[MAX_TX_DQ + 1];

					/* Make sure rn.start < rn.end */
					stats[MAX_TX_DQ] = 1;

					fill_pattern5(ctrl, channel, pat);

					for (tx_dq = 0; tx_dq < MAX_TX_DQ; tx_dq++) {
						FOR_ALL_LANES {
							ctrl->timings[channel][slotrank]
								.lanes[lane].tx_dq = tx_dq;
						}
						program_timings(ctrl, channel);

						test_aggressive_write(ctrl, channel, slotrank);

						raw_stats[tx_dq] = mchbar_read32(
							IOSAV_BYTE_SERROR_C_ch(channel));
					}
					FOR_ALL_LANES {
						struct run rn;
						for (tx_dq = 0; tx_dq < MAX_TX_DQ; tx_dq++) {
							stats[tx_dq] = !!(raw_stats[tx_dq]
									& (1 << lane));
						}

						rn = get_longest_zero_run(stats, MAX_TX_DQ + 1);
						if (rn.all) {
							printk(BIOS_EMERG, "Aggressive "
								"write training failed: "
								"%d, %d, %d\n", channel,
								slotrank, lane);

							return MAKE_ERR;
						}
						printram("tx_dq: %d, %d, %d: "
							 "% 4d-% 4d-% 4d, "
							 "% 4d-% 4d\n", channel, slotrank,
							 i, rn.start, rn.middle, rn.end,
							 rn.start + ctrl->tx_dq_offset[i],
							 rn.end   - ctrl->tx_dq_offset[i]);

						lower[channel][slotrank][lane] =
							MAX(rn.start + ctrl->tx_dq_offset[i],
							    lower[channel][slotrank][lane]);

						upper[channel][slotrank][lane] =
							MIN(rn.end - ctrl->tx_dq_offset[i],
							    upper[channel][slotrank][lane]);

					}
				}
			}
		}
	}

	FOR_ALL_CHANNELS {
		/* Restore nominal write Vref after training */
		set_write_vref(channel, 0);
	}

	/* Disable IOSAV_n_SPECIAL_COMMAND_ADDR optimization */
	if (enable_iosav_opt)
		mchbar_write32(MCMNTS_SPARE, 0);

	printram("CPB\n");

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS FOR_ALL_LANES {
		printram("tx_dq %d, %d, %d: % 4d\n", channel, slotrank, lane,
		       (lower[channel][slotrank][lane] +
			upper[channel][slotrank][lane]) / 2);

		ctrl->timings[channel][slotrank].lanes[lane].tx_dq =
		    (lower[channel][slotrank][lane] +
		     upper[channel][slotrank][lane]) / 2;
	}
	FOR_ALL_POPULATED_CHANNELS {
		program_timings(ctrl, channel);
	}
	return 0;
}

void normalize_training(ramctr_timing *ctrl)
{
	int channel, slotrank, lane;
	int mat;

	FOR_ALL_CHANNELS FOR_ALL_POPULATED_RANKS {
		int delta;
		mat = 0;
		FOR_ALL_LANES mat =
		    MAX(ctrl->timings[channel][slotrank].lanes[lane].rcven, mat);
		printram("normalize %d, %d, %d: mat %d\n",
		    channel, slotrank, lane, mat);

		delta = (mat >> 6) - ctrl->timings[channel][slotrank].io_latency;
		printram("normalize %d, %d, %d: delta %d\n",
		    channel, slotrank, lane, delta);

		ctrl->timings[channel][slotrank].roundtrip_latency += delta;
		ctrl->timings[channel][slotrank].io_latency += delta;
	}

	FOR_ALL_POPULATED_CHANNELS {
		program_timings(ctrl, channel);
	}
}

int channel_test(ramctr_timing *ctrl)
{
	int channel, slotrank, lane;

	slotrank = 0;
	FOR_ALL_POPULATED_CHANNELS
		if (mchbar_read32(MC_INIT_STATE_ch(channel)) & 0xa000) {
			printk(BIOS_EMERG, "Mini channel test failed (1): %d\n", channel);
			return MAKE_ERR;
		}
	FOR_ALL_POPULATED_CHANNELS {
		fill_pattern0(ctrl, channel, 0x12345678, 0x98765432);
	}

	for (slotrank = 0; slotrank < 4; slotrank++)
		FOR_ALL_CHANNELS
			if (ctrl->rankmap[channel] & (1 << slotrank)) {
		FOR_ALL_LANES {
			mchbar_write32(IOSAV_By_ERROR_COUNT(lane), 0);
			mchbar_write32(IOSAV_By_BW_SERROR_C(lane), 0);
		}
		wait_for_iosav(channel);

		iosav_write_memory_test_sequence(ctrl, channel, slotrank);

		iosav_run_once_and_wait(channel);

		FOR_ALL_LANES
			if (mchbar_read32(IOSAV_By_ERROR_COUNT_ch(channel, lane))) {
				printk(BIOS_EMERG, "Mini channel test failed (2): %d, %d, %d\n",
				       channel, slotrank, lane);
				return MAKE_ERR;
			}
	}
	return 0;
}

void channel_scrub(ramctr_timing *ctrl)
{
	int channel, slotrank, row, rowsize;
	u8 bank;

	FOR_ALL_POPULATED_CHANNELS {
		wait_for_iosav(channel);
		fill_pattern0(ctrl, channel, 0, 0);
	}

	/*
	 * During runtime the "scrubber" will periodically scan through the memory in the
	 * physical address space, to identify and fix CRC errors.
	 * The following loops writes to every DRAM address, setting the ECC bits to the
	 * correct value. A read from this location will no longer return a CRC error,
	 * except when a bit has toggled due to external events.
	 * The same could be achieved by writing to the physical memory map, but it's
	 * much more difficult due to SMM remapping, ME stolen memory, GFX stolen memory,
	 * and firmware running in x86_32.
	 */
	FOR_ALL_POPULATED_CHANNELS FOR_ALL_POPULATED_RANKS {
		rowsize = 1 << ctrl->info.dimm[channel][slotrank >> 1].row_bits;
		for (bank = 0; bank < 8; bank++) {
			for (row = 0; row < rowsize; row += 16) {

				u8 gap = MAX((ctrl->tFAW >> 2) + 1, ctrl->tRRD);
				const struct iosav_ssq sequence[] = {
					/*
					 * DRAM command ACT
					 *  Opens the row for writing.
					 */
					[0] = {
						.sp_cmd_ctrl = {
							.command    = IOSAV_ACT,
							.ranksel_ap = 1,
						},
						.subseq_ctrl = {
							.cmd_executions = 1,
							.cmd_delay_gap  = gap,
							.post_ssq_wait  = ctrl->tRCD,
							.data_direction = SSQ_NA,
						},
						.sp_cmd_addr = {
							.address = row,
							.rowbits = 6,
							.bank    = bank,
							.rank    = slotrank,
						},
						.addr_update = {
							.inc_addr_1 = 1,
							.addr_wrap  = 18,
						},
					},
					/*
					 * DRAM command WR
					 *  Writes (128 + 1) * 8 (burst length) * 8 (bus width)
					 *  bytes.
					 */
					[1] = {
						.sp_cmd_ctrl = {
							.command    = IOSAV_WR,
							.ranksel_ap = 1,
						},
						.subseq_ctrl = {
							.cmd_executions = 129,
							.cmd_delay_gap  = 4,
							.post_ssq_wait  = ctrl->tWTR +
									  ctrl->CWL + 8,
							.data_direction = SSQ_WR,
						},
						.sp_cmd_addr = {
							.address = row,
							.rowbits = 0,
							.bank    = bank,
							.rank    = slotrank,
						},
						.addr_update = {
							.inc_addr_8 = 1,
							.addr_wrap  = 9,
						},
					},
					/*
					 * DRAM command PRE
					 *  Closes the row.
					 */
					[2] = {
						.sp_cmd_ctrl = {
							.command    = IOSAV_PRE,
							.ranksel_ap = 1,
						},
						.subseq_ctrl = {
							.cmd_executions = 1,
							.cmd_delay_gap  = 4,
							.post_ssq_wait  = ctrl->tRP,
							.data_direction = SSQ_NA,
						},
						.sp_cmd_addr = {
							.address = 0,
							.rowbits = 6,
							.bank    = bank,
							.rank    = slotrank,
						},
						.addr_update = {
							.addr_wrap = 18,
						},
					},
				};
				iosav_write_sequence(channel, sequence, ARRAY_SIZE(sequence));

				iosav_run_queue(channel, 16, 0);

				wait_for_iosav(channel);
			}
		}
	}
}

void set_scrambling_seed(ramctr_timing *ctrl)
{
	int channel;

	/* FIXME: we hardcode seeds. Do we need to use some PRNG for them? I don't think so. */
	static u32 seeds[NUM_CHANNELS][3] = {
		{0x00009a36, 0xbafcfdcf, 0x46d1ab68},
		{0x00028bfa, 0x53fe4b49, 0x19ed5483}
	};
	FOR_ALL_POPULATED_CHANNELS {
		mchbar_clrbits32(SCHED_CBIT_ch(channel), 1 << 28);
		mchbar_write32(SCRAMBLING_SEED_1_ch(channel),    seeds[channel][0]);
		mchbar_write32(SCRAMBLING_SEED_2_HI_ch(channel), seeds[channel][1]);
		mchbar_write32(SCRAMBLING_SEED_2_LO_ch(channel), seeds[channel][2]);
	}
}

void set_wmm_behavior(const u32 cpu)
{
	if (IS_SANDY_CPU(cpu) && (IS_SANDY_CPU_D0(cpu) || IS_SANDY_CPU_D1(cpu))) {
		mchbar_write32(SC_WDBWM, 0x141d1519);
	} else {
		mchbar_write32(SC_WDBWM, 0x551d1519);
	}
}

void prepare_training(ramctr_timing *ctrl)
{
	int channel;

	FOR_ALL_POPULATED_CHANNELS {
		/* Always drive command bus */
		mchbar_setbits32(TC_RAP_ch(channel), 1 << 29);
	}

	udelay(1);

	FOR_ALL_POPULATED_CHANNELS {
		wait_for_iosav(channel);
	}
}

void set_read_write_timings(ramctr_timing *ctrl)
{
	/* Use a larger delay when running fast to improve stability */
	const u32 tRWDRDD_inc = ctrl->tCK <= TCK_1066MHZ ? 4 : 2;

	int channel, slotrank;

	FOR_ALL_POPULATED_CHANNELS {
		int min_pi = 10000;
		int max_pi = -10000;

		FOR_ALL_POPULATED_RANKS {
			max_pi = MAX(ctrl->timings[channel][slotrank].pi_coding, max_pi);
			min_pi = MIN(ctrl->timings[channel][slotrank].pi_coding, min_pi);
		}

		const u32 tWRDRDD = (max_pi - min_pi > 51) ? 0 : ctrl->ref_card_offset[channel];

		const u32 val = (ctrl->pi_coding_threshold < max_pi - min_pi) ? 3 : 2;

		dram_odt_stretch(ctrl, channel);

		const union tc_rwp_reg tc_rwp = {
			.tRRDR   = 0,
			.tRRDD   = val,
			.tWWDR   = val,
			.tWWDD   = val,
			.tRWDRDD = ctrl->ref_card_offset[channel] + tRWDRDD_inc,
			.tWRDRDD = tWRDRDD,
			.tRWSR   = 2,
			.dec_wrd = 1,
		};
		mchbar_write32(TC_RWP_ch(channel), tc_rwp.raw);
	}
}

void set_normal_operation(ramctr_timing *ctrl)
{
	int channel;
	FOR_ALL_POPULATED_CHANNELS {
		mchbar_write32(MC_INIT_STATE_ch(channel), 1 << 12 | ctrl->rankmap[channel]);
		mchbar_clrbits32(TC_RAP_ch(channel), 1 << 29);
	}
}

/* Encode the watermark latencies in a suitable format for graphics drivers consumption */
static int encode_wm(int ns)
{
	return (ns + 499) / 500;
}

/* FIXME: values in this function should be hardware revision-dependent */
void final_registers(ramctr_timing *ctrl)
{
	int channel;
	int t1_cycles = 0, t1_ns = 0, t2_ns;
	int t3_ns;
	u32 r32;

	/* FIXME: This register only exists on Ivy Bridge */
	mchbar_write32(WMM_READ_CONFIG, 0x46);

	FOR_ALL_CHANNELS {
		union tc_othp_reg tc_othp = {
			.raw = mchbar_read32(TC_OTHP_ch(channel)),
		};
		tc_othp.tCPDED = 1;
		mchbar_write32(TC_OTHP_ch(channel), tc_othp.raw);
	}

	/* 64 DCLKs until idle, decision per rank */
	mchbar_write32(PM_PDWN_CONFIG, get_power_down_mode(ctrl) << 8 | 64);

	FOR_ALL_CHANNELS
		mchbar_write32(PM_TRML_M_CONFIG_ch(channel), 0x00000aaa);

	mchbar_write32(PM_BW_LIMIT_CONFIG, 0x5f7003ff);
	mchbar_write32(PM_DLL_CONFIG, 0x00073000 | ctrl->mdll_wake_delay);

	FOR_ALL_CHANNELS {
		switch (ctrl->rankmap[channel]) {
			/* Unpopulated channel */
		case 0:
			mchbar_write32(PM_CMD_PWR_ch(channel), 0);
			break;
			/* Only single-ranked dimms */
		case 1:
		case 4:
		case 5:
			mchbar_write32(PM_CMD_PWR_ch(channel), 0x00373131);
			break;
			/* Dual-ranked dimms present */
		default:
			mchbar_write32(PM_CMD_PWR_ch(channel), 0x009b6ea1);
			break;
		}
	}

	mchbar_write32(MEM_TRML_ESTIMATION_CONFIG, 0xca9171e5);
	mchbar_clrsetbits32(MEM_TRML_THRESHOLDS_CONFIG, 0x00ffffff, 0x00e4d5d0);
	mchbar_clrbits32(MEM_TRML_INTERRUPT, 0x1f);

	FOR_ALL_CHANNELS {
		union tc_rfp_reg tc_rfp = {
			.raw = mchbar_read32(TC_RFP_ch(channel)),
		};
		tc_rfp.refresh_2x_control = 1;
		mchbar_write32(TC_RFP_ch(channel), tc_rfp.raw);
	}

	mchbar_setbits32(MC_INIT_STATE_G, 1 << 0);
	mchbar_setbits32(MC_INIT_STATE_G, 1 << 7);
	mchbar_write32(BANDTIMERS_SNB, 0xfa);

	/* Find a populated channel */
	FOR_ALL_POPULATED_CHANNELS
		break;

	t1_cycles = (mchbar_read32(TC_ZQCAL_ch(channel)) >> 8) & 0xff;
	r32 = mchbar_read32(PM_DLL_CONFIG);
	if (r32 & (1 << 17))
		t1_cycles += (r32 & 0xfff);
	t1_cycles += mchbar_read32(TC_SRFTP_ch(channel)) & 0xfff;
	t1_ns = t1_cycles * ctrl->tCK / 256 + 544;
	if (!(r32 & (1 << 17)))
		t1_ns += 500;

	t2_ns = 10 * ((mchbar_read32(SAPMTIMERS) >> 8) & 0xfff);
	if (mchbar_read32(SAPMCTL) & 8) {
		t3_ns  = 10 * ((mchbar_read32(BANDTIMERS_IVB) >> 8) & 0xfff);
		t3_ns += 10 * (mchbar_read32(SAPMTIMERS2_IVB) & 0xff);
	} else {
		t3_ns = 500;
	}

	/* The graphics driver will use these watermark values */
	printk(BIOS_DEBUG, "t123: %d, %d, %d\n", t1_ns, t2_ns, t3_ns);
	mchbar_clrsetbits32(SSKPD, 0x3f3f3f3f,
		((encode_wm(t1_ns) + encode_wm(t2_ns)) << 16) | (encode_wm(t1_ns) << 8) |
		((encode_wm(t3_ns) + encode_wm(t2_ns) + encode_wm(t1_ns)) << 24) | 0x0c);
}

void restore_timings(ramctr_timing *ctrl)
{
	int channel;

	FOR_ALL_POPULATED_CHANNELS {
		const union tc_rap_reg tc_rap = {
			.tRRD    = ctrl->tRRD,
			.tRTP    = ctrl->tRTP,
			.tCKE    = ctrl->tCKE,
			.tWTR    = ctrl->tWTR,
			.tFAW    = ctrl->tFAW,
			.tWR     = ctrl->tWR,
			.tCMD    = ctrl->cmd_stretch[channel],
		};
		mchbar_write32(TC_RAP_ch(channel), tc_rap.raw);
	}

	udelay(1);

	FOR_ALL_POPULATED_CHANNELS {
		wait_for_iosav(channel);
	}

	FOR_ALL_POPULATED_CHANNELS
		mchbar_setbits32(TC_RWP_ch(channel), 1 << 27);

	FOR_ALL_POPULATED_CHANNELS {
		udelay(1);
		mchbar_setbits32(SCHED_CBIT_ch(channel), 1 << 21);
	}

	printram("CPE\n");

	mchbar_write32(GDCRTRAININGMOD, 0);
	mchbar_write32(IOSAV_DC_MASK, 0);

	printram("CP5b\n");

	FOR_ALL_POPULATED_CHANNELS {
		program_timings(ctrl, channel);
	}

	u32 reg, addr;

	/* Poll for RCOMP */
	while (!(mchbar_read32(RCOMP_TIMER) & (1 << 16)))
		;

	do {
		reg = mchbar_read32(IOSAV_STATUS_ch(0));
	} while ((reg & 0x14) == 0);

	/* Set state of memory controller */
	mchbar_write32(MC_INIT_STATE_G, 0x116);
	mchbar_write32(MC_INIT_STATE, 0);

	/* Wait 500us */
	udelay(500);

	FOR_ALL_CHANNELS {
		/* Set valid rank CKE */
		reg = 0;
		reg = (reg & ~0x0f) | ctrl->rankmap[channel];
		addr = MC_INIT_STATE_ch(channel);
		mchbar_write32(addr, reg);

		/* Wait 10ns for ranks to settle */
		// udelay(0.01);

		reg = (reg & ~0xf0) | (ctrl->rankmap[channel] << 4);
		mchbar_write32(addr, reg);

		/* Write reset using a NOP */
		write_reset(ctrl);
	}

	/* MRS commands */
	dram_mrscommands(ctrl);

	printram("CP5c\n");

	mchbar_write32(GDCRTRAININGMOD_ch(0), 0);

	FOR_ALL_CHANNELS {
		mchbar_clrbits32(GDCRCMDDEBUGMUXCFG_Cz_S(channel), 0x3f << 24);
		udelay(2);
	}
}
