diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
index f69c83489735b8197bf7871f6f49c3b29a8ea540..3a04a893012d2d46ad8160eddea6320d93302402 100644
--- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c
+++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c
@@ -269,6 +269,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #ifdef CONFIG_SYS_FSL_ERRATUM_USB14
 	puts("Work-around for Erratum USB14 enabled\n");
 #endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A007186
+	puts("Work-around for Erratum A007186 enabled\n");
+#endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_A006593
 	puts("Work-around for Erratum A006593 enabled\n");
 #endif
diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
index 70e09eaed5994a9a8516bc7c597efa9ed575fbe4..d1fc76a13ed25c99e7272b916288cd04fe1c1a41 100644
--- a/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
+++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet2_serdes.c
@@ -147,12 +147,43 @@ int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
 	return -ENODEV;
 }
 
+#define BC3_SHIFT	9
+#define DC3_SHIFT	6
+#define FC3_SHIFT	0
+#define BC2_SHIFT	19
+#define DC2_SHIFT	16
+#define FC2_SHIFT	10
+#define BC1_SHIFT	29
+#define DC1_SHIFT	26
+#define FC1_SHIFT	20
+#define BC_MASK		0x1
+#define DC_MASK		0x7
+#define FC_MASK		0x3F
+
+#define FUSE_VAL_MASK		0x00000003
+#define FUSE_VAL_SHIFT		30
+#define CR0_DCBIAS_SHIFT	5
+#define CR1_FCAP_SHIFT		15
+#define CR1_BCAP_SHIFT		29
+#define FCAP_MASK		0x001F8000
+#define BCAP_MASK		0x20000000
+#define BCAP_OVD_MASK		0x10000000
+#define BYP_CAL_MASK		0x02000000
+
 u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift)
 {
 	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 	u64 serdes_prtcl_map = 0;
 	u32 cfg;
 	int lane;
+#ifdef CONFIG_SYS_FSL_ERRATUM_A007186
+	struct ccsr_sfp_regs  __iomem *sfp_regs =
+			(struct ccsr_sfp_regs __iomem *)(CONFIG_SYS_SFP_ADDR);
+	u32 pll_num, pll_status, bc, dc, fc, pll_cr_upd, pll_cr0, pll_cr1;
+	u32 bc_status, fc_status, dc_status, pll_sr2;
+	serdes_corenet_t  __iomem *srds_regs = (void *)sd_addr;
+	u32 sfp_spfr0, sel;
+#endif
 
 	cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask;
 	/* Is serdes enabled at all? */
@@ -161,6 +192,123 @@ u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift)
 		return 0;
 	}
 
