/*
 * Copyright (C) Marvell International Ltd. and its affiliates
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>

#include "ddr3_init.h"

#define PATTERN_1	0x55555555
#define PATTERN_2	0xaaaaaaaa

#define VALIDATE_TRAINING_LIMIT(e1, e2)			\
	((((e2) - (e1) + 1) > 33) && ((e1) < 67))

u32 phy_reg_bk[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];

u32 training_res[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS *
		 HWS_SEARCH_DIR_LIMIT];

u16 mask_results_dq_reg_map[] = {
	RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
	RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
	RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
	RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
	RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
	RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
	RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
	RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
	RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
	RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
	RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
	RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
	RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
	RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
	RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
	RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
	RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
	RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
	RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
	RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
};

u16 mask_results_pup_reg_map[] = {
	RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
	RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_3_REG,
	RESULT_CONTROL_BYTE_PUP_4_REG
};

u16 mask_results_dq_reg_map_pup3_ecc[] = {
	RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
	RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
	RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
	RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
	RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
	RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
	RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
	RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
	RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
	RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
	RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
	RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
	RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
	RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
	RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
	RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
	RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
	RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
	RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
	RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
};

u16 mask_results_pup_reg_map_pup3_ecc[] = {
	RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
	RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG,
	RESULT_CONTROL_BYTE_PUP_4_REG
};

struct pattern_info pattern_table_16[] = {
	/*
	 * num tx phases, tx burst, delay between, rx pattern,
	 * start_address, pattern_len
	 */
	{1, 1, 2, 1, 0x0080, 2},	/* PATTERN_PBS1 */
	{1, 1, 2, 1, 0x00c0, 2},	/* PATTERN_PBS2 */
	{1, 1, 2, 1, 0x0100, 2},	/* PATTERN_RL */
	{0xf, 0x7, 2, 0x7, 0x0140, 16},	/* PATTERN_STATIC_PBS */
	{0xf, 0x7, 2, 0x7, 0x0190, 16},	/* PATTERN_KILLER_DQ0 */
	{0xf, 0x7, 2, 0x7, 0x01d0, 16},	/* PATTERN_KILLER_DQ1 */
	{0xf, 0x7, 2, 0x7, 0x0210, 16},	/* PATTERN_KILLER_DQ2 */
	{0xf, 0x7, 2, 0x7, 0x0250, 16},	/* PATTERN_KILLER_DQ3 */
	{0xf, 0x7, 2, 0x7, 0x0290, 16},	/* PATTERN_KILLER_DQ4 */
	{0xf, 0x7, 2, 0x7, 0x02d0, 16},	/* PATTERN_KILLER_DQ5 */
	{0xf, 0x7, 2, 0x7, 0x0310, 16},	/* PATTERN_KILLER_DQ6 */
	{0xf, 0x7, 2, 0x7, 0x0350, 16},	/* PATTERN_KILLER_DQ7 */
	{1, 1, 2, 1, 0x0380, 2},	/* PATTERN_PBS3 */
	{1, 1, 2, 1, 0x0000, 2},	/* PATTERN_RL2 */
	{1, 1, 2, 1, 0x0040, 2},	/* PATTERN_TEST */
	{0xf, 0x7, 2, 0x7, 0x03c0, 16},	/* PATTERN_FULL_SSO_1T */
	{0xf, 0x7, 2, 0x7, 0x0400, 16},	/* PATTERN_FULL_SSO_2T */
	{0xf, 0x7, 2, 0x7, 0x0440, 16},	/* PATTERN_FULL_SSO_3T */
	{0xf, 0x7, 2, 0x7, 0x0480, 16},	/* PATTERN_FULL_SSO_4T */
	{0xf, 0x7, 2, 0x7, 0x04c0, 16}	/* PATTERN_VREF */
	/*Note: actual start_address is <<3 of defined addess */
};

struct pattern_info pattern_table_32[] = {
	/*
	 * num tx phases, tx burst, delay between, rx pattern,
	 * start_address, pattern_len
	 */
	{3, 3, 2, 3, 0x0080, 4},	/* PATTERN_PBS1 */
	{3, 3, 2, 3, 0x00c0, 4},	/* PATTERN_PBS2 */
	{3, 3, 2, 3, 0x0100, 4},	/* PATTERN_RL */
	{0x1f, 0xf, 2, 0xf, 0x0140, 32},	/* PATTERN_STATIC_PBS */
	{0x1f, 0xf, 2, 0xf, 0x0190, 32},	/* PATTERN_KILLER_DQ0 */
	{0x1f, 0xf, 2, 0xf, 0x01d0, 32},	/* PATTERN_KILLER_DQ1 */
	{0x1f, 0xf, 2, 0xf, 0x0210, 32},	/* PATTERN_KILLER_DQ2 */
	{0x1f, 0xf, 2, 0xf, 0x0250, 32},	/* PATTERN_KILLER_DQ3 */
	{0x1f, 0xf, 2, 0xf, 0x0290, 32},	/* PATTERN_KILLER_DQ4 */
	{0x1f, 0xf, 2, 0xf, 0x02d0, 32},	/* PATTERN_KILLER_DQ5 */
	{0x1f, 0xf, 2, 0xf, 0x0310, 32},	/* PATTERN_KILLER_DQ6 */
	{0x1f, 0xf, 2, 0xf, 0x0350, 32},	/* PATTERN_KILLER_DQ7 */
	{3, 3, 2, 3, 0x0380, 4},	/* PATTERN_PBS3 */
	{3, 3, 2, 3, 0x0000, 4},	/* PATTERN_RL2 */
	{3, 3, 2, 3, 0x0040, 4},	/* PATTERN_TEST */
	{0x1f, 0xf, 2, 0xf, 0x03c0, 32},	/* PATTERN_FULL_SSO_1T */
	{0x1f, 0xf, 2, 0xf, 0x0400, 32},	/* PATTERN_FULL_SSO_2T */
	{0x1f, 0xf, 2, 0xf, 0x0440, 32},	/* PATTERN_FULL_SSO_3T */
	{0x1f, 0xf, 2, 0xf, 0x0480, 32},	/* PATTERN_FULL_SSO_4T */
	{0x1f, 0xf, 2, 0xf, 0x04c0, 32}	/* PATTERN_VREF */
	/*Note: actual start_address is <<3 of defined addess */
};

