// SPDX-License-Identifier: BSD-3-Clause
/*
 * Copyright Altera Corporation (C) 2012-2015
 */

#include <common.h>
#include <log.h>
#include <asm/io.h>
#include <asm/arch/sdram.h>
#include <errno.h>
#include <hang.h>
#include "sequencer.h"

static const struct socfpga_sdr_rw_load_manager *sdr_rw_load_mgr_regs =
	(struct socfpga_sdr_rw_load_manager *)
		(SDR_PHYGRP_RWMGRGRP_ADDRESS | 0x800);
static const struct socfpga_sdr_rw_load_jump_manager *sdr_rw_load_jump_mgr_regs
	= (struct socfpga_sdr_rw_load_jump_manager *)
		(SDR_PHYGRP_RWMGRGRP_ADDRESS | 0xC00);
static const struct socfpga_sdr_reg_file *sdr_reg_file =
	(struct socfpga_sdr_reg_file *)SDR_PHYGRP_REGFILEGRP_ADDRESS;
static const struct socfpga_sdr_scc_mgr *sdr_scc_mgr =
	(struct socfpga_sdr_scc_mgr *)
		(SDR_PHYGRP_SCCGRP_ADDRESS | 0xe00);
static const struct socfpga_phy_mgr_cmd *phy_mgr_cmd =
	(struct socfpga_phy_mgr_cmd *)SDR_PHYGRP_PHYMGRGRP_ADDRESS;
static const struct socfpga_phy_mgr_cfg *phy_mgr_cfg =
	(struct socfpga_phy_mgr_cfg *)
		(SDR_PHYGRP_PHYMGRGRP_ADDRESS | 0x40);
static const struct socfpga_data_mgr *data_mgr =
	(struct socfpga_data_mgr *)SDR_PHYGRP_DATAMGRGRP_ADDRESS;
static const struct socfpga_sdr_ctrl *sdr_ctrl =
	(struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;

#define DELTA_D		1

/*
 * In order to reduce ROM size, most of the selectable calibration steps are
 * decided at compile time based on the user's calibration mode selection,
 * as captured by the STATIC_CALIB_STEPS selection below.
 *
 * However, to support simulation-time selection of fast simulation mode, where
 * we skip everything except the bare minimum, we need a few of the steps to
 * be dynamic.  In those cases, we either use the DYNAMIC_CALIB_STEPS for the
 * check, which is based on the rtl-supplied value, or we dynamically compute
 * the value to use based on the dynamically-chosen calibration mode
 */

#define DLEVEL 0
#define STATIC_IN_RTL_SIM 0
#define STATIC_SKIP_DELAY_LOOPS 0

#define STATIC_CALIB_STEPS (STATIC_IN_RTL_SIM | CALIB_SKIP_FULL_TEST | \
	STATIC_SKIP_DELAY_LOOPS)

#define SKIP_DELAY_LOOP_VALUE_OR_ZERO(non_skip_value) \
	((non_skip_value) & seq->skip_delay_mask)

bool dram_is_ddr(const u8 ddr)
{
	const struct socfpga_sdram_config *cfg = socfpga_get_sdram_config();
	const u8 type = (cfg->ctrl_cfg >> SDR_CTRLGRP_CTRLCFG_MEMTYPE_LSB) &
			SDR_CTRLGRP_CTRLCFG_MEMTYPE_MASK;

	if (ddr == 2 && type == 1)	/* DDR2 */
		return true;

	if (ddr == 3 && type == 2)	/* DDR3 */
		return true;

	return false;
}

static void set_failing_group_stage(struct socfpga_sdrseq *seq,
				    u32 group, u32 stage, u32 substage)
{
	/*
	 * Only set the global stage if there was not been any other
	 * failing group
	 */
	if (seq->gbl.error_stage == CAL_STAGE_NIL)	{
		seq->gbl.error_substage = substage;
		seq->gbl.error_stage = stage;
		seq->gbl.error_group = group;
	}
}

static void reg_file_set_group(u16 set_group)
{
	clrsetbits_le32(&sdr_reg_file->cur_stage, 0xffff0000, set_group << 16);
}

static void reg_file_set_stage(u8 set_stage)
{
	clrsetbits_le32(&sdr_reg_file->cur_stage, 0xffff, set_stage & 0xff);
}

static void reg_file_set_sub_stage(u8 set_sub_stage)
{
	set_sub_stage &= 0xff;
	clrsetbits_le32(&sdr_reg_file->cur_stage, 0xff00, set_sub_stage << 8);
}

/**
 * phy_mgr_initialize() - Initialize PHY Manager
 *
 * Initialize PHY Manager.
 */
static void phy_mgr_initialize(struct socfpga_sdrseq *seq)
{
	u32 ratio;

	debug("%s:%d\n", __func__, __LINE__);
	/* Calibration has control over path to memory */
	/*
	 * In Hard PHY this is a 2-bit control:
	 * 0: AFI Mux Select
	 * 1: DDIO Mux Select
	 */
	writel(0x3, &phy_mgr_cfg->mux_sel);

	/* USER memory clock is not stable we begin initialization  */
	writel(0, &phy_mgr_cfg->reset_mem_stbl);

	/* USER calibration status all set to zero */
	writel(0, &phy_mgr_cfg->cal_status);

	writel(0, &phy_mgr_cfg->cal_debug_info);

	/* Init params only if we do NOT skip calibration. */
	if ((seq->dyn_calib_steps & CALIB_SKIP_ALL) == CALIB_SKIP_ALL)
		return;

	ratio = seq->rwcfg->mem_dq_per_read_dqs /
		seq->rwcfg->mem_virtual_groups_per_read_dqs;
	seq->param.read_correct_mask_vg = (1 << ratio) - 1;
	seq->param.write_correct_mask_vg = (1 << ratio) - 1;
	seq->param.read_correct_mask = (1 << seq->rwcfg->mem_dq_per_read_dqs)
		- 1;
	seq->param.write_correct_mask = (1 << seq->rwcfg->mem_dq_per_write_dqs)
		- 1;
}

/**
 * set_rank_and_odt_mask() - Set Rank and ODT mask
 * @rank:	Rank mask
 * @odt_mode:	ODT mode, OFF or READ_WRITE
 *
 * Set Rank and ODT mask (On-Die Termination).
 */
static void set_rank_and_odt_mask(struct socfpga_sdrseq *seq,
				  const u32 rank, const u32 odt_mode)
{
	u32 odt_mask_0 = 0;
	u32 odt_mask_1 = 0;
	u32 cs_and_odt_mask;

	if (odt_mode == RW_MGR_ODT_MODE_OFF) {
		odt_mask_0 = 0x0;
		odt_mask_1 = 0x0;
	} else {	/* RW_MGR_ODT_MODE_READ_WRITE */
		switch (seq->rwcfg->mem_number_of_ranks) {
		case 1:	/* 1 Rank */
			/* Read: ODT = 0 ; Write: ODT = 1 */
			odt_mask_0 = 0x0;
			odt_mask_1 = 0x1;
			break;
		case 2:	/* 2 Ranks */
			if (seq->rwcfg->mem_number_of_cs_per_dimm == 1) {
				/*
				 * - Dual-Slot , Single-Rank (1 CS per DIMM)
				 *   OR
				 * - RDIMM, 4 total CS (2 CS per DIMM, 2 DIMM)
				 *
				 * Since MEM_NUMBER_OF_RANKS is 2, they
				 * are both single rank with 2 CS each
				 * (special for RDIMM).
				 *
				 * Read: Turn on ODT on the opposite rank
				 * Write: Turn on ODT on all ranks
				 */
				odt_mask_0 = 0x3 & ~(1 << rank);
				odt_mask_1 = 0x3;
				if (dram_is_ddr(2))
					odt_mask_1 &= ~(1 << rank);
			} else {
				/*
				 * - Single-Slot , Dual-Rank (2 CS per DIMM)
				 *
				 * Read: Turn on ODT off on all ranks
				 * Write: Turn on ODT on active rank
				 */
				odt_mask_0 = 0x0;
				odt_mask_1 = 0x3 & (1 << rank);
			}
			break;
		case 4:	/* 4 Ranks */
			/*
			 * DDR3 Read, DDR2 Read/Write:
			 * ----------+-----------------------+
			 *           |         ODT           |
			 *           +-----------------------+
			 *   Rank    |  3  |  2  |  1  |  0  |
			 * ----------+-----+-----+-----+-----+
			 *     0     |  0  |  1  |  0  |  0  |
			 *     1     |  1  |  0  |  0  |  0  |
			 *     2     |  0  |  0  |  0  |  1  |
			 *     3     |  0  |  0  |  1  |  0  |
			 * ----------+-----+-----+-----+-----+
			 *
			 * DDR3 Write:
			 * ----------+-----------------------+
			 *           |         ODT           |
			 * Write To  +-----------------------+
			 *   Rank    |  3  |  2  |  1  |  0  |
			 * ----------+-----+-----+-----+-----+
			 *     0     |  0  |  1  |  0  |  1  |
			 *     1     |  1  |  0  |  1  |  0  |
			 *     2     |  0  |  1  |  0  |  1  |
			 *     3     |  1  |  0  |  1  |  0  |
			 * ----------+-----+-----+-----+-----+
			 */
			switch (rank) {
			case 0:
				odt_mask_0 = 0x4;
				if (dram_is_ddr(2))
					odt_mask_1 = 0x4;
				else if (dram_is_ddr(3))
					odt_mask_1 = 0x5;
				break;
			case 1:
				odt_mask_0 = 0x8;
				if (dram_is_ddr(2))
					odt_mask_1 = 0x8;
				else if (dram_is_ddr(3))
					odt_mask_1 = 0xA;
				break;
			case 2:
				odt_mask_0 = 0x1;
				if (dram_is_ddr(2))
					odt_mask_1 = 0x1;
				else if (dram_is_ddr(3))
					odt_mask_1 = 0x5;
				break;
			case 3:
				odt_mask_0 = 0x2;
				if (dram_is_ddr(2))
					odt_mask_1 = 0x2;
				else if (dram_is_ddr(3))
					odt_mask_1 = 0xA;
				break;
			}
			break;
		}
	}

	cs_and_odt_mask = (0xFF & ~(1 << rank)) |
			  ((0xFF & odt_mask_0) << 8) |
			  ((0xFF & odt_mask_1) << 16);
	writel(cs_and_odt_mask, SDR_PHYGRP_RWMGRGRP_ADDRESS |
				RW_MGR_SET_CS_AND_ODT_MASK_OFFSET);
}

/**
 * scc_mgr_set() - Set SCC Manager register
 * @off:	Base offset in SCC Manager space
 * @grp:	Read/Write group
 * @val:	Value to be set
 *
 * This function sets the SCC Manager (Scan Chain Control Manager) register.
 */
static void scc_mgr_set(u32 off, u32 grp, u32 val)
{
	writel(val, SDR_PHYGRP_SCCGRP_ADDRESS | off | (grp << 2));
}

/**
 * scc_mgr_initialize() - Initialize SCC Manager registers
 *
 * Initialize SCC Manager registers.
 */
static void scc_mgr_initialize(void)
{
	/*
	 * Clear register file for HPS. 16 (2^4) is the size of the
	 * full register file in the scc mgr:
	 *	RFILE_DEPTH = 1 + log2(MEM_DQ_PER_DQS + 1 + MEM_DM_PER_DQS +
	 *                             MEM_IF_READ_DQS_WIDTH - 1);
	 */
	int i;

	for (i = 0; i < 16; i++) {
		debug_cond(DLEVEL >= 1, "%s:%d: Clearing SCC RFILE index %u\n",
			   __func__, __LINE__, i);
		scc_mgr_set(SCC_MGR_HHP_RFILE_OFFSET, i, 0);
	}
}

static void scc_mgr_set_dqdqs_output_phase(u32 write_group, u32 phase)
{
	scc_mgr_set(SCC_MGR_DQDQS_OUT_PHASE_OFFSET, write_group, phase);
}

static void scc_mgr_set_dqs_bus_in_delay(u32 read_group, u32 delay)
{
	scc_mgr_set(SCC_MGR_DQS_IN_DELAY_OFFSET, read_group, delay);
}

static void scc_mgr_set_dqs_en_phase(u32 read_group, u32 phase)
{
	scc_mgr_set(SCC_MGR_DQS_EN_PHASE_OFFSET, read_group, phase);
}

static void scc_mgr_set_dqs_en_delay(u32 read_group, u32 delay)
{
	scc_mgr_set(SCC_MGR_DQS_EN_DELAY_OFFSET, read_group, delay);
}

static void scc_mgr_set_dq_in_delay(u32 dq_in_group, u32 delay)
{
	scc_mgr_set(SCC_MGR_IO_IN_DELAY_OFFSET, dq_in_group, delay);
}

static void scc_mgr_set_dqs_io_in_delay(struct socfpga_sdrseq *seq,
					u32 delay)
{
	scc_mgr_set(SCC_MGR_IO_IN_DELAY_OFFSET,
		    seq->rwcfg->mem_dq_per_write_dqs, delay);
}

static void scc_mgr_set_dm_in_delay(struct socfpga_sdrseq *seq, u32 dm,
				    u32 delay)
{
	scc_mgr_set(SCC_MGR_IO_IN_DELAY_OFFSET,
		    seq->rwcfg->mem_dq_per_write_dqs + 1 + dm,
		    delay);
}

static void scc_mgr_set_dq_out1_delay(u32 dq_in_group, u32 delay)
{
	scc_mgr_set(SCC_MGR_IO_OUT1_DELAY_OFFSET, dq_in_group, delay);
}

static void scc_mgr_set_dqs_out1_delay(struct socfpga_sdrseq *seq,
				       u32 delay)
{
	scc_mgr_set(SCC_MGR_IO_OUT1_DELAY_OFFSET,
		    seq->rwcfg->mem_dq_per_write_dqs, delay);
}

static void scc_mgr_set_dm_out1_delay(struct socfpga_sdrseq *seq, u32 dm,
				      u32 delay)
{
	scc_mgr_set(SCC_MGR_IO_OUT1_DELAY_OFFSET,
		    seq->rwcfg->mem_dq_per_write_dqs + 1 + dm,
		    delay);
}

/* load up dqs config settings */
static void scc_mgr_load_dqs(u32 dqs)
{
	writel(dqs, &sdr_scc_mgr->dqs_ena);
}

/* load up dqs io config settings */
static void scc_mgr_load_dqs_io(void)
{
	writel(0, &sdr_scc_mgr->dqs_io_ena);
}

/* load up dq config settings */
static void scc_mgr_load_dq(u32 dq_in_group)
{
	writel(dq_in_group, &sdr_scc_mgr->dq_ena);
}

/* load up dm config settings */
static void scc_mgr_load_dm(u32 dm)
{
	writel(dm, &sdr_scc_mgr->dm_ena);
}

/**
 * scc_mgr_set_all_ranks() - Set SCC Manager register for all ranks
 * @off:	Base offset in SCC Manager space
 * @grp:	Read/Write group
 * @val:	Value to be set
 * @update:	If non-zero, trigger SCC Manager update for all ranks
 *
 * This function sets the SCC Manager (Scan Chain Control Manager) register
 * and optionally triggers the SCC update for all ranks.
 */
static void scc_mgr_set_all_ranks(struct socfpga_sdrseq *seq,
				  const u32 off, const u32 grp, const u32 val,
				  const int update)
{
	u32 r;

	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
	     r += NUM_RANKS_PER_SHADOW_REG) {
		scc_mgr_set(off, grp, val);

		if (update || (r == 0)) {
			writel(grp, &sdr_scc_mgr->dqs_ena);
			writel(0, &sdr_scc_mgr->update);
		}
	}
}

static void scc_mgr_set_dqs_en_phase_all_ranks(struct socfpga_sdrseq *seq,
					       u32 read_group, u32 phase)
{
	/*
	 * USER although the h/w doesn't support different phases per
	 * shadow register, for simplicity our scc manager modeling
	 * keeps different phase settings per shadow reg, and it's
	 * important for us to keep them in sync to match h/w.
	 * for efficiency, the scan chain update should occur only
	 * once to sr0.
	 */
	scc_mgr_set_all_ranks(seq, SCC_MGR_DQS_EN_PHASE_OFFSET,
			      read_group, phase, 0);
}

static void scc_mgr_set_dqdqs_output_phase_all_ranks(struct socfpga_sdrseq *seq,
						     u32 write_group, u32 phase)
{
	/*
	 * USER although the h/w doesn't support different phases per
	 * shadow register, for simplicity our scc manager modeling
	 * keeps different phase settings per shadow reg, and it's
	 * important for us to keep them in sync to match h/w.
	 * for efficiency, the scan chain update should occur only
	 * once to sr0.
	 */
	scc_mgr_set_all_ranks(seq, SCC_MGR_DQDQS_OUT_PHASE_OFFSET,
			      write_group, phase, 0);
}

static void scc_mgr_set_dqs_en_delay_all_ranks(struct socfpga_sdrseq *seq,
					       u32 read_group, u32 delay)
{
	/*
	 * In shadow register mode, the T11 settings are stored in
	 * registers in the core, which are updated by the DQS_ENA
	 * signals. Not issuing the SCC_MGR_UPD command allows us to
	 * save lots of rank switching overhead, by calling
	 * select_shadow_regs_for_update with update_scan_chains
	 * set to 0.
	 */
	scc_mgr_set_all_ranks(seq, SCC_MGR_DQS_EN_DELAY_OFFSET,
			      read_group, delay, 1);
}

/**
 * scc_mgr_set_oct_out1_delay() - Set OCT output delay
 * @write_group:	Write group
 * @delay:		Delay value
 *
 * This function sets the OCT output delay in SCC manager.
 */
static void scc_mgr_set_oct_out1_delay(struct socfpga_sdrseq *seq,
				       const u32 write_group, const u32 delay)
{
	const int ratio = seq->rwcfg->mem_if_read_dqs_width /
			 seq->rwcfg->mem_if_write_dqs_width;
	const int base = write_group * ratio;
	int i;
	/*
	 * Load the setting in the SCC manager
	 * Although OCT affects only write data, the OCT delay is controlled
	 * by the DQS logic block which is instantiated once per read group.
	 * For protocols where a write group consists of multiple read groups,
	 * the setting must be set multiple times.
	 */
	for (i = 0; i < ratio; i++)
		scc_mgr_set(SCC_MGR_OCT_OUT1_DELAY_OFFSET, base + i, delay);
}

