board/b4860qds: Add support for configuring SerDes1 Refclks

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>
This commit is contained in:
Shaveta Leekha 2013-07-02 14:43:53 +05:30 committed by York Sun
parent 40f398a42b
commit cb033741f4
3 changed files with 119 additions and 2 deletions

View file

@ -21,12 +21,14 @@
#include "../common/qixis.h" #include "../common/qixis.h"
#include "../common/vsc3316_3308.h" #include "../common/vsc3316_3308.h"
#include "../common/idt8t49n222a_serdes_clk.h"
#include "b4860qds.h" #include "b4860qds.h"
#include "b4860qds_qixis.h" #include "b4860qds_qixis.h"
#include "b4860qds_crossbar_con.h" #include "b4860qds_crossbar_con.h"
#define CLK_MUX_SEL_MASK 0x4 #define CLK_MUX_SEL_MASK 0x4
#define ETH_PHY_CLK_OUT 0x4 #define ETH_PHY_CLK_OUT 0x4
#define PLL_NUM 2
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -237,6 +239,106 @@ int configure_vsc3316_3308(void)
return 0; 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) int board_early_init_r(void)
{ {
const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
@ -262,6 +364,16 @@ int board_early_init_r(void)
#ifdef CONFIG_SYS_DPAA_QBMAN #ifdef CONFIG_SYS_DPAA_QBMAN
setup_portals(); setup_portals();
#endif #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 */ /* Configure VSC3316 and VSC3308 crossbar switches */
if (configure_vsc3316_3308()) if (configure_vsc3316_3308())

View file

@ -201,8 +201,6 @@ int board_eth_init(bd_t *bis)
debug("Setting phy addresses for FM1_DTSEC5: %x and" debug("Setting phy addresses for FM1_DTSEC5: %x and"
"FM1_DTSEC6: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR, "FM1_DTSEC6: %x\n", CONFIG_SYS_FM1_DTSEC5_PHY_ADDR,
CONFIG_SYS_FM1_DTSEC6_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, fm_info_set_phy_address(FM1_DTSEC5,
CONFIG_SYS_FM1_DTSEC5_PHY_ADDR); CONFIG_SYS_FM1_DTSEC5_PHY_ADDR);
fm_info_set_phy_address(FM1_DTSEC6, fm_info_set_phy_address(FM1_DTSEC6,

View file

@ -74,6 +74,13 @@
#define VSC3308_TX_ADDRESS 0x02 #define VSC3308_TX_ADDRESS 0x02
#define VSC3308_RX_ADDRESS 0x03 #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 #define CONFIG_ENV_OVERWRITE
#ifdef CONFIG_SYS_NO_FLASH #ifdef CONFIG_SYS_NO_FLASH