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

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

#include "ddr3_hw_training.h"

/*
 * Debug
 */
#define DEBUG_PBS_FULL_C(s, d, l) \
	DEBUG_PBS_FULL_S(s); DEBUG_PBS_FULL_D(d, l); DEBUG_PBS_FULL_S("\n")
#define DEBUG_PBS_C(s, d, l) \
	DEBUG_PBS_S(s); DEBUG_PBS_D(d, l); DEBUG_PBS_S("\n")

#ifdef MV_DEBUG_PBS
#define DEBUG_PBS_S(s)			puts(s)
#define DEBUG_PBS_D(d, l)		printf("%x", d)
#else
#define DEBUG_PBS_S(s)
#define DEBUG_PBS_D(d, l)
#endif

#ifdef MV_DEBUG_FULL_PBS
#define DEBUG_PBS_FULL_S(s)		puts(s)
#define DEBUG_PBS_FULL_D(d, l)		printf("%x", d)
#else
#define DEBUG_PBS_FULL_S(s)
#define DEBUG_PBS_FULL_D(d, l)
#endif

#if defined(MV88F78X60) || defined(MV88F672X)

/* Temp array for skew data storage */
static u32 skew_array[(MAX_PUP_NUM) * DQ_NUM] = { 0 };

/* PBS locked dq (per pup) */
extern u32 pbs_locked_dq[MAX_PUP_NUM][DQ_NUM];
extern u32 pbs_locked_dm[MAX_PUP_NUM];
extern u32 pbs_locked_value[MAX_PUP_NUM][DQ_NUM];

#if defined(MV88F672X)
extern u32 pbs_pattern[2][LEN_16BIT_PBS_PATTERN];
extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
#else
extern u32 pbs_pattern_32b[2][LEN_PBS_PATTERN];
extern u32 pbs_pattern_64b[2][LEN_PBS_PATTERN];
#endif

extern u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM];

static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
		u32 cur_pup, u32 pbs_pattern_idx, u32 ecc);
static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
		u32 pbs_pattern_idx, u32 ecc);
static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx,
		u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc);
static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx);
static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay);

/*
 * Name:     ddr3_pbs_tx
 * Desc:     Execute the PBS TX phase.
 * Args:     dram_info   ddr3 training information struct
 * Notes:
 * Returns:  MV_OK if success, other error code if fail.
 */