/**
 * scc_mgr_set_hhp_extras() - Set HHP extras.
 *
 * Load the fixed setting in the SCC manager HHP extras.
 */
static void scc_mgr_set_hhp_extras(void)
{
	/*
	 * Load the fixed setting in the SCC manager
	 * bits: 0:0 = 1'b1	- DQS bypass
	 * bits: 1:1 = 1'b1	- DQ bypass
	 * bits: 4:2 = 3'b001	- rfifo_mode
	 * bits: 6:5 = 2'b01	- rfifo clock_select
	 * bits: 7:7 = 1'b0	- separate gating from ungating setting
	 * bits: 8:8 = 1'b0	- separate OE from Output delay setting
	 */
	const u32 value = (0 << 8) | (0 << 7) | (1 << 5) |
			  (1 << 2) | (1 << 1) | (1 << 0);
	const u32 addr = SDR_PHYGRP_SCCGRP_ADDRESS |
			 SCC_MGR_HHP_GLOBALS_OFFSET |
			 SCC_MGR_HHP_EXTRAS_OFFSET;

	debug_cond(DLEVEL >= 1, "%s:%d Setting HHP Extras\n",
		   __func__, __LINE__);
	writel(value, addr);
	debug_cond(DLEVEL >= 1, "%s:%d Done Setting HHP Extras\n",
		   __func__, __LINE__);
}

/**
 * scc_mgr_zero_all() - Zero all DQS config
 *
 * Zero all DQS config.
 */
static void scc_mgr_zero_all(struct socfpga_sdrseq *seq)
{
	int i, r;

	/*
	 * USER Zero all DQS config settings, across all groups and all
	 * shadow registers
	 */
	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
	     r += NUM_RANKS_PER_SHADOW_REG) {
		for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
			/*
			 * The phases actually don't exist on a per-rank basis,
			 * but there's no harm updating them several times, so
			 * let's keep the code simple.
			 */
			scc_mgr_set_dqs_bus_in_delay(i,
						     seq->iocfg->dqs_in_reserve
						     );
			scc_mgr_set_dqs_en_phase(i, 0);
			scc_mgr_set_dqs_en_delay(i, 0);
		}

		for (i = 0; i < seq->rwcfg->mem_if_write_dqs_width; i++) {
			scc_mgr_set_dqdqs_output_phase(i, 0);
			/* Arria V/Cyclone V don't have out2. */
			scc_mgr_set_oct_out1_delay(seq, i,
						   seq->iocfg->dqs_out_reserve);
		}
	}

	/* Multicast to all DQS group enables. */
	writel(0xff, &sdr_scc_mgr->dqs_ena);
	writel(0, &sdr_scc_mgr->update);
}

/**
 * scc_set_bypass_mode() - Set bypass mode and trigger SCC update
 * @write_group:	Write group
 *
 * Set bypass mode and trigger SCC update.
 */
static void scc_set_bypass_mode(const u32 write_group)
{
	/* Multicast to all DQ enables. */
	writel(0xff, &sdr_scc_mgr->dq_ena);
	writel(0xff, &sdr_scc_mgr->dm_ena);

	/* Update current DQS IO enable. */
	writel(0, &sdr_scc_mgr->dqs_io_ena);

	/* Update the DQS logic. */
	writel(write_group, &sdr_scc_mgr->dqs_ena);

	/* Hit update. */
	writel(0, &sdr_scc_mgr->update);
}

/**
 * scc_mgr_load_dqs_for_write_group() - Load DQS settings for Write Group
 * @write_group:	Write group
 *
 * Load DQS settings for Write Group, do not trigger SCC update.
 */
static void scc_mgr_load_dqs_for_write_group(struct socfpga_sdrseq *seq,
					     const u32 write_group)
{
	const int ratio = seq->rwcfg->mem_if_read_dqs_width /
			  seq->rwcfg->mem_if_write_dqs_width;
	const int base = write_group * ratio;
	int i;
	/*
	 * Load the setting in the SCC manager
	 * Although OCT affects only write data, the OCT delay is controlled
	 * by the DQS logic block which is instantiated once per read group.
	 * For protocols where a write group consists of multiple read groups,
	 * the setting must be set multiple times.
	 */
	for (i = 0; i < ratio; i++)
		writel(base + i, &sdr_scc_mgr->dqs_ena);
}

/**
 * scc_mgr_zero_group() - Zero all configs for a group
 *
 * Zero DQ, DM, DQS and OCT configs for a group.
 */
static void scc_mgr_zero_group(struct socfpga_sdrseq *seq,
			       const u32 write_group, const int out_only)
{
	int i, r;

	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
	     r += NUM_RANKS_PER_SHADOW_REG) {
		/* Zero all DQ config settings. */
		for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++) {
			scc_mgr_set_dq_out1_delay(i, 0);
			if (!out_only)
				scc_mgr_set_dq_in_delay(i, 0);
		}

		/* Multicast to all DQ enables. */
		writel(0xff, &sdr_scc_mgr->dq_ena);

		/* Zero all DM config settings. */
		for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++) {
			if (!out_only)
				scc_mgr_set_dm_in_delay(seq, i, 0);
			scc_mgr_set_dm_out1_delay(seq, i, 0);
		}

		/* Multicast to all DM enables. */
		writel(0xff, &sdr_scc_mgr->dm_ena);

		/* Zero all DQS IO settings. */
		if (!out_only)
			scc_mgr_set_dqs_io_in_delay(seq, 0);

		/* Arria V/Cyclone V don't have out2. */
		scc_mgr_set_dqs_out1_delay(seq, seq->iocfg->dqs_out_reserve);
		scc_mgr_set_oct_out1_delay(seq, write_group,
					   seq->iocfg->dqs_out_reserve);
		scc_mgr_load_dqs_for_write_group(seq, write_group);

		/* Multicast to all DQS IO enables (only 1 in total). */
		writel(0, &sdr_scc_mgr->dqs_io_ena);

		/* Hit update to zero everything. */
		writel(0, &sdr_scc_mgr->update);
	}
}

/*
 * apply and load a particular input delay for the DQ pins in a group
 * group_bgn is the index of the first dq pin (in the write group)
 */
static void scc_mgr_apply_group_dq_in_delay(struct socfpga_sdrseq *seq,
					    u32 group_bgn, u32 delay)
{
	u32 i, p;

	for (i = 0, p = group_bgn; i < seq->rwcfg->mem_dq_per_read_dqs;
	     i++, p++) {
		scc_mgr_set_dq_in_delay(p, delay);
		scc_mgr_load_dq(p);
	}
}

/**
 * scc_mgr_apply_group_dq_out1_delay() - Apply and load an output delay for the
 * DQ pins in a group
 * @delay:		Delay value
 *
 * Apply and load a particular output delay for the DQ pins in a group.
 */
static void scc_mgr_apply_group_dq_out1_delay(struct socfpga_sdrseq *seq,
					      const u32 delay)
{
	int i;

	for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++) {
		scc_mgr_set_dq_out1_delay(i, delay);
		scc_mgr_load_dq(i);
	}
}

/* apply and load a particular output delay for the DM pins in a group */
static void scc_mgr_apply_group_dm_out1_delay(struct socfpga_sdrseq *seq,
					      u32 delay1)
{
	u32 i;

	for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++) {
		scc_mgr_set_dm_out1_delay(seq, i, delay1);
		scc_mgr_load_dm(i);
	}
}


/* apply and load delay on both DQS and OCT out1 */
static void scc_mgr_apply_group_dqs_io_and_oct_out1(struct socfpga_sdrseq *seq,
						    u32 write_group, u32 delay)
{
	scc_mgr_set_dqs_out1_delay(seq, delay);
	scc_mgr_load_dqs_io();

	scc_mgr_set_oct_out1_delay(seq, write_group, delay);
	scc_mgr_load_dqs_for_write_group(seq, write_group);
}

/**
 * scc_mgr_apply_group_all_out_delay_add() - Apply a delay to the entire output
 * side: DQ, DM, DQS, OCT
 * @write_group:	Write group
 * @delay:		Delay value
 *
 * Apply a delay to the entire output side: DQ, DM, DQS, OCT.
 */
static void scc_mgr_apply_group_all_out_delay_add(struct socfpga_sdrseq *seq,
						  const u32 write_group,
						  const u32 delay)
{
	u32 i, new_delay;

	/* DQ shift */
	for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++)
		scc_mgr_load_dq(i);

	/* DM shift */
	for (i = 0; i < RW_MGR_NUM_DM_PER_WRITE_GROUP; i++)
		scc_mgr_load_dm(i);

	/* DQS shift */
	new_delay = READ_SCC_DQS_IO_OUT2_DELAY + delay;
	if (new_delay > seq->iocfg->io_out2_delay_max) {
		debug_cond(DLEVEL >= 1,
			   "%s:%d (%u, %u) DQS: %u > %d; adding %u to OUT1\n",
			   __func__, __LINE__, write_group, delay, new_delay,
			   seq->iocfg->io_out2_delay_max,
			   new_delay - seq->iocfg->io_out2_delay_max);
		new_delay -= seq->iocfg->io_out2_delay_max;
		scc_mgr_set_dqs_out1_delay(seq, new_delay);
	}

	scc_mgr_load_dqs_io();

	/* OCT shift */
	new_delay = READ_SCC_OCT_OUT2_DELAY + delay;
	if (new_delay > seq->iocfg->io_out2_delay_max) {
		debug_cond(DLEVEL >= 1,
			   "%s:%d (%u, %u) DQS: %u > %d; adding %u to OUT1\n",
			   __func__, __LINE__, write_group, delay,
			   new_delay, seq->iocfg->io_out2_delay_max,
			   new_delay - seq->iocfg->io_out2_delay_max);
		new_delay -= seq->iocfg->io_out2_delay_max;
		scc_mgr_set_oct_out1_delay(seq, write_group, new_delay);
	}

	scc_mgr_load_dqs_for_write_group(seq, write_group);
}

/**
 * scc_mgr_apply_group_all_out_delay_add() - Apply a delay to the entire output
 * side to all ranks
 * @write_group:	Write group
 * @delay:		Delay value
 *
 * Apply a delay to the entire output side (DQ, DM, DQS, OCT) to all ranks.
 */
static void
scc_mgr_apply_group_all_out_delay_add_all_ranks(struct socfpga_sdrseq *seq,
						const u32 write_group,
						const u32 delay)
{
	int r;

	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
	     r += NUM_RANKS_PER_SHADOW_REG) {
		scc_mgr_apply_group_all_out_delay_add(seq, write_group, delay);
		writel(0, &sdr_scc_mgr->update);
	}
}

/**
 * set_jump_as_return() - Return instruction optimization
 *
 * Optimization used to recover some slots in ddr3 inst_rom could be
 * applied to other protocols if we wanted to
 */
static void set_jump_as_return(struct socfpga_sdrseq *seq)
{
	/*
	 * To save space, we replace return with jump to special shared
	 * RETURN instruction so we set the counter to large value so that
	 * we always jump.
	 */
	writel(0xff, &sdr_rw_load_mgr_regs->load_cntr0);
	writel(seq->rwcfg->rreturn, &sdr_rw_load_jump_mgr_regs->load_jump_add0);
}

/**
 * delay_for_n_mem_clocks() - Delay for N memory clocks
 * @clocks:	Length of the delay
 *
 * Delay for N memory clocks.
 */
static void delay_for_n_mem_clocks(struct socfpga_sdrseq *seq,
				   const u32 clocks)
{
	u32 afi_clocks;
	u16 c_loop;
	u8 inner;
	u8 outer;

	debug("%s:%d: clocks=%u ... start\n", __func__, __LINE__, clocks);

	/* Scale (rounding up) to get afi clocks. */
	afi_clocks = DIV_ROUND_UP(clocks, seq->misccfg->afi_rate_ratio);
	if (afi_clocks)	/* Temporary underflow protection */
		afi_clocks--;

	/*
	 * Note, we don't bother accounting for being off a little
	 * bit because of a few extra instructions in outer loops.
	 * Note, the loops have a test at the end, and do the test
	 * before the decrement, and so always perform the loop
	 * 1 time more than the counter value
	 */
	c_loop = afi_clocks >> 16;
	outer = c_loop ? 0xff : (afi_clocks >> 8);
	inner = outer ? 0xff : afi_clocks;

	/*
	 * rom instructions are structured as follows:
	 *
	 *    IDLE_LOOP2: jnz cntr0, TARGET_A
	 *    IDLE_LOOP1: jnz cntr1, TARGET_B
	 *                return
	 *
	 * so, when doing nested loops, TARGET_A is set to IDLE_LOOP2, and
	 * TARGET_B is set to IDLE_LOOP2 as well
	 *
	 * if we have no outer loop, though, then we can use IDLE_LOOP1 only,
	 * and set TARGET_B to IDLE_LOOP1 and we skip IDLE_LOOP2 entirely
	 *
	 * a little confusing, but it helps save precious space in the inst_rom
	 * and sequencer rom and keeps the delays more accurate and reduces
	 * overhead
	 */
	if (afi_clocks < 0x100) {
		writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(inner),
		       &sdr_rw_load_mgr_regs->load_cntr1);

		writel(seq->rwcfg->idle_loop1,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);

		writel(seq->rwcfg->idle_loop1, SDR_PHYGRP_RWMGRGRP_ADDRESS |
					  RW_MGR_RUN_SINGLE_GROUP_OFFSET);
	} else {
		writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(inner),
		       &sdr_rw_load_mgr_regs->load_cntr0);

		writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(outer),
		       &sdr_rw_load_mgr_regs->load_cntr1);

		writel(seq->rwcfg->idle_loop2,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);

		writel(seq->rwcfg->idle_loop2,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);

		do {
			writel(seq->rwcfg->idle_loop2,
			       SDR_PHYGRP_RWMGRGRP_ADDRESS |
			       RW_MGR_RUN_SINGLE_GROUP_OFFSET);
		} while (c_loop-- != 0);
	}
	debug("%s:%d clocks=%u ... end\n", __func__, __LINE__, clocks);
}

static void delay_for_n_ns(struct socfpga_sdrseq *seq, const u32 ns)
{
	delay_for_n_mem_clocks(seq, (ns * seq->misccfg->afi_clk_freq *
				seq->misccfg->afi_rate_ratio) / 1000);
}

/**
 * rw_mgr_mem_init_load_regs() - Load instruction registers
 * @cntr0:	Counter 0 value
 * @cntr1:	Counter 1 value
 * @cntr2:	Counter 2 value
 * @jump:	Jump instruction value
 *
 * Load instruction registers.
 */
static void rw_mgr_mem_init_load_regs(struct socfpga_sdrseq *seq,
				      u32 cntr0, u32 cntr1, u32 cntr2, u32 jump)
{
	u32 grpaddr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
			   RW_MGR_RUN_SINGLE_GROUP_OFFSET;

	/* Load counters */
	writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(cntr0),
	       &sdr_rw_load_mgr_regs->load_cntr0);
	writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(cntr1),
	       &sdr_rw_load_mgr_regs->load_cntr1);
	writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(cntr2),
	       &sdr_rw_load_mgr_regs->load_cntr2);

	/* Load jump address */
	writel(jump, &sdr_rw_load_jump_mgr_regs->load_jump_add0);
	writel(jump, &sdr_rw_load_jump_mgr_regs->load_jump_add1);
	writel(jump, &sdr_rw_load_jump_mgr_regs->load_jump_add2);

	/* Execute count instruction */
	writel(jump, grpaddr);
}

/**
 * rw_mgr_mem_load_user_ddr2() - Load user calibration values for DDR2
 * @handoff:	Indicate whether this is initialization or handoff phase
 *
 * Load user calibration values and optionally precharge the banks.
 */
static void rw_mgr_mem_load_user_ddr2(struct socfpga_sdrseq *seq,
				      const int handoff)
{
	u32 grpaddr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
		      RW_MGR_RUN_SINGLE_GROUP_OFFSET;
	u32 r;

	for (r = 0; r < seq->rwcfg->mem_number_of_ranks; r++) {
		/* set rank */
		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_OFF);

		/* precharge all banks ... */
		writel(seq->rwcfg->precharge_all, grpaddr);

		writel(seq->rwcfg->emr2, grpaddr);
		writel(seq->rwcfg->emr3, grpaddr);
		writel(seq->rwcfg->emr, grpaddr);

		if (handoff) {
			writel(seq->rwcfg->mr_user, grpaddr);
			continue;
		}

		writel(seq->rwcfg->mr_dll_reset, grpaddr);

		writel(seq->rwcfg->precharge_all, grpaddr);

		writel(seq->rwcfg->refresh, grpaddr);
		delay_for_n_ns(seq, 200);
		writel(seq->rwcfg->refresh, grpaddr);
		delay_for_n_ns(seq, 200);

		writel(seq->rwcfg->mr_calib, grpaddr);
		writel(/*seq->rwcfg->*/0x0b, grpaddr);	// EMR_OCD_ENABLE
		writel(seq->rwcfg->emr, grpaddr);
		delay_for_n_mem_clocks(seq, 200);
	}
}

/**
 * rw_mgr_mem_load_user_ddr3() - Load user calibration values
 * @fin1:	Final instruction 1
 * @fin2:	Final instruction 2
 * @precharge:	If 1, precharge the banks at the end
 *
 * Load user calibration values and optionally precharge the banks.
 */
