/*
 * Copyright 2011-2012 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <i2c.h>
#include <netdev.h>
#include <linux/compiler.h>
#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/errno.h>
#include <asm/cache.h>
#include <asm/immap_85xx.h>
#include <asm/fsl_law.h>
#include <asm/fsl_serdes.h>
#include <asm/fsl_liodn.h>
#include <fm_eth.h>
#include <hwconfig.h>

#include "../common/qixis.h"
#include "../common/vsc3316_3308.h"
#include "../common/idt8t49n222a_serdes_clk.h"
#include "../common/zm7300.h"
#include "b4860qds.h"
#include "b4860qds_qixis.h"
#include "b4860qds_crossbar_con.h"

#define CLK_MUX_SEL_MASK	0x4
#define ETH_PHY_CLK_OUT		0x4

DECLARE_GLOBAL_DATA_PTR;

int checkboard(void)
{
	char buf[64];
	u8 sw;
	struct cpu_type *cpu = gd->arch.cpu;
	static const char *const freq[] = {"100", "125", "156.25", "161.13",
						"122.88", "122.88", "122.88"};
	int clock;

	printf("Board: %sQDS, ", cpu->name);
	printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
		QIXIS_READ(id), QIXIS_READ(arch));

	sw = QIXIS_READ(brdcfg[0]);
	sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;

	if (sw < 0x8)
		printf("vBank: %d\n", sw);
	else if (sw >= 0x8 && sw <= 0xE)
		puts("NAND\n");
	else
		printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);

	printf("FPGA: v%d (%s), build %d",
		(int)QIXIS_READ(scver), qixis_read_tag(buf),
		(int)qixis_read_minor());
	/* the timestamp string contains "\n" at the end */
	printf(" on %s", qixis_read_time(buf));

	/*
	 * Display the actual SERDES reference clocks as configured by the
	 * dip switches on the board.  Note that the SWx registers could
	 * technically be set to force the reference clocks to match the
	 * values that the SERDES expects (or vice versa).  For now, however,
	 * we just display both values and hope the user notices when they
	 * don't match.
	 */
	puts("SERDES Reference Clocks: ");
	sw = QIXIS_READ(brdcfg[2]);
	clock = (sw >> 5) & 7;
	printf("Bank1=%sMHz ", freq[clock]);
	sw = QIXIS_READ(brdcfg[4]);
	clock = (sw >> 6) & 3;
	printf("Bank2=%sMHz\n", freq[clock]);

	return 0;
}

int select_i2c_ch_pca(u8 ch)
{
	int ret;

	/* Selecting proper channel via PCA*/
	ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
	if (ret) {
		printf("PCA: failed to select proper channel.\n");
		return ret;
	}

	return 0;
}

/*
 * read_voltage from sensor on I2C bus
 * We use average of 4 readings, waiting for 532us befor another reading
 */
#define WAIT_FOR_ADC	532	/* wait for 532 microseconds for ADC */
#define NUM_READINGS	4	/* prefer to be power of 2 for efficiency */

static inline int read_voltage(void)
{
	int i, ret, voltage_read = 0;
	u16 vol_mon;

	for (i = 0; i < NUM_READINGS; i++) {
		ret = i2c_read(I2C_VOL_MONITOR_ADDR,
			I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
		if (ret) {
			printf("VID: failed to read core voltage\n");
			return ret;
		}
		if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
			printf("VID: Core voltage sensor error\n");
			return -1;
		}
		debug("VID: bus voltage reads 0x%04x\n", vol_mon);
		/* LSB = 4mv */
		voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
		udelay(WAIT_FOR_ADC);
	}
	/* calculate the average */
	voltage_read /= NUM_READINGS;

	return voltage_read;
}