int ddr3_pbs_tx(MV_DRAM_INFO *dram_info)
{
	/* Array of Deskew results */

	/*
	 * Array to hold the total sum of skew from all iterations
	 * (for average purpose)
	 */
	u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };

	/*
	 * Array to hold the total average skew from both patterns
	 * (for average purpose)
	 */
	u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };

	u32 pbs_rep_time = 0;	/* counts number of loop in case of fail */
	/* bit array for unlock pups - used to repeat on the RX operation */
	u32 cur_pup;
	u32 max_pup;
	u32 pbs_retry;
	u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
	u32 pattern_idx;
	u32 ecc;
	/* indicates whether we need to start the loop again */
	int start_over;

	DEBUG_PBS_S("DDR3 - PBS TX - Starting PBS TX procedure\n");

	pups = dram_info->num_of_total_pups;
	max_pup = dram_info->num_of_total_pups;

	/* Enable SW override */
	reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
		(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
	/* [0] = 1 - Enable SW override  */
	/* 0x15B8 - Training SW 2 Register */
	reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
	DEBUG_PBS_S("DDR3 - PBS RX - SW Override Enabled\n");

	reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
	reg_write(REG_DRAM_TRAINING_ADDR, reg);	/* 0x15B0 - Training Register */

	/* Running twice for 2 different patterns. each patterns - 3 times */
	for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) {
		DEBUG_PBS_C("DDR3 - PBS TX - Working with pattern - ",
			    pattern_idx, 1);

		/* Reset sum array */
		for (pup = 0; pup < pups; pup++) {
			for (dq = 0; dq < DQ_NUM; dq++)
				skew_sum_array[pup][dq] = 0;
		}

		/*
		 * Perform PBS several of times (3 for each pattern).
		 * At the end, we'll use the average
		 */
		/* If there is ECC, do each PBS again with mux change */
		for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) {
			for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {

				/*
				 * This parameter stores the current PUP
				 * num - ecc mode dependent - 4-8 / 1 pups
				 */
				cur_max_pup = (1 - ecc) *
					dram_info->num_of_std_pups + ecc;

				if (ecc) {
					/* Only 1 pup in this case */
					valid_pup = 0x1;
				} else if (cur_max_pup > 4) {
					/* 64 bit - 8 pups */
					valid_pup = 0xFF;
				} else if (cur_max_pup == 4) {
					/* 32 bit - 4 pups */
					valid_pup = 0xF;
				} else {
					/* 16 bit - 2 pups */
					valid_pup = 0x3;
				}

				/* ECC Support - Switch ECC Mux on ecc=1 */
				reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
					~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
				reg |= (dram_info->ecc_ena * ecc <<
					REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
				reg_write(REG_DRAM_TRAINING_2_ADDR, reg);

				if (ecc)
					DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Enabled\n");
				else
					DEBUG_PBS_S("DDR3 - PBS Tx - ECC Mux Disabled\n");

				/* Init iteration values */
				/* Clear the locked DQs */
				for (pup = 0; pup < cur_max_pup; pup++) {
					for (dq = 0; dq < DQ_NUM; dq++) {
						pbs_locked_dq[
							pup + ecc *
							(max_pup - 1)][dq] =
							0;
					}
				}

				pbs_rep_time = 0;
				cur_pup = valid_pup;
				start_over = 0;

				/*
				 * Run loop On current Pattern and current
				 * pattern iteration (just to cover the false
				 * fail problem)
				 */
				do {
					DEBUG_PBS_S("DDR3 - PBS Tx - Pbs Rep Loop is ");
					DEBUG_PBS_D(pbs_rep_time, 1);
					DEBUG_PBS_S(", for Retry No.");
					DEBUG_PBS_D(pbs_retry, 1);
					DEBUG_PBS_S("\n");

					/* Set all PBS values to MIN (0) */
					DEBUG_PBS_S("DDR3 - PBS Tx - Set all PBS values to MIN\n");

					for (dq = 0; dq < DQ_NUM; dq++) {
						ddr3_write_pup_reg(
							PUP_PBS_TX +
							pbs_dq_mapping[pup *
								(1 - ecc) +
								ecc * ECC_PUP]
							[dq], CS0, (1 - ecc) *
							PUP_BC + ecc * ECC_PUP, 0,
							0);
					}

					/*
					 * Shift DQ ADLL right, One step before
					 * fail
					 */
					DEBUG_PBS_S("DDR3 - PBS Tx - ADLL shift right one phase before fail\n");

					if (MV_OK != ddr3_tx_shift_dqs_adll_step_before_fail
					    (dram_info, cur_pup, pattern_idx,
					     ecc))
						return MV_DDR3_TRAINING_ERR_PBS_ADLL_SHR_1PHASE;

					/* PBS For each bit */
					DEBUG_PBS_S("DDR3 - PBS Tx - perform PBS for each bit\n");

					/*
					 * In this stage - start_over = 0
					 */
					if (MV_OK != ddr3_pbs_per_bit(
						    dram_info, &start_over, 1,
						    &cur_pup, pattern_idx, ecc))
						return MV_DDR3_TRAINING_ERR_PBS_TX_PER_BIT;

				} while ((start_over == 1) &&
					 (++pbs_rep_time < COUNT_PBS_STARTOVER));

				if (pbs_rep_time == COUNT_PBS_STARTOVER &&
				    start_over == 1) {
					DEBUG_PBS_S("DDR3 - PBS Tx - FAIL - Adll reach max value\n");
					return MV_DDR3_TRAINING_ERR_PBS_TX_MAX_VAL;
				}

				DEBUG_PBS_FULL_C("DDR3 - PBS TX - values for iteration - ",
						 pbs_retry, 1);
				for (pup = 0; pup < cur_max_pup; pup++) {
					/*
					 * To minimize delay elements, inc
					 * from pbs value the min pbs val
					 */
					DEBUG_PBS_S("DDR3 - PBS - PUP");
					DEBUG_PBS_D((pup + (ecc * ECC_PUP)), 1);
					DEBUG_PBS_S(": ");

					for (dq = 0; dq < DQ_NUM; dq++) {
						/* Set skew value for all dq */
						/*
						 * Bit# Deskew <- Bit# Deskew -
						 * last / first  failing bit
						 * Deskew For all bits (per PUP)
						 * (minimize delay elements)
						 */
						DEBUG_PBS_S("DQ");
						DEBUG_PBS_D(dq, 1);
						DEBUG_PBS_S("-");
						DEBUG_PBS_D(skew_array
							    [((pup) * DQ_NUM) +
							     dq], 2);
						DEBUG_PBS_S(", ");
					}
					DEBUG_PBS_S("\n");
				}

				/*
				 * Collect the results we got on this trial
				 * of PBS
				 */
				for (pup = 0; pup < cur_max_pup; pup++) {
					for (dq = 0; dq < DQ_NUM; dq++) {
						skew_sum_array[pup + (ecc * (max_pup - 1))]
							[dq] += skew_array
							[((pup) * DQ_NUM) + dq];
					}
				}

				/* ECC Support - Disable ECC MUX */
				reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
					~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
				reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
			}
		}

		DEBUG_PBS_C("DDR3 - PBS TX - values for current pattern - ",
			    pattern_idx, 1);
		for (pup = 0; pup < max_pup; pup++) {
			/*
			 * To minimize delay elements, inc from pbs value the
			 * min pbs val
			 */
			DEBUG_PBS_S("DDR3 - PBS - PUP");
			DEBUG_PBS_D(pup, 1);
			DEBUG_PBS_S(": ");

			for (dq = 0; dq < DQ_NUM; dq++) {
				/* set skew value for all dq */
				/* Bit# Deskew <- Bit# Deskew - last / first  failing bit Deskew For all bits (per PUP) (minimize delay elements) */
				DEBUG_PBS_S("DQ");
				DEBUG_PBS_D(dq, 1);
				DEBUG_PBS_S("-");
				DEBUG_PBS_D(skew_sum_array[pup][dq] /
					    COUNT_PBS_REPEAT, 2);
				DEBUG_PBS_S(", ");
			}
			DEBUG_PBS_S("\n");
		}

		/*
		 * Calculate the average skew for current pattern for each
		 * pup and each bit
		 */
		DEBUG_PBS_C("DDR3 - PBS TX - Average for pattern - ",
			    pattern_idx, 1);

		for (pup = 0; pup < max_pup; pup++) {
			/*
			 * FOR ECC only :: found min and max value for current
			 * pattern skew array
			 */
			/* Loop for all dqs */
			for (dq = 0; dq < DQ_NUM; dq++) {
				pattern_skew_array[pup][dq] +=
					(skew_sum_array[pup][dq] /
					 COUNT_PBS_REPEAT);
			}
		}
	}

	/* Calculate the average skew */
	for (pup = 0; pup < max_pup; pup++) {
		for (dq = 0; dq < DQ_NUM; dq++)
			skew_array[((pup) * DQ_NUM) + dq] =
				pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN;
	}

	DEBUG_PBS_S("DDR3 - PBS TX - Average for all patterns:\n");
	for (pup = 0; pup < max_pup; pup++) {
		/*
		 * To minimize delay elements, inc from pbs value the min
		 * pbs val
		 */
		DEBUG_PBS_S("DDR3 - PBS - PUP");
		DEBUG_PBS_D(pup, 1);
		DEBUG_PBS_S(": ");

		for (dq = 0; dq < DQ_NUM; dq++) {
			/* Set skew value for all dq */
			/*
			 * Bit# Deskew <- Bit# Deskew - last / first
			 * failing bit Deskew For all bits (per PUP)
			 * (minimize delay elements)
			 */
			DEBUG_PBS_S("DQ");
			DEBUG_PBS_D(dq, 1);
			DEBUG_PBS_S("-");
			DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
			DEBUG_PBS_S(", ");
		}
		DEBUG_PBS_S("\n");
	}

	/* Return ADLL to default value */
	for (pup = 0; pup < max_pup; pup++) {
		if (pup == (max_pup - 1) && dram_info->ecc_ena)
			pup = ECC_PUP;
		ddr3_pbs_write_pup_dqs_reg(CS0, pup, INIT_WL_DELAY);
	}

	/* Set averaged PBS results */
	ddr3_set_pbs_results(dram_info, 1);

	/* Disable SW override - Must be in a different stage */
	/* [0]=0 - Enable SW override  */
	reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
	reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
	/* 0x15B8 - Training SW 2 Register */
	reg_write(REG_DRAM_TRAINING_2_ADDR, reg);

	reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
		(1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
	reg_write(REG_DRAM_TRAINING_1_ADDR, reg);

	DEBUG_PBS_S("DDR3 - PBS Tx - PBS TX ended successfuly\n");

	return MV_OK;
}

/*
 * Name:     ddr3_tx_shift_dqs_adll_step_before_fail
 * Desc:     Execute the Tx shift DQ phase.
 * Args:     dram_info            ddr3 training information struct
 *           cur_pup              bit array of the function active pups.
 *           pbs_pattern_idx      Index of PBS pattern
 * Notes:
 * Returns:  MV_OK if success, other error code if fail.
 */