static void rw_mgr_mem_load_user_ddr3(struct socfpga_sdrseq *seq,
				 const u32 fin1, const u32 fin2,
				 const int precharge)
{
	u32 grpaddr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
		      RW_MGR_RUN_SINGLE_GROUP_OFFSET;
	u32 r;

	for (r = 0; r < seq->rwcfg->mem_number_of_ranks; r++) {
		/* set rank */
		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_OFF);

		/* precharge all banks ... */
		if (precharge)
			writel(seq->rwcfg->precharge_all, grpaddr);

		/*
		 * USER Use Mirror-ed commands for odd ranks if address
		 * mirrorring is on
		 */
		if ((seq->rwcfg->mem_address_mirroring >> r) & 0x1) {
			set_jump_as_return(seq);
			writel(seq->rwcfg->mrs2_mirr, grpaddr);
			delay_for_n_mem_clocks(seq, 4);
			set_jump_as_return(seq);
			writel(seq->rwcfg->mrs3_mirr, grpaddr);
			delay_for_n_mem_clocks(seq, 4);
			set_jump_as_return(seq);
			writel(seq->rwcfg->mrs1_mirr, grpaddr);
			delay_for_n_mem_clocks(seq, 4);
			set_jump_as_return(seq);
			writel(fin1, grpaddr);
		} else {
			set_jump_as_return(seq);
			writel(seq->rwcfg->mrs2, grpaddr);
			delay_for_n_mem_clocks(seq, 4);
			set_jump_as_return(seq);
			writel(seq->rwcfg->mrs3, grpaddr);
			delay_for_n_mem_clocks(seq, 4);
			set_jump_as_return(seq);
			writel(seq->rwcfg->mrs1, grpaddr);
			set_jump_as_return(seq);
			writel(fin2, grpaddr);
		}

		if (precharge)
			continue;

		set_jump_as_return(seq);
		writel(seq->rwcfg->zqcl, grpaddr);

		/* tZQinit = tDLLK = 512 ck cycles */
		delay_for_n_mem_clocks(seq, 512);
	}
}

/**
 * rw_mgr_mem_load_user() - Load user calibration values
 * @fin1:	Final instruction 1
 * @fin2:	Final instruction 2
 * @precharge:	If 1, precharge the banks at the end
 *
 * Load user calibration values and optionally precharge the banks.
 */
static void rw_mgr_mem_load_user(struct socfpga_sdrseq *seq,
				 const u32 fin1, const u32 fin2,
				 const int precharge)
{
	if (dram_is_ddr(2))
		rw_mgr_mem_load_user_ddr2(seq, precharge);
	else if (dram_is_ddr(3))
		rw_mgr_mem_load_user_ddr3(seq, fin1, fin2, precharge);
	else
		hang();
}
/**
 * rw_mgr_mem_initialize() - Initialize RW Manager
 *
 * Initialize RW Manager.
 */
static void rw_mgr_mem_initialize(struct socfpga_sdrseq *seq)
{
	debug("%s:%d\n", __func__, __LINE__);

	/* The reset / cke part of initialization is broadcasted to all ranks */
	if (dram_is_ddr(3)) {
		writel(RW_MGR_RANK_ALL, SDR_PHYGRP_RWMGRGRP_ADDRESS |
					RW_MGR_SET_CS_AND_ODT_MASK_OFFSET);
	}

	/*
	 * Here's how you load register for a loop
	 * Counters are located @ 0x800
	 * Jump address are located @ 0xC00
	 * For both, registers 0 to 3 are selected using bits 3 and 2, like
	 * in 0x800, 0x804, 0x808, 0x80C and 0xC00, 0xC04, 0xC08, 0xC0C
	 * I know this ain't pretty, but Avalon bus throws away the 2 least
	 * significant bits
	 */

	/* Start with memory RESET activated */

	/* tINIT = 200us */

	/*
	 * 200us @ 266MHz (3.75 ns) ~ 54000 clock cycles
	 * If a and b are the number of iteration in 2 nested loops
	 * it takes the following number of cycles to complete the operation:
	 * number_of_cycles = ((2 + n) * a + 2) * b
	 * where n is the number of instruction in the inner loop
	 * One possible solution is n = 0 , a = 256 , b = 106 => a = FF,
	 * b = 6A
	 */
	rw_mgr_mem_init_load_regs(seq, seq->misccfg->tinit_cntr0_val,
				  seq->misccfg->tinit_cntr1_val,
				  seq->misccfg->tinit_cntr2_val,
				  seq->rwcfg->init_reset_0_cke_0);

	/* Indicate that memory is stable. */
	writel(1, &phy_mgr_cfg->reset_mem_stbl);

	if (dram_is_ddr(2)) {
		writel(seq->rwcfg->nop, SDR_PHYGRP_RWMGRGRP_ADDRESS |
					RW_MGR_RUN_SINGLE_GROUP_OFFSET);

		/* Bring up clock enable. */

		/* tXRP < 400 ck cycles */
		delay_for_n_ns(seq, 400);
	} else if (dram_is_ddr(3)) {
		/*
		 * transition the RESET to high
		 * Wait for 500us
		 */

		/*
		 * 500us @ 266MHz (3.75 ns) ~ 134000 clock cycles
		 * If a and b are the number of iteration in 2 nested loops
		 * it takes the following number of cycles to complete the
		 * operation number_of_cycles = ((2 + n) * a + 2) * b
		 * where n is the number of instruction in the inner loop
		 * One possible solution is
		 * n = 2 , a = 131 , b = 256 => a = 83, b = FF
		 */
		rw_mgr_mem_init_load_regs(seq, seq->misccfg->treset_cntr0_val,
					  seq->misccfg->treset_cntr1_val,
					  seq->misccfg->treset_cntr2_val,
					  seq->rwcfg->init_reset_1_cke_0);
		/* Bring up clock enable. */

		/* tXRP < 250 ck cycles */
		delay_for_n_mem_clocks(seq, 250);
	}

	rw_mgr_mem_load_user(seq, seq->rwcfg->mrs0_dll_reset_mirr,
			     seq->rwcfg->mrs0_dll_reset, 0);
}

/**
 * rw_mgr_mem_handoff() - Hand off the memory to user
 *
 * At the end of calibration we have to program the user settings in
 * and hand off the memory to the user.
 */
static void rw_mgr_mem_handoff(struct socfpga_sdrseq *seq)
{
	rw_mgr_mem_load_user(seq, seq->rwcfg->mrs0_user_mirr,
			     seq->rwcfg->mrs0_user, 1);
	/*
	 * Need to wait tMOD (12CK or 15ns) time before issuing other
	 * commands, but we will have plenty of NIOS cycles before actual
	 * handoff so its okay.
	 */
}

/**
 * rw_mgr_mem_calibrate_write_test_issue() - Issue write test command
 * @group:	Write Group
 * @use_dm:	Use DM
 *
 * Issue write test command. Two variants are provided, one that just tests
 * a write pattern and another that tests datamask functionality.
 */
static void rw_mgr_mem_calibrate_write_test_issue(struct socfpga_sdrseq *seq,
						  u32 group, u32 test_dm)
{
	const u32 quick_write_mode =
		(STATIC_CALIB_STEPS & CALIB_SKIP_WRITES) &&
		seq->misccfg->enable_super_quick_calibration;
	u32 mcc_instruction;
	u32 rw_wl_nop_cycles;

	/*
	 * Set counter and jump addresses for the right
	 * number of NOP cycles.
	 * The number of supported NOP cycles can range from -1 to infinity
	 * Three different cases are handled:
	 *
	 * 1. For a number of NOP cycles greater than 0, the RW Mgr looping
	 *    mechanism will be used to insert the right number of NOPs
	 *
	 * 2. For a number of NOP cycles equals to 0, the micro-instruction
	 *    issuing the write command will jump straight to the
	 *    micro-instruction that turns on DQS (for DDRx), or outputs write
	 *    data (for RLD), skipping
	 *    the NOP micro-instruction all together
	 *
	 * 3. A number of NOP cycles equal to -1 indicates that DQS must be
	 *    turned on in the same micro-instruction that issues the write
	 *    command. Then we need
	 *    to directly jump to the micro-instruction that sends out the data
	 *
	 * NOTE: Implementing this mechanism uses 2 RW Mgr jump-counters
	 *       (2 and 3). One jump-counter (0) is used to perform multiple
	 *       write-read operations.
	 *       one counter left to issue this command in "multiple-group" mode
	 */

	rw_wl_nop_cycles = seq->gbl.rw_wl_nop_cycles;

	if (rw_wl_nop_cycles == -1) {
		/*
		 * CNTR 2 - We want to execute the special write operation that
		 * turns on DQS right away and then skip directly to the
		 * instruction that sends out the data. We set the counter to a
		 * large number so that the jump is always taken.
		 */
		writel(0xFF, &sdr_rw_load_mgr_regs->load_cntr2);

		/* CNTR 3 - Not used */
		if (test_dm) {
			mcc_instruction = seq->rwcfg->lfsr_wr_rd_dm_bank_0_wl_1;
			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_data,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_nop,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
		} else {
			mcc_instruction = seq->rwcfg->lfsr_wr_rd_bank_0_wl_1;
			writel(seq->rwcfg->lfsr_wr_rd_bank_0_data,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
			writel(seq->rwcfg->lfsr_wr_rd_bank_0_nop,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
		}
	} else if (rw_wl_nop_cycles == 0) {
		/*
		 * CNTR 2 - We want to skip the NOP operation and go straight
		 * to the DQS enable instruction. We set the counter to a large
		 * number so that the jump is always taken.
		 */
		writel(0xFF, &sdr_rw_load_mgr_regs->load_cntr2);

		/* CNTR 3 - Not used */
		if (test_dm) {
			mcc_instruction = seq->rwcfg->lfsr_wr_rd_dm_bank_0;
			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_dqs,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
		} else {
			mcc_instruction = seq->rwcfg->lfsr_wr_rd_bank_0;
			writel(seq->rwcfg->lfsr_wr_rd_bank_0_dqs,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
		}
	} else {
		/*
		 * CNTR 2 - In this case we want to execute the next instruction
		 * and NOT take the jump. So we set the counter to 0. The jump
		 * address doesn't count.
		 */
		writel(0x0, &sdr_rw_load_mgr_regs->load_cntr2);
		writel(0x0, &sdr_rw_load_jump_mgr_regs->load_jump_add2);

		/*
		 * CNTR 3 - Set the nop counter to the number of cycles we
		 * need to loop for, minus 1.
		 */
		writel(rw_wl_nop_cycles - 1, &sdr_rw_load_mgr_regs->load_cntr3);
		if (test_dm) {
			mcc_instruction = seq->rwcfg->lfsr_wr_rd_dm_bank_0;
			writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_nop,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
		} else {
			mcc_instruction = seq->rwcfg->lfsr_wr_rd_bank_0;
			writel(seq->rwcfg->lfsr_wr_rd_bank_0_nop,
			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
		}
	}

	writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
		  RW_MGR_RESET_READ_DATAPATH_OFFSET);

	if (quick_write_mode)
		writel(0x08, &sdr_rw_load_mgr_regs->load_cntr0);
	else
		writel(0x40, &sdr_rw_load_mgr_regs->load_cntr0);

	writel(mcc_instruction, &sdr_rw_load_jump_mgr_regs->load_jump_add0);

	/*
	 * CNTR 1 - This is used to ensure enough time elapses
	 * for read data to come back.
	 */
	writel(0x30, &sdr_rw_load_mgr_regs->load_cntr1);

	if (test_dm) {
		writel(seq->rwcfg->lfsr_wr_rd_dm_bank_0_wait,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
	} else {
		writel(seq->rwcfg->lfsr_wr_rd_bank_0_wait,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);
	}

	writel(mcc_instruction, (SDR_PHYGRP_RWMGRGRP_ADDRESS |
				RW_MGR_RUN_SINGLE_GROUP_OFFSET) +
				(group << 2));
}

/**
 * rw_mgr_mem_calibrate_write_test() - Test writes, check for single/multiple
 * pass
 * @rank_bgn:		Rank number
 * @write_group:	Write Group
 * @use_dm:		Use DM
 * @all_correct:	All bits must be correct in the mask
 * @bit_chk:		Resulting bit mask after the test
 * @all_ranks:		Test all ranks
 *
 * Test writes, can check for a single bit pass or multiple bit pass.
 */
static int
rw_mgr_mem_calibrate_write_test(struct socfpga_sdrseq *seq,
				const u32 rank_bgn, const u32 write_group,
				const u32 use_dm, const u32 all_correct,
				u32 *bit_chk, const u32 all_ranks)
{
	const u32 rank_end = all_ranks ?
				seq->rwcfg->mem_number_of_ranks :
				(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
	const u32 shift_ratio = seq->rwcfg->mem_dq_per_write_dqs /
				seq->rwcfg->mem_virtual_groups_per_write_dqs;
	const u32 correct_mask_vg = seq->param.write_correct_mask_vg;

	u32 tmp_bit_chk, base_rw_mgr, group;
	int vg, r;

	*bit_chk = seq->param.write_correct_mask;

	for (r = rank_bgn; r < rank_end; r++) {
		/* Set rank */
		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);

		tmp_bit_chk = 0;
		for (vg = seq->rwcfg->mem_virtual_groups_per_write_dqs - 1;
		     vg >= 0; vg--) {
			/* Reset the FIFOs to get pointers to known state. */
			writel(0, &phy_mgr_cmd->fifo_reset);

			group = write_group *
				seq->rwcfg->mem_virtual_groups_per_write_dqs
				+ vg;
			rw_mgr_mem_calibrate_write_test_issue(seq, group,
							      use_dm);

			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
			tmp_bit_chk <<= shift_ratio;
			tmp_bit_chk |= (correct_mask_vg & ~(base_rw_mgr));
		}

		*bit_chk &= tmp_bit_chk;
	}

	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);
	if (all_correct) {
		debug_cond(DLEVEL >= 2,
			   "write_test(%u,%u,ALL) : %u == %u => %i\n",
			   write_group, use_dm, *bit_chk,
			   seq->param.write_correct_mask,
			   *bit_chk == seq->param.write_correct_mask);
		return *bit_chk == seq->param.write_correct_mask;
	} else {
		debug_cond(DLEVEL >= 2,
			   "write_test(%u,%u,ONE) : %u != %i => %i\n",
			   write_group, use_dm, *bit_chk, 0, *bit_chk != 0);
		return *bit_chk != 0x00;
	}
}

/**
 * rw_mgr_mem_calibrate_read_test_patterns() - Read back test patterns
 * @rank_bgn:	Rank number
 * @group:	Read/Write Group
 * @all_ranks:	Test all ranks
 *
 * Performs a guaranteed read on the patterns we are going to use during a
 * read test to ensure memory works.
 */
static int
rw_mgr_mem_calibrate_read_test_patterns(struct socfpga_sdrseq *seq,
					const u32 rank_bgn, const u32 group,
					const u32 all_ranks)
{
	const u32 addr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
			 RW_MGR_RUN_SINGLE_GROUP_OFFSET;
	const u32 addr_offset =
			 (group * seq->rwcfg->mem_virtual_groups_per_read_dqs)
			 << 2;
	const u32 rank_end = all_ranks ?
				seq->rwcfg->mem_number_of_ranks :
				(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
	const u32 shift_ratio = seq->rwcfg->mem_dq_per_read_dqs /
				seq->rwcfg->mem_virtual_groups_per_read_dqs;
	const u32 correct_mask_vg = seq->param.read_correct_mask_vg;

	u32 tmp_bit_chk, base_rw_mgr, bit_chk;
	int vg, r;
	int ret = 0;

	bit_chk = seq->param.read_correct_mask;

	for (r = rank_bgn; r < rank_end; r++) {
		/* Set rank */
		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);

		/* Load up a constant bursts of read commands */
		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr0);
		writel(seq->rwcfg->guaranteed_read,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);

		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr1);
		writel(seq->rwcfg->guaranteed_read_cont,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);

		tmp_bit_chk = 0;
		for (vg = seq->rwcfg->mem_virtual_groups_per_read_dqs - 1;
		     vg >= 0; vg--) {
			/* Reset the FIFOs to get pointers to known state. */
			writel(0, &phy_mgr_cmd->fifo_reset);
			writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
				  RW_MGR_RESET_READ_DATAPATH_OFFSET);
			writel(seq->rwcfg->guaranteed_read,
			       addr + addr_offset + (vg << 2));

			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
			tmp_bit_chk <<= shift_ratio;
			tmp_bit_chk |= correct_mask_vg & ~base_rw_mgr;
		}

		bit_chk &= tmp_bit_chk;
	}

	writel(seq->rwcfg->clear_dqs_enable, addr + (group << 2));

	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);

	if (bit_chk != seq->param.read_correct_mask)
		ret = -EIO;

	debug_cond(DLEVEL >= 1,
		   "%s:%d test_load_patterns(%u,ALL) => (%u == %u) => %i\n",
		   __func__, __LINE__, group, bit_chk,
		   seq->param.read_correct_mask, ret);

	return ret;
}

/**
 * rw_mgr_mem_calibrate_read_load_patterns() - Load up the patterns for read
 * test
 * @rank_bgn:	Rank number
 * @all_ranks:	Test all ranks
 *
 * Load up the patterns we are going to use during a read test.
 */
static void rw_mgr_mem_calibrate_read_load_patterns(struct socfpga_sdrseq *seq,
						    const u32 rank_bgn,
						    const int all_ranks)
{
	const u32 rank_end = all_ranks ?
			seq->rwcfg->mem_number_of_ranks :
			(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
	u32 r;

	debug("%s:%d\n", __func__, __LINE__);

	for (r = rank_bgn; r < rank_end; r++) {
		/* set rank */
		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);

		/* Load up a constant bursts */
		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr0);

		writel(seq->rwcfg->guaranteed_write_wait0,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);

		writel(0x20, &sdr_rw_load_mgr_regs->load_cntr1);

		writel(seq->rwcfg->guaranteed_write_wait1,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);

		writel(0x04, &sdr_rw_load_mgr_regs->load_cntr2);

		writel(seq->rwcfg->guaranteed_write_wait2,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add2);

		writel(0x04, &sdr_rw_load_mgr_regs->load_cntr3);

		writel(seq->rwcfg->guaranteed_write_wait3,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add3);

		writel(seq->rwcfg->guaranteed_write,
		       SDR_PHYGRP_RWMGRGRP_ADDRESS |
		       RW_MGR_RUN_SINGLE_GROUP_OFFSET);
	}

	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);
}