+/* Erratum A-007186
+ * Freescale Scratch Pad Fuse Register n (SFP_FSPFR0)
+ * The workaround requires factory pre-set SerDes calibration values to be
+ * read from a fuse block(Freescale Scratch Pad Fuse Register SFP_FSPFR0)
+ * These values have been shown to work across the
+ * entire temperature range for all SerDes. These values are then written into
+ * the SerDes registers to calibrate the SerDes PLL.
+ *
+ * This workaround for the protocols and rates that only have the Ring VCO.
+ */
+#ifdef CONFIG_SYS_FSL_ERRATUM_A007186
+	sfp_spfr0 = in_be32(&sfp_regs->fsl_spfr0);
+	debug("A007186: sfp_spfr0= %x\n", sfp_spfr0);
+
+	sel = (sfp_spfr0 >> FUSE_VAL_SHIFT) & FUSE_VAL_MASK;
+
+	if (sel == 0x01 || sel == 0x02) {
+		for (pll_num = 0; pll_num < SRDS_MAX_BANK; pll_num++) {
+			pll_status = in_be32(&srds_regs->bank[pll_num].pllcr0);
+			debug("A007186: pll_num=%x pllcr0=%x\n",
+			      pll_num, pll_status);
+			/* STEP 1 */
+			/* Read factory pre-set SerDes calibration values
+			 * from fuse block(SFP scratch register-sfp_spfr0)
+			 */
+			switch (pll_status & SRDS_PLLCR0_FRATE_SEL_MASK) {
+			case SRDS_PLLCR0_FRATE_SEL_3_0:
+			case SRDS_PLLCR0_FRATE_SEL_3_072:
+				debug("A007186: 3.0/3.072 protocol rate\n");
+				bc = (sfp_spfr0 >> BC1_SHIFT) & BC_MASK;
+				dc = (sfp_spfr0 >> DC1_SHIFT) & DC_MASK;
+				fc = (sfp_spfr0 >> FC1_SHIFT) & FC_MASK;
+				break;
+			case SRDS_PLLCR0_FRATE_SEL_3_125:
+				debug("A007186: 3.125 protocol rate\n");
+				bc = (sfp_spfr0 >> BC2_SHIFT) & BC_MASK;
+				dc = (sfp_spfr0 >> DC2_SHIFT) & DC_MASK;
+				fc = (sfp_spfr0 >> FC2_SHIFT) & FC_MASK;
+				break;
+			case SRDS_PLLCR0_FRATE_SEL_3_75:
+				debug("A007186: 3.75 protocol rate\n");
+				bc = (sfp_spfr0 >> BC1_SHIFT) & BC_MASK;
+				dc = (sfp_spfr0 >> DC1_SHIFT) & DC_MASK;
+				fc = (sfp_spfr0 >> FC1_SHIFT) & FC_MASK;
+				break;
+			default:
+				continue;
+			}
+
+			/* STEP 2 */
+			/* Write SRDSxPLLnCR1[11:16] = FC
+			 * Write SRDSxPLLnCR1[2] = BC
+			 */
+			pll_cr1 = in_be32(&srds_regs->bank[pll_num].pllcr1);
+			pll_cr_upd = (((bc << CR1_BCAP_SHIFT) & BCAP_MASK) |
+				      ((fc << CR1_FCAP_SHIFT) & FCAP_MASK));
+			out_be32(&srds_regs->bank[pll_num].pllcr1,
+				 (pll_cr_upd | pll_cr1));
+			debug("A007186: pll_num=%x Updated PLLCR1=%x\n",
+			      pll_num, (pll_cr_upd | pll_cr1));
+			/* Write SRDSxPLLnCR0[24:26] = DC
+			 */
+			pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
+			out_be32(&srds_regs->bank[pll_num].pllcr0,
+				 pll_cr0 | (dc << CR0_DCBIAS_SHIFT));
+			debug("A007186: pll_num=%x, Updated PLLCR0=%x\n",
+			      pll_num, (pll_cr0 | (dc << CR0_DCBIAS_SHIFT)));
+			/* Write SRDSxPLLnCR1[3] = 1
+			 * Write SRDSxPLLnCR1[6] = 1
+			 */
+			pll_cr1 = in_be32(&srds_regs->bank[pll_num].pllcr1);
+			pll_cr_upd = (BCAP_OVD_MASK | BYP_CAL_MASK);
+			out_be32(&srds_regs->bank[pll_num].pllcr1,
+				 (pll_cr_upd | pll_cr1));
+			debug("A007186: pll_num=%x Updated PLLCR1=%x\n",
+			      pll_num, (pll_cr_upd | pll_cr1));
+
+			/* STEP 3 */
+			/* Read the status Registers */
+			/* Verify SRDSxPLLnSR2[8] = BC */
+			pll_sr2 = in_be32(&srds_regs->bank[pll_num].pllsr2);
+			debug("A007186: pll_num=%x pllsr2=%x\n",
+			      pll_num, pll_sr2);
+			bc_status = (pll_sr2 >> 23) & BC_MASK;
+			if (bc_status != bc)
+				debug("BC mismatch\n");
+			fc_status = (pll_sr2 >> 16) & FC_MASK;
+			if (fc_status != fc)
+				debug("FC mismatch\n");
+			pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
+			out_be32(&srds_regs->bank[pll_num].pllcr0, pll_cr0 |
+								0x02000000);
+			pll_sr2 = in_be32(&srds_regs->bank[pll_num].pllsr2);
+			dc_status = (pll_sr2 >> 17) & DC_MASK;
+			if (dc_status != dc)
+				debug("DC mismatch\n");
+			pll_cr0 = in_be32(&srds_regs->bank[pll_num].pllcr0);
+			out_be32(&srds_regs->bank[pll_num].pllcr0, pll_cr0 &
+								0xfdffffff);
+
+			/* STEP 4 */
+			/* Wait 750us to verify the PLL is locked
+			 * by checking SRDSxPLLnCR0[8] = 1.
+			 */
+			udelay(750);
+			pll_status = in_be32(&srds_regs->bank[pll_num].pllcr0);
+			debug("A007186: pll_num=%x pllcr0=%x\n",
+			      pll_num, pll_status);
+
+			if ((pll_status & SRDS_PLLCR0_PLL_LCK) == 0)
+				printf("A007186 Serdes PLL not locked\n");
+			else
+				debug("A007186 Serdes PLL locked\n");
+		}
+	}
+#endif
+
 	cfg >>= sd_prctl_shift;
 	printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
 	if (!is_serdes_prtcl_valid(sd, cfg))
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index c9fd2a554aa0e1c9a69f22350e2f8d42aedb6e58..712f2ef4b3020aab86eefd459b0d9e324e068924 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -675,8 +675,10 @@
 #define CONFIG_SYS_FSL_ERRATUM_A005871
 #define CONFIG_SYS_FSL_ERRATUM_A006261
 #define CONFIG_SYS_FSL_ERRATUM_A006379
