/*
 * Copyright 2009-2011 Freescale Semiconductor, Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
#include <hwconfig.h>
#endif
#include <asm/fsl_serdes.h>
#include <asm/immap_85xx.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/fsl_law.h>
#include <asm/errno.h>
#include "fsl_corenet_serdes.h"

/*
 * The work-arounds for erratum SERDES8 and SERDES-A001 are linked together.
 * The code is already very complicated as it is, and separating the two
 * completely would just make things worse.  We try to keep them as separate
 * as possible, but for now we require SERDES8 if SERDES_A001 is defined.
 */
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001
#ifndef CONFIG_SYS_P4080_ERRATUM_SERDES8
#error "CONFIG_SYS_P4080_ERRATUM_SERDES_A001 requires CONFIG_SYS_P4080_ERRATUM_SERDES8"
#endif
#endif

static u32 serdes_prtcl_map;

#ifdef DEBUG
static const char *serdes_prtcl_str[] = {
	[NONE] = "NA",
	[PCIE1] = "PCIE1",
	[PCIE2] = "PCIE2",
	[PCIE3] = "PCIE3",
	[PCIE4] = "PCIE4",
	[SATA1] = "SATA1",
	[SATA2] = "SATA2",
	[SRIO1] = "SRIO1",
	[SRIO2] = "SRIO2",
	[SGMII_FM1_DTSEC1] = "SGMII_FM1_DTSEC1",
	[SGMII_FM1_DTSEC2] = "SGMII_FM1_DTSEC2",
	[SGMII_FM1_DTSEC3] = "SGMII_FM1_DTSEC3",
	[SGMII_FM1_DTSEC4] = "SGMII_FM1_DTSEC4",
	[SGMII_FM1_DTSEC5] = "SGMII_FM1_DTSEC5",
	[SGMII_FM2_DTSEC1] = "SGMII_FM2_DTSEC1",
	[SGMII_FM2_DTSEC2] = "SGMII_FM2_DTSEC2",
	[SGMII_FM2_DTSEC3] = "SGMII_FM2_DTSEC3",
	[SGMII_FM2_DTSEC4] = "SGMII_FM2_DTSEC4",
	[SGMII_FM2_DTSEC5] = "SGMII_FM2_DTSEC5",
	[XAUI_FM1] = "XAUI_FM1",
	[XAUI_FM2] = "XAUI_FM2",
	[AURORA] = "DEBUG",
};
#endif

static const struct {
	int idx;
	unsigned int lpd; /* RCW lane powerdown bit */
	int bank;
} lanes[SRDS_MAX_LANES] = {
	{ 0, 152, FSL_SRDS_BANK_1 },
	{ 1, 153, FSL_SRDS_BANK_1 },
	{ 2, 154, FSL_SRDS_BANK_1 },
	{ 3, 155, FSL_SRDS_BANK_1 },
	{ 4, 156, FSL_SRDS_BANK_1 },
	{ 5, 157, FSL_SRDS_BANK_1 },
	{ 6, 158, FSL_SRDS_BANK_1 },
	{ 7, 159, FSL_SRDS_BANK_1 },
	{ 8, 160, FSL_SRDS_BANK_1 },
	{ 9, 161, FSL_SRDS_BANK_1 },
	{ 16, 162, FSL_SRDS_BANK_2 },
	{ 17, 163, FSL_SRDS_BANK_2 },
	{ 18, 164, FSL_SRDS_BANK_2 },
	{ 19, 165, FSL_SRDS_BANK_2 },
	{ 20, 170, FSL_SRDS_BANK_3 },
	{ 21, 171, FSL_SRDS_BANK_3 },
	{ 22, 172, FSL_SRDS_BANK_3 },
	{ 23, 173, FSL_SRDS_BANK_3 },
};

int serdes_get_lane_idx(int lane)
{
	return lanes[lane].idx;
}

int serdes_get_bank_by_lane(int lane)
{
	return lanes[lane].bank;
}