/**
 * rw_mgr_mem_calibrate_read_test() - Perform READ test on single rank
 * @rank_bgn:		Rank number
 * @group:		Read/Write group
 * @num_tries:		Number of retries of the test
 * @all_correct:	All bits must be correct in the mask
 * @bit_chk:		Resulting bit mask after the test
 * @all_groups:		Test all R/W groups
 * @all_ranks:		Test all ranks
 *
 * Try a read and see if it returns correct data back. Test has dummy reads
 * inserted into the mix used to align DQS enable. Test has more thorough
 * checks than the regular read test.
 */
static int
rw_mgr_mem_calibrate_read_test(struct socfpga_sdrseq *seq,
			       const u32 rank_bgn, const u32 group,
			       const u32 num_tries, const u32 all_correct,
			       u32 *bit_chk,
			       const u32 all_groups, const u32 all_ranks)
{
	const u32 rank_end = all_ranks ? seq->rwcfg->mem_number_of_ranks :
		(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
	const u32 quick_read_mode =
		((STATIC_CALIB_STEPS & CALIB_SKIP_DELAY_SWEEPS) &&
		 seq->misccfg->enable_super_quick_calibration);
	u32 correct_mask_vg = seq->param.read_correct_mask_vg;
	u32 tmp_bit_chk;
	u32 base_rw_mgr;
	u32 addr;

	int r, vg, ret;

	*bit_chk = seq->param.read_correct_mask;

	for (r = rank_bgn; r < rank_end; r++) {
		/* set rank */
		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_READ_WRITE);

		writel(0x10, &sdr_rw_load_mgr_regs->load_cntr1);

		writel(seq->rwcfg->read_b2b_wait1,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);

		writel(0x10, &sdr_rw_load_mgr_regs->load_cntr2);
		writel(seq->rwcfg->read_b2b_wait2,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add2);

		if (quick_read_mode)
			writel(0x1, &sdr_rw_load_mgr_regs->load_cntr0);
			/* need at least two (1+1) reads to capture failures */
		else if (all_groups)
			writel(0x06, &sdr_rw_load_mgr_regs->load_cntr0);
		else
			writel(0x32, &sdr_rw_load_mgr_regs->load_cntr0);

		writel(seq->rwcfg->read_b2b,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);
		if (all_groups)
			writel(seq->rwcfg->mem_if_read_dqs_width *
			       seq->rwcfg->mem_virtual_groups_per_read_dqs - 1,
			       &sdr_rw_load_mgr_regs->load_cntr3);
		else
			writel(0x0, &sdr_rw_load_mgr_regs->load_cntr3);

		writel(seq->rwcfg->read_b2b,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add3);

		tmp_bit_chk = 0;
		for (vg = seq->rwcfg->mem_virtual_groups_per_read_dqs - 1;
		     vg >= 0; vg--) {
			/* Reset the FIFOs to get pointers to known state. */
			writel(0, &phy_mgr_cmd->fifo_reset);
			writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
				  RW_MGR_RESET_READ_DATAPATH_OFFSET);

			if (all_groups) {
				addr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
				       RW_MGR_RUN_ALL_GROUPS_OFFSET;
			} else {
				addr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
				       RW_MGR_RUN_SINGLE_GROUP_OFFSET;
			}

			writel(seq->rwcfg->read_b2b, addr +
			       ((group *
				 seq->rwcfg->mem_virtual_groups_per_read_dqs +
				 vg) << 2));

			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
			tmp_bit_chk <<=
				seq->rwcfg->mem_dq_per_read_dqs /
				seq->rwcfg->mem_virtual_groups_per_read_dqs;
			tmp_bit_chk |= correct_mask_vg & ~(base_rw_mgr);
		}

		*bit_chk &= tmp_bit_chk;
	}

	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_SINGLE_GROUP_OFFSET;
	writel(seq->rwcfg->clear_dqs_enable, addr + (group << 2));

	set_rank_and_odt_mask(seq, 0, RW_MGR_ODT_MODE_OFF);

	if (all_correct) {
		ret = (*bit_chk == seq->param.read_correct_mask);
		debug_cond(DLEVEL >= 2,
			   "%s:%d read_test(%u,ALL,%u) => (%u == %u) => %i\n",
			   __func__, __LINE__, group, all_groups, *bit_chk,
			   seq->param.read_correct_mask, ret);
	} else	{
		ret = (*bit_chk != 0x00);
		debug_cond(DLEVEL >= 2,
			   "%s:%d read_test(%u,ONE,%u) => (%u != %u) => %i\n",
			   __func__, __LINE__, group, all_groups, *bit_chk,
			   0, ret);
	}

	return ret;
}

/**
 * rw_mgr_mem_calibrate_read_test_all_ranks() - Perform READ test on all ranks
 * @grp:		Read/Write group
 * @num_tries:		Number of retries of the test
 * @all_correct:	All bits must be correct in the mask
 * @all_groups:		Test all R/W groups
 *
 * Perform a READ test across all memory ranks.
 */
static int
rw_mgr_mem_calibrate_read_test_all_ranks(struct socfpga_sdrseq *seq,
					 const u32 grp, const u32 num_tries,
					 const u32 all_correct,
					 const u32 all_groups)
{
	u32 bit_chk;
	return rw_mgr_mem_calibrate_read_test(seq, 0, grp, num_tries,
					      all_correct, &bit_chk, all_groups,
					      1);
}

/**
 * rw_mgr_incr_vfifo() - Increase VFIFO value
 * @grp:	Read/Write group
 *
 * Increase VFIFO value.
 */
static void rw_mgr_incr_vfifo(const u32 grp)
{
	writel(grp, &phy_mgr_cmd->inc_vfifo_hard_phy);
}

/**
 * rw_mgr_decr_vfifo() - Decrease VFIFO value
 * @grp:	Read/Write group
 *
 * Decrease VFIFO value.
 */
static void rw_mgr_decr_vfifo(struct socfpga_sdrseq *seq, const u32 grp)
{
	u32 i;

	for (i = 0; i < seq->misccfg->read_valid_fifo_size - 1; i++)
		rw_mgr_incr_vfifo(grp);
}

/**
 * find_vfifo_failing_read() - Push VFIFO to get a failing read
 * @grp:	Read/Write group
 *
 * Push VFIFO until a failing read happens.
 */
static int find_vfifo_failing_read(struct socfpga_sdrseq *seq,
				   const u32 grp)
{
	u32 v, ret, fail_cnt = 0;

	for (v = 0; v < seq->misccfg->read_valid_fifo_size; v++) {
		debug_cond(DLEVEL >= 2, "%s:%d: vfifo %u\n",
			   __func__, __LINE__, v);
		ret = rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
							       PASS_ONE_BIT, 0);
		if (!ret) {
			fail_cnt++;

			if (fail_cnt == 2)
				return v;
		}

		/* Fiddle with FIFO. */
		rw_mgr_incr_vfifo(grp);
	}

	/* No failing read found! Something must have gone wrong. */
	debug_cond(DLEVEL >= 2, "%s:%d: vfifo failed\n", __func__, __LINE__);
	return 0;
}

/**
 * sdr_find_phase_delay() - Find DQS enable phase or delay
 * @working:	If 1, look for working phase/delay, if 0, look for non-working
 * @delay:	If 1, look for delay, if 0, look for phase
 * @grp:	Read/Write group
 * @work:	Working window position
 * @work_inc:	Working window increment
 * @pd:		DQS Phase/Delay Iterator
 *
 * Find working or non-working DQS enable phase setting.
 */
static int sdr_find_phase_delay(struct socfpga_sdrseq *seq, int working,
				int delay, const u32 grp, u32 *work,
				const u32 work_inc, u32 *pd)
{
	const u32 max = delay ? seq->iocfg->dqs_en_delay_max :
				seq->iocfg->dqs_en_phase_max;
	u32 ret;

	for (; *pd <= max; (*pd)++) {
		if (delay)
			scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, *pd);
		else
			scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, *pd);

		ret = rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
							       PASS_ONE_BIT, 0);
		if (!working)
			ret = !ret;

		if (ret)
			return 0;

		if (work)
			*work += work_inc;
	}

	return -EINVAL;
}
/**
 * sdr_find_phase() - Find DQS enable phase
 * @working:	If 1, look for working phase, if 0, look for non-working phase
 * @grp:	Read/Write group
 * @work:	Working window position
 * @i:		Iterator
 * @p:		DQS Phase Iterator
 *
 * Find working or non-working DQS enable phase setting.
 */
static int sdr_find_phase(struct socfpga_sdrseq *seq, int working,
			  const u32 grp, u32 *work, u32 *i, u32 *p)
{
	const u32 end = seq->misccfg->read_valid_fifo_size + (working ? 0 : 1);
	int ret;

	for (; *i < end; (*i)++) {
		if (working)
			*p = 0;

		ret = sdr_find_phase_delay(seq, working, 0, grp, work,
					   seq->iocfg->delay_per_opa_tap, p);
		if (!ret)
			return 0;

		if (*p > seq->iocfg->dqs_en_phase_max) {
			/* Fiddle with FIFO. */
			rw_mgr_incr_vfifo(grp);
			if (!working)
				*p = 0;
		}
	}

	return -EINVAL;
}

/**
 * sdr_working_phase() - Find working DQS enable phase
 * @grp:	Read/Write group
 * @work_bgn:	Working window start position
 * @d:		dtaps output value
 * @p:		DQS Phase Iterator
 * @i:		Iterator
 *
 * Find working DQS enable phase setting.
 */
static int sdr_working_phase(struct socfpga_sdrseq *seq, const u32 grp,
			     u32 *work_bgn, u32 *d, u32 *p, u32 *i)
{
	const u32 dtaps_per_ptap = seq->iocfg->delay_per_opa_tap /
				   seq->iocfg->delay_per_dqs_en_dchain_tap;
	int ret;

	*work_bgn = 0;

	for (*d = 0; *d <= dtaps_per_ptap; (*d)++) {
		*i = 0;
		scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, *d);
		ret = sdr_find_phase(seq, 1, grp, work_bgn, i, p);
		if (!ret)
			return 0;
		*work_bgn += seq->iocfg->delay_per_dqs_en_dchain_tap;
	}

	/* Cannot find working solution */
	debug_cond(DLEVEL >= 2, "%s:%d find_dqs_en_phase: no vfifo/ptap/dtap\n",
		   __func__, __LINE__);
	return -EINVAL;
}

/**
 * sdr_backup_phase() - Find DQS enable backup phase
 * @grp:	Read/Write group
 * @work_bgn:	Working window start position
 * @p:		DQS Phase Iterator
 *
 * Find DQS enable backup phase setting.
 */
static void sdr_backup_phase(struct socfpga_sdrseq *seq, const u32 grp,
			     u32 *work_bgn, u32 *p)
{
	u32 tmp_delay, d;
	int ret;

	/* Special case code for backing up a phase */
	if (*p == 0) {
		*p = seq->iocfg->dqs_en_phase_max;
		rw_mgr_decr_vfifo(seq, grp);
	} else {
		(*p)--;
	}
	tmp_delay = *work_bgn - seq->iocfg->delay_per_opa_tap;
	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, *p);

	for (d = 0; d <= seq->iocfg->dqs_en_delay_max && tmp_delay < *work_bgn;
	     d++) {
		scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, d);

		ret = rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
							       PASS_ONE_BIT, 0);
		if (ret) {
			*work_bgn = tmp_delay;
			break;
		}

		tmp_delay += seq->iocfg->delay_per_dqs_en_dchain_tap;
	}

	/* Restore VFIFO to old state before we decremented it (if needed). */
	(*p)++;
	if (*p > seq->iocfg->dqs_en_phase_max) {
		*p = 0;
		rw_mgr_incr_vfifo(grp);
	}

	scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, 0);
}

/**
 * sdr_nonworking_phase() - Find non-working DQS enable phase
 * @grp:	Read/Write group
 * @work_end:	Working window end position
 * @p:		DQS Phase Iterator
 * @i:		Iterator
 *
 * Find non-working DQS enable phase setting.
 */
static int sdr_nonworking_phase(struct socfpga_sdrseq *seq,
				const u32 grp, u32 *work_end, u32 *p, u32 *i)
{
	int ret;

	(*p)++;
	*work_end += seq->iocfg->delay_per_opa_tap;
	if (*p > seq->iocfg->dqs_en_phase_max) {
		/* Fiddle with FIFO. */
		*p = 0;
		rw_mgr_incr_vfifo(grp);
	}

	ret = sdr_find_phase(seq, 0, grp, work_end, i, p);
	if (ret) {
		/* Cannot see edge of failing read. */
		debug_cond(DLEVEL >= 2, "%s:%d: end: failed\n",
			   __func__, __LINE__);
	}

	return ret;
}

/**
 * sdr_find_window_center() - Find center of the working DQS window.
 * @grp:	Read/Write group
 * @work_bgn:	First working settings
 * @work_end:	Last working settings
 *
 * Find center of the working DQS enable window.
 */
static int sdr_find_window_center(struct socfpga_sdrseq *seq,
				  const u32 grp, const u32 work_bgn,
				  const u32 work_end)
{
	u32 work_mid;
	int tmp_delay = 0;
	int i, p, d;

	work_mid = (work_bgn + work_end) / 2;

	debug_cond(DLEVEL >= 2, "work_bgn=%d work_end=%d work_mid=%d\n",
		   work_bgn, work_end, work_mid);
	/* Get the middle delay to be less than a VFIFO delay */
	tmp_delay = (seq->iocfg->dqs_en_phase_max + 1)
		* seq->iocfg->delay_per_opa_tap;

	debug_cond(DLEVEL >= 2, "vfifo ptap delay %d\n", tmp_delay);
	work_mid %= tmp_delay;
	debug_cond(DLEVEL >= 2, "new work_mid %d\n", work_mid);

	tmp_delay = rounddown(work_mid, seq->iocfg->delay_per_opa_tap);
	if (tmp_delay > seq->iocfg->dqs_en_phase_max
		* seq->iocfg->delay_per_opa_tap) {
		tmp_delay = seq->iocfg->dqs_en_phase_max
			* seq->iocfg->delay_per_opa_tap;
	}
	p = tmp_delay / seq->iocfg->delay_per_opa_tap;

	debug_cond(DLEVEL >= 2, "new p %d, tmp_delay=%d\n", p, tmp_delay);

	d = DIV_ROUND_UP(work_mid - tmp_delay,
			 seq->iocfg->delay_per_dqs_en_dchain_tap);
	if (d > seq->iocfg->dqs_en_delay_max)
		d = seq->iocfg->dqs_en_delay_max;
	tmp_delay += d * seq->iocfg->delay_per_dqs_en_dchain_tap;

	debug_cond(DLEVEL >= 2, "new d %d, tmp_delay=%d\n", d, tmp_delay);

	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, p);
	scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, d);

	/*
	 * push vfifo until we can successfully calibrate. We can do this
	 * because the largest possible margin in 1 VFIFO cycle.
	 */
	for (i = 0; i < seq->misccfg->read_valid_fifo_size; i++) {
		debug_cond(DLEVEL >= 2, "find_dqs_en_phase: center\n");
		if (rw_mgr_mem_calibrate_read_test_all_ranks(seq, grp, 1,
							     PASS_ONE_BIT,
							     0)) {
			debug_cond(DLEVEL >= 2,
				   "%s:%d center: found: ptap=%u dtap=%u\n",
				   __func__, __LINE__, p, d);
			return 0;
		}

		/* Fiddle with FIFO. */
		rw_mgr_incr_vfifo(grp);
	}

	debug_cond(DLEVEL >= 2, "%s:%d center: failed.\n",
		   __func__, __LINE__);
	return -EINVAL;
}

/**
 * rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() - Find a good DQS enable to
 * use
 * @grp:	Read/Write Group
 *
 * Find a good DQS enable to use.
 */