u32 train_dev_num;
enum hws_ddr_cs traintrain_cs_type;
u32 train_pup_num;
enum hws_training_result train_result_type;
enum hws_control_element train_control_element;
enum hws_search_dir traine_search_dir;
enum hws_dir train_direction;
u32 train_if_select;
u32 train_init_value;
u32 train_number_iterations;
enum hws_pattern train_pattern;
enum hws_edge_compare train_edge_compare;
u32 train_cs_num;
u32 train_if_acess, train_if_id, train_pup_access;
u32 max_polling_for_done = 1000000;

u32 *ddr3_tip_get_buf_ptr(u32 dev_num, enum hws_search_dir search,
			  enum hws_training_result result_type,
			  u32 interface_num)
{
	u32 *buf_ptr = NULL;

	buf_ptr = &training_res
		[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS * search +
		 interface_num * MAX_BUS_NUM * BUS_WIDTH_IN_BITS];

	return buf_ptr;
}

/*
 * IP Training search
 * Note: for one edge search only from fail to pass, else jitter can
 * be be entered into solution.
 */
int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
			 u32 interface_num,
			 enum hws_access_type pup_access_type,
			 u32 pup_num, enum hws_training_result result_type,
			 enum hws_control_element control_element,
			 enum hws_search_dir search_dir, enum hws_dir direction,
			 u32 interface_mask, u32 init_value, u32 num_iter,
			 enum hws_pattern pattern,
			 enum hws_edge_compare edge_comp,
			 enum hws_ddr_cs cs_type, u32 cs_num,
			 enum hws_training_ip_stat *train_status)
{
	u32 mask_dq_num_of_regs, mask_pup_num_of_regs, index_cnt, poll_cnt,
		reg_data, pup_id;
	u32 tx_burst_size;
	u32 delay_between_burst;
	u32 rd_mode;
	u32 read_data[MAX_INTERFACE_NUM];
	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
	struct hws_topology_map *tm = ddr3_get_topology_map();