static int ddr3_tx_shift_dqs_adll_step_before_fail(MV_DRAM_INFO *dram_info,
						   u32 cur_pup,
						   u32 pbs_pattern_idx, u32 ecc)
{
	u32 unlock_pup;		/* bit array of unlock pups  */
	u32 new_lockup_pup;	/* bit array of compare failed pups */
	u32 adll_val = 4;	/* INIT_WL_DELAY */
	u32 cur_max_pup, pup;
	u32 dqs_dly_set[MAX_PUP_NUM] = { 0 };
	u32 *pattern_ptr;

	/* Choose pattern */
	switch (dram_info->ddr_width) {
#if defined(MV88F672X)
	case 16:
		pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
		break;
#endif
	case 32:
		pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
		break;
#if defined(MV88F78X60)
	case 64:
		pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
		break;
#endif
	default:
		return MV_FAIL;
	}

	/* Set current pup number */
	if (cur_pup == 0x1)	/* Ecc mode */
		cur_max_pup = 1;
	else
		cur_max_pup = dram_info->num_of_std_pups;

	unlock_pup = cur_pup;	/* '1' for each unlocked pup */

	/* Loop on all ADLL Vaules */
	do {
		/* Loop until found first fail */
		adll_val++;

		/*
		 * Increment (Move to right - ADLL) DQ TX delay
		 * (broadcast to all Data PUPs)
		 */
		for (pup = 0; pup < cur_max_pup; pup++)
			ddr3_pbs_write_pup_dqs_reg(CS0,
						   pup * (1 - ecc) +
						   ECC_PUP * ecc, adll_val);

		/*
		 * Write and Read, compare results (read was already verified)
		 */
		/* 0 - all locked */
		new_lockup_pup = 0;

		if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
						&new_lockup_pup,
						pattern_ptr, LEN_PBS_PATTERN,
						SDRAM_PBS_TX_OFFS, 1, 0,
						NULL,
						0))
			return MV_FAIL;

		unlock_pup &= ~new_lockup_pup;

		DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: ");
		DEBUG_PBS_FULL_D(unlock_pup, 2);
		DEBUG_PBS_FULL_C(", Set ADLL value = ", adll_val, 2);

		/* If any PUP failed there is '1' to mark the PUP */
		if (new_lockup_pup != 0) {
			/*
			 * Decrement (Move Back to Left two steps - ADLL)
			 * DQ TX delay for current failed pups and save
			 */
			for (pup = 0; pup < cur_max_pup; pup++) {
				if (((new_lockup_pup >> pup) & 0x1) &&
				    dqs_dly_set[pup] == 0)
					dqs_dly_set[pup] = adll_val - 1;
			}
		}
	} while ((unlock_pup != 0) && (adll_val != ADLL_MAX));

	if (unlock_pup != 0) {
		DEBUG_PBS_FULL_S("DDR3 - PBS Tx - Shift DQ - Adll value reached maximum\n");

		for (pup = 0; pup < cur_max_pup; pup++) {
			if (((unlock_pup >> pup) & 0x1) &&
			    dqs_dly_set[pup] == 0)
				dqs_dly_set[pup] = adll_val - 1;
		}
	}

	DEBUG_PBS_FULL_C("PBS TX one step before fail last pups locked Adll ",
			 adll_val - 2, 2);

	/* Set the PUP DQS DLY Values */
	for (pup = 0; pup < cur_max_pup; pup++)
		ddr3_pbs_write_pup_dqs_reg(CS0, pup * (1 - ecc) + ECC_PUP * ecc,
					   dqs_dly_set[pup]);

	/* Found one phase before fail */
	return MV_OK;
}

/*
 * Name:     ddr3_pbs_rx
 * Desc:     Execute the PBS RX phase.
 * Args:     dram_info   ddr3 training information struct
 * Notes:
 * Returns:  MV_OK if success, other error code if fail.
 */