static int
rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(struct socfpga_sdrseq *seq,
					     const u32 grp)
{
	u32 d, p, i;
	u32 dtaps_per_ptap;
	u32 work_bgn, work_end;
	u32 found_passing_read, found_failing_read = 0, initial_failing_dtap;
	int ret;

	debug("%s:%d %u\n", __func__, __LINE__, grp);

	reg_file_set_sub_stage(CAL_SUBSTAGE_VFIFO_CENTER);

	scc_mgr_set_dqs_en_delay_all_ranks(seq, grp, 0);
	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, 0);

	/* Step 0: Determine number of delay taps for each phase tap. */
	dtaps_per_ptap = seq->iocfg->delay_per_opa_tap /
			 seq->iocfg->delay_per_dqs_en_dchain_tap;

	/* Step 1: First push vfifo until we get a failing read. */
	find_vfifo_failing_read(seq, grp);

	/* Step 2: Find first working phase, increment in ptaps. */
	work_bgn = 0;
	ret = sdr_working_phase(seq, grp, &work_bgn, &d, &p, &i);
	if (ret)
		return ret;

	work_end = work_bgn;

	/*
	 * If d is 0 then the working window covers a phase tap and we can
	 * follow the old procedure. Otherwise, we've found the beginning
	 * and we need to increment the dtaps until we find the end.
	 */
	if (d == 0) {
		/*
		 * Step 3a: If we have room, back off by one and
		 *          increment in dtaps.
		 */
		sdr_backup_phase(seq, grp, &work_bgn, &p);

		/*
		 * Step 4a: go forward from working phase to non working
		 * phase, increment in ptaps.
		 */
		ret = sdr_nonworking_phase(seq, grp, &work_end, &p, &i);
		if (ret)
			return ret;

		/* Step 5a: Back off one from last, increment in dtaps. */

		/* Special case code for backing up a phase */
		if (p == 0) {
			p = seq->iocfg->dqs_en_phase_max;
			rw_mgr_decr_vfifo(seq, grp);
		} else {
			p = p - 1;
		}

		work_end -= seq->iocfg->delay_per_opa_tap;
		scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, p);

		d = 0;

		debug_cond(DLEVEL >= 2, "%s:%d p: ptap=%u\n",
			   __func__, __LINE__, p);
	}

	/* The dtap increment to find the failing edge is done here. */
	sdr_find_phase_delay(seq, 0, 1, grp, &work_end,
			     seq->iocfg->delay_per_dqs_en_dchain_tap, &d);

	/* Go back to working dtap */
	if (d != 0)
		work_end -= seq->iocfg->delay_per_dqs_en_dchain_tap;

	debug_cond(DLEVEL >= 2,
		   "%s:%d p/d: ptap=%u dtap=%u end=%u\n",
		   __func__, __LINE__, p, d - 1, work_end);

	if (work_end < work_bgn) {
		/* nil range */
		debug_cond(DLEVEL >= 2, "%s:%d end-2: failed\n",
			   __func__, __LINE__);
		return -EINVAL;
	}

	debug_cond(DLEVEL >= 2, "%s:%d found range [%u,%u]\n",
		   __func__, __LINE__, work_bgn, work_end);

	/*
	 * We need to calculate the number of dtaps that equal a ptap.
	 * To do that we'll back up a ptap and re-find the edge of the
	 * window using dtaps
	 */
	debug_cond(DLEVEL >= 2, "%s:%d calculate dtaps_per_ptap for tracking\n",
		   __func__, __LINE__);

	/* Special case code for backing up a phase */
	if (p == 0) {
		p = seq->iocfg->dqs_en_phase_max;
		rw_mgr_decr_vfifo(seq, grp);
		debug_cond(DLEVEL >= 2, "%s:%d backedup cycle/phase: p=%u\n",
			   __func__, __LINE__, p);
	} else {
		p = p - 1;
		debug_cond(DLEVEL >= 2, "%s:%d backedup phase only: p=%u",
			   __func__, __LINE__, p);
	}

	scc_mgr_set_dqs_en_phase_all_ranks(seq, grp, p);

	/*
	 * Increase dtap until we first see a passing read (in case the
	 * window is smaller than a ptap), and then a failing read to
	 * mark the edge of the window again.
	 */

	/* Find a passing read. */
	debug_cond(DLEVEL >= 2, "%s:%d find passing read\n",
		   __func__, __LINE__);

	initial_failing_dtap = d;

	found_passing_read = !sdr_find_phase_delay(seq, 1, 1, grp, NULL, 0, &d);
	if (found_passing_read) {
		/* Find a failing read. */
		debug_cond(DLEVEL >= 2, "%s:%d find failing read\n",
			   __func__, __LINE__);
		d++;
		found_failing_read = !sdr_find_phase_delay(seq, 0, 1, grp, NULL,
							   0, &d);
	} else {
		debug_cond(DLEVEL >= 1,
			   "%s:%d failed to calculate dtaps per ptap. Fall back on static value\n",
			   __func__, __LINE__);
	}

	/*
	 * The dynamically calculated dtaps_per_ptap is only valid if we
	 * found a passing/failing read. If we didn't, it means d hit the max
	 * (seq->iocfg->dqs_en_delay_max). Otherwise, dtaps_per_ptap retains its
	 * statically calculated value.
	 */
	if (found_passing_read && found_failing_read)
		dtaps_per_ptap = d - initial_failing_dtap;

	writel(dtaps_per_ptap, &sdr_reg_file->dtaps_per_ptap);
	debug_cond(DLEVEL >= 2, "%s:%d dtaps_per_ptap=%u - %u = %u",
		   __func__, __LINE__, d, initial_failing_dtap, dtaps_per_ptap);

	/* Step 6: Find the centre of the window. */
	ret = sdr_find_window_center(seq, grp, work_bgn, work_end);

	return ret;
}

/**
 * search_stop_check() - Check if the detected edge is valid
 * @write:		Perform read (Stage 2) or write (Stage 3) calibration
 * @d:			DQS delay
 * @rank_bgn:		Rank number
 * @write_group:	Write Group
 * @read_group:		Read Group
 * @bit_chk:		Resulting bit mask after the test
 * @sticky_bit_chk:	Resulting sticky bit mask after the test
 * @use_read_test:	Perform read test
 *
 * Test if the found edge is valid.
 */
static u32 search_stop_check(struct socfpga_sdrseq *seq, const int write,
			     const int d, const int rank_bgn,
			     const u32 write_group, const u32 read_group,
			     u32 *bit_chk, u32 *sticky_bit_chk,
			     const u32 use_read_test)
{
	const u32 ratio = seq->rwcfg->mem_if_read_dqs_width /
			  seq->rwcfg->mem_if_write_dqs_width;
	const u32 correct_mask = write ? seq->param.write_correct_mask :
					 seq->param.read_correct_mask;
	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
				    seq->rwcfg->mem_dq_per_read_dqs;
	u32 ret;
	/*
	 * Stop searching when the read test doesn't pass AND when
	 * we've seen a passing read on every bit.
	 */
	if (write) {			/* WRITE-ONLY */
		ret = !rw_mgr_mem_calibrate_write_test(seq, rank_bgn,
							 write_group, 0,
							 PASS_ONE_BIT, bit_chk,
							 0);
	} else if (use_read_test) {	/* READ-ONLY */
		ret = !rw_mgr_mem_calibrate_read_test(seq, rank_bgn, read_group,
							NUM_READ_PB_TESTS,
							PASS_ONE_BIT, bit_chk,
							0, 0);
	} else {			/* READ-ONLY */
		rw_mgr_mem_calibrate_write_test(seq, rank_bgn, write_group, 0,
						PASS_ONE_BIT, bit_chk, 0);
		*bit_chk = *bit_chk >> (per_dqs *
			(read_group - (write_group * ratio)));
		ret = (*bit_chk == 0);
	}
	*sticky_bit_chk = *sticky_bit_chk | *bit_chk;
	ret = ret && (*sticky_bit_chk == correct_mask);
	debug_cond(DLEVEL >= 2,
		   "%s:%d center(left): dtap=%u => %u == %u && %u",
		   __func__, __LINE__, d,
		   *sticky_bit_chk, correct_mask, ret);
	return ret;
}

/**
 * search_left_edge() - Find left edge of DQ/DQS working phase
 * @write:		Perform read (Stage 2) or write (Stage 3) calibration
 * @rank_bgn:		Rank number
 * @write_group:	Write Group
 * @read_group:		Read Group
 * @test_bgn:		Rank number to begin the test
 * @sticky_bit_chk:	Resulting sticky bit mask after the test
 * @left_edge:		Left edge of the DQ/DQS phase
 * @right_edge:		Right edge of the DQ/DQS phase
 * @use_read_test:	Perform read test
 *
 * Find left edge of DQ/DQS working phase.
 */
static void search_left_edge(struct socfpga_sdrseq *seq, const int write,
			     const int rank_bgn, const u32 write_group,
			     const u32 read_group, const u32 test_bgn,
			     u32 *sticky_bit_chk, int *left_edge,
			     int *right_edge, const u32 use_read_test)
{
	const u32 delay_max = write ? seq->iocfg->io_out1_delay_max :
				      seq->iocfg->io_in_delay_max;
	const u32 dqs_max = write ? seq->iocfg->io_out1_delay_max :
				    seq->iocfg->dqs_in_delay_max;
	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
				    seq->rwcfg->mem_dq_per_read_dqs;
	u32 stop, bit_chk;
	int i, d;

	for (d = 0; d <= dqs_max; d++) {
		if (write)
			scc_mgr_apply_group_dq_out1_delay(seq, d);
		else
			scc_mgr_apply_group_dq_in_delay(seq, test_bgn, d);

		writel(0, &sdr_scc_mgr->update);

		stop = search_stop_check(seq, write, d, rank_bgn, write_group,
					 read_group, &bit_chk, sticky_bit_chk,
					 use_read_test);
		if (stop == 1)
			break;

		/* stop != 1 */
		for (i = 0; i < per_dqs; i++) {
			if (bit_chk & 1) {
				/*
				 * Remember a passing test as
				 * the left_edge.
				 */
				left_edge[i] = d;
			} else {
				/*
				 * If a left edge has not been seen
				 * yet, then a future passing test
				 * will mark this edge as the right
				 * edge.
				 */
				if (left_edge[i] == delay_max + 1)
					right_edge[i] = -(d + 1);
			}
			bit_chk >>= 1;
		}
	}

	/* Reset DQ delay chains to 0 */
	if (write)
		scc_mgr_apply_group_dq_out1_delay(seq, 0);
	else
		scc_mgr_apply_group_dq_in_delay(seq, test_bgn, 0);

	*sticky_bit_chk = 0;
	for (i = per_dqs - 1; i >= 0; i--) {
		debug_cond(DLEVEL >= 2,
			   "%s:%d vfifo_center: left_edge[%u]: %d right_edge[%u]: %d\n",
			   __func__, __LINE__, i, left_edge[i],
			   i, right_edge[i]);

		/*
		 * Check for cases where we haven't found the left edge,
		 * which makes our assignment of the the right edge invalid.
		 * Reset it to the illegal value.
		 */
		if ((left_edge[i] == delay_max + 1) &&
		    (right_edge[i] != delay_max + 1)) {
			right_edge[i] = delay_max + 1;
			debug_cond(DLEVEL >= 2,
				   "%s:%d vfifo_center: reset right_edge[%u]: %d\n",
				   __func__, __LINE__, i, right_edge[i]);
		}

		/*
		 * Reset sticky bit
		 * READ: except for bits where we have seen both
		 *       the left and right edge.
		 * WRITE: except for bits where we have seen the
		 *        left edge.
		 */
		*sticky_bit_chk <<= 1;
		if (write) {
			if (left_edge[i] != delay_max + 1)
				*sticky_bit_chk |= 1;
		} else {
			if ((left_edge[i] != delay_max + 1) &&
			    (right_edge[i] != delay_max + 1))
				*sticky_bit_chk |= 1;
		}
	}
}

/**
 * search_right_edge() - Find right edge of DQ/DQS working phase
 * @write:		Perform read (Stage 2) or write (Stage 3) calibration
 * @rank_bgn:		Rank number
 * @write_group:	Write Group
 * @read_group:		Read Group
 * @start_dqs:		DQS start phase
 * @start_dqs_en:	DQS enable start phase
 * @sticky_bit_chk:	Resulting sticky bit mask after the test
 * @left_edge:		Left edge of the DQ/DQS phase
 * @right_edge:		Right edge of the DQ/DQS phase
 * @use_read_test:	Perform read test
 *
 * Find right edge of DQ/DQS working phase.
 */
static int search_right_edge(struct socfpga_sdrseq *seq, const int write,
			     const int rank_bgn, const u32 write_group,
			     const u32 read_group, const int start_dqs,
			     const int start_dqs_en, u32 *sticky_bit_chk,
			     int *left_edge, int *right_edge,
			     const u32 use_read_test)
{
	const u32 delay_max = write ? seq->iocfg->io_out1_delay_max :
				      seq->iocfg->io_in_delay_max;
	const u32 dqs_max = write ? seq->iocfg->io_out1_delay_max :
				    seq->iocfg->dqs_in_delay_max;
	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
				    seq->rwcfg->mem_dq_per_read_dqs;
	u32 stop, bit_chk;
	int i, d;

	for (d = 0; d <= dqs_max - start_dqs; d++) {
		if (write) {	/* WRITE-ONLY */
			scc_mgr_apply_group_dqs_io_and_oct_out1(seq,
								write_group,
								d + start_dqs);
		} else {	/* READ-ONLY */
			scc_mgr_set_dqs_bus_in_delay(read_group, d + start_dqs);
			if (seq->iocfg->shift_dqs_en_when_shift_dqs) {
				u32 delay = d + start_dqs_en;
				if (delay > seq->iocfg->dqs_en_delay_max)
					delay = seq->iocfg->dqs_en_delay_max;
				scc_mgr_set_dqs_en_delay(read_group, delay);
			}
			scc_mgr_load_dqs(read_group);
		}

		writel(0, &sdr_scc_mgr->update);

		stop = search_stop_check(seq, write, d, rank_bgn, write_group,
					 read_group, &bit_chk, sticky_bit_chk,
					 use_read_test);
		if (stop == 1) {
			if (write && (d == 0)) {	/* WRITE-ONLY */
				for (i = 0;
				     i < seq->rwcfg->mem_dq_per_write_dqs;
				     i++) {
					/*
					 * d = 0 failed, but it passed when
					 * testing the left edge, so it must be
					 * marginal, set it to -1
					 */
					if (right_edge[i] == delay_max + 1 &&
					    left_edge[i] != delay_max + 1)
						right_edge[i] = -1;
				}
			}
			break;
		}

		/* stop != 1 */
		for (i = 0; i < per_dqs; i++) {
			if (bit_chk & 1) {
				/*
				 * Remember a passing test as
				 * the right_edge.
				 */
				right_edge[i] = d;
			} else {
				if (d != 0) {
					/*
					 * If a right edge has not
					 * been seen yet, then a future
					 * passing test will mark this
					 * edge as the left edge.
					 */
					if (right_edge[i] == delay_max + 1)
						left_edge[i] = -(d + 1);
				} else {
					/*
					 * d = 0 failed, but it passed
					 * when testing the left edge,
					 * so it must be marginal, set
					 * it to -1
					 */
					if (right_edge[i] == delay_max + 1 &&
					    left_edge[i] != delay_max + 1)
						right_edge[i] = -1;
					/*
					 * If a right edge has not been
					 * seen yet, then a future
					 * passing test will mark this
					 * edge as the left edge.
					 */
					else if (right_edge[i] == delay_max + 1)
						left_edge[i] = -(d + 1);
				}
			}

			debug_cond(DLEVEL >= 2, "%s:%d center[r,d=%u]: ",
				   __func__, __LINE__, d);
			debug_cond(DLEVEL >= 2,
				   "bit_chk_test=%i left_edge[%u]: %d ",
				   bit_chk & 1, i, left_edge[i]);
			debug_cond(DLEVEL >= 2, "right_edge[%u]: %d\n", i,
				   right_edge[i]);
			bit_chk >>= 1;
		}
	}

	/* Check that all bits have a window */
	for (i = 0; i < per_dqs; i++) {
		debug_cond(DLEVEL >= 2,
			   "%s:%d write_center: left_edge[%u]: %d right_edge[%u]: %d",
			   __func__, __LINE__, i, left_edge[i],
			   i, right_edge[i]);
		if ((left_edge[i] == dqs_max + 1) ||
		    (right_edge[i] == dqs_max + 1))
			return i + 1;	/* FIXME: If we fail, retval > 0 */
	}

	return 0;
}

/**
 * get_window_mid_index() - Find the best middle setting of DQ/DQS phase
 * @write:		Perform read (Stage 2) or write (Stage 3) calibration
 * @left_edge:		Left edge of the DQ/DQS phase
 * @right_edge:		Right edge of the DQ/DQS phase
 * @mid_min:		Best DQ/DQS phase middle setting
 *
 * Find index and value of the middle of the DQ/DQS working phase.
 */
static int get_window_mid_index(struct socfpga_sdrseq *seq,
				const int write, int *left_edge,
				int *right_edge, int *mid_min)
{
	const u32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
				    seq->rwcfg->mem_dq_per_read_dqs;
	int i, mid, min_index;

	/* Find middle of window for each DQ bit */
	*mid_min = left_edge[0] - right_edge[0];
	min_index = 0;
	for (i = 1; i < per_dqs; i++) {
		mid = left_edge[i] - right_edge[i];
		if (mid < *mid_min) {
			*mid_min = mid;
			min_index = i;
		}
	}

	/*
	 * -mid_min/2 represents the amount that we need to move DQS.
	 * If mid_min is odd and positive we'll need to add one to make
	 * sure the rounding in further calculations is correct (always
	 * bias to the right), so just add 1 for all positive values.
	 */
	if (*mid_min > 0)
		(*mid_min)++;
	*mid_min = *mid_min / 2;

	debug_cond(DLEVEL >= 1, "%s:%d vfifo_center: *mid_min=%d (index=%u)\n",
		   __func__, __LINE__, *mid_min, min_index);
	return min_index;
}

/**
 * center_dq_windows() - Center the DQ/DQS windows
 * @write:		Perform read (Stage 2) or write (Stage 3) calibration
 * @left_edge:		Left edge of the DQ/DQS phase
 * @right_edge:		Right edge of the DQ/DQS phase
 * @mid_min:		Adjusted DQ/DQS phase middle setting
 * @orig_mid_min:	Original DQ/DQS phase middle setting
 * @min_index:		DQ/DQS phase middle setting index
 * @test_bgn:		Rank number to begin the test
 * @dq_margin:		Amount of shift for the DQ
 * @dqs_margin:		Amount of shift for the DQS
 *
 * Align the DQ/DQS windows in each group.
 */
static void center_dq_windows(struct socfpga_sdrseq *seq,
			      const int write, int *left_edge, int *right_edge,
			      const int mid_min, const int orig_mid_min,
			      const int min_index, const int test_bgn,
			      int *dq_margin, int *dqs_margin)
{
	const s32 delay_max = write ? seq->iocfg->io_out1_delay_max :
				      seq->iocfg->io_in_delay_max;
	const s32 per_dqs = write ? seq->rwcfg->mem_dq_per_write_dqs :
				    seq->rwcfg->mem_dq_per_read_dqs;
	const s32 delay_off = write ? SCC_MGR_IO_OUT1_DELAY_OFFSET :
				      SCC_MGR_IO_IN_DELAY_OFFSET;
	const s32 addr = SDR_PHYGRP_SCCGRP_ADDRESS | delay_off;

	s32 temp_dq_io_delay1;
	int shift_dq, i, p;

	/* Initialize data for export structures */
	*dqs_margin = delay_max + 1;
	*dq_margin  = delay_max + 1;

	/* add delay to bring centre of all DQ windows to the same "level" */
	for (i = 0, p = test_bgn; i < per_dqs; i++, p++) {
		/* Use values before divide by 2 to reduce round off error */
		shift_dq = (left_edge[i] - right_edge[i] -
			(left_edge[min_index] - right_edge[min_index]))/2  +
			(orig_mid_min - mid_min);

		debug_cond(DLEVEL >= 2,
			   "vfifo_center: before: shift_dq[%u]=%d\n",
			   i, shift_dq);

		temp_dq_io_delay1 = readl(addr + (i << 2));

		if (shift_dq + temp_dq_io_delay1 > delay_max)
			shift_dq = delay_max - temp_dq_io_delay1;
		else if (shift_dq + temp_dq_io_delay1 < 0)
			shift_dq = -temp_dq_io_delay1;

		debug_cond(DLEVEL >= 2,
			   "vfifo_center: after: shift_dq[%u]=%d\n",
			   i, shift_dq);

		if (write)
			scc_mgr_set_dq_out1_delay(i,
						  temp_dq_io_delay1 + shift_dq);
		else
			scc_mgr_set_dq_in_delay(p,
						temp_dq_io_delay1 + shift_dq);

		scc_mgr_load_dq(p);

		debug_cond(DLEVEL >= 2,
			   "vfifo_center: margin[%u]=[%d,%d]\n", i,
			   left_edge[i] - shift_dq + (-mid_min),
			   right_edge[i] + shift_dq - (-mid_min));

		/* To determine values for export structures */
		if (left_edge[i] - shift_dq + (-mid_min) < *dq_margin)
			*dq_margin = left_edge[i] - shift_dq + (-mid_min);

		if (right_edge[i] + shift_dq - (-mid_min) < *dqs_margin)
			*dqs_margin = right_edge[i] + shift_dq - (-mid_min);
	}
}