	if (pup_num >= tm->num_of_bus_per_interface) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("pup_num %d not valid\n", pup_num));
	}
	if (interface_num >= MAX_INTERFACE_NUM) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("if_id %d not valid\n",
					  interface_num));
	}
	if (train_status == NULL) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("error param 4\n"));
		return MV_BAD_PARAM;
	}

	/* load pattern */
	if (cs_type == CS_SINGLE) {
		/* All CSs to CS0     */
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, access_type, interface_num,
			      CS_ENABLE_REG, 1 << 3, 1 << 3));
		/* All CSs to CS0     */
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, access_type, interface_num,
			      ODPG_DATA_CONTROL_REG,
			      (0x3 | (effective_cs << 26)), 0xc000003));
	} else {
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, access_type, interface_num,
			      CS_ENABLE_REG, 0, 1 << 3));
		/*  CS select */
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, access_type, interface_num,
			      ODPG_DATA_CONTROL_REG, 0x3 | cs_num << 26,
			      0x3 | 3 << 26));
	}

	/* load pattern to ODPG */
	ddr3_tip_load_pattern_to_odpg(dev_num, access_type, interface_num,
				      pattern,
				      pattern_table[pattern].start_addr);
	tx_burst_size =	(direction == OPER_WRITE) ?
		pattern_table[pattern].tx_burst_size : 0;
	delay_between_burst = (direction == OPER_WRITE) ? 2 : 0;
	rd_mode = (direction == OPER_WRITE) ? 1 : 0;
	CHECK_STATUS(ddr3_tip_configure_odpg
		     (dev_num, access_type, interface_num, direction,
		      pattern_table[pattern].num_of_phases_tx, tx_burst_size,
		      pattern_table[pattern].num_of_phases_rx,
		      delay_between_burst, rd_mode, effective_cs, STRESS_NONE,
		      DURATION_SINGLE));
	reg_data = (direction == OPER_READ) ? 0 : (0x3 << 30);
	reg_data |= (direction == OPER_READ) ? 0x60 : 0xfa;
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, access_type, interface_num,
		      ODPG_WRITE_READ_MODE_ENABLE_REG, reg_data,
		      MASK_ALL_BITS));
	reg_data = (edge_comp == EDGE_PF || edge_comp == EDGE_FP) ? 0 : 1 << 6;
	reg_data |= (edge_comp == EDGE_PF || edge_comp == EDGE_PFP) ?
		(1 << 7) : 0;

	/* change from Pass to Fail will lock the result */
	if (pup_access_type == ACCESS_TYPE_MULTICAST)
		reg_data |= 0xe << 14;
	else
		reg_data |= pup_num << 14;

	if (edge_comp == EDGE_FP) {
		/* don't search for readl edge change, only the state */
		reg_data |= (0 << 20);
	} else if (edge_comp == EDGE_FPF) {
		reg_data |= (0 << 20);
	} else {
		reg_data |= (3 << 20);
	}

	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, access_type, interface_num,
		      ODPG_TRAINING_CONTROL_REG,
		      reg_data | (0x7 << 8) | (0x7 << 11),
		      (0x3 | (0x3 << 2) | (0x3 << 6) | (1 << 5) | (0x7 << 8) |
		       (0x7 << 11) | (0xf << 14) | (0x3 << 18) | (3 << 20))));
	reg_data = (search_dir == HWS_LOW2HIGH) ? 0 : (1 << 8);
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, access_type, interface_num, ODPG_OBJ1_OPCODE_REG,
		      1 | reg_data | init_value << 9 | (1 << 25) | (1 << 26),
		      0xff | (1 << 8) | (0xffff << 9) | (1 << 25) | (1 << 26)));

	/*
	 * Write2_dunit(0x10b4, Number_iteration , [15:0])
	 * Max number of iterations
	 */
	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
				       ODPG_OBJ1_ITER_CNT_REG, num_iter,
				       0xffff));
	if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
	    direction == OPER_READ) {
		/*
		 * Write2_dunit(0x10c0, 0x5f , [7:0])
		 * MC PBS Reg Address at DDR PHY
		 */
		reg_data = 0x5f +
			effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
	} else if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
		   direction == OPER_WRITE) {
		reg_data = 0x1f +
			effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
	} else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
		   direction == OPER_WRITE) {
		/*
		 * LOOP         0x00000001 + 4*n:
		 * where n (0-3) represents M_CS number
		 */
		/*
		 * Write2_dunit(0x10c0, 0x1 , [7:0])
		 * ADLL WR Reg Address at DDR PHY
		 */
		reg_data = 1 + effective_cs * CS_REGISTER_ADDR_OFFSET;
	} else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
		   direction == OPER_READ) {
		/* ADLL RD Reg Address at DDR PHY */
		reg_data = 3 + effective_cs * CS_REGISTER_ADDR_OFFSET;
	} else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
		   direction == OPER_WRITE) {
		/* TBD not defined in 0.5.0 requirement  */
	} else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
		   direction == OPER_READ) {
		/* TBD not defined in 0.5.0 requirement */
	}

	reg_data |= (0x6 << 28);
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, access_type, interface_num, CALIB_OBJ_PRFA_REG,
		      reg_data | (init_value << 8),
		      0xff | (0xffff << 8) | (0xf << 24) | (u32) (0xf << 28)));

	mask_dq_num_of_regs = tm->num_of_bus_per_interface * BUS_WIDTH_IN_BITS;
	mask_pup_num_of_regs = tm->num_of_bus_per_interface;

	if (result_type == RESULT_PER_BIT) {
		for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
		     index_cnt++) {
			CHECK_STATUS(ddr3_tip_if_write
				     (dev_num, access_type, interface_num,
				      mask_results_dq_reg_map[index_cnt], 0,
				      1 << 24));
		}

		/* Mask disabled buses */
		for (pup_id = 0; pup_id < tm->num_of_bus_per_interface;
		     pup_id++) {
			if (IS_ACTIVE(tm->bus_act_mask, pup_id) == 1)
				continue;

			for (index_cnt = (mask_dq_num_of_regs - pup_id * 8);
			     index_cnt <
				     (mask_dq_num_of_regs - (pup_id + 1) * 8);
			     index_cnt++) {
				CHECK_STATUS(ddr3_tip_if_write
					     (dev_num, access_type,
					      interface_num,
					      mask_results_dq_reg_map
					      [index_cnt], (1 << 24), 1 << 24));
			}
		}

		for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
		     index_cnt++) {
			CHECK_STATUS(ddr3_tip_if_write
				     (dev_num, access_type, interface_num,
				      mask_results_pup_reg_map[index_cnt],
				      (1 << 24), 1 << 24));
		}
	} else if (result_type == RESULT_PER_BYTE) {
		/* write to adll */
		for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
		     index_cnt++) {
			CHECK_STATUS(ddr3_tip_if_write
				     (dev_num, access_type, interface_num,
				      mask_results_pup_reg_map[index_cnt], 0,
				      1 << 24));
		}
		for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
		     index_cnt++) {
			CHECK_STATUS(ddr3_tip_if_write
				     (dev_num, access_type, interface_num,
				      mask_results_dq_reg_map[index_cnt],
				      (1 << 24), (1 << 24)));
		}
	}

	/* Start Training Trigger */
	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
				       ODPG_TRAINING_TRIGGER_REG, 1, 1));
	/* wait for all RFU tests to finish (or timeout) */
	/* WA for 16 bit mode, more investigation needed */
	mdelay(1);

	/* Training "Done ?" */
	for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
		if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
			continue;

		if (interface_mask & (1 << index_cnt)) {
			/* need to check results for this Dunit */
			for (poll_cnt = 0; poll_cnt < max_polling_for_done;
			     poll_cnt++) {
				CHECK_STATUS(ddr3_tip_if_read
					     (dev_num, ACCESS_TYPE_UNICAST,
					      index_cnt,
					      ODPG_TRAINING_STATUS_REG,
					      &reg_data, MASK_ALL_BITS));
				if ((reg_data & 0x2) != 0) {
					/*done */
					train_status[index_cnt] =
						HWS_TRAINING_IP_STATUS_SUCCESS;
					break;
				}
			}

			if (poll_cnt == max_polling_for_done) {
				train_status[index_cnt] =
					HWS_TRAINING_IP_STATUS_TIMEOUT;
			}
		}
		/* Be sure that ODPG done */
		CHECK_STATUS(is_odpg_access_done(dev_num, index_cnt));
	}

	/* Write ODPG done in Dunit */
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_STATUS_DONE_REG, 0, 0x1));

	/* wait for all Dunit tests to finish (or timeout) */
	/* Training "Done ?" */
	/* Training "Pass ?" */
	for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
		if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
			continue;

		if (interface_mask & (1 << index_cnt)) {
			/* need to check results for this Dunit */
			for (poll_cnt = 0; poll_cnt < max_polling_for_done;
			     poll_cnt++) {
				CHECK_STATUS(ddr3_tip_if_read
					     (dev_num, ACCESS_TYPE_UNICAST,
					      index_cnt,
					      ODPG_TRAINING_TRIGGER_REG,
					      read_data, MASK_ALL_BITS));
				reg_data = read_data[index_cnt];
				if ((reg_data & 0x2) != 0) {
					/* done */
					if ((reg_data & 0x4) == 0) {
						train_status[index_cnt] =
							HWS_TRAINING_IP_STATUS_SUCCESS;
					} else {
						train_status[index_cnt] =
							HWS_TRAINING_IP_STATUS_FAIL;
					}
					break;
				}
			}

			if (poll_cnt == max_polling_for_done) {
				train_status[index_cnt] =
					HWS_TRAINING_IP_STATUS_TIMEOUT;
			}
		}
	}

	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));

	return MV_OK;
}

