board/b4860qds: Add support for configuring SerDes1 Refclks
authorShaveta Leekha <shaveta@freescale.com>
Tue, 2 Jul 2013 09:13:53 +0000 (14:43 +0530)
committerYork Sun <yorksun@freescale.com>
Fri, 9 Aug 2013 19:41:41 +0000 (12:41 -0700)
1) Add support in B4860 board files for using IDT driver where
   IDT8T49N222A is a low phase noise Frequency Translator / Synthesizer
   that generate different refclks for SerDes modules, used this driver
   for reconfiguring SerDes1 Refclks(based on SerDes1 protocols)
   for CPRI to work. CPRI works on 122.88MHz and default refclks coming
   on board are not suitable for it
2) Move SerDes1 refclk1 source selection from eth_b4860qds.c file
   to b4860qds board file, as SerDes1 Refclk1 would come from
   PHY MUX in case of certain protocols, that have been checked here.
   This change would make on board SGMIIs to work
3) Add I2C addresses for IDT8T49N222A devices in board/include file
4) Add define for PCA-I2C bus multiplexer, on which IDT devices exist

Signed-off-by: Shaveta Leekha <shaveta@freescale.com>
Acked-by: York Sun <yorksun@freescale.com>
board/freescale/b4860qds/b4860qds.c
board/freescale/b4860qds/eth_b4860qds.c
include/configs/B4860QDS.h

index e4f4bfdc5b1bd35d422cd01cf45f9c6d04e8875b..f74651c5209c1ea84793397d72973cbd6c7689aa 100644 (file)
 
 #include "../common/qixis.h"
 #include "../common/vsc3316_3308.h"
+#include "../common/idt8t49n222a_serdes_clk.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
+#define PLL_NUM                        2
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -237,6 +239,106 @@ int configure_vsc3316_3308(void)
        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_prtcl = 0;
+       int ret, i;
+
+       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);
+
+       /* Clear SRDS_RSTCTL_RST bit for both PLLs before changing refclks
+        */
+       for (i = 0; i < PLL_NUM; i++)
+               clrbits_be32(&srds_regs->bank[i].rstctl, SRDS_RSTCTL_RST);
+       /* 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 0x2A:
+       case 0x2C:
+       case 0x2D:
+       case 0x2E:
+               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");
+                               return ret;
+                       } else
+                               printf("IDT8T49N222A configured.\n");
+               } else {
+                       return ret;
+               }
+               select_i2c_ch_pca(I2C_CH_DEFAULT);
+
+               /* Change SerDes1's Refclk1 to 125MHz for on board
+                * SGMIIs 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:
+                               flag_sgmii_prtcl++;
+                               break;
+                       default:
+                               break;
+                       }
+               }
+
+               if (flag_sgmii_prtcl)
+                       QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
+
+               /* Steps For SerDes PLLs reset and reconfiguration after
+                * changing SerDes's refclks
+                */
+               for (i = 0; i < PLL_NUM; 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);
+               return -1;
+       }
+
+       return 0;
+}
+
 int board_early_init_r(void)
 {
        const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
@@ -262,6 +364,16 @@ int board_early_init_r(void)
 #ifdef CONFIG_SYS_DPAA_QBMAN
        setup_portals();
 #endif
+       /* 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");
 
        /* Configure VSC3316 and VSC3308 crossbar switches */
        if (configure_vsc3316_3308())
index 19ca66e3d035a9122ac03c9e34e9cf62e26d9181..dc4ef80fc883f4ef85c57d2ca16499636d49b0ae 100644 (file)
@@ -201,8 +201,6 @@ int board_eth_init(bd_t *bis)
                debug("Setting phy addresses for FM1_DTSEC5: %x and"
                        "FM1_DTSEC6: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR,
                        CONFIG_SYS_FM1_DTSEC6_PHY_ADDR);
-               /* Fixing Serdes clock by programming FPGA register */
-               QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
                fm_info_set_phy_address(FM1_DTSEC5,
                                CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
                fm_info_set_phy_address(FM1_DTSEC6,
index 0f40179aca9d27bb215d14a13a874c8cdec3a668..7bc3428f4acbd9539ac41b0f6357169f80891ba8 100644 (file)
 #define VSC3308_TX_ADDRESS              0x02
 #define VSC3308_RX_ADDRESS              0x03
 
+/* IDT clock synthesizers */
+#define CONFIG_IDT8T49N222A
+#define I2C_CH_IDT                     0x9
+
+#define IDT_SERDES1_ADDRESS            0x6E
+#define IDT_SERDES2_ADDRESS            0x6C
+
 #define CONFIG_ENV_OVERWRITE
 
 #ifdef CONFIG_SYS_NO_FLASH