/**
 * rw_mgr_mem_calibrate_vfifo_center() - Per-bit deskew DQ and centering
 * @rank_bgn:		Rank number
 * @rw_group:		Read/Write Group
 * @test_bgn:		Rank at which the test begins
 * @use_read_test:	Perform a read test
 * @update_fom:		Update FOM
 *
 * Per-bit deskew DQ and centering.
 */
static int rw_mgr_mem_calibrate_vfifo_center(struct socfpga_sdrseq *seq,
					     const u32 rank_bgn,
					     const u32 rw_group,
					     const u32 test_bgn,
					     const int use_read_test,
					     const int update_fom)
{
	const u32 addr =
		SDR_PHYGRP_SCCGRP_ADDRESS + SCC_MGR_DQS_IN_DELAY_OFFSET +
		(rw_group << 2);
	/*
	 * Store these as signed since there are comparisons with
	 * signed numbers.
	 */
	u32 sticky_bit_chk;
	s32 left_edge[seq->rwcfg->mem_dq_per_read_dqs];
	s32 right_edge[seq->rwcfg->mem_dq_per_read_dqs];
	s32 orig_mid_min, mid_min;
	s32 new_dqs, start_dqs, start_dqs_en = 0, final_dqs_en;
	s32 dq_margin, dqs_margin;
	int i, min_index;
	int ret;

	debug("%s:%d: %u %u", __func__, __LINE__, rw_group, test_bgn);

	start_dqs = readl(addr);
	if (seq->iocfg->shift_dqs_en_when_shift_dqs)
		start_dqs_en = readl(addr - seq->iocfg->dqs_en_delay_offset);

	/* set the left and right edge of each bit to an illegal value */
	/* use (seq->iocfg->io_in_delay_max + 1) as an illegal value */
	sticky_bit_chk = 0;
	for (i = 0; i < seq->rwcfg->mem_dq_per_read_dqs; i++) {
		left_edge[i]  = seq->iocfg->io_in_delay_max + 1;
		right_edge[i] = seq->iocfg->io_in_delay_max + 1;
	}

	/* Search for the left edge of the window for each bit */
	search_left_edge(seq, 0, rank_bgn, rw_group, rw_group, test_bgn,
			 &sticky_bit_chk,
			 left_edge, right_edge, use_read_test);


	/* Search for the right edge of the window for each bit */
	ret = search_right_edge(seq, 0, rank_bgn, rw_group, rw_group,
				start_dqs, start_dqs_en,
				&sticky_bit_chk,
				left_edge, right_edge, use_read_test);
	if (ret) {
		/*
		 * Restore delay chain settings before letting the loop
		 * in rw_mgr_mem_calibrate_vfifo to retry different
		 * dqs/ck relationships.
		 */
		scc_mgr_set_dqs_bus_in_delay(rw_group, start_dqs);
		if (seq->iocfg->shift_dqs_en_when_shift_dqs)
			scc_mgr_set_dqs_en_delay(rw_group, start_dqs_en);

		scc_mgr_load_dqs(rw_group);
		writel(0, &sdr_scc_mgr->update);

		debug_cond(DLEVEL >= 1,
			   "%s:%d vfifo_center: failed to find edge [%u]: %d %d",
			   __func__, __LINE__, i, left_edge[i], right_edge[i]);
		if (use_read_test) {
			set_failing_group_stage(seq, rw_group *
				seq->rwcfg->mem_dq_per_read_dqs + i,
				CAL_STAGE_VFIFO,
				CAL_SUBSTAGE_VFIFO_CENTER);
		} else {
			set_failing_group_stage(seq, rw_group *
				seq->rwcfg->mem_dq_per_read_dqs + i,
				CAL_STAGE_VFIFO_AFTER_WRITES,
				CAL_SUBSTAGE_VFIFO_CENTER);
		}
		return -EIO;
	}

	min_index = get_window_mid_index(seq, 0, left_edge, right_edge,
					 &mid_min);

	/* Determine the amount we can change DQS (which is -mid_min) */
	orig_mid_min = mid_min;
	new_dqs = start_dqs - mid_min;
	if (new_dqs > seq->iocfg->dqs_in_delay_max)
		new_dqs = seq->iocfg->dqs_in_delay_max;
	else if (new_dqs < 0)
		new_dqs = 0;

	mid_min = start_dqs - new_dqs;
	debug_cond(DLEVEL >= 1, "vfifo_center: new mid_min=%d new_dqs=%d\n",
		   mid_min, new_dqs);

	if (seq->iocfg->shift_dqs_en_when_shift_dqs) {
		if (start_dqs_en - mid_min > seq->iocfg->dqs_en_delay_max)
			mid_min += start_dqs_en - mid_min -
				   seq->iocfg->dqs_en_delay_max;
		else if (start_dqs_en - mid_min < 0)
			mid_min += start_dqs_en - mid_min;
	}
	new_dqs = start_dqs - mid_min;

	debug_cond(DLEVEL >= 1,
		   "vfifo_center: start_dqs=%d start_dqs_en=%d new_dqs=%d mid_min=%d\n",
		   start_dqs,
		   seq->iocfg->shift_dqs_en_when_shift_dqs ? start_dqs_en : -1,
		   new_dqs, mid_min);

	/* Add delay to bring centre of all DQ windows to the same "level". */
	center_dq_windows(seq, 0, left_edge, right_edge, mid_min, orig_mid_min,
			  min_index, test_bgn, &dq_margin, &dqs_margin);

	/* Move DQS-en */
	if (seq->iocfg->shift_dqs_en_when_shift_dqs) {
		final_dqs_en = start_dqs_en - mid_min;
		scc_mgr_set_dqs_en_delay(rw_group, final_dqs_en);
		scc_mgr_load_dqs(rw_group);
	}

	/* Move DQS */
	scc_mgr_set_dqs_bus_in_delay(rw_group, new_dqs);
	scc_mgr_load_dqs(rw_group);
	debug_cond(DLEVEL >= 2,
		   "%s:%d vfifo_center: dq_margin=%d dqs_margin=%d",
		   __func__, __LINE__, dq_margin, dqs_margin);

	/*
	 * Do not remove this line as it makes sure all of our decisions
	 * have been applied. Apply the update bit.
	 */
	writel(0, &sdr_scc_mgr->update);

	if ((dq_margin < 0) || (dqs_margin < 0))
		return -EINVAL;

	return 0;
}

/**
 * rw_mgr_mem_calibrate_guaranteed_write() - Perform guaranteed write into the
 * device
 * @rw_group:	Read/Write Group
 * @phase:	DQ/DQS phase
 *
 * Because initially no communication ca be reliably performed with the memory
 * device, the sequencer uses a guaranteed write mechanism to write data into
 * the memory device.
 */
static int rw_mgr_mem_calibrate_guaranteed_write(struct socfpga_sdrseq *seq,
						 const u32 rw_group,
						 const u32 phase)
{
	int ret;

	/* Set a particular DQ/DQS phase. */
	scc_mgr_set_dqdqs_output_phase_all_ranks(seq, rw_group, phase);

	debug_cond(DLEVEL >= 1, "%s:%d guaranteed write: g=%u p=%u\n",
		   __func__, __LINE__, rw_group, phase);

	/*
	 * Altera EMI_RM 2015.05.04 :: Figure 1-25
	 * Load up the patterns used by read calibration using the
	 * current DQDQS phase.
	 */
	rw_mgr_mem_calibrate_read_load_patterns(seq, 0, 1);

	if (seq->gbl.phy_debug_mode_flags & PHY_DEBUG_DISABLE_GUARANTEED_READ)
		return 0;

	/*
	 * Altera EMI_RM 2015.05.04 :: Figure 1-26
	 * Back-to-Back reads of the patterns used for calibration.
	 */
	ret = rw_mgr_mem_calibrate_read_test_patterns(seq, 0, rw_group, 1);
	if (ret)
		debug_cond(DLEVEL >= 1,
			   "%s:%d Guaranteed read test failed: g=%u p=%u\n",
			   __func__, __LINE__, rw_group, phase);
	return ret;
}

/**
 * rw_mgr_mem_calibrate_dqs_enable_calibration() - DQS Enable Calibration
 * @rw_group:	Read/Write Group
 * @test_bgn:	Rank at which the test begins
 *
 * DQS enable calibration ensures reliable capture of the DQ signal without
 * glitches on the DQS line.
 */
static int
rw_mgr_mem_calibrate_dqs_enable_calibration(struct socfpga_sdrseq *seq,
					    const u32 rw_group,
					    const u32 test_bgn)
{
	/*
	 * Altera EMI_RM 2015.05.04 :: Figure 1-27
	 * DQS and DQS Eanble Signal Relationships.
	 */

	/* We start at zero, so have one less dq to devide among */
	const u32 delay_step = seq->iocfg->io_in_delay_max /
			       (seq->rwcfg->mem_dq_per_read_dqs - 1);
	int ret;
	u32 i, p, d, r;

	debug("%s:%d (%u,%u)\n", __func__, __LINE__, rw_group, test_bgn);

	/* Try different dq_in_delays since the DQ path is shorter than DQS. */
	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
	     r += NUM_RANKS_PER_SHADOW_REG) {
		for (i = 0, p = test_bgn, d = 0;
		     i < seq->rwcfg->mem_dq_per_read_dqs;
		     i++, p++, d += delay_step) {
			debug_cond(DLEVEL >= 1,
				   "%s:%d: g=%u r=%u i=%u p=%u d=%u\n",
				   __func__, __LINE__, rw_group, r, i, p, d);

			scc_mgr_set_dq_in_delay(p, d);
			scc_mgr_load_dq(p);
		}

		writel(0, &sdr_scc_mgr->update);
	}

	/*
	 * Try rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase across different
	 * dq_in_delay values
	 */
	ret = rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(seq, rw_group);

	debug_cond(DLEVEL >= 1,
		   "%s:%d: g=%u found=%u; Reseting delay chain to zero\n",
		   __func__, __LINE__, rw_group, !ret);

	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
	     r += NUM_RANKS_PER_SHADOW_REG) {
		scc_mgr_apply_group_dq_in_delay(seq, test_bgn, 0);
		writel(0, &sdr_scc_mgr->update);
	}

	return ret;
}

/**
 * rw_mgr_mem_calibrate_dq_dqs_centering() - Centering DQ/DQS
 * @rw_group:		Read/Write Group
 * @test_bgn:		Rank at which the test begins
 * @use_read_test:	Perform a read test
 * @update_fom:		Update FOM
 *
 * The centerin DQ/DQS stage attempts to align DQ and DQS signals on reads
 * within a group.
 */
static int
rw_mgr_mem_calibrate_dq_dqs_centering(struct socfpga_sdrseq *seq,
				      const u32 rw_group, const u32 test_bgn,
				      const int use_read_test,
				      const int update_fom)

{
	int ret, grp_calibrated;
	u32 rank_bgn, sr;

	/*
	 * Altera EMI_RM 2015.05.04 :: Figure 1-28
	 * Read per-bit deskew can be done on a per shadow register basis.
	 */
	grp_calibrated = 1;
	for (rank_bgn = 0, sr = 0;
	     rank_bgn < seq->rwcfg->mem_number_of_ranks;
	     rank_bgn += NUM_RANKS_PER_SHADOW_REG, sr++) {
		ret = rw_mgr_mem_calibrate_vfifo_center(seq, rank_bgn, rw_group,
							test_bgn,
							use_read_test,
							update_fom);
		if (!ret)
			continue;

		grp_calibrated = 0;
	}

	if (!grp_calibrated)
		return -EIO;

	return 0;
}

/**
 * rw_mgr_mem_calibrate_vfifo() - Calibrate the read valid prediction FIFO
 * @rw_group:		Read/Write Group
 * @test_bgn:		Rank at which the test begins
 *
 * Stage 1: Calibrate the read valid prediction FIFO.
 *
 * This function implements UniPHY calibration Stage 1, as explained in
 * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
 *
 * - read valid prediction will consist of finding:
 *   - DQS enable phase and DQS enable delay (DQS Enable Calibration)
 *   - DQS input phase  and DQS input delay (DQ/DQS Centering)
 *  - we also do a per-bit deskew on the DQ lines.
 */
static int rw_mgr_mem_calibrate_vfifo(struct socfpga_sdrseq *seq,
				      const u32 rw_group, const u32 test_bgn)
{
	u32 p, d;
	u32 dtaps_per_ptap;
	u32 failed_substage;

	int ret;

	debug("%s:%d: %u %u\n", __func__, __LINE__, rw_group, test_bgn);

	/* Update info for sims */
	reg_file_set_group(rw_group);
	reg_file_set_stage(CAL_STAGE_VFIFO);
	reg_file_set_sub_stage(CAL_SUBSTAGE_GUARANTEED_READ);

	failed_substage = CAL_SUBSTAGE_GUARANTEED_READ;

	/* USER Determine number of delay taps for each phase tap. */
	dtaps_per_ptap = DIV_ROUND_UP(seq->iocfg->delay_per_opa_tap,
				      seq->iocfg->delay_per_dqs_en_dchain_tap)
				      - 1;

	for (d = 0; d <= dtaps_per_ptap; d += 2) {
		/*
		 * In RLDRAMX we may be messing the delay of pins in
		 * the same write rw_group but outside of the current read
		 * the rw_group, but that's ok because we haven't calibrated
		 * output side yet.
		 */
		if (d > 0) {
			scc_mgr_apply_group_all_out_delay_add_all_ranks(seq,
									rw_group,
									d);
		}

		for (p = 0; p <= seq->iocfg->dqdqs_out_phase_max; p++) {
			/* 1) Guaranteed Write */
			ret = rw_mgr_mem_calibrate_guaranteed_write(seq,
								    rw_group,
								    p);
			if (ret)
				break;

			/* 2) DQS Enable Calibration */
			ret = rw_mgr_mem_calibrate_dqs_enable_calibration(seq,
									  rw_group,
									  test_bgn);
			if (ret) {
				failed_substage = CAL_SUBSTAGE_DQS_EN_PHASE;
				continue;
			}

			/* 3) Centering DQ/DQS */
			/*
			 * If doing read after write calibration, do not update
			 * FOM now. Do it then.
			 */
			ret = rw_mgr_mem_calibrate_dq_dqs_centering(seq,
								    rw_group,
								    test_bgn,
								    1, 0);
			if (ret) {
				failed_substage = CAL_SUBSTAGE_VFIFO_CENTER;
				continue;
			}

			/* All done. */
			goto cal_done_ok;
		}
	}

	/* Calibration Stage 1 failed. */
	set_failing_group_stage(seq, rw_group, CAL_STAGE_VFIFO,
				failed_substage);
	return 0;

	/* Calibration Stage 1 completed OK. */
cal_done_ok:
	/*
	 * Reset the delay chains back to zero if they have moved > 1
	 * (check for > 1 because loop will increase d even when pass in
	 * first case).
	 */
	if (d > 2)
		scc_mgr_zero_group(seq, rw_group, 1);

	return 1;
}

/**
 * rw_mgr_mem_calibrate_vfifo_end() - DQ/DQS Centering.
 * @rw_group:		Read/Write Group
 * @test_bgn:		Rank at which the test begins
 *
 * Stage 3: DQ/DQS Centering.
 *
 * This function implements UniPHY calibration Stage 3, as explained in
 * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
 */
static int rw_mgr_mem_calibrate_vfifo_end(struct socfpga_sdrseq *seq,
					  const u32 rw_group,
					  const u32 test_bgn)
{
	int ret;

	debug("%s:%d %u %u", __func__, __LINE__, rw_group, test_bgn);

	/* Update info for sims. */
	reg_file_set_group(rw_group);
	reg_file_set_stage(CAL_STAGE_VFIFO_AFTER_WRITES);
	reg_file_set_sub_stage(CAL_SUBSTAGE_VFIFO_CENTER);

	ret = rw_mgr_mem_calibrate_dq_dqs_centering(seq, rw_group, test_bgn, 0,
						    1);
	if (ret)
		set_failing_group_stage(seq, rw_group,
					CAL_STAGE_VFIFO_AFTER_WRITES,
					CAL_SUBSTAGE_VFIFO_CENTER);
	return ret;
}

/**
 * rw_mgr_mem_calibrate_lfifo() - Minimize latency
 *
 * Stage 4: Minimize latency.
 *
 * This function implements UniPHY calibration Stage 4, as explained in
 * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
 * Calibrate LFIFO to find smallest read latency.
 */
static u32 rw_mgr_mem_calibrate_lfifo(struct socfpga_sdrseq *seq)
{
	int found_one = 0;

	debug("%s:%d\n", __func__, __LINE__);

	/* Update info for sims. */
	reg_file_set_stage(CAL_STAGE_LFIFO);
	reg_file_set_sub_stage(CAL_SUBSTAGE_READ_LATENCY);

	/* Load up the patterns used by read calibration for all ranks */
	rw_mgr_mem_calibrate_read_load_patterns(seq, 0, 1);

	do {
		writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);
		debug_cond(DLEVEL >= 2, "%s:%d lfifo: read_lat=%u",
			   __func__, __LINE__, seq->gbl.curr_read_lat);

		if (!rw_mgr_mem_calibrate_read_test_all_ranks(seq, 0,
							      NUM_READ_TESTS,
							      PASS_ALL_BITS, 1))
			break;

		found_one = 1;
		/*
		 * Reduce read latency and see if things are
		 * working correctly.
		 */
		seq->gbl.curr_read_lat--;
	} while (seq->gbl.curr_read_lat > 0);

	/* Reset the fifos to get pointers to known state. */
	writel(0, &phy_mgr_cmd->fifo_reset);

	if (found_one) {
		/* Add a fudge factor to the read latency that was determined */
		seq->gbl.curr_read_lat += 2;
		writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);
		debug_cond(DLEVEL >= 2,
			   "%s:%d lfifo: success: using read_lat=%u\n",
			   __func__, __LINE__, seq->gbl.curr_read_lat);
	} else {
		set_failing_group_stage(seq, 0xff, CAL_STAGE_LFIFO,
					CAL_SUBSTAGE_READ_LATENCY);

		debug_cond(DLEVEL >= 2,
			   "%s:%d lfifo: failed at initial read_lat=%u\n",
			   __func__, __LINE__, seq->gbl.curr_read_lat);
	}

	return found_one;
}