/*
 * Load expected Pattern to ODPG
 */
int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
				  u32 if_id, enum hws_pattern pattern,
				  u32 load_addr)
{
	u32 pattern_length_cnt = 0;
	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();

	for (pattern_length_cnt = 0;
	     pattern_length_cnt < pattern_table[pattern].pattern_len;
	     pattern_length_cnt++) {
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, access_type, if_id,
			      ODPG_PATTERN_DATA_LOW_REG,
			      pattern_table_get_word(dev_num, pattern,
						     (u8) (pattern_length_cnt *
							   2)), MASK_ALL_BITS));
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, access_type, if_id,
			      ODPG_PATTERN_DATA_HI_REG,
			      pattern_table_get_word(dev_num, pattern,
						     (u8) (pattern_length_cnt *
							   2 + 1)),
			      MASK_ALL_BITS));
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, access_type, if_id,
			      ODPG_PATTERN_ADDR_REG, pattern_length_cnt,
			      MASK_ALL_BITS));
	}

	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, access_type, if_id,
		      ODPG_PATTERN_ADDR_OFFSET_REG, load_addr, MASK_ALL_BITS));

	return MV_OK;
}

/*
 * Configure ODPG
 */
int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
			    u32 if_id, enum hws_dir direction, u32 tx_phases,
			    u32 tx_burst_size, u32 rx_phases,
			    u32 delay_between_burst, u32 rd_mode, u32 cs_num,
			    u32 addr_stress_jump, u32 single_pattern)
{
	u32 data_value = 0;
	int ret;

	data_value = ((single_pattern << 2) | (tx_phases << 5) |
		      (tx_burst_size << 11) | (delay_between_burst << 15) |
		      (rx_phases << 21) | (rd_mode << 25) | (cs_num << 26) |
		      (addr_stress_jump << 29));
	ret = ddr3_tip_if_write(dev_num, access_type, if_id,
				ODPG_DATA_CONTROL_REG, data_value, 0xaffffffc);
	if (ret != MV_OK)
		return ret;

	return MV_OK;
}

int ddr3_tip_process_result(u32 *ar_result, enum hws_edge e_edge,
			    enum hws_edge_search e_edge_search,
			    u32 *edge_result)
{
	u32 i, res;
	int tap_val, max_val = -10000, min_val = 10000;
	int lock_success = 1;

	for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
		res = GET_LOCK_RESULT(ar_result[i]);
		if (res == 0) {
			lock_success = 0;
			break;
		}
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("lock failed for bit %d\n", i));
	}

	if (lock_success == 1) {
		for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
			tap_val = GET_TAP_RESULT(ar_result[i], e_edge);
			if (tap_val > max_val)
				max_val = tap_val;
			if (tap_val < min_val)
				min_val = tap_val;
			if (e_edge_search == TRAINING_EDGE_MAX)
				*edge_result = (u32) max_val;
			else
				*edge_result = (u32) min_val;

			DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
						 ("i %d ar_result[i] 0x%x tap_val %d max_val %d min_val %d Edge_result %d\n",
						  i, ar_result[i], tap_val,
						  max_val, min_val,
						  *edge_result));
		}
	} else {
		return MV_FAIL;
	}

	return MV_OK;
}

/*
 * Read training search result
 */
int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
				  enum hws_access_type pup_access_type,
				  u32 pup_num, u32 bit_num,
				  enum hws_search_dir search,
				  enum hws_dir direction,
				  enum hws_training_result result_type,
				  enum hws_training_load_op operation,
				  u32 cs_num_type, u32 **load_res,
				  int is_read_from_db, u8 cons_tap,
				  int is_check_result_validity)
{
	u32 reg_offset, pup_cnt, start_pup, end_pup, start_reg, end_reg;
	u32 *interface_train_res = NULL;
	u16 *reg_addr = NULL;
	u32 read_data[MAX_INTERFACE_NUM];
	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
	struct hws_topology_map *tm = ddr3_get_topology_map();

	/*
	 * Agreed assumption: all CS mask contain same number of bits,
	 * i.e. in multi CS, the number of CS per memory is the same for
	 * all pups
	 */
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_UNICAST, if_id, CS_ENABLE_REG,
		      (cs_num_type == 0) ? 1 << 3 : 0, (1 << 3)));
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_UNICAST, if_id,
		      ODPG_DATA_CONTROL_REG, (cs_num_type << 26), (3 << 26)));
	DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
				 ("Read_from_d_b %d cs_type %d oper %d result_type %d direction %d search %d pup_num %d if_id %d pup_access_type %d\n",
				  is_read_from_db, cs_num_type, operation,
				  result_type, direction, search, pup_num,
				  if_id, pup_access_type));

	if ((load_res == NULL) && (is_read_from_db == 1)) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("ddr3_tip_read_training_result load_res = NULL"));
		return MV_FAIL;
	}
	if (pup_num >= tm->num_of_bus_per_interface) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("pup_num %d not valid\n", pup_num));
	}
	if (if_id >= MAX_INTERFACE_NUM) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("if_id %d not valid\n", if_id));
	}
	if (result_type == RESULT_PER_BIT)
		reg_addr = mask_results_dq_reg_map;
	else
		reg_addr = mask_results_pup_reg_map;
	if (pup_access_type == ACCESS_TYPE_UNICAST) {
		start_pup = pup_num;
		end_pup = pup_num;
	} else {		/*pup_access_type == ACCESS_TYPE_MULTICAST) */

		start_pup = 0;
		end_pup = tm->num_of_bus_per_interface - 1;
	}

	for (pup_cnt = start_pup; pup_cnt <= end_pup; pup_cnt++) {
		VALIDATE_ACTIVE(tm->bus_act_mask, pup_cnt);
		DEBUG_TRAINING_IP_ENGINE(
			DEBUG_LEVEL_TRACE,
			("if_id %d start_pup %d end_pup %d pup_cnt %d\n",
			 if_id, start_pup, end_pup, pup_cnt));
		if (result_type == RESULT_PER_BIT) {
			if (bit_num == ALL_BITS_PER_PUP) {
				start_reg = pup_cnt * BUS_WIDTH_IN_BITS;
				end_reg = (pup_cnt + 1) * BUS_WIDTH_IN_BITS - 1;
			} else {
				start_reg =
					pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
				end_reg = pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
			}
		} else {
			start_reg = pup_cnt;
			end_reg = pup_cnt;
		}

		interface_train_res =
			ddr3_tip_get_buf_ptr(dev_num, search, result_type,
					     if_id);
		DEBUG_TRAINING_IP_ENGINE(
			DEBUG_LEVEL_TRACE,
			("start_reg %d end_reg %d interface %p\n",
			 start_reg, end_reg, interface_train_res));
		if (interface_train_res == NULL) {
			DEBUG_TRAINING_IP_ENGINE(
				DEBUG_LEVEL_ERROR,
				("interface_train_res is NULL\n"));
			return MV_FAIL;
		}

		for (reg_offset = start_reg; reg_offset <= end_reg;
		     reg_offset++) {
			if (operation == TRAINING_LOAD_OPERATION_UNLOAD) {
				if (is_read_from_db == 0) {
					CHECK_STATUS(ddr3_tip_if_read
						     (dev_num,
						      ACCESS_TYPE_UNICAST,
						      if_id,
						      reg_addr[reg_offset],
						      read_data,
						      MASK_ALL_BITS));
					if (is_check_result_validity == 1) {
						if ((read_data[if_id] &
						     0x02000000) == 0) {
							interface_train_res
								[reg_offset] =
								0x02000000 +
								64 + cons_tap;
						} else {
							interface_train_res
								[reg_offset] =
								read_data
								[if_id] +
								cons_tap;
						}
					} else {
						interface_train_res[reg_offset]
							= read_data[if_id] +
							cons_tap;
					}
					DEBUG_TRAINING_IP_ENGINE
						(DEBUG_LEVEL_TRACE,
						 ("reg_offset %d value 0x%x addr %p\n",
						  reg_offset,
						  interface_train_res
						  [reg_offset],
						  &interface_train_res
						  [reg_offset]));
				} else {
					*load_res =
						&interface_train_res[start_reg];
					DEBUG_TRAINING_IP_ENGINE
						(DEBUG_LEVEL_TRACE,
						 ("*load_res %p\n", *load_res));
				}
			} else {
				DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
							 ("not supported\n"));
			}
		}
	}

	return MV_OK;
}