+#define CONFIG_SYS_FSL_ERRATUM_A007186
 #define CONFIG_SYS_FSL_ERRATUM_A006593
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
+#define CONFIG_SYS_FSL_SFP_VER_3_0
 #define CONFIG_SYS_FSL_PCI_VER_3_X
 
 #elif defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_B4420)
@@ -702,12 +704,14 @@
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
 #define CONFIG_SYS_FSL_ERRATUM_A005871
 #define CONFIG_SYS_FSL_ERRATUM_A006379
+#define CONFIG_SYS_FSL_ERRATUM_A007186
 #define CONFIG_SYS_FSL_ERRATUM_A006593
 #define CONFIG_SYS_FSL_ERRATUM_A007075
 #define CONFIG_SYS_FSL_ERRATUM_A006475
 #define CONFIG_SYS_FSL_ERRATUM_A006384
 #define CONFIG_SYS_FSL_ERRATUM_A007212
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
+#define CONFIG_SYS_FSL_SFP_VER_3_0
 
 #ifdef CONFIG_PPC_B4860
 #define CONFIG_SYS_FSL_CORES_PER_CLUSTER 4
@@ -827,8 +831,10 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_A006261
 #define CONFIG_SYS_FSL_ERRATUM_A006593
+#define CONFIG_SYS_FSL_ERRATUM_A007186
 #define CONFIG_SYS_FSL_ERRATUM_A006379
 #define ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