static int adjust_vdd(ulong vdd_override)
{
	int re_enable = disable_interrupts();
	ccsr_gur_t __iomem *gur =
		(void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 fusesr;
	u8 vid;
	int vdd_target, vdd_last;
	int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */
	int ret;
	unsigned int orig_i2c_speed;
	unsigned long vdd_string_override;
	char *vdd_string;
	static const uint16_t vdd[32] = {
		0,	/* unused */
		9875,	/* 0.9875V */
		9750,
		9625,
		9500,
		9375,
		9250,
		9125,
		9000,
		8875,
		8750,
		8625,
		8500,
		8375,
		8250,
		8125,
		10000,	/* 1.0000V */
		10125,
		10250,
		10375,
		10500,
		10625,
		10750,
		10875,
		11000,
		0,	/* reserved */
	};
	struct vdd_drive {
		u8 vid;
		unsigned voltage;
	};

	ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
	if (ret) {
		printf("VID: I2c failed to switch channel\n");
		ret = -1;
		goto exit;
	}

	/* get the voltage ID from fuse status register */
	fusesr = in_be32(&gur->dcfg_fusesr);
	vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
		FSL_CORENET_DCFG_FUSESR_VID_MASK;
	if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
		vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
			FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
	}
	vdd_target = vdd[vid];
	debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n",
	      vid, vdd_target/10);

	/* check override variable for overriding VDD */
	vdd_string = getenv("b4qds_vdd_mv");
	if (vdd_override == 0 && vdd_string &&
	    !strict_strtoul(vdd_string, 10, &vdd_string_override))
		vdd_override = vdd_string_override;
	if (vdd_override >= 819 && vdd_override <= 1212) {
		vdd_target = vdd_override * 10; /* convert to 1/10 mV */
		debug("VDD override is %lu\n", vdd_override);
	} else if (vdd_override != 0) {
		printf("Invalid value.\n");
	}

	if (vdd_target == 0) {
		printf("VID: VID not used\n");
		ret = 0;
		goto exit;
	}

	/*
	 * Read voltage monitor to check real voltage.
	 * Voltage monitor LSB is 4mv.
	 */
	vdd_last = read_voltage();
	if (vdd_last < 0) {
		printf("VID: abort VID adjustment\n");
		ret = -1;
		goto exit;
	}

	debug("VID: Core voltage is at %d mV\n", vdd_last);
	ret = select_i2c_ch_pca(I2C_MUX_CH_DPM);
	if (ret) {
		printf("VID: I2c failed to switch channel to DPM\n");
		ret = -1;
		goto exit;
	}

	/* Round up to the value of step of Voltage regulator */
	voltage = roundup(vdd_target, ZM_STEP);
	debug("VID: rounded up voltage = %d\n", voltage);

	/* lower the speed to 100kHz to access ZM7300 device */
	debug("VID: Setting bus speed to 100KHz if not already set\n");
	orig_i2c_speed = i2c_get_bus_speed();
	if (orig_i2c_speed != 100000)
		i2c_set_bus_speed(100000);

	/* Read the existing level on board, if equal to requsted one,
	   no need to re-set */
	existing_voltage = zm_read_voltage();

	/* allowing the voltage difference of one step 0.0125V acceptable */
	if ((existing_voltage >= voltage) &&
	    (existing_voltage < (voltage + ZM_STEP))) {
		debug("VID: voltage already set as requested,returning\n");
		ret = existing_voltage;
		goto out;
	}
	debug("VID: Changing voltage for board from %dmV to %dmV\n",
	      existing_voltage/10, voltage/10);

	if (zm_disable_wp() < 0) {
		ret = -1;
		goto out;
	}
	/* Change Voltage: the change is done through all the steps in the
	   way, to avoid reset to the board due to power good signal fail
	   in big voltage change gap jump.
	*/
	if (existing_voltage > voltage) {
		temp_voltage = existing_voltage - ZM_STEP;
			while (temp_voltage >= voltage) {
				ret = zm_write_voltage(temp_voltage);
				if (ret == temp_voltage) {
					temp_voltage -= ZM_STEP;
				} else {
					/* ZM7300 device failed to set
					 * the voltage */
					printf
					("VID:Stepping down vol failed:%dmV\n",
					 temp_voltage/10);
				     ret = -1;
				     goto out;
				}
			}
	} else {
		temp_voltage = existing_voltage + ZM_STEP;
			while (temp_voltage < (voltage + ZM_STEP)) {
				ret = zm_write_voltage(temp_voltage);
				if (ret == temp_voltage) {
					temp_voltage += ZM_STEP;
				} else {
					/* ZM7300 device failed to set
					 * the voltage */
					printf
					("VID:Stepping up vol failed:%dmV\n",
					 temp_voltage/10);
				     ret = -1;
				     goto out;
				}
			}
	}

	if (zm_enable_wp() < 0)
		ret = -1;

	/* restore the speed to 400kHz */
out:	debug("VID: Restore the I2C bus speed to %dKHz\n",
				orig_i2c_speed/1000);
	i2c_set_bus_speed(orig_i2c_speed);
	if (ret < 0)
		goto exit;

	ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
	if (ret) {
		printf("VID: I2c failed to switch channel\n");
		ret = -1;
		goto exit;
	}
	vdd_last = read_voltage();
	select_i2c_ch_pca(I2C_CH_DEFAULT);

	if (vdd_last > 0)
		printf("VID: Core voltage %d mV\n", vdd_last);
	else
		ret = -1;

exit:
	if (re_enable)
		enable_interrupts();
	return ret;
}