/*
 * Load all pattern to memory using ODPG
 */
int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
{
	u32 pattern = 0, if_id;
	struct hws_topology_map *tm = ddr3_get_topology_map();

	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
		training_result[training_stage][if_id] = TEST_SUCCESS;
	}

	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
		/* enable single cs */
		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
			      CS_ENABLE_REG, (1 << 3), (1 << 3)));
	}

	for (pattern = 0; pattern < PATTERN_LIMIT; pattern++)
		ddr3_tip_load_pattern_to_mem(dev_num, pattern);

	return MV_OK;
}

/*
 * Wait till ODPG access is ready
 */
int is_odpg_access_done(u32 dev_num, u32 if_id)
{
	u32 poll_cnt = 0, data_value;
	u32 read_data[MAX_INTERFACE_NUM];

	for (poll_cnt = 0; poll_cnt < MAX_POLLING_ITERATIONS; poll_cnt++) {
		CHECK_STATUS(ddr3_tip_if_read
			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
			      ODPG_BIST_DONE, read_data, MASK_ALL_BITS));
		data_value = read_data[if_id];
		if (((data_value >> ODPG_BIST_DONE_BIT_OFFS) & 0x1) ==
		    ODPG_BIST_DONE_BIT_VALUE) {
				data_value = data_value & 0xfffffffe;
				CHECK_STATUS(ddr3_tip_if_write
					     (dev_num, ACCESS_TYPE_UNICAST,
					      if_id, ODPG_BIST_DONE, data_value,
					      MASK_ALL_BITS));
				break;
			}
	}

	if (poll_cnt >= MAX_POLLING_ITERATIONS) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("Bist Activate: poll failure 2\n"));
		return MV_FAIL;
	}

	return MV_OK;
}

/*
 * Load specific pattern to memory using ODPG
 */
int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern)
{
	u32 reg_data, if_id;
	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
	struct hws_topology_map *tm = ddr3_get_topology_map();

	/* load pattern to memory */
	/*
	 * Write Tx mode, CS0, phases, Tx burst size, delay between burst,
	 * rx pattern phases
	 */
	reg_data =
		0x1 | (pattern_table[pattern].num_of_phases_tx << 5) |
		(pattern_table[pattern].tx_burst_size << 11) |
		(pattern_table[pattern].delay_between_bursts << 15) |
		(pattern_table[pattern].num_of_phases_rx << 21) | (0x1 << 25) |
		(effective_cs << 26);
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_DATA_CONTROL_REG, reg_data, MASK_ALL_BITS));
	/* ODPG Write enable from BIST */
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_DATA_CONTROL_REG, (0x1 | (effective_cs << 26)),
		      0xc000003));
	/* disable error injection */
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_WRITE_DATA_ERROR_REG, 0, 0x1));
	/* load pattern to ODPG */
	ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
				      PARAM_NOT_CARE, pattern,
				      pattern_table[pattern].start_addr);

	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
		if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
			continue;

		CHECK_STATUS(ddr3_tip_if_write
			     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1498,
			      0x3, 0xf));
	}

	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_ENABLE_REG, 0x1 << ODPG_ENABLE_OFFS,
		      (0x1 << ODPG_ENABLE_OFFS)));

	mdelay(1);

	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
		CHECK_STATUS(is_odpg_access_done(dev_num, if_id));
	}

	/* Disable ODPG and stop write to memory */
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_DATA_CONTROL_REG, (0x1 << 30), (u32) (0x3 << 30)));

	/* return to default */
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
		      ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));

	/* Disable odt0 for CS0 training - need to adjust for multy CS */
	CHECK_STATUS(ddr3_tip_if_write
		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498,
		      0x0, 0xf));

	/* temporary added */
	mdelay(1);

	return MV_OK;
}