int serdes_lane_enabled(int lane)
{
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	serdes_corenet_t *regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;

	int bank = lanes[lane].bank;
	int word = lanes[lane].lpd / 32;
	int bit = lanes[lane].lpd % 32;

	if (in_be32(&regs->bank[bank].rstctl) & SRDS_RSTCTL_SDPD)
		return 0;

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
	/*
	 * For banks two and three, use the srds_lpd_b[] array instead of the
	 * RCW, because this array contains the real values of SRDS_LPD_B2 and
	 * SRDS_LPD_B3.
	 */
	if (bank > 0)
		return !(srds_lpd_b[bank] & (8 >> (lane - (6 + 4 * bank))));
#endif

	return !(in_be32(&gur->rcwsr[word]) & (0x80000000 >> bit));
}

int is_serdes_configured(enum srds_prtcl device)
{
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);

	/* Is serdes enabled at all? */
	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN))
		return 0;

	return (1 << device) & serdes_prtcl_map;
}

static int __serdes_get_first_lane(uint32_t prtcl, enum srds_prtcl device)
{
	int i;

	for (i = 0; i < SRDS_MAX_LANES; i++) {
		if (serdes_get_prtcl(prtcl, i) == device)
			return i;
	}

	return -ENODEV;
}

/*
 * Returns the SERDES lane (0..SRDS_MAX_LANES-1) that routes to the given
 * device. This depends on the current SERDES protocol, as defined in the RCW.
 *
 * Returns a negative error code if SERDES is disabled or the given device is
 * not supported in the current SERDES protocol.
 */