int configure_vsc3316_3308(void)
{
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	unsigned int num_vsc16_con, num_vsc08_con;
	u32 serdes1_prtcl, serdes2_prtcl;
	int ret;
	char buffer[HWCONFIG_BUFFER_SIZE];
	char *buf = NULL;

	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
	if (!serdes1_prtcl) {
		printf("SERDES1 is not enabled\n");
		return 0;
	}
	serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
	debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);

	serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
			FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
	if (!serdes2_prtcl) {
		printf("SERDES2 is not enabled\n");
		return 0;
	}
	serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
	debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);

	switch (serdes1_prtcl) {
	case 0x29:
	case 0x2a:
	case 0x2C:
	case 0x2D:
	case 0x2E:
			/*
			 * Configuration:
			 * SERDES: 1
			 * Lanes: A,B: SGMII
			 * Lanes: C,D,E,F,G,H: CPRI
			 */
		debug("Configuring crossbar to use onboard SGMII PHYs:"
				"srds_prctl:%x\n", serdes1_prtcl);
		num_vsc16_con = NUM_CON_VSC3316;
		/* Configure VSC3316 crossbar switch */
		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
		if (!ret) {
			ret = vsc3316_config(VSC3316_TX_ADDRESS,
					vsc16_tx_4sfp_sgmii_12_56,
					num_vsc16_con);
			if (ret)
				return ret;
			ret = vsc3316_config(VSC3316_RX_ADDRESS,
					vsc16_rx_4sfp_sgmii_12_56,
					num_vsc16_con);
			if (ret)
				return ret;
		} else {
			return ret;
		}
		break;

	case 0x01:
	case 0x02:
	case 0x04:
	case 0x05:
	case 0x06:
	case 0x07:
	case 0x08:
	case 0x09:
	case 0x0A:
	case 0x0B:
	case 0x0C:
	case 0x2F:
	case 0x30:
	case 0x32:
	case 0x33:
	case 0x34:
	case 0x39:
	case 0x3A:
	case 0x3C:
	case 0x3D:
	case 0x5C:
	case 0x5D:
			/*
			 * Configuration:
			 * SERDES: 1
			 * Lanes: A,B: AURORA
			 * Lanes: C,d: SGMII
			 * Lanes: E,F,G,H: CPRI
			 */
		debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
				" and CPRI. srds_prctl:%x\n", serdes1_prtcl);
		num_vsc16_con = NUM_CON_VSC3316;
		/* Configure VSC3316 crossbar switch */
		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
		if (!ret) {
			ret = vsc3316_config(VSC3316_TX_ADDRESS,
					vsc16_tx_sfp_sgmii_aurora,
					num_vsc16_con);
			if (ret)
				return ret;
			ret = vsc3316_config(VSC3316_RX_ADDRESS,
					vsc16_rx_sfp_sgmii_aurora,
					num_vsc16_con);
			if (ret)
				return ret;
		} else {
			return ret;
		}
		break;

#ifdef CONFIG_PPC_B4420
	case 0x17:
	case 0x18:
			/*
			 * Configuration:
			 * SERDES: 1
			 * Lanes: A,B,C,D: SGMII
			 * Lanes: E,F,G,H: CPRI
			 */
		debug("Configuring crossbar to use onboard SGMII PHYs:"
				"srds_prctl:%x\n", serdes1_prtcl);
		num_vsc16_con = NUM_CON_VSC3316;
		/* Configure VSC3316 crossbar switch */
		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
		if (!ret) {
			ret = vsc3316_config(VSC3316_TX_ADDRESS,
					vsc16_tx_sgmii_lane_cd, num_vsc16_con);
			if (ret)
				return ret;
			ret = vsc3316_config(VSC3316_RX_ADDRESS,
					vsc16_rx_sgmii_lane_cd, num_vsc16_con);
			if (ret)
				return ret;
		} else {
			return ret;
		}
		break;