/*
 * Load specific pattern to memory using CPU
 */
int ddr3_tip_load_pattern_to_mem_by_cpu(u32 dev_num, enum hws_pattern pattern,
					u32 offset)
{
	/* eranba - TBD */
	return MV_OK;
}

/*
 * Training search routine
 */
int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
				     enum hws_access_type access_type,
				     u32 if_id,
				     enum hws_access_type pup_access_type,
				     u32 pup_num, u32 bit_num,
				     enum hws_training_result result_type,
				     enum hws_control_element control_element,
				     enum hws_search_dir search_dir,
				     enum hws_dir direction,
				     u32 interface_mask, u32 init_value_l2h,
				     u32 init_value_h2l, u32 num_iter,
				     enum hws_pattern pattern,
				     enum hws_edge_compare edge_comp,
				     enum hws_ddr_cs train_cs_type, u32 cs_num,
				     enum hws_training_ip_stat *train_status)
{
	u32 interface_num = 0, start_if, end_if, init_value_used;
	enum hws_search_dir search_dir_id, start_search, end_search;
	enum hws_edge_compare edge_comp_used;
	u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
	struct hws_topology_map *tm = ddr3_get_topology_map();

	if (train_status == NULL) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("train_status is NULL\n"));
		return MV_FAIL;
	}

	if ((train_cs_type > CS_NON_SINGLE) ||
	    (edge_comp >= EDGE_PFP) ||
	    (pattern >= PATTERN_LIMIT) ||
	    (direction > OPER_WRITE_AND_READ) ||
	    (search_dir > HWS_HIGH2LOW) ||
	    (control_element > HWS_CONTROL_ELEMENT_DQS_SKEW) ||
	    (result_type > RESULT_PER_BYTE) ||
	    (pup_num >= tm->num_of_bus_per_interface) ||
	    (pup_access_type > ACCESS_TYPE_MULTICAST) ||
	    (if_id > 11) || (access_type > ACCESS_TYPE_MULTICAST)) {
		DEBUG_TRAINING_IP_ENGINE(
			DEBUG_LEVEL_ERROR,
			("wrong parameter train_cs_type %d edge_comp %d pattern %d direction %d search_dir %d control_element %d result_type %d pup_num %d pup_access_type %d if_id %d access_type %d\n",
			 train_cs_type, edge_comp, pattern, direction,
			 search_dir, control_element, result_type, pup_num,
			 pup_access_type, if_id, access_type));
		return MV_FAIL;
	}

	if (edge_comp == EDGE_FPF) {
		start_search = HWS_LOW2HIGH;
		end_search = HWS_HIGH2LOW;
		edge_comp_used = EDGE_FP;
	} else {
		start_search = search_dir;
		end_search = search_dir;
		edge_comp_used = edge_comp;
	}

	for (search_dir_id = start_search; search_dir_id <= end_search;
	     search_dir_id++) {
		init_value_used = (search_dir_id == HWS_LOW2HIGH) ?
			init_value_l2h : init_value_h2l;
		DEBUG_TRAINING_IP_ENGINE(
			DEBUG_LEVEL_TRACE,
			("dev_num %d, access_type %d, if_id %d, pup_access_type %d,pup_num %d, result_type %d, control_element %d search_dir_id %d, direction %d, interface_mask %d,init_value_used %d, num_iter %d, pattern %d, edge_comp_used %d, train_cs_type %d, cs_num %d\n",
			 dev_num, access_type, if_id, pup_access_type, pup_num,
			 result_type, control_element, search_dir_id,
			 direction, interface_mask, init_value_used, num_iter,
			 pattern, edge_comp_used, train_cs_type, cs_num));

		ddr3_tip_ip_training(dev_num, access_type, if_id,
				     pup_access_type, pup_num, result_type,
				     control_element, search_dir_id, direction,
				     interface_mask, init_value_used, num_iter,
				     pattern, edge_comp_used, train_cs_type,
				     cs_num, train_status);
		if (access_type == ACCESS_TYPE_MULTICAST) {
			start_if = 0;
			end_if = MAX_INTERFACE_NUM - 1;
		} else {
			start_if = if_id;
			end_if = if_id;
		}

		for (interface_num = start_if; interface_num <= end_if;
		     interface_num++) {
			VALIDATE_ACTIVE(tm->if_act_mask, interface_num);
			cs_num = 0;
			CHECK_STATUS(ddr3_tip_read_training_result
				     (dev_num, interface_num, pup_access_type,
				      pup_num, bit_num, search_dir_id,
				      direction, result_type,
				      TRAINING_LOAD_OPERATION_UNLOAD,
				      train_cs_type, NULL, 0, cons_tap,
				      0));
		}
	}

	return MV_OK;
}

/*
 * Training search & read result routine
 */
int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
				 u32 if_id,
				 enum hws_access_type pup_access_type,
				 u32 pup_num,
				 enum hws_training_result result_type,
				 enum hws_control_element control_element,
				 enum hws_search_dir search_dir,
				 enum hws_dir direction, u32 interface_mask,
				 u32 init_value_l2h, u32 init_value_h2l,
				 u32 num_iter, enum hws_pattern pattern,
				 enum hws_edge_compare edge_comp,
				 enum hws_ddr_cs train_cs_type, u32 cs_num,
				 enum hws_training_ip_stat *train_status)
{
	u8 e1, e2;
	u32 interface_cnt, bit_id, start_if, end_if, bit_end = 0;
	u32 *result[HWS_SEARCH_DIR_LIMIT] = { 0 };
	u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
	u8 bit_bit_mask[MAX_BUS_NUM] = { 0 }, bit_bit_mask_active = 0;
	u8 pup_id;
	struct hws_topology_map *tm = ddr3_get_topology_map();