int ddr3_pbs_rx(MV_DRAM_INFO *dram_info)
{
	/*
	 * Array to hold the total sum of skew from all iterations
	 * (for average purpose)
	 */
	u32 skew_sum_array[MAX_PUP_NUM][DQ_NUM] = { {0} };

	/*
	 * Array to hold the total average skew from both patterns
	 * (for average purpose)
	 */
	u32 pattern_skew_array[MAX_PUP_NUM][DQ_NUM] = { {0} };

	u32 pbs_rep_time = 0;	/* counts number of loop in case of fail */
	/* bit array for unlock pups - used to repeat on the RX operation */
	u32 cur_pup;
	u32 max_pup;
	u32 pbs_retry;
	u32 pup, dq, pups, cur_max_pup, valid_pup, reg;
	u32 pattern_idx;
	u32 ecc;
	/* indicates whether we need to start the loop again */
	int start_over;
	int status;

	DEBUG_PBS_S("DDR3 - PBS RX - Starting PBS RX procedure\n");

	pups = dram_info->num_of_total_pups;
	max_pup = dram_info->num_of_total_pups;

	/* Enable SW override */
	reg = reg_read(REG_DRAM_TRAINING_2_ADDR) |
		(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
	/* [0] = 1 - Enable SW override  */
	/* 0x15B8 - Training SW 2 Register */
	reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
	DEBUG_PBS_FULL_S("DDR3 - PBS RX - SW Override Enabled\n");

	reg = 1 << REG_DRAM_TRAINING_AUTO_OFFS;
	reg_write(REG_DRAM_TRAINING_ADDR, reg);	/* 0x15B0 - Training Register */

	/* Running twice for 2 different patterns. each patterns - 3 times */
	for (pattern_idx = 0; pattern_idx < COUNT_PBS_PATTERN; pattern_idx++) {
		DEBUG_PBS_FULL_C("DDR3 - PBS RX - Working with pattern - ",
				 pattern_idx, 1);

		/* Reset sum array */
		for (pup = 0; pup < pups; pup++) {
			for (dq = 0; dq < DQ_NUM; dq++)
				skew_sum_array[pup][dq] = 0;
		}

		/*
		 * Perform PBS several of times (3 for each pattern).
		 * At the end, we'll use the average
		 */
		/* If there is ECC, do each PBS again with mux change */
		for (pbs_retry = 0; pbs_retry < COUNT_PBS_REPEAT; pbs_retry++) {
			for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) {
				/*
				 * This parameter stores the current PUP
				 * num - ecc mode dependent - 4-8 / 1 pups
				 */
				cur_max_pup = (1 - ecc) *
					dram_info->num_of_std_pups + ecc;

				if (ecc) {
					/* Only 1 pup in this case */
					valid_pup = 0x1;
				} else if (cur_max_pup > 4) {
					/* 64 bit - 8 pups */
					valid_pup = 0xFF;
				} else if (cur_max_pup == 4) {
					/* 32 bit - 4 pups */
					valid_pup = 0xF;
				} else {
					/* 16 bit - 2 pups */
					valid_pup = 0x3;
				}

				/* ECC Support - Switch ECC Mux on ecc=1 */
				reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
					~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
				reg |= (dram_info->ecc_ena * ecc <<
					REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
				reg_write(REG_DRAM_TRAINING_2_ADDR, reg);

				if (ecc)
					DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Enabled\n");
				else
					DEBUG_PBS_FULL_S("DDR3 - PBS Rx - ECC Mux Disabled\n");

				/* Init iteration values */
				/* Clear the locked DQs */
				for (pup = 0; pup < cur_max_pup; pup++) {
					for (dq = 0; dq < DQ_NUM; dq++) {
						pbs_locked_dq[
							pup + ecc * (max_pup - 1)][dq] =
							0;
					}
				}

				pbs_rep_time = 0;
				cur_pup = valid_pup;
				start_over = 0;

				/*
				 * Run loop On current Pattern and current
				 * pattern iteration (just to cover the false
				 * fail problem
				 */
				do {
					DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Pbs Rep Loop is ");
					DEBUG_PBS_FULL_D(pbs_rep_time, 1);
					DEBUG_PBS_FULL_S(", for Retry No.");
					DEBUG_PBS_FULL_D(pbs_retry, 1);
					DEBUG_PBS_FULL_S("\n");

					/* Set all PBS values to MAX (31) */
					for (pup = 0; pup < cur_max_pup; pup++) {
						for (dq = 0; dq < DQ_NUM; dq++)
							ddr3_write_pup_reg(
								PUP_PBS_RX +
								pbs_dq_mapping[
								pup * (1 - ecc)
								+ ecc * ECC_PUP]
								[dq], CS0,
								pup + ecc * ECC_PUP,
								0, MAX_PBS);
					}

					/* Set all DQS PBS values to MIN (0) */
					for (pup = 0; pup < cur_max_pup; pup++) {
						ddr3_write_pup_reg(PUP_PBS_RX +
								   DQ_NUM, CS0,
								   pup +
								   ecc *
								   ECC_PUP, 0,
								   0);
					}

					/* Shift DQS, To first Fail */
					DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift RX DQS to first fail\n");

					status = ddr3_rx_shift_dqs_to_first_fail
						(dram_info, cur_pup,
						 pattern_idx, ecc);
					if (MV_OK != status) {
						DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_rx_shift_dqs_to_first_fail failed.\n");
						DEBUG_PBS_D(status, 8);
						DEBUG_PBS_S("\nDDR3 - PBS Rx - SKIP.\n");

						/* Reset read FIFO */
						reg = reg_read(REG_DRAM_TRAINING_ADDR);
						/* Start Auto Read Leveling procedure */
						reg |= (1 << REG_DRAM_TRAINING_RL_OFFS);
						/* 0x15B0 - Training Register */
						reg_write(REG_DRAM_TRAINING_ADDR, reg);

						reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
						reg |= ((1 << REG_DRAM_TRAINING_2_FIFO_RST_OFFS)
							+ (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS));
						/* [0] = 1 - Enable SW override, [4] = 1 - FIFO reset  */
						/* 0x15B8 - Training SW 2 Register */
						reg_write(REG_DRAM_TRAINING_2_ADDR, reg);

						do {
							reg = (reg_read(REG_DRAM_TRAINING_2_ADDR))
								& (1 <<	REG_DRAM_TRAINING_2_FIFO_RST_OFFS);
						} while (reg);	/* Wait for '0' */

						reg = reg_read(REG_DRAM_TRAINING_ADDR);
						/* Clear Auto Read Leveling procedure */
						reg &= ~(1 << REG_DRAM_TRAINING_RL_OFFS);
						/* 0x15B0 - Training Register */
						reg_write(REG_DRAM_TRAINING_ADDR, reg);

						/* Set ADLL to 15 */
						for (pup = 0; pup < max_pup;
						     pup++) {
							ddr3_write_pup_reg
							    (PUP_DQS_RD, CS0,
							     pup +
							     (ecc * ECC_PUP), 0,
							     15);
						}

						/* Set all PBS values to MIN (0) */
						for (pup = 0; pup < cur_max_pup;
						     pup++) {
							for (dq = 0;
							     dq < DQ_NUM; dq++)
								ddr3_write_pup_reg
								    (PUP_PBS_RX +
								     pbs_dq_mapping
								     [pup * (1 - ecc) +
								      ecc * ECC_PUP]
								     [dq], CS0,
								     pup + ecc * ECC_PUP,
								     0, MIN_PBS);
						}

						return MV_OK;
					}

					/* PBS For each bit */
					DEBUG_PBS_FULL_S("DDR3 - PBS Rx - perform PBS for each bit\n");
					/* in this stage - start_over = 0; */
					if (MV_OK != ddr3_pbs_per_bit(
						    dram_info, &start_over,
						    0, &cur_pup,
						    pattern_idx, ecc)) {
						DEBUG_PBS_S("DDR3 - PBS Rx - ddr3_pbs_per_bit failed.");
						return MV_DDR3_TRAINING_ERR_PBS_RX_PER_BIT;
					}

				} while ((start_over == 1) &&
					 (++pbs_rep_time < COUNT_PBS_STARTOVER));

				if (pbs_rep_time == COUNT_PBS_STARTOVER &&
				    start_over == 1) {
					DEBUG_PBS_FULL_S("DDR3 - PBS Rx - FAIL - Algorithm failed doing RX PBS\n");
					return MV_DDR3_TRAINING_ERR_PBS_RX_MAX_VAL;
				}

				/* Return DQS ADLL to default value - 15 */
				/* Set all DQS PBS values to MIN (0) */
				for (pup = 0; pup < cur_max_pup; pup++)
					ddr3_write_pup_reg(PUP_DQS_RD, CS0,
							   pup + ecc * ECC_PUP,
							   0, INIT_RL_DELAY);

				DEBUG_PBS_FULL_C("DDR3 - PBS RX - values for iteration - ",
						 pbs_retry, 1);
				for (pup = 0; pup < cur_max_pup; pup++) {
					/*
					 * To minimize delay elements, inc from
					 * pbs value the min pbs val
					 */
					DEBUG_PBS_FULL_S("DDR3 - PBS - PUP");
					DEBUG_PBS_FULL_D((pup +
							  (ecc * ECC_PUP)), 1);
					DEBUG_PBS_FULL_S(": ");

					for (dq = 0; dq < DQ_NUM; dq++) {
						/* Set skew value for all dq */
						/*
						 * Bit# Deskew <- Bit# Deskew -
						 * last / first  failing bit
						 * Deskew For all bits (per PUP)
						 * (minimize delay elements)
						 */
						DEBUG_PBS_FULL_S("DQ");
						DEBUG_PBS_FULL_D(dq, 1);
						DEBUG_PBS_FULL_S("-");
						DEBUG_PBS_FULL_D(skew_array
								 [((pup) *
								   DQ_NUM) +
								  dq], 2);
						DEBUG_PBS_FULL_S(", ");
					}
					DEBUG_PBS_FULL_S("\n");
				}

				/*
				 * Collect the results we got on this trial
				 * of PBS
				 */
				for (pup = 0; pup < cur_max_pup; pup++) {
					for (dq = 0; dq < DQ_NUM; dq++) {
						skew_sum_array
							[pup + (ecc * (max_pup - 1))]
							[dq] +=
							skew_array[((pup) * DQ_NUM) + dq];
					}
				}

				/* ECC Support - Disable ECC MUX */
				reg = reg_read(REG_DRAM_TRAINING_2_ADDR) &
					~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS);
				reg_write(REG_DRAM_TRAINING_2_ADDR, reg);
			}
		}

		/*
		 * Calculate the average skew for current pattern for each
		 * pup and each bit
		 */
		DEBUG_PBS_FULL_C("DDR3 - PBS RX - Average for pattern - ",
				 pattern_idx, 1);
		for (pup = 0; pup < max_pup; pup++) {
			/*
			 * FOR ECC only :: found min and max value for
			 * current pattern skew array
			 */
			/* Loop for all dqs */
			for (dq = 0; dq < DQ_NUM; dq++) {
				pattern_skew_array[pup][dq] +=
					(skew_sum_array[pup][dq] /
					 COUNT_PBS_REPEAT);
			}
		}

		DEBUG_PBS_C("DDR3 - PBS RX - values for current pattern - ",
			    pattern_idx, 1);
		for (pup = 0; pup < max_pup; pup++) {
			/*
			 * To minimize delay elements, inc from pbs value the
			 * min pbs val
			 */
			DEBUG_PBS_S("DDR3 - PBS RX - PUP");
			DEBUG_PBS_D(pup, 1);
			DEBUG_PBS_S(": ");

			for (dq = 0; dq < DQ_NUM; dq++) {
				/* Set skew value for all dq */
				/*
				 * Bit# Deskew <- Bit# Deskew - last / first
				 * failing bit Deskew For all bits (per PUP)
				 * (minimize delay elements)
				 */
				DEBUG_PBS_S("DQ");
				DEBUG_PBS_D(dq, 1);
				DEBUG_PBS_S("-");
				DEBUG_PBS_D(skew_sum_array[pup][dq] /
					    COUNT_PBS_REPEAT, 2);
				DEBUG_PBS_S(", ");
			}
			DEBUG_PBS_S("\n");
		}
	}

	/* Calculate the average skew */
	for (pup = 0; pup < max_pup; pup++) {
		for (dq = 0; dq < DQ_NUM; dq++)
			skew_array[((pup) * DQ_NUM) + dq] =
				pattern_skew_array[pup][dq] / COUNT_PBS_PATTERN;
	}

	DEBUG_PBS_S("DDR3 - PBS RX - Average for all patterns:\n");
	for (pup = 0; pup < max_pup; pup++) {
		/*
		 * To minimize delay elements, inc from pbs value the
		 * min pbs val
		 */
		DEBUG_PBS_S("DDR3 - PBS - PUP");
		DEBUG_PBS_D(pup, 1);
		DEBUG_PBS_S(": ");

		for (dq = 0; dq < DQ_NUM; dq++) {
			/* Set skew value for all dq */
			/*
			 * Bit# Deskew <- Bit# Deskew - last / first
			 * failing bit Deskew For all bits (per PUP)
			 * (minimize delay elements)
			 */
			DEBUG_PBS_S("DQ");
			DEBUG_PBS_D(dq, 1);
			DEBUG_PBS_S("-");
			DEBUG_PBS_D(skew_array[(pup * DQ_NUM) + dq], 2);
			DEBUG_PBS_S(", ");
		}
		DEBUG_PBS_S("\n");
	}

	/* Return ADLL to default value */
	ddr3_write_pup_reg(PUP_DQS_RD, CS0, PUP_BC, 0, INIT_RL_DELAY);

	/* Set averaged PBS results */
	ddr3_set_pbs_results(dram_info, 0);

	/* Disable SW override - Must be in a different stage */
	/* [0]=0 - Enable SW override  */
	reg = reg_read(REG_DRAM_TRAINING_2_ADDR);
	reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS);
	/* 0x15B8 - Training SW 2 Register */
	reg_write(REG_DRAM_TRAINING_2_ADDR, reg);

	reg = reg_read(REG_DRAM_TRAINING_1_ADDR) |
		(1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS);
	reg_write(REG_DRAM_TRAINING_1_ADDR, reg);

	DEBUG_PBS_FULL_S("DDR3 - PBS RX - ended successfuly\n");

	return MV_OK;
}