#endif

	case 0x3E:
	case 0x0D:
	case 0x0E:
	case 0x12:
		num_vsc16_con = NUM_CON_VSC3316;
		/* Configure VSC3316 crossbar switch */
		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
		if (!ret) {
			ret = vsc3316_config(VSC3316_TX_ADDRESS,
					vsc16_tx_sfp, num_vsc16_con);
			if (ret)
				return ret;
			ret = vsc3316_config(VSC3316_RX_ADDRESS,
					vsc16_rx_sfp, num_vsc16_con);
			if (ret)
				return ret;
		} else {
			return ret;
		}
		break;
	default:
		printf("WARNING:VSC crossbars programming not supported for:%x"
					" SerDes1 Protocol.\n", serdes1_prtcl);
		return -1;
	}

	num_vsc08_con = NUM_CON_VSC3308;
	/* Configure VSC3308 crossbar switch */
	ret = select_i2c_ch_pca(I2C_CH_VSC3308);
	switch (serdes2_prtcl) {
#ifdef CONFIG_PPC_B4420
	case 0x9d:
#endif
	case 0x9E:
	case 0x9A:
	case 0x98:
	case 0x48:
	case 0x49:
	case 0x4E:
	case 0x79:
	case 0x7A:
		if (!ret) {
			ret = vsc3308_config(VSC3308_TX_ADDRESS,
					vsc08_tx_amc, num_vsc08_con);
			if (ret)
				return ret;
			ret = vsc3308_config(VSC3308_RX_ADDRESS,
					vsc08_rx_amc, num_vsc08_con);
			if (ret)
				return ret;
		} else {
			return ret;
		}
		break;
	case 0x80:
	case 0x81:
	case 0x82:
	case 0x83:
	case 0x84:
	case 0x85:
	case 0x86:
	case 0x87:
	case 0x88:
	case 0x89:
	case 0x8a:
	case 0x8b:
	case 0x8c:
	case 0x8d:
	case 0x8e:
	case 0xb1:
	case 0xb2:
		if (!ret) {
			/*
			 * Extract hwconfig from environment since environment
			 * is not setup properly yet
			 */
			getenv_f("hwconfig", buffer, sizeof(buffer));
			buf = buffer;

			if (hwconfig_subarg_cmp_f("fsl_b4860_serdes2",
						  "sfp_amc", "sfp", buf)) {
#ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
				/* change default VSC3308 for XFI erratum */
				ret = vsc3308_config_adjust(VSC3308_TX_ADDRESS,
						vsc08_tx_sfp, num_vsc08_con);
				if (ret)
					return ret;

				ret = vsc3308_config_adjust(VSC3308_RX_ADDRESS,
						vsc08_rx_sfp, num_vsc08_con);
				if (ret)
					return ret;
#else
				ret = vsc3308_config(VSC3308_TX_ADDRESS,
						vsc08_tx_sfp, num_vsc08_con);
				if (ret)
					return ret;

				ret = vsc3308_config(VSC3308_RX_ADDRESS,
						vsc08_rx_sfp, num_vsc08_con);
				if (ret)
					return ret;
#endif
			} else {
				ret = vsc3308_config(VSC3308_TX_ADDRESS,
						vsc08_tx_amc, num_vsc08_con);
				if (ret)
					return ret;

				ret = vsc3308_config(VSC3308_RX_ADDRESS,
						vsc08_rx_amc, num_vsc08_con);
				if (ret)
					return ret;
			}

		} else {
			return ret;
		}
		break;
	default:
		printf("WARNING:VSC crossbars programming not supported for: %x"
					" SerDes2 Protocol.\n", serdes2_prtcl);
		return -1;
	}

	return 0;
}