	if (pup_num >= tm->num_of_bus_per_interface) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("pup_num %d not valid\n", pup_num));
	}

	if (if_id >= MAX_INTERFACE_NUM) {
		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
					 ("if_id %d not valid\n", if_id));
	}

	CHECK_STATUS(ddr3_tip_ip_training_wrapper_int
		     (dev_num, access_type, if_id, pup_access_type, pup_num,
		      ALL_BITS_PER_PUP, result_type, control_element,
		      search_dir, direction, interface_mask, init_value_l2h,
		      init_value_h2l, num_iter, pattern, edge_comp,
		      train_cs_type, cs_num, train_status));

	if (access_type == ACCESS_TYPE_MULTICAST) {
		start_if = 0;
		end_if = MAX_INTERFACE_NUM - 1;
	} else {
		start_if = if_id;
		end_if = if_id;
	}

	for (interface_cnt = start_if; interface_cnt <= end_if;
	     interface_cnt++) {
		VALIDATE_ACTIVE(tm->if_act_mask, interface_cnt);
		for (pup_id = 0;
		     pup_id <= (tm->num_of_bus_per_interface - 1); pup_id++) {
			VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
			if (result_type == RESULT_PER_BIT)
				bit_end = BUS_WIDTH_IN_BITS - 1;
			else
				bit_end = 0;

			bit_bit_mask[pup_id] = 0;
			for (bit_id = 0; bit_id <= bit_end; bit_id++) {
				enum hws_search_dir search_dir_id;
				for (search_dir_id = HWS_LOW2HIGH;
				     search_dir_id <= HWS_HIGH2LOW;
				     search_dir_id++) {
					CHECK_STATUS
						(ddr3_tip_read_training_result
						 (dev_num, interface_cnt,
						  ACCESS_TYPE_UNICAST, pup_id,
						  bit_id, search_dir_id,
						  direction, result_type,
						  TRAINING_LOAD_OPERATION_UNLOAD,
						  CS_SINGLE,
						  &result[search_dir_id],
						  1, 0, 0));
				}
				e1 = GET_TAP_RESULT(result[HWS_LOW2HIGH][0],
						    EDGE_1);
				e2 = GET_TAP_RESULT(result[HWS_HIGH2LOW][0],
						    EDGE_1);
				DEBUG_TRAINING_IP_ENGINE(
					DEBUG_LEVEL_INFO,
					("wrapper if_id %d pup_id %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x)\n",
					 interface_cnt, pup_id, bit_id,
					 result[HWS_LOW2HIGH][0], e1,
					 result[HWS_HIGH2LOW][0], e2));
				/* TBD validate is valid only for tx */
				if (VALIDATE_TRAINING_LIMIT(e1, e2) == 1 &&
				    GET_LOCK_RESULT(result[HWS_LOW2HIGH][0]) &&
				    GET_LOCK_RESULT(result[HWS_LOW2HIGH][0])) {
					/* Mark problem bits */
					bit_bit_mask[pup_id] |= 1 << bit_id;
					bit_bit_mask_active = 1;
				}
			}	/* For all bits */
		}		/* For all PUPs */

		/* Fix problem bits */
		if (bit_bit_mask_active != 0) {
			u32 *l2h_if_train_res = NULL;
			u32 *h2l_if_train_res = NULL;
			l2h_if_train_res =
				ddr3_tip_get_buf_ptr(dev_num, HWS_LOW2HIGH,
						     result_type,
						     interface_cnt);
			h2l_if_train_res =
				ddr3_tip_get_buf_ptr(dev_num, HWS_HIGH2LOW,
						     result_type,
						     interface_cnt);

			ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
					     interface_cnt,
					     ACCESS_TYPE_MULTICAST,
					     PARAM_NOT_CARE, result_type,
					     control_element, HWS_LOW2HIGH,
					     direction, interface_mask,
					     num_iter / 2, num_iter / 2,
					     pattern, EDGE_FP, train_cs_type,
					     cs_num, train_status);

			for (pup_id = 0;
			     pup_id <= (tm->num_of_bus_per_interface - 1);
			     pup_id++) {
				VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);

				if (bit_bit_mask[pup_id] == 0)
					continue;

				for (bit_id = 0; bit_id <= bit_end; bit_id++) {
					if ((bit_bit_mask[pup_id] &
					     (1 << bit_id)) == 0)
						continue;
					CHECK_STATUS
						(ddr3_tip_read_training_result
						 (dev_num, interface_cnt,
						  ACCESS_TYPE_UNICAST, pup_id,
						  bit_id, HWS_LOW2HIGH,
						  direction,
						  result_type,
						  TRAINING_LOAD_OPERATION_UNLOAD,
						  CS_SINGLE, &l2h_if_train_res,
						  0, 0, 1));
				}
			}

			ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
					     interface_cnt,
					     ACCESS_TYPE_MULTICAST,
					     PARAM_NOT_CARE, result_type,
					     control_element, HWS_HIGH2LOW,
					     direction, interface_mask,
					     num_iter / 2, num_iter / 2,
					     pattern, EDGE_FP, train_cs_type,
					     cs_num, train_status);

			for (pup_id = 0;
			     pup_id <= (tm->num_of_bus_per_interface - 1);
			     pup_id++) {
				VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);

				if (bit_bit_mask[pup_id] == 0)
					continue;

				for (bit_id = 0; bit_id <= bit_end; bit_id++) {
					if ((bit_bit_mask[pup_id] &
					     (1 << bit_id)) == 0)
						continue;
					CHECK_STATUS
						(ddr3_tip_read_training_result
						 (dev_num, interface_cnt,
						  ACCESS_TYPE_UNICAST, pup_id,
						  bit_id, HWS_HIGH2LOW, direction,
						  result_type,
						  TRAINING_LOAD_OPERATION_UNLOAD,
						  CS_SINGLE, &h2l_if_train_res,
						  0, cons_tap, 1));
				}
			}
		}		/* if bit_bit_mask_active */
	}			/* For all Interfacess */

	return MV_OK;
}

/*
 * Load phy values
 */