/*
 * Name:     ddr3_rx_shift_dqs_to_first_fail
 * Desc:     Execute the Rx shift DQ phase.
 * Args:     dram_info           ddr3 training information struct
 *           cur_pup             bit array of the function active pups.
 *           pbs_pattern_idx     Index of PBS pattern
 * Notes:
 * Returns:  MV_OK if success, other error code if fail.
 */
static int ddr3_rx_shift_dqs_to_first_fail(MV_DRAM_INFO *dram_info, u32 cur_pup,
					   u32 pbs_pattern_idx, u32 ecc)
{
	u32 unlock_pup;		/* bit array of unlock pups  */
	u32 new_lockup_pup;	/* bit array of compare failed pups */
	u32 adll_val = MAX_DELAY;
	u32 dqs_deskew_val = 0;	/* current value of DQS PBS deskew */
	u32 cur_max_pup, pup, pass_pup;
	u32 *pattern_ptr;

	/* Choose pattern */
	switch (dram_info->ddr_width) {
#if defined(MV88F672X)
	case 16:
		pattern_ptr = (u32 *)&pbs_pattern[pbs_pattern_idx];
		break;
#endif
	case 32:
		pattern_ptr = (u32 *)&pbs_pattern_32b[pbs_pattern_idx];
		break;
#if defined(MV88F78X60)
	case 64:
		pattern_ptr = (u32 *)&pbs_pattern_64b[pbs_pattern_idx];
		break;
#endif
	default:
		return MV_FAIL;
	}

	/* Set current pup number */
	if (cur_pup == 0x1)	/* Ecc mode */
		cur_max_pup = 1;
	else
		cur_max_pup = dram_info->num_of_std_pups;

	unlock_pup = cur_pup;	/* '1' for each unlocked pup */

	DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Starting...\n");

	/* Set DQS ADLL to MAX */
	DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Set DQS ADLL to Max for all PUPs\n");
	for (pup = 0; pup < cur_max_pup; pup++)
		ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP, 0,
				   MAX_DELAY);

	/* Loop on all ADLL Vaules */
	do {
		/* Loop until found fail for all pups */
		new_lockup_pup = 0;
		if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup,
						&new_lockup_pup,
						pattern_ptr, LEN_PBS_PATTERN,
						SDRAM_PBS_I_OFFS +
						pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
						0, 0, NULL, 0)) {
			DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n");
			return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
		}

		if ((new_lockup_pup != 0) && (dqs_deskew_val <= 1)) {
			/* Fail on start with first deskew value */
			/* Decrement DQS ADLL */
			--adll_val;
			if (adll_val == ADLL_MIN) {
				DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - fail on start with first deskew value\n");
				return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
			}
			ddr3_write_pup_reg(PUP_DQS_RD, CS0, pup + ecc * ECC_PUP,
					   0, adll_val);
			continue;
		}

		/* Update all new locked pups */
		unlock_pup &= ~new_lockup_pup;

		if ((unlock_pup == 0) || (dqs_deskew_val == MAX_PBS)) {
			if (dqs_deskew_val == MAX_PBS) {
				/*
				 * Reach max value of dqs deskew or get fail
				 * for all pups
				 */
				DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - DQS deskew reached maximum value\n");
			}
			break;
		}

		DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - Inc DQS deskew for PUPs: ");
		DEBUG_PBS_FULL_D(unlock_pup, 2);
		DEBUG_PBS_FULL_C(", deskew = ", dqs_deskew_val, 2);

		/* Increment DQS deskew elements - Only for unlocked pups */
		dqs_deskew_val++;
		for (pup = 0; pup < cur_max_pup; pup++) {
			if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
				ddr3_write_pup_reg(PUP_PBS_RX + DQS_DQ_NUM, CS0,
						   pup + ecc * ECC_PUP, 0,
						   dqs_deskew_val);
			}
		}
	} while (1);

	DEBUG_PBS_FULL_S("DDR3 - PBS RX - Shift DQS - ADLL shift one step before fail\n");
	/* Continue to ADLL shift one step before fail */
	unlock_pup = cur_pup;
	do {
		/* Loop until pass compare for all pups */
		new_lockup_pup = 0;
		/* Read and compare results  */
		if (MV_OK != ddr3_sdram_compare(dram_info, unlock_pup, &new_lockup_pup,
						pattern_ptr, LEN_PBS_PATTERN,
						SDRAM_PBS_I_OFFS +
						pbs_pattern_idx * SDRAM_PBS_NEXT_OFFS,
						1, 0, NULL, 0)) {
			DEBUG_PBS_S("DDR3 - PBS Rx - Shift DQS - MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP(ddr3_sdram_compare)\n");
			return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_SRAM_CMP;
		}

		/*
		 * Get mask for pup which passed so their adll will be
		 * changed to 2 steps before fails
		 */
		pass_pup = unlock_pup & ~new_lockup_pup;

		DEBUG_PBS_FULL_S("Shift DQS by 2 steps for PUPs: ");
		DEBUG_PBS_FULL_D(pass_pup, 2);
		DEBUG_PBS_FULL_C(", Set ADLL value = ", (adll_val - 2), 2);

		/* Only for pass pups   */
		for (pup = 0; pup < cur_max_pup; pup++) {
			if (IS_PUP_ACTIVE(pass_pup, pup) == 1) {
				ddr3_write_pup_reg(PUP_DQS_RD, CS0,
						   pup + ecc * ECC_PUP, 0,
						   (adll_val - 2));
			}
		}

		/* Locked pups that compare success  */
		unlock_pup &= new_lockup_pup;

		if (unlock_pup == 0) {
			/* All pups locked */
			break;
		}

		/* Found error */
		if (adll_val == 0) {
			DEBUG_PBS_FULL_S("DDR3 - PBS Rx - Shift DQS - Adll reach min value\n");
			return MV_DDR3_TRAINING_ERR_PBS_SHIFT_QDS_MAX_VAL;
		}

		/*
		 * Decrement (Move Back to Left one phase - ADLL) dqs RX delay
		 */
		adll_val--;
		for (pup = 0; pup < cur_max_pup; pup++) {
			if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) {
				ddr3_write_pup_reg(PUP_DQS_RD, CS0,
						   pup + ecc * ECC_PUP, 0,
						   adll_val);
			}
		}
	} while (1);

	return MV_OK;
}