static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
{
	u32 rst_err;

	/* Steps For SerDes PLLs reset and reconfiguration
	 * or PLL power-up procedure
	 */
	debug("CALIBRATE PLL:%d\n", pll_num);
	clrbits_be32(&srds_regs->bank[pll_num].rstctl,
			SRDS_RSTCTL_SDRST_B);
	udelay(10);
	clrbits_be32(&srds_regs->bank[pll_num].rstctl,
		(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
	udelay(10);
	setbits_be32(&srds_regs->bank[pll_num].rstctl,
			SRDS_RSTCTL_RST);
	setbits_be32(&srds_regs->bank[pll_num].rstctl,
		(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
		| SRDS_RSTCTL_SDRST_B));

	udelay(20);

	/* Check whether PLL has been locked or not */
	rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
				SRDS_RSTCTL_RSTERR;
	rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
	debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
	if (rst_err)
		return rst_err;

	return rst_err;
}

static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
{
	int ret = 0;
	u32 fcap, dcbias, bcap, pllcr1, pllcr0;

	if (calibrate_pll(srds_regs, pll_num)) {
		/* STEP 1 */
		/* Read fcap, dcbias and bcap value */
		clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
				SRDS_PLLCR0_DCBIAS_OUT_EN);
		fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
					SRDS_PLLSR2_FCAP;
		fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
		bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
					SRDS_PLLSR2_BCAP_EN;
		bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
		setbits_be32(&srds_regs->bank[pll_num].pllcr0,
				SRDS_PLLCR0_DCBIAS_OUT_EN);
		dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
					SRDS_PLLSR2_DCBIAS;
		dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
		debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
					bcap, fcap, dcbias);
		if (fcap == 0 && bcap == 1) {
			/* Step 3 */
			clrbits_be32(&srds_regs->bank[pll_num].rstctl,
				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
				 | SRDS_RSTCTL_SDRST_B));
			clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
					SRDS_PLLCR1_BCAP_EN);
			setbits_be32(&srds_regs->bank[pll_num].pllcr1,
					SRDS_PLLCR1_BCAP_OVD);
			if (calibrate_pll(srds_regs, pll_num)) {
				/*save the fcap, dcbias and bcap values*/
				clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
						SRDS_PLLCR0_DCBIAS_OUT_EN);
				fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
					& SRDS_PLLSR2_FCAP;
				fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
				bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
					& SRDS_PLLSR2_BCAP_EN;
				bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
				setbits_be32(&srds_regs->bank[pll_num].pllcr0,
						SRDS_PLLCR0_DCBIAS_OUT_EN);
				dcbias = in_be32
					(&srds_regs->bank[pll_num].pllsr2) &
							SRDS_PLLSR2_DCBIAS;
				dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;

				/* Step 4*/
				clrbits_be32(&srds_regs->bank[pll_num].rstctl,
				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
				 | SRDS_RSTCTL_SDRST_B));
				setbits_be32(&srds_regs->bank[pll_num].pllcr1,
						SRDS_PLLCR1_BYP_CAL);
				clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
						SRDS_PLLCR1_BCAP_EN);
				setbits_be32(&srds_regs->bank[pll_num].pllcr1,
						SRDS_PLLCR1_BCAP_OVD);
				/* change the fcap and dcbias to the saved
				 * values from Step 3 */
				clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
							SRDS_PLLCR1_PLL_FCAP);
				pllcr1 = (in_be32
					(&srds_regs->bank[pll_num].pllcr1)|
					(fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
				out_be32(&srds_regs->bank[pll_num].pllcr1,
							pllcr1);
				clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
						SRDS_PLLCR0_DCBIAS_OVRD);
				pllcr0 = (in_be32
				(&srds_regs->bank[pll_num].pllcr0)|
				(dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
				out_be32(&srds_regs->bank[pll_num].pllcr0,
							pllcr0);
				ret = calibrate_pll(srds_regs, pll_num);
				if (ret)
					return ret;
			} else {
				goto out;
			}
		} else { /* Step 5 */
			clrbits_be32(&srds_regs->bank[pll_num].rstctl,
				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
				 | SRDS_RSTCTL_SDRST_B));
			udelay(10);
			/* Change the fcap, dcbias, and bcap to the
			 * values from Step 1 */
			setbits_be32(&srds_regs->bank[pll_num].pllcr1,
					SRDS_PLLCR1_BYP_CAL);
			clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
						SRDS_PLLCR1_PLL_FCAP);
			pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
				(fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
			out_be32(&srds_regs->bank[pll_num].pllcr1,
						pllcr1);
			clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
						SRDS_PLLCR0_DCBIAS_OVRD);
			pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
				(dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
			out_be32(&srds_regs->bank[pll_num].pllcr0,
						pllcr0);
			clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
					SRDS_PLLCR1_BCAP_EN);
			setbits_be32(&srds_regs->bank[pll_num].pllcr1,
					SRDS_PLLCR1_BCAP_OVD);
			ret = calibrate_pll(srds_regs, pll_num);
			if (ret)
				return ret;
		}
	}
out:
	return 0;
}

static int check_serdes_pll_locks(void)
{
	serdes_corenet_t *srds1_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
	serdes_corenet_t *srds2_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
	int i, ret1, ret2;

	debug("\nSerDes1 Lock check\n");
	for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
		ret1 = check_pll_locks(srds1_regs, i);
		if (ret1) {
			printf("SerDes1, PLL:%d didnt lock\n", i);
			return ret1;
		}
	}
	debug("\nSerDes2 Lock check\n");
	for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
		ret2 = check_pll_locks(srds2_regs, i);
		if (ret2) {
			printf("SerDes2, PLL:%d didnt lock\n", i);
			return ret2;
		}
	}

	return 0;
}