int serdes_get_first_lane(enum srds_prtcl device)
{
	u32 prtcl;
	const ccsr_gur_t *gur;

	gur = (typeof(gur))CONFIG_SYS_MPC85xx_GUTS_ADDR;

	/* Is serdes enabled at all? */
	if (unlikely((in_be32(&gur->rcwsr[5]) & 0x2000) == 0))
		return -ENODEV;

	prtcl = (in_be32(&gur->rcwsr[4]) & FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;

	return __serdes_get_first_lane(prtcl, device);
}

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
/*
 * Returns the SERDES bank (1, 2, or 3) that a given device is on for a given
 * SERDES protocol.
 *
 * Returns a negative error code if the given device is not supported for the
 * given SERDES protocol.
 */
static int serdes_get_bank_by_device(uint32_t prtcl, enum srds_prtcl device)
{
	int lane;

	lane = __serdes_get_first_lane(prtcl, device);
	if (unlikely(lane < 0))
		return lane;

	return serdes_get_bank_by_lane(lane);
}

static uint32_t __serdes_get_lane_count(uint32_t prtcl, enum srds_prtcl device,
					int first)
{
	int lane;

	for (lane = first; lane < SRDS_MAX_LANES; lane++) {
		if (serdes_get_prtcl(prtcl, lane) != device)
			break;
	}

	return lane - first;
}

static void __serdes_reset_rx(serdes_corenet_t *regs,
			      uint32_t prtcl,
			      enum srds_prtcl device)
{
	int lane, idx, first, last;

	lane = __serdes_get_first_lane(prtcl, device);
	if (unlikely(lane < 0))
		return;
	first = serdes_get_lane_idx(lane);
	last = first + __serdes_get_lane_count(prtcl, device, lane);

	/*
	 * Set BnGCRy0[RRST] = 0 for each lane in the each bank that is
	 * selected as XAUI to place the lane into reset.
	*/
	for (idx = first; idx < last; idx++)
		clrbits_be32(&regs->lane[idx].gcr0, SRDS_GCR0_RRST);

	/* Wait at least 250 ns */
	udelay(1);

	/*
	 * Set BnGCRy0[RRST] = 1 for each lane in the each bank that is
	 * selected as XAUI to bring the lane out of reset.
	 */
	for (idx = first; idx < last; idx++)
		setbits_be32(&regs->lane[idx].gcr0, SRDS_GCR0_RRST);
}

void serdes_reset_rx(enum srds_prtcl device)
{
	u32 prtcl;
	const ccsr_gur_t *gur;
	serdes_corenet_t *regs;

	if (unlikely(device == NONE))
		return;

	gur = (typeof(gur))CONFIG_SYS_MPC85xx_GUTS_ADDR;

	/* Is serdes enabled at all? */
	if (unlikely((in_be32(&gur->rcwsr[5]) & 0x2000) == 0))
		return;

	regs = (typeof(regs))CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
	prtcl = (in_be32(&gur->rcwsr[4]) & FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;

	__serdes_reset_rx(regs, prtcl, device);
}
#endif

#ifndef CONFIG_SYS_DCSRBAR_PHYS
#define CONFIG_SYS_DCSRBAR_PHYS	0x80000000 /* Must be 1GB-aligned for rev1.0 */
#define CONFIG_SYS_DCSRBAR	0x80000000
#define __DCSR_NOT_DEFINED_BY_CONFIG
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
/*
 * Enable a SERDES bank that was disabled via the RCW
 *
 * We only call this function for SERDES8 and SERDES-A001 in cases we really
 * want to enable the bank, whether we actually want to use the lanes or not,
 * so make sure at least one lane is enabled.  We're only enabling this one
 * lane to satisfy errata requirements that the bank be enabled.
 *
 * We use a local variable instead of srds_lpd_b[] because we want drivers to
 * think that the lanes actually are disabled.
 */
static void enable_bank(ccsr_gur_t *gur, int bank)
{
	u32 rcw5;
	u32 temp_lpd_b = srds_lpd_b[bank];

	/*
	 * If we're asked to disable all lanes, just pretend we're doing
	 * that.
	 */
	if (temp_lpd_b == 0xF)
		temp_lpd_b = 0xE;

	/*
	 * Enable the lanes SRDS_LPD_Bn.  The RCW bits are read-only in
	 * CCSR, and read/write in DSCR.
	 */
	rcw5 = in_be32(gur->rcwsr + 5);
	if (bank == FSL_SRDS_BANK_2) {
		rcw5 &= ~FSL_CORENET_RCWSRn_SRDS_LPD_B2;
		rcw5 |= temp_lpd_b << 26;
	} else if (bank == FSL_SRDS_BANK_3) {
		rcw5 &= ~FSL_CORENET_RCWSRn_SRDS_LPD_B3;
		rcw5 |= temp_lpd_b << 18;
	} else {
		printf("SERDES: enable_bank: bad bank %d\n", bank + 1);
		return;
	}

	/* See similar code in cpu/mpc85xx/cpu_init.c for an explanation
	 * of the DCSR mapping.
	 */
	{
#ifdef __DCSR_NOT_DEFINED_BY_CONFIG
		struct law_entry law = find_law(CONFIG_SYS_DCSRBAR_PHYS);
		int law_index;
		if (law.index == -1)
			law_index = set_next_law(CONFIG_SYS_DCSRBAR_PHYS,
						 LAW_SIZE_1M, LAW_TRGT_IF_DCSR);
		else
			set_law(law.index, CONFIG_SYS_DCSRBAR_PHYS, LAW_SIZE_1M,
				LAW_TRGT_IF_DCSR);
#endif
		u32 *p = (void *)CONFIG_SYS_DCSRBAR + 0x20114;
		out_be32(p, rcw5);
#ifdef __DCSR_NOT_DEFINED_BY_CONFIG
		if (law.index == -1)
			disable_law(law_index);
		else
			set_law(law.index, law.addr, law.size, law.trgt_id);
#endif
	}
}

/*
 * To avoid problems with clock jitter, rev 2 p4080 uses the pll from
 * bank 3 to clock banks 2 and 3, as well as a limited selection of
 * protocol configurations.  This requires that banks 2 and 3's lanes be
 * disabled in the RCW, and enabled with some fixup here to re-enable
 * them, and to configure bank 2's clock parameters in bank 3's pll in
 * cases where they differ.
 */
static void p4080_erratum_serdes8(serdes_corenet_t *regs, ccsr_gur_t *gur,
				  u32 devdisr, u32 devdisr2, int cfg)
{
	int srds_ratio_b2;
	int rfck_sel;

	/*
	 * The disabled lanes of bank 2 will cause the associated
	 * logic blocks to be disabled in DEVDISR.  We reverse that here.
	 *
	 * Note that normally it is not permitted to clear DEVDISR bits
	 * once the device has been disabled, but the hardware people
	 * say that this special case is OK.
	 */
	clrbits_be32(&gur->devdisr, devdisr);
	clrbits_be32(&gur->devdisr2, devdisr2);

	/*
	 * Some protocols require special handling.  There are a few
	 * additional protocol configurations that can be used, which are
	 * not listed here.  See app note 4065 for supported protocol
	 * configurations.
	 */
	switch (cfg) {
	case 0x19:
		/*
		 * Bank 2 has PCIe which wants BWSEL -- tell bank 3's PLL.
		 * SGMII on bank 3 should still be usable.
		 */
		setbits_be32(&regs->bank[FSL_SRDS_BANK_3].pllcr1,
			     SRDS_PLLCR1_PLL_BWSEL);
		break;

	case 0x0f:
	case 0x10:
		/*
		 * Banks 2 (XAUI) and 3 (SGMII) have different clocking
		 * requirements in these configurations.  Bank 3 cannot
		 * be used and should have its lanes (but not the bank
		 * itself) disabled in the RCW.  We set up bank 3's pll
		 * for bank 2's needs here.
		 */
		srds_ratio_b2 = (in_be32(&gur->rcwsr[4]) >> 13) & 7;

		/* Determine refclock from XAUI ratio */
		switch (srds_ratio_b2) {
		case 1: /* 20:1 */
			rfck_sel = SRDS_PLLCR0_RFCK_SEL_156_25;
			break;
		case 2: /* 25:1 */
			rfck_sel = SRDS_PLLCR0_RFCK_SEL_125;
			break;
		default:
			printf("SERDES: bad SRDS_RATIO_B2 %d\n",
			       srds_ratio_b2);
			return;
		}

		clrsetbits_be32(&regs->bank[FSL_SRDS_BANK_3].pllcr0,
				SRDS_PLLCR0_RFCK_SEL_MASK, rfck_sel);

		clrsetbits_be32(&regs->bank[FSL_SRDS_BANK_3].pllcr0,
				SRDS_PLLCR0_FRATE_SEL_MASK,
				SRDS_PLLCR0_FRATE_SEL_6_25);
		break;
	}

	enable_bank(gur, FSL_SRDS_BANK_3);
}
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A005
/*
 * If PCIe is not selected as a protocol for any lanes driven by a given PLL,
 * that PLL should have SRDSBnPLLCR1[PLLBW_SEL] = 0.
 */
static void p4080_erratum_serdes_a005(serdes_corenet_t *regs, unsigned int cfg)
{
	enum srds_prtcl device;

	switch (cfg) {
	case 0x13:
	case 0x16:
		/*
		 * If SRDS_PRTCL = 0x13 or 0x16, set SRDSB1PLLCR1[PLLBW_SEL]
		 * to 0.
		 */
		clrbits_be32(&regs->bank[FSL_SRDS_BANK_1].pllcr1,
			     SRDS_PLLCR1_PLL_BWSEL);
		break;
	case 0x19:
		/*
		 * If SRDS_PRTCL = 0x19, set SRDSB1PLLCR1[PLLBW_SEL] to 0 and
		 * SRDSB3PLLCR1[PLLBW_SEL] to 1.
		 */
		clrbits_be32(&regs->bank[FSL_SRDS_BANK_1].pllcr1,
			     SRDS_PLLCR1_PLL_BWSEL);
		setbits_be32(&regs->bank[FSL_SRDS_BANK_3].pllcr1,
			     SRDS_PLLCR1_PLL_BWSEL);
		break;
	}

	/*
	 * Set SRDSBnPLLCR1[PLLBW_SEL] to 0 for each bank that selects XAUI
	 * before XAUI is initialized.
	 */
	for (device = XAUI_FM1; device <= XAUI_FM2; device++) {
		if (is_serdes_configured(device)) {
			int bank = serdes_get_bank_by_device(cfg, device);

			clrbits_be32(&regs->bank[bank].pllcr1,
				     SRDS_PLLCR1_PLL_BWSEL);
		}
	}
}
#endif

/*
 * Wait for the RSTDONE bit to get set, or a one-second timeout.
 */
static void wait_for_rstdone(unsigned int bank)
{
	serdes_corenet_t *srds_regs =
		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
	unsigned long long end_tick;
	u32 rstctl;

	/* wait for reset complete or 1-second timeout */
	end_tick = usec2ticks(1000000) + get_ticks();
	do {
		rstctl = in_be32(&srds_regs->bank[bank].rstctl);
		if (rstctl & SRDS_RSTCTL_RSTDONE)
			break;
	} while (end_tick > get_ticks());

	if (!(rstctl & SRDS_RSTCTL_RSTDONE))
		printf("SERDES: timeout resetting bank %u\n", bank + 1);
}


void __soc_serdes_init(void)
{
	/* Allow for SoC-specific initialization in <SOC>_serdes.c  */
};
void soc_serdes_init(void) __attribute__((weak, alias("__soc_serdes_init")));

void fsl_serdes_init(void)
{
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	int cfg;
	serdes_corenet_t *srds_regs;
	int lane, bank, idx;
	int have_bank[SRDS_MAX_BANK] = {};
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
	u32 serdes8_devdisr = 0;
	u32 serdes8_devdisr2 = 0;
	char srds_lpd_opt[16];
	const char *srds_lpd_arg;
	size_t arglen;
#endif
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001
	int need_serdes_a001;	/* TRUE == need work-around for SERDES A001 */
#endif
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
	char buffer[HWCONFIG_BUFFER_SIZE];
	char *buf = NULL;

	/*
	 * Extract hwconfig from environment since we have not properly setup
	 * the environment but need it for ddr config params
	 */
	if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
		buf = buffer;
#endif

	/* Is serdes enabled at all? */
	if (!(in_be32(&gur->rcwsr[5]) & FSL_CORENET_RCWSR5_SRDS_EN))
		return;

	srds_regs = (void *)(CONFIG_SYS_FSL_CORENET_SERDES_ADDR);
	cfg = (in_be32(&gur->rcwsr[4]) & FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
	debug("Using SERDES configuration 0x%x, lane settings:\n", cfg);

	if (!is_serdes_prtcl_valid(cfg)) {
		printf("SERDES[PRTCL] = 0x%x is not valid\n", cfg);
		return;
	}

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
	/*
	 * Display a warning if banks two and three are not disabled in the RCW,
	 * since our work-around for SERDES8 depends on these banks being
	 * disabled at power-on.
	 */
#define B2_B3 (FSL_CORENET_RCWSRn_SRDS_LPD_B2 | FSL_CORENET_RCWSRn_SRDS_LPD_B3)
	if ((in_be32(&gur->rcwsr[5]) & B2_B3) != B2_B3) {
		printf("Warning: SERDES8 requires banks two and "
		       "three to be disabled in the RCW\n");
	}

	/*
	 * Store the values of the fsl_srds_lpd_b2 and fsl_srds_lpd_b3
	 * hwconfig options into the srds_lpd_b[] array.  See README.p4080ds
	 * for a description of these options.
	 */
	for (bank = 1; bank < ARRAY_SIZE(srds_lpd_b); bank++) {
		sprintf(srds_lpd_opt, "fsl_srds_lpd_b%u", bank + 1);
		srds_lpd_arg =
			hwconfig_subarg_f("serdes", srds_lpd_opt, &arglen, buf);
		if (srds_lpd_arg)
			srds_lpd_b[bank] =
				simple_strtoul(srds_lpd_arg, NULL, 0) & 0xf;
	}

	if ((cfg == 0xf) || (cfg == 0x10)) {
		/*
		 * For SERDES protocols 0xF and 0x10, force bank 3 to be
		 * disabled, because it is not supported.
		 */
		srds_lpd_b[FSL_SRDS_BANK_3] = 0xF;
	}
#endif

	/* Look for banks with all lanes disabled, and power down the bank. */
	for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
		enum srds_prtcl lane_prtcl = serdes_get_prtcl(cfg, lane);
		if (serdes_lane_enabled(lane)) {
			have_bank[serdes_get_bank_by_lane(lane)] = 1;
			serdes_prtcl_map |= (1 << lane_prtcl);
		}
	}

	soc_serdes_init();

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
	/*
	 * Bank two uses the clock from bank three, so if bank two is enabled,
	 * then bank three must also be enabled.
	 */
	if (have_bank[FSL_SRDS_BANK_2])
		have_bank[FSL_SRDS_BANK_3] = 1;
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001
	/*
	 * The work-aroud for erratum SERDES-A001 is needed only if bank two
	 * is disabled and bank three is enabled.  The converse is also true,
	 * but SERDES8 ensures that bank 3 is always enabled if bank 2 is
	 * enabled, so there's no point in complicating the code to handle
	 * that situation.
	 */
	need_serdes_a001 =
		!have_bank[FSL_SRDS_BANK_2] && have_bank[FSL_SRDS_BANK_3];
#endif

	/* Power down the banks we're not interested in */
	for (bank = 0; bank < SRDS_MAX_BANK; bank++) {
		if (!have_bank[bank]) {
			printf("SERDES: bank %d disabled\n", bank + 1);
#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001
			/*
			 * Erratum SERDES-A001 says bank two needs to be powered
			 * down after bank three is powered up, so don't power
			 * down bank two here.
			 */
			if (!need_serdes_a001 || (bank != FSL_SRDS_BANK_2))
				setbits_be32(&srds_regs->bank[bank].rstctl,
					     SRDS_RSTCTL_SDPD);
#else
			setbits_be32(&srds_regs->bank[bank].rstctl,
				     SRDS_RSTCTL_SDPD);
#endif
		}
	}

#if defined(CONFIG_SYS_P4080_ERRATUM_SERDES8) || defined (CONFIG_SYS_P4080_ERRATUM_SERDES9)
	for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
		enum srds_prtcl lane_prtcl;

		idx = serdes_get_lane_idx(lane);
		lane_prtcl = serdes_get_prtcl(cfg, lane);

#ifdef DEBUG
		switch (lane) {
		case 0:
			puts("Bank1: ");
			break;
		case 10:
			puts("\nBank2: ");
			break;
		case 14:
			puts("\nBank3: ");
			break;
		default:
			break;
		}

		printf("%s ", serdes_prtcl_str[lane_prtcl]);
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES9
		/*
		 * Set BnTTLCRy0[FLT_SEL] = 000011 and set BnTTLCRy0[17] = 1 for
		 * each of the SerDes lanes selected as SGMII, XAUI, SRIO, or
		 * AURORA before the device is initialized.
		 */
		switch (lane_prtcl) {
		case SGMII_FM1_DTSEC1:
		case SGMII_FM1_DTSEC2:
		case SGMII_FM1_DTSEC3:
		case SGMII_FM1_DTSEC4:
		case SGMII_FM2_DTSEC1:
		case SGMII_FM2_DTSEC2:
		case SGMII_FM2_DTSEC3:
		case SGMII_FM2_DTSEC4:
		case SGMII_FM2_DTSEC5:
		case XAUI_FM1:
		case XAUI_FM2:
		case SRIO1:
		case SRIO2:
		case AURORA:
			clrsetbits_be32(&srds_regs->lane[idx].ttlcr0,
					SRDS_TTLCR0_FLT_SEL_MASK,
					SRDS_TTLCR0_FLT_SEL_750PPM |
					SRDS_TTLCR0_PM_DIS);
		default:
			break;
		}
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
		switch (lane_prtcl) {
		case PCIE1:
		case PCIE2:
		case PCIE3:
			serdes8_devdisr |= FSL_CORENET_DEVDISR_PCIE1 >>
					   (lane_prtcl - PCIE1);
			break;
		case SRIO1:
		case SRIO2:
			serdes8_devdisr |= FSL_CORENET_DEVDISR_SRIO1 >>
					   (lane_prtcl - SRIO1);
			break;
		case SGMII_FM1_DTSEC1:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 |
					    FSL_CORENET_DEVDISR2_DTSEC1_1;
			break;
		case SGMII_FM1_DTSEC2:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 |
					    FSL_CORENET_DEVDISR2_DTSEC1_2;
			break;
		case SGMII_FM1_DTSEC3:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 |
					    FSL_CORENET_DEVDISR2_DTSEC1_3;
			break;
		case SGMII_FM1_DTSEC4:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1 |
					    FSL_CORENET_DEVDISR2_DTSEC1_4;
			break;
		case SGMII_FM2_DTSEC1:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 |
					    FSL_CORENET_DEVDISR2_DTSEC2_1;
			break;
		case SGMII_FM2_DTSEC2:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 |
					    FSL_CORENET_DEVDISR2_DTSEC2_2;
			break;
		case SGMII_FM2_DTSEC3:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 |
					    FSL_CORENET_DEVDISR2_DTSEC2_3;
			break;
		case SGMII_FM2_DTSEC4:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 |
					    FSL_CORENET_DEVDISR2_DTSEC2_4;
			break;
		case SGMII_FM2_DTSEC5:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2 |
					    FSL_CORENET_DEVDISR2_DTSEC2_5;
			break;
		case XAUI_FM1:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM1	|
					    FSL_CORENET_DEVDISR2_10GEC1;
			break;
		case XAUI_FM2:
			serdes8_devdisr2 |= FSL_CORENET_DEVDISR2_FM2	|
					    FSL_CORENET_DEVDISR2_10GEC2;
			break;
		case AURORA:
			break;
		default:
			break;
		}

#endif
	}
#endif

#ifdef DEBUG
	puts("\n");
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A005
	p4080_erratum_serdes_a005(srds_regs, cfg);
#endif

	for (idx = 0; idx < SRDS_MAX_BANK; idx++) {
		bank = idx;

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
		/*
		 * Change bank init order to 0, 2, 1, so that the third bank's
		 * PLL is established before we start the second bank.  The
		 * second bank uses the third bank's PLL.
		 */

		if (idx == 1)
			bank = FSL_SRDS_BANK_3;
		else if (idx == 2)
			bank = FSL_SRDS_BANK_2;
#endif

		/* Skip disabled banks */
		if (!have_bank[bank])
			continue;

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES8
		if (idx == 1) {
			/*
			 * Re-enable devices on banks two and three that were
			 * disabled by the RCW, and then enable bank three. The
			 * devices need to be enabled before either bank is
			 * powered up.
			 */
			p4080_erratum_serdes8(srds_regs, gur, serdes8_devdisr,
					      serdes8_devdisr2, cfg);
		} else if (idx == 2) {
			/* Enable bank two now that bank three is enabled. */
			enable_bank(gur, FSL_SRDS_BANK_2);
		}
#endif

		wait_for_rstdone(bank);
	}

#ifdef CONFIG_SYS_P4080_ERRATUM_SERDES_A001
	if (need_serdes_a001) {
		/* Bank 3 has been enabled, so now we can disable bank 2 */
		setbits_be32(&srds_regs->bank[FSL_SRDS_BANK_2].rstctl,
			     SRDS_RSTCTL_SDPD);
	}
#endif
}