/*
 * lock_pups() extracted from ddr3_pbs_per_bit(). This just got too
 * much indented making it hard to read / edit.
 */
static void lock_pups(u32 pup, u32 *pup_locked, u8 *unlock_pup_dq_array,
		      u32 pbs_curr_val, u32 start_pbs, u32 ecc, int is_tx)
{
	u32 dq;
	int idx;

	/* Lock PBS value for all remaining PUPs bits */
	DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Lock PBS value for all remaining PUPs bits, pup ");
	DEBUG_PBS_FULL_D(pup, 1);
	DEBUG_PBS_FULL_C(" pbs value ", pbs_curr_val, 2);

	idx = pup * (1 - ecc) + ecc * ECC_PUP;
	*pup_locked &= ~(1 << pup);

	for (dq = 0; dq < DQ_NUM; dq++) {
		if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup) == 1) {
			int offs;

			/* Lock current dq */
			unlock_pup_dq_array[dq] &= ~(1 << pup);
			skew_array[(pup * DQ_NUM) + dq] = pbs_curr_val;

			if (is_tx == 1)
				offs = PUP_PBS_TX;
			else
				offs = PUP_PBS_RX;

			ddr3_write_pup_reg(offs +
					   pbs_dq_mapping[idx][dq], CS0,
					   idx, 0, start_pbs);
		}
	}
}

/*
 * Name:     ddr3_pbs_per_bit
 * Desc:     Execute the Per Bit Skew phase.
 * Args:     start_over      Return whether need to start over the algorithm
 *           is_tx           Indicate whether Rx or Tx
 *           pcur_pup        bit array of the function active pups. return the
 *                           pups that need to repeat on the PBS
 *           pbs_pattern_idx Index of PBS pattern
 *
 * Notes:    Current implementation supports double activation of this function.
 *           i.e. in order to activate this function (using start_over) more than
 *           twice, the implementation should change.
 *           imlementation limitation are marked using
 *           ' CHIP-ONLY! - Implementation Limitation '
 * Returns:  MV_OK if success, other error code if fail.
 */