int config_serdes1_refclks(void)
{
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	serdes_corenet_t *srds_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
	u32 serdes1_prtcl, lane;
	unsigned int flag_sgmii_aurora_prtcl = 0;
	int i;
	int ret = 0;

	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
	if (!serdes1_prtcl) {
		printf("SERDES1 is not enabled\n");
		return -1;
	}
	serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
	debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);

	/* To prevent generation of reset request from SerDes
	 * while changing the refclks, By setting SRDS_RST_MSK bit,
	 * SerDes reset event cannot cause a reset request
	 */
	setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);

	/* Reconfigure IDT idt8t49n222a device for CPRI to work
	 * For this SerDes1's Refclk1 and refclk2 need to be set
	 * to 122.88MHz
	 */
	switch (serdes1_prtcl) {
	case 0x29:
	case 0x2A:
	case 0x2C:
	case 0x2D:
	case 0x2E:
	case 0x01:
	case 0x02:
	case 0x04:
	case 0x05:
	case 0x06:
	case 0x07:
	case 0x08:
	case 0x09:
	case 0x0A:
	case 0x0B:
	case 0x0C:
	case 0x2F:
	case 0x30:
	case 0x32:
	case 0x33:
	case 0x34:
	case 0x39:
	case 0x3A:
	case 0x3C:
	case 0x3D:
	case 0x5C:
	case 0x5D:
		debug("Configuring idt8t49n222a for CPRI SerDes clks:"
			" for srds_prctl:%x\n", serdes1_prtcl);
		ret = select_i2c_ch_pca(I2C_CH_IDT);
		if (!ret) {
			ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
					SERDES_REFCLK_122_88,
					SERDES_REFCLK_122_88, 0);
			if (ret) {
				printf("IDT8T49N222A configuration failed.\n");
				goto out;
			} else
				debug("IDT8T49N222A configured.\n");
		} else {
			goto out;
		}
		select_i2c_ch_pca(I2C_CH_DEFAULT);

		/* Change SerDes1's Refclk1 to 125MHz for on board
		 * SGMIIs or Aurora to work
		 */
		for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
			enum srds_prtcl lane_prtcl = serdes_get_prtcl
						(0, serdes1_prtcl, lane);
			switch (lane_prtcl) {
			case SGMII_FM1_DTSEC1:
			case SGMII_FM1_DTSEC2:
			case SGMII_FM1_DTSEC3:
			case SGMII_FM1_DTSEC4:
			case SGMII_FM1_DTSEC5:
			case SGMII_FM1_DTSEC6:
			case AURORA:
				flag_sgmii_aurora_prtcl++;
				break;
			default:
				break;
			}
		}

		if (flag_sgmii_aurora_prtcl)
			QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);

		/* Steps For SerDes PLLs reset and reconfiguration after
		 * changing SerDes's refclks
		 */
		for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
			debug("For PLL%d reset and reconfiguration after"
			       " changing refclks\n", i+1);
			clrbits_be32(&srds_regs->bank[i].rstctl,
					SRDS_RSTCTL_SDRST_B);
			udelay(10);
			clrbits_be32(&srds_regs->bank[i].rstctl,
				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
			udelay(10);
			setbits_be32(&srds_regs->bank[i].rstctl,
					SRDS_RSTCTL_RST);
			setbits_be32(&srds_regs->bank[i].rstctl,
				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
				| SRDS_RSTCTL_SDRST_B));
		}
		break;
	default:
		printf("WARNING:IDT8T49N222A configuration not"
			" supported for:%x SerDes1 Protocol.\n",
			serdes1_prtcl);
	}

out:
	/* Clearing SRDS_RST_MSK bit as now
	 * SerDes reset event can cause a reset request
	 */
	clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
	return ret;
}

int config_serdes2_refclks(void)
{
	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	serdes_corenet_t *srds2_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
	u32 serdes2_prtcl;
	int ret = 0;
	int i;

	serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
			FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
	if (!serdes2_prtcl) {
		debug("SERDES2 is not enabled\n");
		return -ENODEV;
	}
	serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
	debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);

	/* To prevent generation of reset request from SerDes
	 * while changing the refclks, By setting SRDS_RST_MSK bit,
	 * SerDes reset event cannot cause a reset request
	 */
	setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);

	/* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
	 * For this SerDes2's Refclk1 need to be set to 100MHz
	 */
	switch (serdes2_prtcl) {
#ifdef CONFIG_PPC_B4420
	case 0x9d:
#endif
	case 0x9E:
	case 0x9A:
		/* fallthrough */
	case 0xb1:
	case 0xb2:
		debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
			serdes2_prtcl);
		ret = select_i2c_ch_pca(I2C_CH_IDT);
		if (!ret) {
			ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
					SERDES_REFCLK_100,
					SERDES_REFCLK_156_25, 0);
			if (ret) {
				printf("IDT8T49N222A configuration failed.\n");
				goto out;
			} else
				debug("IDT8T49N222A configured.\n");
		} else {
			goto out;
		}
		select_i2c_ch_pca(I2C_CH_DEFAULT);

		/* Steps For SerDes PLLs reset and reconfiguration after
		 * changing SerDes's refclks
		 */
		for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
			clrbits_be32(&srds2_regs->bank[i].rstctl,
					SRDS_RSTCTL_SDRST_B);
			udelay(10);
			clrbits_be32(&srds2_regs->bank[i].rstctl,
				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
			udelay(10);
			setbits_be32(&srds2_regs->bank[i].rstctl,
					SRDS_RSTCTL_RST);
			setbits_be32(&srds2_regs->bank[i].rstctl,
				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
				| SRDS_RSTCTL_SDRST_B));

			udelay(10);
		}
		break;
	default:
		printf("IDT configuration not supported for:%x S2 Protocol.\n",
			serdes2_prtcl);
	}