+#define CONFIG_SYS_FSL_SFP_VER_3_0
 
 
 #elif defined(CONFIG_PPC_C29X)
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index eff573b5aded3c83b75dc83083aa46bc60897b98..fe1dcc27d6d078d9885a89408c0b9afcce7a3e20 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -2521,14 +2521,17 @@ typedef struct serdes_corenet {
 #define SRDS_PLLCR0_RFCK_SEL_150	0x30000000
 #define SRDS_PLLCR0_RFCK_SEL_161_13	0x40000000
 #define SRDS_PLLCR0_RFCK_SEL_122_88	0x50000000
+#define SRDS_PLLCR0_PLL_LCK		0x00800000
 #define SRDS_PLLCR0_DCBIAS_OUT_EN      0x02000000
 #define SRDS_PLLCR0_FRATE_SEL_MASK	0x000f0000
 #define SRDS_PLLCR0_FRATE_SEL_5		0x00000000
+#define SRDS_PLLCR0_FRATE_SEL_4_9152	0x00030000
 #define SRDS_PLLCR0_FRATE_SEL_3_75	0x00050000
 #define SRDS_PLLCR0_FRATE_SEL_5_15	0x00060000
 #define SRDS_PLLCR0_FRATE_SEL_4		0x00070000
-#define SRDS_PLLCR0_FRATE_SEL_3_12	0x00090000
-#define SRDS_PLLCR0_FRATE_SEL_3		0x000a0000
+#define SRDS_PLLCR0_FRATE_SEL_3_125	0x00090000
+#define SRDS_PLLCR0_FRATE_SEL_3_0	0x000a0000
+#define SRDS_PLLCR0_FRATE_SEL_3_072	0x000c0000
 #define SRDS_PLLCR0_DCBIAS_OVRD		0x000000F0
 #define SRDS_PLLCR0_DCBIAS_OVRD_SHIFT	4
 		u32	pllcr1; /* PLL Control Register 1 */
@@ -2863,6 +2866,21 @@ struct ccsr_pman {
 	u8	res_f4[0xf0c];
 };
 #endif
+#ifdef CONFIG_SYS_FSL_SFP_VER_3_0
+struct ccsr_sfp_regs {
+	u32 ospr;		/* 0x200 */
+	u32 reserved0[14];
+	u32 srk_hash[8];	/* 0x23c Super Root Key Hash */
+	u32 oem_uid;		/* 0x9c OEM Unique ID */
+	u8 reserved2[0x04];
+	u32 ovpr;			/* 0xA4  Intent To Secure */
+	u8 reserved4[0x08];
+	u32 fsl_uid;		/* 0xB0  FSL Unique ID */
+	u8 reserved5[0x04];
+	u32 fsl_spfr0;		/* Scratch Pad Fuse Register 0 */
+	u32 fsl_spfr1;		/* Scratch Pad Fuse Register 1 */
+};
+#endif
 
 #ifdef CONFIG_FSL_CORENET
 #define CONFIG_SYS_FSL_CORENET_CCM_OFFSET	0x0000
@@ -2876,6 +2894,14 @@ struct ccsr_pman {
 #define CONFIG_SYS_MPC8xxx_DDR3_OFFSET		0xA000
 #define CONFIG_SYS_FSL_CORENET_CLK_OFFSET	0xE1000
 #define CONFIG_SYS_FSL_CORENET_RCPM_OFFSET	0xE2000
+#ifdef CONFIG_SYS_FSL_SFP_VER_3_0
+/* In SFPv3, OSPR register is now at offset 0x200.
+ *  * So directly mapping sfp register map to this address */
+#define CONFIG_SYS_OSPR_OFFSET                  0x200
+#define CONFIG_SYS_SFP_OFFSET            (0xE8000 + CONFIG_SYS_OSPR_OFFSET)
+#else
+#define CONFIG_SYS_SFP_OFFSET                   0xE8000
+#endif
 #define CONFIG_SYS_FSL_CORENET_SERDES_OFFSET	0xEA000
 #define CONFIG_SYS_FSL_CORENET_SERDES2_OFFSET	0xEB000
 #define CONFIG_SYS_FSL_CPC_OFFSET		0x10000
@@ -3094,6 +3120,9 @@ struct ccsr_pman {
 #define CONFIG_SYS_PCIE4_ADDR \
 	(CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIE4_OFFSET)
 
+#define CONFIG_SYS_SFP_ADDR  \
+	(CONFIG_SYS_IMMR + CONFIG_SYS_SFP_OFFSET)
+
 #define TSEC_BASE_ADDR		(CONFIG_SYS_IMMR + CONFIG_SYS_TSEC1_OFFSET)
 #define MDIO_BASE_ADDR		(CONFIG_SYS_IMMR + CONFIG_SYS_MDIO1_OFFSET)