static int ddr3_pbs_per_bit(MV_DRAM_INFO *dram_info, int *start_over, int is_tx,
			    u32 *pcur_pup, u32 pbs_pattern_idx, u32 ecc)
{
	/*
	 * Bit array to indicate if we already get fail on bit per pup & dq bit
	 */
	u8 unlock_pup_dq_array[DQ_NUM] = {
		*pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup, *pcur_pup,
		*pcur_pup, *pcur_pup, *pcur_pup
	};

	u8 cmp_unlock_pup_dq_array[COUNT_PBS_COMP_RETRY_NUM][DQ_NUM];
	u32 pup, dq;
	/* value of pbs is according to RX or TX */
	u32 start_pbs, last_pbs;
	u32 pbs_curr_val;
	/* bit array that indicates all dq of the pup locked */
	u32 pup_locked;
	u32 first_fail[MAX_PUP_NUM] = { 0 };	/* count first fail per pup */
	/* indicates whether we get first fail per pup */
	int first_failed[MAX_PUP_NUM] = { 0 };
	/* bit array that indicates pup already get fail */
	u32 sum_pup_fail;
	/* use to calculate diff between curr pbs to first fail pbs */
	u32 calc_pbs_diff;
	u32 pbs_cmp_retry;
	u32 max_pup;

	/* Set init values for retry array - 8 retry */
	for (pbs_cmp_retry = 0; pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
	     pbs_cmp_retry++) {
		for (dq = 0; dq < DQ_NUM; dq++)
			cmp_unlock_pup_dq_array[pbs_cmp_retry][dq] = *pcur_pup;
	}

	memset(&skew_array, 0, MAX_PUP_NUM * DQ_NUM * sizeof(u32));

	DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Started\n");

	/* The pbs value depends if rx or tx */
	if (is_tx == 1) {
		start_pbs = MIN_PBS;
		last_pbs = MAX_PBS;
	} else {
		start_pbs = MAX_PBS;
		last_pbs = MIN_PBS;
	}

	pbs_curr_val = start_pbs;
	pup_locked = *pcur_pup;

	/* Set current pup number */
	if (pup_locked == 0x1)	/* Ecc mode */
		max_pup = 1;
	else
		max_pup = dram_info->num_of_std_pups;

	do {
		/* Increment/ decrement PBS for un-lock bits only */
		if (is_tx == 1)
			pbs_curr_val++;
		else
			pbs_curr_val--;

		/* Set Current PBS delay  */
		for (dq = 0; dq < DQ_NUM; dq++) {
			/* Check DQ bits to see if locked in all pups */
			if (unlock_pup_dq_array[dq] == 0) {
				DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - All pups are locked for DQ ");
				DEBUG_PBS_FULL_D(dq, 1);
				DEBUG_PBS_FULL_S("\n");
				continue;
			}

			for (pup = 0; pup < max_pup; pup++) {
				int idx;

				idx = pup * (1 - ecc) + ecc * ECC_PUP;

				if (IS_PUP_ACTIVE(unlock_pup_dq_array[dq], pup)
				    == 0)
					continue;

				if (is_tx == 1)
					ddr3_write_pup_reg(
						PUP_PBS_TX + pbs_dq_mapping[idx][dq],
						CS0, idx, 0, pbs_curr_val);
				else
					ddr3_write_pup_reg(
						PUP_PBS_RX + pbs_dq_mapping[idx][dq],
						CS0, idx, 0, pbs_curr_val);
			}
		}

		/*
		 * Write Read and compare results - run the test
		 * DDR_PBS_COMP_RETRY_NUM times
		 */
		/* Run number of read and write to verify */
		for (pbs_cmp_retry = 0;
		     pbs_cmp_retry < COUNT_PBS_COMP_RETRY_NUM;
		     pbs_cmp_retry++) {

			if (MV_OK !=
			    ddr3_sdram_pbs_compare(dram_info, pup_locked, is_tx,
						   pbs_pattern_idx,
						   pbs_curr_val, start_pbs,
						   skew_array,
						   cmp_unlock_pup_dq_array
						   [pbs_cmp_retry], ecc))
				return MV_FAIL;

			for (pup = 0; pup < max_pup; pup++) {
				for (dq = 0; dq < DQ_NUM; dq++) {
					if ((IS_PUP_ACTIVE(unlock_pup_dq_array[dq],
							   pup) == 1)
					    && (IS_PUP_ACTIVE(cmp_unlock_pup_dq_array
					      [pbs_cmp_retry][dq],
					      pup) == 0)) {
						DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PbsCurrVal: ");
						DEBUG_PBS_FULL_D(pbs_curr_val, 2);
						DEBUG_PBS_FULL_S(" PUP: ");
						DEBUG_PBS_FULL_D(pup, 1);
						DEBUG_PBS_FULL_S(" DQ: ");
						DEBUG_PBS_FULL_D(dq, 1);
						DEBUG_PBS_FULL_S(" - failed\n");
					}
				}
			}

			for (dq = 0; dq < DQ_NUM; dq++) {
				unlock_pup_dq_array[dq] &=
				    cmp_unlock_pup_dq_array[pbs_cmp_retry][dq];
			}
		}

		pup_locked = 0;
		sum_pup_fail = *pcur_pup;

		/* Check which DQ is failed */
		for (dq = 0; dq < DQ_NUM; dq++) {
			/* Summarize the locked pup */
			pup_locked |= unlock_pup_dq_array[dq];

			/* Check if get fail */
			sum_pup_fail &= unlock_pup_dq_array[dq];
		}

		/* If all PUPS are locked in all DQ - Break */
		if (pup_locked == 0) {
			/* All pups are locked */
			*start_over = 0;
			DEBUG_PBS_FULL_S("DDR3 - PBS Per bit -  All bit in all pups are successfully locked\n");
			break;
		}

		/* PBS deskew elements reach max ? */
		if (pbs_curr_val == last_pbs) {
			DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - PBS deskew elements reach max\n");
			/* CHIP-ONLY! - Implementation Limitation */
			*start_over = (sum_pup_fail != 0) && (!(*start_over));
			*pcur_pup = pup_locked;

			DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - StartOver: ");
			DEBUG_PBS_FULL_D(*start_over, 1);
			DEBUG_PBS_FULL_S("  pup_locked: ");
			DEBUG_PBS_FULL_D(pup_locked, 2);
			DEBUG_PBS_FULL_S("  sum_pup_fail: ");
			DEBUG_PBS_FULL_D(sum_pup_fail, 2);
			DEBUG_PBS_FULL_S("\n");

			/* Lock PBS value for all remaining  bits */
			for (pup = 0; pup < max_pup; pup++) {
				/* Check if current pup already received error */
				if (IS_PUP_ACTIVE(pup_locked, pup) == 1) {
					/* Valid pup for current function */
					if (IS_PUP_ACTIVE(sum_pup_fail, pup) ==
					    1 && (*start_over == 1)) {
						DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - skipping lock of pup (first loop of pbs)",
								 pup, 1);
						continue;
					} else
					    if (IS_PUP_ACTIVE(sum_pup_fail, pup)
						== 1) {
						DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - Locking pup %d (even though it wasn't supposed to be locked)",
								 pup, 1);
					}

					/* Already got fail on the PUP */
					/* Lock PBS value for all remaining bits */
					DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Locking remaning DQs for pup - ");
					DEBUG_PBS_FULL_D(pup, 1);
					DEBUG_PBS_FULL_S(": ");

					for (dq = 0; dq < DQ_NUM; dq++) {
						if (IS_PUP_ACTIVE
						    (unlock_pup_dq_array[dq],
						     pup) == 1) {
							DEBUG_PBS_FULL_D(dq, 1);
							DEBUG_PBS_FULL_S(",");
							/* set current PBS */
							skew_array[((pup) *
								    DQ_NUM) +
								   dq] =
							    pbs_curr_val;
						}
					}

					if (*start_over == 1) {
						/*
						 * Reset this pup bit - when
						 * restart the PBS, ignore this
						 * pup
						 */
						*pcur_pup &= ~(1 << pup);
					}
					DEBUG_PBS_FULL_S("\n");
				} else {
					DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - Pup ");
					DEBUG_PBS_FULL_D(pup, 1);
					DEBUG_PBS_FULL_C(" is not set in puplocked - ",
							 pup_locked, 1);
				}
			}

			/* Need to start the PBS again */
			if (*start_over == 1) {
				DEBUG_PBS_FULL_S("DDR3 - PBS Per bit - false fail - returning to start\n");
				return MV_OK;
			}
			break;
		}

		/* Diff Check */
		for (pup = 0; pup < max_pup; pup++) {
			if (IS_PUP_ACTIVE(pup_locked, pup) == 1) {
				/* pup is not locked */
				if (first_failed[pup] == 0) {
					/* No first fail until now */
					if (IS_PUP_ACTIVE(sum_pup_fail, pup) ==
					    0) {
						/* Get first fail */
						DEBUG_PBS_FULL_C("DDR3 - PBS Per bit - First fail in pup ",
								 pup, 1);
						first_failed[pup] = 1;
						first_fail[pup] = pbs_curr_val;
					}
				} else {
					/* Already got first fail */
					if (is_tx == 1) {
						/* TX - inc pbs */
						calc_pbs_diff =	pbs_curr_val -
							first_fail[pup];
					} else {
						/* RX - dec pbs */
						calc_pbs_diff = first_fail[pup] -
							pbs_curr_val;
					}

					if (calc_pbs_diff >= PBS_DIFF_LIMIT) {
						lock_pups(pup, &pup_locked,
							  unlock_pup_dq_array,
							  pbs_curr_val,
							  start_pbs, ecc, is_tx);
					}
				}
			}
		}
	} while (1);

	return MV_OK;
}