out:
	/* Clearing SRDS_RST_MSK bit as now
	 * SerDes reset event can cause a reset request
	 */
	clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
	return ret;
}

int board_early_init_r(void)
{
	const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
	int flash_esel = find_tlb_idx((void *)flashbase, 1);
	int ret;
	u32 svr = SVR_SOC_VER(get_svr());

	/* Create law for MAPLE only for personalities having MAPLE */
	if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
	    (svr == SVR_B4420) || (svr == SVR_B4220)) {
		set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
			     LAW_TRGT_IF_MAPLE);
	}

	/*
	 * Remap Boot flash + PROMJET region to caching-inhibited
	 * so that flash can be erased properly.
	 */

	/* Flush d-cache and invalidate i-cache of any FLASH data */
	flush_dcache();
	invalidate_icache();

	if (flash_esel == -1) {
		/* very unlikely unless something is messed up */
		puts("Error: Could not find TLB for FLASH BASE\n");
		flash_esel = 2;	/* give our best effort to continue */
	} else {
		/* invalidate existing TLB entry for flash + promjet */
		disable_tlb(flash_esel);
	}

	set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
			0, flash_esel, BOOKE_PAGESZ_256M, 1);

	/*
	 * Adjust core voltage according to voltage ID
	 * This function changes I2C mux to channel 2.
	 */
	if (adjust_vdd(0) < 0)
		printf("Warning: Adjusting core voltage failed\n");

	/* SerDes1 refclks need to be set again, as default clks
	 * are not suitable for CPRI and onboard SGMIIs to work
	 * simultaneously.
	 * This function will set SerDes1's Refclk1 and refclk2
	 * as per SerDes1 protocols
	 */
	if (config_serdes1_refclks())
		printf("SerDes1 Refclks couldn't set properly.\n");
	else
		printf("SerDes1 Refclks have been set.\n");

	/* SerDes2 refclks need to be set again, as default clks
	 * are not suitable for PCIe SATA to work
	 * This function will set SerDes2's Refclk1 and refclk2
	 * for SerDes2 protocols having PCIe in them
	 * for PCIe SATA to work
	 */
	ret = config_serdes2_refclks();
	if (!ret)
		printf("SerDes2 Refclks have been set.\n");
	else if (ret == -ENODEV)
		printf("SerDes disable, Refclks couldn't change.\n");
	else
		printf("SerDes2 Refclk reconfiguring failed.\n");

#if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
			defined(CONFIG_SYS_FSL_ERRATUM_A006475)
	/* Rechecking the SerDes locks after all SerDes configurations
	 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
	 * and at cold temperatures.
	 * Following sequence ensure the proper locking of SerDes PLLs.
	 */
	if (SVR_MAJ(get_svr()) == 1) {
		if (check_serdes_pll_locks())
			printf("SerDes plls still not locked properly.\n");
		else
			printf("SerDes plls have been locked well.\n");
	}
#endif

	/* Configure VSC3316 and VSC3308 crossbar switches */
	if (configure_vsc3316_3308())
		printf("VSC:failed to configure VSC3316/3308.\n");
	else
		printf("VSC:VSC3316/3308 successfully configured.\n");

	select_i2c_ch_pca(I2C_CH_DEFAULT);

	return 0;
}

unsigned long get_board_sys_clk(void)
{
	u8 sysclk_conf = QIXIS_READ(brdcfg[1]);

	switch ((sysclk_conf & 0x0C) >> 2) {
	case QIXIS_CLK_100:
		return 100000000;
	case QIXIS_CLK_125:
		return 125000000;
	case QIXIS_CLK_133:
		return 133333333;
	}
	return 66666666;
}

unsigned long get_board_ddr_clk(void)
{
	u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);

	switch (ddrclk_conf & 0x03) {
	case QIXIS_CLK_100:
		return 100000000;
	case QIXIS_CLK_125:
		return 125000000;
	case QIXIS_CLK_133:
		return 133333333;
	}
	return 66666666;
}

