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

#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 <linux/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 },
#ifdef CONFIG_ARCH_P4080
	{ 20, 170, FSL_SRDS_BANK_3 },
	{ 21, 171, FSL_SRDS_BANK_3 },
	{ 22, 172, FSL_SRDS_BANK_3 },
	{ 23, 173, FSL_SRDS_BANK_3 },
#else
	{ 20, 166, FSL_SRDS_BANK_3 },
	{ 21, 167, FSL_SRDS_BANK_3 },
	{ 22, 168, FSL_SRDS_BANK_3 },
	{ 23, 169, FSL_SRDS_BANK_3 },
#endif
#if SRDS_MAX_BANK > 3
	{ 24, 175, FSL_SRDS_BANK_4 },
	{ 25, 176, FSL_SRDS_BANK_4 },
#endif
};

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;

	if (!(serdes_prtcl_map & (1 << NONE)))
		fsl_serdes_init();

	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);
}


static 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;
#ifdef CONFIG_ARCH_P5040
	serdes_corenet_t *srds2_regs;
#endif
	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
	if (serdes_prtcl_map & (1 << NONE))
		return;

	/* 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);
		}
	}

#ifdef CONFIG_ARCH_P5040
	/*
	 * Lanes on bank 4 on P5040 are commented-out, but for some SERDES
	 * protocols, these lanes are routed to SATA.  We use serdes_prtcl_map
	 * to decide whether a protocol is supported on a given lane, so SATA
	 * will be identified as not supported, and therefore not initialized.
	 * So for protocols which use SATA on bank4, we add SATA support in
	 * serdes_prtcl_map.
	 */
	switch (cfg) {
	case 0x0:
	case 0x1:
	case 0x2:
	case 0x3:
	case 0x4:
	case 0x5:
	case 0x6:
	case 0x7:
		serdes_prtcl_map |= 1 << SATA1 | 1 << SATA2;
		break;
	default:
		srds2_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;

		/* We don't need bank 4, so power it down */
		setbits_be32(&srds2_regs->bank[0].rstctl, SRDS_RSTCTL_SDPD);
	}
#endif

	soc_serdes_init();

	/* Set the first bit to indicate serdes has been initialized */
	serdes_prtcl_map |= (1 << NONE);

#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
		}
	}

#ifdef CONFIG_SYS_FSL_ERRATUM_A004699
	/*
	 * To avoid the situation that resulted in the P4080 erratum
	 * SERDES-8, a given SerDes bank will use the PLLs from the previous
	 * bank if one of the PLL frequencies is a multiple of the other.  For
	 * instance, if bank 3 is running at 2.5GHz and bank 2 is at 1.25GHz,
	 * then bank 3 will use bank 2's PLL.  P5040 Erratum A-004699 says
	 * that, in this situation, lane synchronization is not initiated.  So
	 * when we detect a bank with a "borrowed" PLL, we have to manually
	 * initiate lane synchronization.
	 */
	for (bank = FSL_SRDS_BANK_2; bank <= FSL_SRDS_BANK_3; bank++) {
		/* Determine the first lane for this bank */
		unsigned int lane;

		for (lane = 0; lane < SRDS_MAX_LANES; lane++)
			if (lanes[lane].bank == bank)
				break;
		idx = lanes[lane].idx;

		/*
		 * Check if the PLL for the bank is borrowed.  The UOTHL
		 * bit of the first lane will tell us that.
		 */
		if (in_be32(&srds_regs->lane[idx].gcr0) & SRDS_GCR0_UOTHL) {
			/* Manually start lane synchronization */
			setbits_be32(&srds_regs->bank[bank].pllcr0,
				     SRDS_PLLCR0_PVCOCNT_EN);
		}
	}
#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] = 011011 and set BnTTLCRy0[31] = 1
		 * for each of the SerDes lanes selected as SGMII, XAUI, SRIO,
		 * or AURORA before the device is initialized.
		 *
		 * Note that this part of the SERDES-9 work-around is
		 * redundant if the work-around for A-4580 has already been
		 * applied via PBI.
		 */
		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:
			out_be32(&srds_regs->lane[idx].ttlcr0,
				 SRDS_TTLCR0_FLT_SEL_KFR_26 |
				 SRDS_TTLCR0_FLT_SEL_KPH_28 |
				 SRDS_TTLCR0_FLT_SEL_750PPM |
				 SRDS_TTLCR0_FREQOVD_EN);
			break;
		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
}

const char *serdes_clock_to_string(u32 clock)
{
	switch (clock) {
	case SRDS_PLLCR0_RFCK_SEL_100:
		return "100";
	case SRDS_PLLCR0_RFCK_SEL_125:
		return "125";
	case SRDS_PLLCR0_RFCK_SEL_156_25:
		return "156.25";
	case SRDS_PLLCR0_RFCK_SEL_161_13:
		return "161.1328123";
	default:
		return "150";
	}
}

