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? */
                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))
 
 #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)
 #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
 #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)
 
 #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 */
        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
 #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
 #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)