static int serdes_refclock(u8 sw, u8 sdclk)
{
	unsigned int clock;
	int ret = -1;
	u8 brdcfg4;

	if (sdclk == 1) {
		brdcfg4 = QIXIS_READ(brdcfg[4]);
		if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
			return SRDS_PLLCR0_RFCK_SEL_125;
		else
			clock = (sw >> 5) & 7;
	} else
		clock = (sw >> 6) & 3;

	switch (clock) {
	case 0:
		ret = SRDS_PLLCR0_RFCK_SEL_100;
		break;
	case 1:
		ret = SRDS_PLLCR0_RFCK_SEL_125;
		break;
	case 2:
		ret = SRDS_PLLCR0_RFCK_SEL_156_25;
		break;
	case 3:
		ret = SRDS_PLLCR0_RFCK_SEL_161_13;
		break;
	case 4:
	case 5:
	case 6:
		ret = SRDS_PLLCR0_RFCK_SEL_122_88;
		break;
	default:
		ret = -1;
		break;
	}

	return ret;
}

#define NUM_SRDS_BANKS	2

int misc_init_r(void)
{
	u8 sw;
	serdes_corenet_t *srds_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
	u32 actual[NUM_SRDS_BANKS];
	unsigned int i;
	int clock;

	sw = QIXIS_READ(brdcfg[2]);
	clock = serdes_refclock(sw, 1);
	if (clock >= 0)
		actual[0] = clock;
	else
		printf("Warning: SDREFCLK1 switch setting is unsupported\n");

	sw = QIXIS_READ(brdcfg[4]);
	clock = serdes_refclock(sw, 2);
	if (clock >= 0)
		actual[1] = clock;
	else
		printf("Warning: SDREFCLK2 switch setting unsupported\n");

	for (i = 0; i < NUM_SRDS_BANKS; i++) {
		u32 pllcr0 = srds_regs->bank[i].pllcr0;
		u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
		if (expected != actual[i]) {
			printf("Warning: SERDES bank %u expects reference clock"
			       " %sMHz, but actual is %sMHz\n", i + 1,
			       serdes_clock_to_string(expected),
			       serdes_clock_to_string(actual[i]));
		}
	}

	return 0;
}

int ft_board_setup(void *blob, bd_t *bd)
{
	phys_addr_t base;
	phys_size_t size;

	ft_cpu_setup(blob, bd);

	base = getenv_bootm_low();
	size = getenv_bootm_size();

	fdt_fixup_memory(blob, (u64)base, (u64)size);

#ifdef CONFIG_PCI
	pci_of_setup(blob, bd);
#endif

	fdt_fixup_liodn(blob);

#ifdef CONFIG_HAS_FSL_DR_USB
	fdt_fixup_dr_usb(blob, bd);
#endif

#ifdef CONFIG_SYS_DPAA_FMAN
	fdt_fixup_fman_ethernet(blob);
	fdt_fixup_board_enet(blob);
#endif

	return 0;
}

/*
 * Dump board switch settings.
 * The bits that cannot be read/sampled via some FPGA or some
 * registers, they will be displayed as
 * underscore in binary format. mask[] has those bits.
 * Some bits are calculated differently than the actual switches
 * if booting with overriding by FPGA.
 */
void qixis_dump_switch(void)
{
	int i;
	u8 sw[5];

	/*
	 * Any bit with 1 means that bit cannot be reverse engineered.
	 * It will be displayed as _ in binary format.
	 */
	static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
	char buf[10];
	u8 brdcfg[16], dutcfg[16];

	for (i = 0; i < 16; i++) {
		brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
		dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
	}

	sw[0] = ((brdcfg[0] & 0x0f) << 4)	| \
		(brdcfg[9] & 0x08);
	sw[1] = ((dutcfg[1] & 0x01) << 7)	| \
		((dutcfg[2] & 0x07) << 4)       | \
		((dutcfg[6] & 0x10) >> 1)       | \
		((dutcfg[6] & 0x80) >> 5)       | \
		((dutcfg[1] & 0x40) >> 5)       | \
		(dutcfg[6] & 0x01);
	sw[2] = dutcfg[0];
	sw[3] = 0;
	sw[4] = ((brdcfg[1] & 0x30) << 2)	| \
		((brdcfg[1] & 0xc0) >> 2)	| \
		(brdcfg[1] & 0x0f);

	puts("DIP switch settings:\n");
	for (i = 0; i < 5; i++) {
		printf("SW%d         = 0b%s (0x%02x)\n",
			i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
	}
}