/**
 * search_window() - Search for the/part of the window with DM/DQS shift
 * @search_dm:		If 1, search for the DM shift, if 0, search for DQS
 *			shift
 * @rank_bgn:		Rank number
 * @write_group:	Write Group
 * @bgn_curr:		Current window begin
 * @end_curr:		Current window end
 * @bgn_best:		Current best window begin
 * @end_best:		Current best window end
 * @win_best:		Size of the best window
 * @new_dqs:		New DQS value (only applicable if search_dm = 0).
 *
 * Search for the/part of the window with DM/DQS shift.
 */
static void search_window(struct socfpga_sdrseq *seq,
			  const int search_dm, const u32 rank_bgn,
			  const u32 write_group, int *bgn_curr, int *end_curr,
			  int *bgn_best, int *end_best, int *win_best,
			  int new_dqs)
{
	u32 bit_chk;
	const int max = seq->iocfg->io_out1_delay_max - new_dqs;
	int d, di;

	/* Search for the/part of the window with DM/DQS shift. */
	for (di = max; di >= 0; di -= DELTA_D) {
		if (search_dm) {
			d = di;
			scc_mgr_apply_group_dm_out1_delay(seq, d);
		} else {
			/* For DQS, we go from 0...max */
			d = max - di;
			/*
			 * Note: This only shifts DQS, so are we limiting
			 *       ourselves to width of DQ unnecessarily.
			 */
			scc_mgr_apply_group_dqs_io_and_oct_out1(seq,
								write_group,
								d + new_dqs);
		}

		writel(0, &sdr_scc_mgr->update);

		if (rw_mgr_mem_calibrate_write_test(seq, rank_bgn, write_group,
						    1, PASS_ALL_BITS, &bit_chk,
						    0)) {
			/* Set current end of the window. */
			*end_curr = search_dm ? -d : d;

			/*
			 * If a starting edge of our window has not been seen
			 * this is our current start of the DM window.
			 */
			if (*bgn_curr == seq->iocfg->io_out1_delay_max + 1)
				*bgn_curr = search_dm ? -d : d;

			/*
			 * If current window is bigger than best seen.
			 * Set best seen to be current window.
			 */
			if ((*end_curr - *bgn_curr + 1) > *win_best) {
				*win_best = *end_curr - *bgn_curr + 1;
				*bgn_best = *bgn_curr;
				*end_best = *end_curr;
			}
		} else {
			/* We just saw a failing test. Reset temp edge. */
			*bgn_curr = seq->iocfg->io_out1_delay_max + 1;
			*end_curr = seq->iocfg->io_out1_delay_max + 1;

			/* Early exit is only applicable to DQS. */
			if (search_dm)
				continue;

			/*
			 * Early exit optimization: if the remaining delay
			 * chain space is less than already seen largest
			 * window we can exit.
			 */
			if (*win_best - 1 > seq->iocfg->io_out1_delay_max
				- new_dqs - d)
				break;
		}
	}
}

/*
 * rw_mgr_mem_calibrate_writes_center() - Center all windows
 * @rank_bgn:		Rank number
 * @write_group:	Write group
 * @test_bgn:		Rank at which the test begins
 *
 * Center all windows. Do per-bit-deskew to possibly increase size of
 * certain windows.
 */
static int
rw_mgr_mem_calibrate_writes_center(struct socfpga_sdrseq *seq,
				   const u32 rank_bgn, const u32 write_group,
				   const u32 test_bgn)
{
	int i;
	u32 sticky_bit_chk;
	u32 min_index;
	int left_edge[seq->rwcfg->mem_dq_per_write_dqs];
	int right_edge[seq->rwcfg->mem_dq_per_write_dqs];
	int mid;
	int mid_min, orig_mid_min;
	int new_dqs, start_dqs;
	int dq_margin, dqs_margin, dm_margin;
	int bgn_curr = seq->iocfg->io_out1_delay_max + 1;
	int end_curr = seq->iocfg->io_out1_delay_max + 1;
	int bgn_best = seq->iocfg->io_out1_delay_max + 1;
	int end_best = seq->iocfg->io_out1_delay_max + 1;
	int win_best = 0;

	int ret;

	debug("%s:%d %u %u", __func__, __LINE__, write_group, test_bgn);

	dm_margin = 0;

	start_dqs = readl((SDR_PHYGRP_SCCGRP_ADDRESS |
			  SCC_MGR_IO_OUT1_DELAY_OFFSET) +
			  (seq->rwcfg->mem_dq_per_write_dqs << 2));

	/* Per-bit deskew. */

	/*
	 * Set the left and right edge of each bit to an illegal value.
	 * Use (seq->iocfg->io_out1_delay_max + 1) as an illegal value.
	 */
	sticky_bit_chk = 0;
	for (i = 0; i < seq->rwcfg->mem_dq_per_write_dqs; i++) {
		left_edge[i]  = seq->iocfg->io_out1_delay_max + 1;
		right_edge[i] = seq->iocfg->io_out1_delay_max + 1;
	}

	/* Search for the left edge of the window for each bit. */
	search_left_edge(seq, 1, rank_bgn, write_group, 0, test_bgn,
			 &sticky_bit_chk,
			 left_edge, right_edge, 0);

	/* Search for the right edge of the window for each bit. */
	ret = search_right_edge(seq, 1, rank_bgn, write_group, 0,
				start_dqs, 0,
				&sticky_bit_chk,
				left_edge, right_edge, 0);
	if (ret) {
		set_failing_group_stage(seq, test_bgn + ret - 1,
					CAL_STAGE_WRITES,
					CAL_SUBSTAGE_WRITES_CENTER);
		return -EINVAL;
	}

	min_index = get_window_mid_index(seq, 1, left_edge, right_edge,
					 &mid_min);

	/* Determine the amount we can change DQS (which is -mid_min). */
	orig_mid_min = mid_min;
	new_dqs = start_dqs;
	mid_min = 0;
	debug_cond(DLEVEL >= 1,
		   "%s:%d write_center: start_dqs=%d new_dqs=%d mid_min=%d\n",
		   __func__, __LINE__, start_dqs, new_dqs, mid_min);

	/* Add delay to bring centre of all DQ windows to the same "level". */
	center_dq_windows(seq, 1, left_edge, right_edge, mid_min, orig_mid_min,
			  min_index, 0, &dq_margin, &dqs_margin);

	/* Move DQS */
	scc_mgr_apply_group_dqs_io_and_oct_out1(seq, write_group, new_dqs);
	writel(0, &sdr_scc_mgr->update);

	/* Centre DM */
	debug_cond(DLEVEL >= 2, "%s:%d write_center: DM\n", __func__, __LINE__);

	/* Search for the/part of the window with DM shift. */
	search_window(seq, 1, rank_bgn, write_group, &bgn_curr, &end_curr,
		      &bgn_best, &end_best, &win_best, 0);

	/* Reset DM delay chains to 0. */
	scc_mgr_apply_group_dm_out1_delay(seq, 0);

	/*
	 * Check to see if the current window nudges up aganist 0 delay.
	 * If so we need to continue the search by shifting DQS otherwise DQS
	 * search begins as a new search.
	 */
	if (end_curr != 0) {
		bgn_curr = seq->iocfg->io_out1_delay_max + 1;
		end_curr = seq->iocfg->io_out1_delay_max + 1;
	}

	/* Search for the/part of the window with DQS shifts. */
	search_window(seq, 0, rank_bgn, write_group, &bgn_curr, &end_curr,
		      &bgn_best, &end_best, &win_best, new_dqs);

	/* Assign left and right edge for cal and reporting. */
	left_edge[0] = -1 * bgn_best;
	right_edge[0] = end_best;

	debug_cond(DLEVEL >= 2, "%s:%d dm_calib: left=%d right=%d\n",
		   __func__, __LINE__, left_edge[0], right_edge[0]);

	/* Move DQS (back to orig). */
	scc_mgr_apply_group_dqs_io_and_oct_out1(seq, write_group, new_dqs);

	/* Move DM */

	/* Find middle of window for the DM bit. */
	mid = (left_edge[0] - right_edge[0]) / 2;

	/* Only move right, since we are not moving DQS/DQ. */
	if (mid < 0)
		mid = 0;

	/* dm_marign should fail if we never find a window. */
	if (win_best == 0)
		dm_margin = -1;
	else
		dm_margin = left_edge[0] - mid;

	scc_mgr_apply_group_dm_out1_delay(seq, mid);
	writel(0, &sdr_scc_mgr->update);

	debug_cond(DLEVEL >= 2,
		   "%s:%d dm_calib: left=%d right=%d mid=%d dm_margin=%d\n",
		   __func__, __LINE__, left_edge[0], right_edge[0],
		   mid, dm_margin);
	/* Export values. */
	seq->gbl.fom_out += dq_margin + dqs_margin;

	debug_cond(DLEVEL >= 2,
		   "%s:%d write_center: dq_margin=%d dqs_margin=%d dm_margin=%d\n",
		   __func__, __LINE__, dq_margin, dqs_margin, dm_margin);

	/*
	 * Do not remove this line as it makes sure all of our
	 * decisions have been applied.
	 */
	writel(0, &sdr_scc_mgr->update);

	if ((dq_margin < 0) || (dqs_margin < 0) || (dm_margin < 0))
		return -EINVAL;

	return 0;
}

/**
 * rw_mgr_mem_calibrate_writes() - Write Calibration Part One
 * @rank_bgn:		Rank number
 * @group:		Read/Write Group
 * @test_bgn:		Rank at which the test begins
 *
 * Stage 2: Write Calibration Part One.
 *
 * This function implements UniPHY calibration Stage 2, as explained in
 * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
 */
static int rw_mgr_mem_calibrate_writes(struct socfpga_sdrseq *seq,
				       const u32 rank_bgn, const u32 group,
				       const u32 test_bgn)
{
	int ret;

	/* Update info for sims */
	debug("%s:%d %u %u\n", __func__, __LINE__, group, test_bgn);

	reg_file_set_group(group);
	reg_file_set_stage(CAL_STAGE_WRITES);
	reg_file_set_sub_stage(CAL_SUBSTAGE_WRITES_CENTER);

	ret = rw_mgr_mem_calibrate_writes_center(seq, rank_bgn, group,
						 test_bgn);
	if (ret)
		set_failing_group_stage(seq, group, CAL_STAGE_WRITES,
					CAL_SUBSTAGE_WRITES_CENTER);

	return ret;
}

/**
 * mem_precharge_and_activate() - Precharge all banks and activate
 *
 * Precharge all banks and activate row 0 in bank "000..." and bank "111...".
 */
static void mem_precharge_and_activate(struct socfpga_sdrseq *seq)
{
	int r;

	for (r = 0; r < seq->rwcfg->mem_number_of_ranks; r++) {
		/* Set rank. */
		set_rank_and_odt_mask(seq, r, RW_MGR_ODT_MODE_OFF);

		/* Precharge all banks. */
		writel(seq->rwcfg->precharge_all, SDR_PHYGRP_RWMGRGRP_ADDRESS |
					     RW_MGR_RUN_SINGLE_GROUP_OFFSET);

		writel(0x0F, &sdr_rw_load_mgr_regs->load_cntr0);
		writel(seq->rwcfg->activate_0_and_1_wait1,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add0);

		writel(0x0F, &sdr_rw_load_mgr_regs->load_cntr1);
		writel(seq->rwcfg->activate_0_and_1_wait2,
		       &sdr_rw_load_jump_mgr_regs->load_jump_add1);

		/* Activate rows. */
		writel(seq->rwcfg->activate_0_and_1,
		       SDR_PHYGRP_RWMGRGRP_ADDRESS |
		       RW_MGR_RUN_SINGLE_GROUP_OFFSET);
	}
}

/**
 * mem_init_latency() - Configure memory RLAT and WLAT settings
 *
 * Configure memory RLAT and WLAT parameters.
 */
static void mem_init_latency(struct socfpga_sdrseq *seq)
{
	/*
	 * For AV/CV, LFIFO is hardened and always runs at full rate
	 * so max latency in AFI clocks, used here, is correspondingly
	 * smaller.
	 */
	const u32 max_latency = (1 << seq->misccfg->max_latency_count_width)
		- 1;
	u32 rlat, wlat;

	debug("%s:%d\n", __func__, __LINE__);

	/*
	 * Read in write latency.
	 * WL for Hard PHY does not include additive latency.
	 */
	wlat = readl(&data_mgr->t_wl_add);
	wlat += readl(&data_mgr->mem_t_add);

	seq->gbl.rw_wl_nop_cycles = wlat - 1;

	/* Read in readl latency. */
	rlat = readl(&data_mgr->t_rl_add);

	/* Set a pretty high read latency initially. */
	seq->gbl.curr_read_lat = rlat + 16;
	if (seq->gbl.curr_read_lat > max_latency)
		seq->gbl.curr_read_lat = max_latency;

	writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);

	/* Advertise write latency. */
	writel(wlat, &phy_mgr_cfg->afi_wlat);
}

/**
 * @mem_skip_calibrate() - Set VFIFO and LFIFO to instant-on settings
 *
 * Set VFIFO and LFIFO to instant-on settings in skip calibration mode.
 */
static void mem_skip_calibrate(struct socfpga_sdrseq *seq)
{
	u32 vfifo_offset;
	u32 i, j, r;

	debug("%s:%d\n", __func__, __LINE__);
	/* Need to update every shadow register set used by the interface */
	for (r = 0; r < seq->rwcfg->mem_number_of_ranks;
	     r += NUM_RANKS_PER_SHADOW_REG) {
		/*
		 * Set output phase alignment settings appropriate for
		 * skip calibration.
		 */
		for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
			scc_mgr_set_dqs_en_phase(i, 0);
			if (seq->iocfg->dll_chain_length == 6)
				scc_mgr_set_dqdqs_output_phase(i, 6);
			else
				scc_mgr_set_dqdqs_output_phase(i, 7);
			/*
			 * Case:33398
			 *
			 * Write data arrives to the I/O two cycles before write
			 * latency is reached (720 deg).
			 *   -> due to bit-slip in a/c bus
			 *   -> to allow board skew where dqs is longer than ck
			 *      -> how often can this happen!?
			 *      -> can claim back some ptaps for high freq
			 *       support if we can relax this, but i digress...
			 *
			 * The write_clk leads mem_ck by 90 deg
			 * The minimum ptap of the OPA is 180 deg
			 * Each ptap has (360 / IO_DLL_CHAIN_LENGH) deg of delay
			 * The write_clk is always delayed by 2 ptaps
			 *
			 * Hence, to make DQS aligned to CK, we need to delay
			 * DQS by:
			 *    (720 - 90 - 180 - 2) *
			 *      (360 / seq->iocfg->dll_chain_length)
			 *
			 * Dividing the above by
			 (360 / seq->iocfg->dll_chain_length)
			 * gives us the number of ptaps, which simplies to:
			 *
			 *    (1.25 * seq->iocfg->dll_chain_length - 2)
			 */
			scc_mgr_set_dqdqs_output_phase(i,
				       ((125 * seq->iocfg->dll_chain_length)
				       / 100) - 2);
		}
		writel(0xff, &sdr_scc_mgr->dqs_ena);
		writel(0xff, &sdr_scc_mgr->dqs_io_ena);

		for (i = 0; i < seq->rwcfg->mem_if_write_dqs_width; i++) {
			writel(i, SDR_PHYGRP_SCCGRP_ADDRESS |
				  SCC_MGR_GROUP_COUNTER_OFFSET);
		}
		writel(0xff, &sdr_scc_mgr->dq_ena);
		writel(0xff, &sdr_scc_mgr->dm_ena);
		writel(0, &sdr_scc_mgr->update);
	}

	/* Compensate for simulation model behaviour */
	for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
		scc_mgr_set_dqs_bus_in_delay(i, 10);
		scc_mgr_load_dqs(i);
	}
	writel(0, &sdr_scc_mgr->update);

	/*
	 * ArriaV has hard FIFOs that can only be initialized by incrementing
	 * in sequencer.
	 */
	vfifo_offset = seq->misccfg->calib_vfifo_offset;
	for (j = 0; j < vfifo_offset; j++)
		writel(0xff, &phy_mgr_cmd->inc_vfifo_hard_phy);
	writel(0, &phy_mgr_cmd->fifo_reset);

	/*
	 * For Arria V and Cyclone V with hard LFIFO, we get the skip-cal
	 * setting from generation-time constant.
	 */
	seq->gbl.curr_read_lat = seq->misccfg->calib_lfifo_offset;
	writel(seq->gbl.curr_read_lat, &phy_mgr_cfg->phy_rlat);
}

/**
 * mem_calibrate() - Memory calibration entry point.
 *
 * Perform memory calibration.
 */