int ddr3_tip_load_phy_values(int b_load)
{
	u32 bus_cnt = 0, if_id, dev_num = 0;
	struct hws_topology_map *tm = ddr3_get_topology_map();

	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
		for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
		     bus_cnt++) {
			VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
			if (b_load == 1) {
				CHECK_STATUS(ddr3_tip_bus_read
					     (dev_num, if_id,
					      ACCESS_TYPE_UNICAST, bus_cnt,
					      DDR_PHY_DATA,
					      WRITE_CENTRALIZATION_PHY_REG +
					      (effective_cs *
					       CS_REGISTER_ADDR_OFFSET),
					      &phy_reg_bk[if_id][bus_cnt]
					      [0]));
				CHECK_STATUS(ddr3_tip_bus_read
					     (dev_num, if_id,
					      ACCESS_TYPE_UNICAST, bus_cnt,
					      DDR_PHY_DATA,
					      RL_PHY_REG +
					      (effective_cs *
					       CS_REGISTER_ADDR_OFFSET),
					      &phy_reg_bk[if_id][bus_cnt]
					      [1]));
				CHECK_STATUS(ddr3_tip_bus_read
					     (dev_num, if_id,
					      ACCESS_TYPE_UNICAST, bus_cnt,
					      DDR_PHY_DATA,
					      READ_CENTRALIZATION_PHY_REG +
					      (effective_cs *
					       CS_REGISTER_ADDR_OFFSET),
					      &phy_reg_bk[if_id][bus_cnt]
					      [2]));
			} else {
				CHECK_STATUS(ddr3_tip_bus_write
					     (dev_num, ACCESS_TYPE_UNICAST,
					      if_id, ACCESS_TYPE_UNICAST,
					      bus_cnt, DDR_PHY_DATA,
					      WRITE_CENTRALIZATION_PHY_REG +
					      (effective_cs *
					       CS_REGISTER_ADDR_OFFSET),
					      phy_reg_bk[if_id][bus_cnt]
					      [0]));
				CHECK_STATUS(ddr3_tip_bus_write
					     (dev_num, ACCESS_TYPE_UNICAST,
					      if_id, ACCESS_TYPE_UNICAST,
					      bus_cnt, DDR_PHY_DATA,
					      RL_PHY_REG +
					      (effective_cs *
					       CS_REGISTER_ADDR_OFFSET),
					      phy_reg_bk[if_id][bus_cnt]
					      [1]));
				CHECK_STATUS(ddr3_tip_bus_write
					     (dev_num, ACCESS_TYPE_UNICAST,
					      if_id, ACCESS_TYPE_UNICAST,
					      bus_cnt, DDR_PHY_DATA,
					      READ_CENTRALIZATION_PHY_REG +
					      (effective_cs *
					       CS_REGISTER_ADDR_OFFSET),
					      phy_reg_bk[if_id][bus_cnt]
					      [2]));
			}
		}
	}

	return MV_OK;
}

int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
			      enum hws_search_dir search_dir,
			      enum hws_dir direction,
			      enum hws_edge_compare edge,
			      u32 init_val1, u32 init_val2,
			      u32 num_of_iterations,
			      u32 start_pattern, u32 end_pattern)
{
	u32 pattern, if_id, pup_id;
	enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
	u32 *res = NULL;
	u32 search_state = 0;
	struct hws_topology_map *tm = ddr3_get_topology_map();

	ddr3_tip_load_phy_values(1);

	for (pattern = start_pattern; pattern <= end_pattern; pattern++) {
		for (search_state = 0; search_state < HWS_SEARCH_DIR_LIMIT;
		     search_state++) {
			ddr3_tip_ip_training_wrapper(dev_num,
						     ACCESS_TYPE_MULTICAST, 0,
						     ACCESS_TYPE_MULTICAST, 0,
						     result_type,
						     HWS_CONTROL_ELEMENT_ADLL,
						     search_dir, direction,
						     0xfff, init_val1,
						     init_val2,
						     num_of_iterations, pattern,
						     edge, CS_SINGLE,
						     PARAM_NOT_CARE,
						     train_status);

			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
			     if_id++) {
				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
				for (pup_id = 0; pup_id <
					     tm->num_of_bus_per_interface;
				     pup_id++) {
					VALIDATE_ACTIVE(tm->bus_act_mask,
							pup_id);
					CHECK_STATUS
						(ddr3_tip_read_training_result
						 (dev_num, if_id,
						  ACCESS_TYPE_UNICAST, pup_id,
						  ALL_BITS_PER_PUP,
						  search_state,
						  direction, result_type,
						  TRAINING_LOAD_OPERATION_UNLOAD,
						  CS_SINGLE, &res, 1, 0,
						  0));
					if (result_type == RESULT_PER_BYTE) {
						DEBUG_TRAINING_IP_ENGINE
							(DEBUG_LEVEL_INFO,
							 ("search_state %d if_id %d pup_id %d 0x%x\n",
							  search_state, if_id,
							  pup_id, res[0]));
					} else {
						DEBUG_TRAINING_IP_ENGINE
							(DEBUG_LEVEL_INFO,
							 ("search_state %d if_id %d pup_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
							  search_state, if_id,
							  pup_id, res[0],
							  res[1], res[2],
							  res[3], res[4],
							  res[5], res[6],
							  res[7]));
					}
				}
			}	/* interface */
		}		/* search */
	}			/* pattern */

	ddr3_tip_load_phy_values(0);

	return MV_OK;
}

struct pattern_info *ddr3_tip_get_pattern_table()
{
	struct hws_topology_map *tm = ddr3_get_topology_map();

	if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0)
		return pattern_table_32;
	else
		return pattern_table_16;
}

u16 *ddr3_tip_get_mask_results_dq_reg()
{
	struct hws_topology_map *tm = ddr3_get_topology_map();

	if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
		return mask_results_dq_reg_map_pup3_ecc;
	else
		return mask_results_dq_reg_map;
}

u16 *ddr3_tip_get_mask_results_pup_reg_map()
{
	struct hws_topology_map *tm = ddr3_get_topology_map();

	if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
		return mask_results_pup_reg_map_pup3_ecc;
	else
		return mask_results_pup_reg_map;
}