/*
 * Name:         ddr3_set_pbs_results
 * Desc:         Set to HW the PBS phase results.
 * Args:         is_tx       Indicates whether to set Tx or RX results
 * Notes:
 * Returns:      MV_OK if success, other error code if fail.
 */
static int ddr3_set_pbs_results(MV_DRAM_INFO *dram_info, int is_tx)
{
	u32 pup, phys_pup, dq;
	u32 max_pup;		/* number of valid pups */
	u32 pbs_min;		/* minimal pbs val per pup */
	u32 pbs_max;		/* maximum pbs val per pup */
	u32 val[9];

	max_pup = dram_info->num_of_total_pups;
	DEBUG_PBS_FULL_S("DDR3 - PBS - ddr3_set_pbs_results:\n");

	/* Loop for all dqs & pups */
	for (pup = 0; pup < max_pup; pup++) {
		if (pup == (max_pup - 1) && dram_info->ecc_ena)
			phys_pup = ECC_PUP;
		else
			phys_pup = pup;

		/*
		 * To minimize delay elements, inc from pbs value the min
		 * pbs val
		 */
		pbs_min = MAX_PBS;
		pbs_max = 0;
		for (dq = 0; dq < DQ_NUM; dq++) {
			if (pbs_min > skew_array[(pup * DQ_NUM) + dq])
				pbs_min = skew_array[(pup * DQ_NUM) + dq];

			if (pbs_max < skew_array[(pup * DQ_NUM) + dq])
				pbs_max = skew_array[(pup * DQ_NUM) + dq];
		}

		pbs_max -= pbs_min;

		DEBUG_PBS_FULL_S("DDR3 - PBS - PUP");
		DEBUG_PBS_FULL_D(phys_pup, 1);
		DEBUG_PBS_FULL_S(": Min Val = ");
		DEBUG_PBS_FULL_D(pbs_min, 2);
		DEBUG_PBS_FULL_C(", Max Val = ", pbs_max, 2);

		val[pup] = 0;

		for (dq = 0; dq < DQ_NUM; dq++) {
			int idx;
			int offs;

			/* Set skew value for all dq */
			/*
			 * Bit# Deskew <- Bit# Deskew - last / first
			 * failing bit Deskew For all bits (per PUP)
			 * (minimize delay elements)
			 */

			DEBUG_PBS_FULL_S("DQ");
			DEBUG_PBS_FULL_D(dq, 1);
			DEBUG_PBS_FULL_S("-");
			DEBUG_PBS_FULL_D((skew_array[(pup * DQ_NUM) + dq] -
					  pbs_min), 2);
			DEBUG_PBS_FULL_S(", ");

			idx = (pup * DQ_NUM) + dq;

			if (is_tx == 1)
				offs = PUP_PBS_TX;
			else
				offs = PUP_PBS_RX;

			ddr3_write_pup_reg(offs + pbs_dq_mapping[phys_pup][dq],
					   CS0, phys_pup, 0,
					   skew_array[idx] - pbs_min);

			if (is_tx == 1)
				val[pup] += skew_array[idx] - pbs_min;
		}

		DEBUG_PBS_FULL_S("\n");

		/* Set the DQS the half of the Max PBS of the DQs  */
		if (is_tx == 1) {
			ddr3_write_pup_reg(PUP_PBS_TX + 8, CS0, phys_pup, 0,
					   pbs_max / 2);
			ddr3_write_pup_reg(PUP_PBS_TX + 0xa, CS0, phys_pup, 0,
					   val[pup] / 8);
		} else
			ddr3_write_pup_reg(PUP_PBS_RX + 8, CS0, phys_pup, 0,
					   pbs_max / 2);
	}

	return MV_OK;
}

static void ddr3_pbs_write_pup_dqs_reg(u32 cs, u32 pup, u32 dqs_delay)
{
	u32 reg, delay;

	reg = (ddr3_read_pup_reg(PUP_WL_MODE, cs, pup) & 0x3FF);
	delay = reg & PUP_DELAY_MASK;
	reg |= ((dqs_delay + delay) << REG_PHY_DQS_REF_DLY_OFFS);
	reg |= REG_PHY_REGISTRY_FILE_ACCESS_OP_WR;
	reg |= (pup << REG_PHY_PUP_OFFS);
	reg |= ((0x4 * cs + PUP_WL_MODE) << REG_PHY_CS_OFFS);

	reg_write(REG_PHY_REGISTRY_FILE_ACCESS_ADDR, reg);	/* 0x16A0 */
	do {
		reg = reg_read(REG_PHY_REGISTRY_FILE_ACCESS_ADDR) &
			REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE;
	} while (reg);	/* Wait for '0' to mark the end of the transaction */

	udelay(10);
}

/*
 * Set training patterns
 */
int ddr3_load_pbs_patterns(MV_DRAM_INFO *dram_info)
{
	u32 cs, cs_count, cs_tmp;
	u32 sdram_addr;
	u32 *pattern_ptr0, *pattern_ptr1;

	/* Choose pattern */
	switch (dram_info->ddr_width) {
#if defined(MV88F672X)
	case 16:
		pattern_ptr0 = (u32 *)&pbs_pattern[0];
		pattern_ptr1 = (u32 *)&pbs_pattern[1];
		break;
#endif
	case 32:
		pattern_ptr0 = (u32 *)&pbs_pattern_32b[0];
		pattern_ptr1 = (u32 *)&pbs_pattern_32b[1];
		break;
#if defined(MV88F78X60)
	case 64:
		pattern_ptr0 = (u32 *)&pbs_pattern_64b[0];
		pattern_ptr1 = (u32 *)&pbs_pattern_64b[1];
		break;
#endif
	default:
		return MV_FAIL;
	}

	/* Loop for each CS */
	for (cs = 0; cs < MAX_CS; cs++) {
		if (dram_info->cs_ena & (1 << cs)) {
			cs_count = 0;
			for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) {
				if (dram_info->cs_ena & (1 << cs_tmp))
					cs_count++;
			}

			/* Init PBS I pattern */
			sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
				      SDRAM_PBS_I_OFFS);
			if (MV_OK !=
			    ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
					       pattern_ptr0, LEN_STD_PATTERN,
					       sdram_addr, 1, 0, NULL,
					       0))
				return MV_FAIL;

			/* Init PBS II pattern */
			sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) +
				      SDRAM_PBS_II_OFFS);
			if (MV_OK !=
			    ddr3_sdram_compare(dram_info, (u32) NULL, NULL,
					       pattern_ptr1, LEN_STD_PATTERN,
					       sdram_addr, 1, 0, NULL,
					       0))
				return MV_FAIL;
		}
	}

	return MV_OK;
}
#endif