static u32 mem_calibrate(struct socfpga_sdrseq *seq)
{
	u32 i;
	u32 rank_bgn, sr;
	u32 write_group, write_test_bgn;
	u32 read_group, read_test_bgn;
	u32 run_groups, current_run;
	u32 failing_groups = 0;
	u32 group_failed = 0;

	const u32 rwdqs_ratio = seq->rwcfg->mem_if_read_dqs_width /
				seq->rwcfg->mem_if_write_dqs_width;

	debug("%s:%d\n", __func__, __LINE__);

	/* Initialize the data settings */
	seq->gbl.error_substage = CAL_SUBSTAGE_NIL;
	seq->gbl.error_stage = CAL_STAGE_NIL;
	seq->gbl.error_group = 0xff;
	seq->gbl.fom_in = 0;
	seq->gbl.fom_out = 0;

	/* Initialize WLAT and RLAT. */
	mem_init_latency(seq);

	/* Initialize bit slips. */
	mem_precharge_and_activate(seq);

	for (i = 0; i < seq->rwcfg->mem_if_read_dqs_width; i++) {
		writel(i, SDR_PHYGRP_SCCGRP_ADDRESS |
			  SCC_MGR_GROUP_COUNTER_OFFSET);
		/* Only needed once to set all groups, pins, DQ, DQS, DM. */
		if (i == 0)
			scc_mgr_set_hhp_extras();

		scc_set_bypass_mode(i);
	}

	/* Calibration is skipped. */
	if ((seq->dyn_calib_steps & CALIB_SKIP_ALL) == CALIB_SKIP_ALL) {
		/*
		 * Set VFIFO and LFIFO to instant-on settings in skip
		 * calibration mode.
		 */
		mem_skip_calibrate(seq);

		/*
		 * Do not remove this line as it makes sure all of our
		 * decisions have been applied.
		 */
		writel(0, &sdr_scc_mgr->update);
		return 1;
	}

	/* Calibration is not skipped. */
	for (i = 0; i < NUM_CALIB_REPEAT; i++) {
		/*
		 * Zero all delay chain/phase settings for all
		 * groups and all shadow register sets.
		 */
		scc_mgr_zero_all(seq);

		run_groups = ~0;

		for (write_group = 0, write_test_bgn = 0; write_group
			< seq->rwcfg->mem_if_write_dqs_width; write_group++,
			write_test_bgn += seq->rwcfg->mem_dq_per_write_dqs) {
			/* Initialize the group failure */
			group_failed = 0;

			current_run = run_groups & ((1 <<
				RW_MGR_NUM_DQS_PER_WRITE_GROUP) - 1);
			run_groups = run_groups >>
				RW_MGR_NUM_DQS_PER_WRITE_GROUP;

			if (current_run == 0)
				continue;

			writel(write_group, SDR_PHYGRP_SCCGRP_ADDRESS |
					    SCC_MGR_GROUP_COUNTER_OFFSET);
			scc_mgr_zero_group(seq, write_group, 0);

			for (read_group = write_group * rwdqs_ratio,
			     read_test_bgn = 0;
			     read_group < (write_group + 1) * rwdqs_ratio;
			     read_group++,
			     read_test_bgn += seq->rwcfg->mem_dq_per_read_dqs) {
				if (STATIC_CALIB_STEPS & CALIB_SKIP_VFIFO)
					continue;

				/* Calibrate the VFIFO */
				if (rw_mgr_mem_calibrate_vfifo(seq, read_group,
							       read_test_bgn))
					continue;

				if (!(seq->gbl.phy_debug_mode_flags &
				      PHY_DEBUG_SWEEP_ALL_GROUPS))
					return 0;

				/* The group failed, we're done. */
				goto grp_failed;
			}

			/* Calibrate the output side */
			for (rank_bgn = 0, sr = 0;
			     rank_bgn < seq->rwcfg->mem_number_of_ranks;
			     rank_bgn += NUM_RANKS_PER_SHADOW_REG, sr++) {
				if (STATIC_CALIB_STEPS & CALIB_SKIP_WRITES)
					continue;

				/* Not needed in quick mode! */
				if (STATIC_CALIB_STEPS &
				    CALIB_SKIP_DELAY_SWEEPS)
					continue;

				/* Calibrate WRITEs */
				if (!rw_mgr_mem_calibrate_writes(seq, rank_bgn,
								 write_group,
								 write_test_bgn))
					continue;

				group_failed = 1;
				if (!(seq->gbl.phy_debug_mode_flags &
				      PHY_DEBUG_SWEEP_ALL_GROUPS))
					return 0;
			}

			/* Some group failed, we're done. */
			if (group_failed)
				goto grp_failed;

			for (read_group = write_group * rwdqs_ratio,
			     read_test_bgn = 0;
			     read_group < (write_group + 1) * rwdqs_ratio;
			     read_group++,
			     read_test_bgn += seq->rwcfg->mem_dq_per_read_dqs) {
				if (STATIC_CALIB_STEPS & CALIB_SKIP_WRITES)
					continue;

				if (!rw_mgr_mem_calibrate_vfifo_end(seq,
								    read_group,
								    read_test_bgn))
					continue;

				if (!(seq->gbl.phy_debug_mode_flags &
				      PHY_DEBUG_SWEEP_ALL_GROUPS))
					return 0;

				/* The group failed, we're done. */
				goto grp_failed;
			}

			/* No group failed, continue as usual. */
			continue;

grp_failed:		/* A group failed, increment the counter. */
			failing_groups++;
		}

		/*
		 * USER If there are any failing groups then report
		 * the failure.
		 */
		if (failing_groups != 0)
			return 0;

		if (STATIC_CALIB_STEPS & CALIB_SKIP_LFIFO)
			continue;

		/* Calibrate the LFIFO */
		if (!rw_mgr_mem_calibrate_lfifo(seq))
			return 0;
	}

	/*
	 * Do not remove this line as it makes sure all of our decisions
	 * have been applied.
	 */
	writel(0, &sdr_scc_mgr->update);
	return 1;
}

/**
 * run_mem_calibrate() - Perform memory calibration
 *
 * This function triggers the entire memory calibration procedure.
 */
static int run_mem_calibrate(struct socfpga_sdrseq *seq)
{
	int pass;
	u32 ctrl_cfg;

	debug("%s:%d\n", __func__, __LINE__);

	/* Reset pass/fail status shown on afi_cal_success/fail */
	writel(PHY_MGR_CAL_RESET, &phy_mgr_cfg->cal_status);

	/* Stop tracking manager. */
	ctrl_cfg = readl(&sdr_ctrl->ctrl_cfg);
	writel(ctrl_cfg & ~SDR_CTRLGRP_CTRLCFG_DQSTRKEN_MASK,
	       &sdr_ctrl->ctrl_cfg);

	phy_mgr_initialize(seq);
	rw_mgr_mem_initialize(seq);

	/* Perform the actual memory calibration. */
	pass = mem_calibrate(seq);

	mem_precharge_and_activate(seq);
	writel(0, &phy_mgr_cmd->fifo_reset);

	/* Handoff. */
	rw_mgr_mem_handoff(seq);
	/*
	 * In Hard PHY this is a 2-bit control:
	 * 0: AFI Mux Select
	 * 1: DDIO Mux Select
	 */
	writel(0x2, &phy_mgr_cfg->mux_sel);

	/* Start tracking manager. */
	writel(ctrl_cfg, &sdr_ctrl->ctrl_cfg);

	return pass;
}

/**
 * debug_mem_calibrate() - Report result of memory calibration
 * @pass:	Value indicating whether calibration passed or failed
 *
 * This function reports the results of the memory calibration
 * and writes debug information into the register file.
 */
static void debug_mem_calibrate(struct socfpga_sdrseq *seq, int pass)
{
	u32 debug_info;

	if (pass) {
		debug(KBUILD_BASENAME ": CALIBRATION PASSED\n");

		seq->gbl.fom_in /= 2;
		seq->gbl.fom_out /= 2;

		if (seq->gbl.fom_in > 0xff)
			seq->gbl.fom_in = 0xff;

		if (seq->gbl.fom_out > 0xff)
			seq->gbl.fom_out = 0xff;

		/* Update the FOM in the register file */
		debug_info = seq->gbl.fom_in;
		debug_info |= seq->gbl.fom_out << 8;
		writel(debug_info, &sdr_reg_file->fom);

		writel(debug_info, &phy_mgr_cfg->cal_debug_info);
		writel(PHY_MGR_CAL_SUCCESS, &phy_mgr_cfg->cal_status);
	} else {
		debug(KBUILD_BASENAME ": CALIBRATION FAILED\n");

		debug_info = seq->gbl.error_stage;
		debug_info |= seq->gbl.error_substage << 8;
		debug_info |= seq->gbl.error_group << 16;

		writel(debug_info, &sdr_reg_file->failing_stage);
		writel(debug_info, &phy_mgr_cfg->cal_debug_info);
		writel(PHY_MGR_CAL_FAIL, &phy_mgr_cfg->cal_status);

		/* Update the failing group/stage in the register file */
		debug_info = seq->gbl.error_stage;
		debug_info |= seq->gbl.error_substage << 8;
		debug_info |= seq->gbl.error_group << 16;
		writel(debug_info, &sdr_reg_file->failing_stage);
	}

	debug(KBUILD_BASENAME ": Calibration complete\n");
}

/**
 * hc_initialize_rom_data() - Initialize ROM data
 *
 * Initialize ROM data.
 */
static void hc_initialize_rom_data(void)
{
	unsigned int nelem = 0;
	const u32 *rom_init;
	u32 i, addr;

	socfpga_get_seq_inst_init(&rom_init, &nelem);
	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_INST_ROM_WRITE_OFFSET;
	for (i = 0; i < nelem; i++)
		writel(rom_init[i], addr + (i << 2));

	socfpga_get_seq_ac_init(&rom_init, &nelem);
	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_AC_ROM_WRITE_OFFSET;
	for (i = 0; i < nelem; i++)
		writel(rom_init[i], addr + (i << 2));
}

/**
 * initialize_reg_file() - Initialize SDR register file
 *
 * Initialize SDR register file.
 */
static void initialize_reg_file(struct socfpga_sdrseq *seq)
{
	/* Initialize the register file with the correct data */
	writel(seq->misccfg->reg_file_init_seq_signature,
	       &sdr_reg_file->signature);
	writel(0, &sdr_reg_file->debug_data_addr);
	writel(0, &sdr_reg_file->cur_stage);
	writel(0, &sdr_reg_file->fom);
	writel(0, &sdr_reg_file->failing_stage);
	writel(0, &sdr_reg_file->debug1);
	writel(0, &sdr_reg_file->debug2);
}

/**
 * initialize_hps_phy() - Initialize HPS PHY
 *
 * Initialize HPS PHY.
 */
static void initialize_hps_phy(void)
{
	u32 reg;
	/*
	 * Tracking also gets configured here because it's in the
	 * same register.
	 */
	u32 trk_sample_count = 7500;
	u32 trk_long_idle_sample_count = (10 << 16) | 100;
	/*
	 * Format is number of outer loops in the 16 MSB, sample
	 * count in 16 LSB.
	 */

	reg = 0;
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_ACDELAYEN_SET(2);
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_DQDELAYEN_SET(1);
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_DQSDELAYEN_SET(1);
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_DQSLOGICDELAYEN_SET(1);
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_RESETDELAYEN_SET(0);
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_LPDDRDIS_SET(1);
	/*
	 * This field selects the intrinsic latency to RDATA_EN/FULL path.
	 * 00-bypass, 01- add 5 cycles, 10- add 10 cycles, 11- add 15 cycles.
	 */
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_ADDLATSEL_SET(0);
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_SAMPLECOUNT_19_0_SET(
		trk_sample_count);
	writel(reg, &sdr_ctrl->phy_ctrl0);

	reg = 0;
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_1_SAMPLECOUNT_31_20_SET(
		trk_sample_count >>
		SDR_CTRLGRP_PHYCTRL_PHYCTRL_0_SAMPLECOUNT_19_0_WIDTH);
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_1_LONGIDLESAMPLECOUNT_19_0_SET(
		trk_long_idle_sample_count);
	writel(reg, &sdr_ctrl->phy_ctrl1);

	reg = 0;
	reg |= SDR_CTRLGRP_PHYCTRL_PHYCTRL_2_LONGIDLESAMPLECOUNT_31_20_SET(
		trk_long_idle_sample_count >>
		SDR_CTRLGRP_PHYCTRL_PHYCTRL_1_LONGIDLESAMPLECOUNT_19_0_WIDTH);
	writel(reg, &sdr_ctrl->phy_ctrl2);
}

/**
 * initialize_tracking() - Initialize tracking
 *
 * Initialize the register file with usable initial data.
 */
static void initialize_tracking(struct socfpga_sdrseq *seq)
{
	/*
	 * Initialize the register file with the correct data.
	 * Compute usable version of value in case we skip full
	 * computation later.
	 */
	writel(DIV_ROUND_UP(seq->iocfg->delay_per_opa_tap,
			    seq->iocfg->delay_per_dchain_tap) - 1,
	       &sdr_reg_file->dtaps_per_ptap);

	/* trk_sample_count */
	writel(7500, &sdr_reg_file->trk_sample_count);

	/* longidle outer loop [15:0] */
	writel((10 << 16) | (100 << 0), &sdr_reg_file->trk_longidle);

	/*
	 * longidle sample count [31:24]
	 * trfc, worst case of 933Mhz 4Gb [23:16]
	 * trcd, worst case [15:8]
	 * vfifo wait [7:0]
	 */
	writel((243 << 24) | (14 << 16) | (10 << 8) | (4 << 0),
	       &sdr_reg_file->delays);

	/* mux delay */
	if (dram_is_ddr(2)) {
		writel(0, &sdr_reg_file->trk_rw_mgr_addr);
	} else if (dram_is_ddr(3)) {
		writel((seq->rwcfg->idle << 24) |
		       (seq->rwcfg->activate_1 << 16) |
		       (seq->rwcfg->sgle_read << 8) |
		       (seq->rwcfg->precharge_all << 0),
		       &sdr_reg_file->trk_rw_mgr_addr);
	}

	writel(seq->rwcfg->mem_if_read_dqs_width,
	       &sdr_reg_file->trk_read_dqs_width);

	/* trefi [7:0] */
	if (dram_is_ddr(2)) {
		writel(1000 << 0, &sdr_reg_file->trk_rfsh);
	} else if (dram_is_ddr(3)) {
		writel((seq->rwcfg->refresh_all << 24) | (1000 << 0),
		       &sdr_reg_file->trk_rfsh);
	}
}

int sdram_calibration_full(struct socfpga_sdr *sdr)
{
	u32 pass;
	struct socfpga_sdrseq seq;

	/*
	 * For size reasons, this file uses hard coded addresses.
	 * Check if we are called with the correct address.
	 */
	if (sdr != (struct socfpga_sdr *)SOCFPGA_SDR_ADDRESS)
		return -ENODEV;

	memset(&seq, 0, sizeof(seq));

	seq.rwcfg = socfpga_get_sdram_rwmgr_config();
	seq.iocfg = socfpga_get_sdram_io_config();
	seq.misccfg = socfpga_get_sdram_misc_config();

	/* Set the calibration enabled by default */
	seq.gbl.phy_debug_mode_flags |= PHY_DEBUG_ENABLE_CAL_RPT;
	/*
	 * Only sweep all groups (regardless of fail state) by default
	 * Set enabled read test by default.
	 */
#if DISABLE_GUARANTEED_READ
	seq.gbl.phy_debug_mode_flags |= PHY_DEBUG_DISABLE_GUARANTEED_READ;
#endif
	/* Initialize the register file */
	initialize_reg_file(&seq);

	/* Initialize any PHY CSR */
	initialize_hps_phy();

	scc_mgr_initialize();

	initialize_tracking(&seq);

	debug(KBUILD_BASENAME ": Preparing to start memory calibration\n");

	debug("%s:%d\n", __func__, __LINE__);
	debug_cond(DLEVEL >= 1,
		   "DDR3 FULL_RATE ranks=%u cs/dimm=%u dq/dqs=%u,%u vg/dqs=%u,%u ",
		   seq.rwcfg->mem_number_of_ranks,
		   seq.rwcfg->mem_number_of_cs_per_dimm,
		   seq.rwcfg->mem_dq_per_read_dqs,
		   seq.rwcfg->mem_dq_per_write_dqs,
		   seq.rwcfg->mem_virtual_groups_per_read_dqs,
		   seq.rwcfg->mem_virtual_groups_per_write_dqs);
	debug_cond(DLEVEL >= 1,
		   "dqs=%u,%u dq=%u dm=%u ptap_delay=%u dtap_delay=%u ",
		   seq.rwcfg->mem_if_read_dqs_width,
		   seq.rwcfg->mem_if_write_dqs_width,
		   seq.rwcfg->mem_data_width, seq.rwcfg->mem_data_mask_width,
		   seq.iocfg->delay_per_opa_tap,
		   seq.iocfg->delay_per_dchain_tap);
	debug_cond(DLEVEL >= 1, "dtap_dqsen_delay=%u, dll=%u",
		   seq.iocfg->delay_per_dqs_en_dchain_tap,
		   seq.iocfg->dll_chain_length);
	debug_cond(DLEVEL >= 1,
		   "max values: en_p=%u dqdqs_p=%u en_d=%u dqs_in_d=%u ",
		   seq.iocfg->dqs_en_phase_max, seq.iocfg->dqdqs_out_phase_max,
		   seq.iocfg->dqs_en_delay_max, seq.iocfg->dqs_in_delay_max);
	debug_cond(DLEVEL >= 1, "io_in_d=%u io_out1_d=%u io_out2_d=%u ",
		   seq.iocfg->io_in_delay_max, seq.iocfg->io_out1_delay_max,
		   seq.iocfg->io_out2_delay_max);
	debug_cond(DLEVEL >= 1, "dqs_in_reserve=%u dqs_out_reserve=%u\n",
		   seq.iocfg->dqs_in_reserve, seq.iocfg->dqs_out_reserve);

	hc_initialize_rom_data();

	/* update info for sims */
	reg_file_set_stage(CAL_STAGE_NIL);
	reg_file_set_group(0);

	/*
	 * Load global needed for those actions that require
	 * some dynamic calibration support.
	 */
	seq.dyn_calib_steps = STATIC_CALIB_STEPS;
	/*
	 * Load global to allow dynamic selection of delay loop settings
	 * based on calibration mode.
	 */
	if (!(seq.dyn_calib_steps & CALIB_SKIP_DELAY_LOOPS))
		seq.skip_delay_mask = 0xff;
	else
		seq.skip_delay_mask = 0x0;

	pass = run_mem_calibrate(&seq);
	debug_mem_calibrate(&seq, pass);
	return pass;
}
