diff options
| author | Shaohui Xie <Shaohui.Xie@freescale.com> | 2013-08-19 18:58:52 +0800 | 
|---|---|---|
| committer | York Sun <yorksun@freescale.com> | 2013-08-20 10:46:48 -0700 | 
| commit | 1c68d01eea92137482b980318e2a7f7c0ebef2d4 (patch) | |
| tree | c8626489bd3dce8596d7d49f9d33a2386806eca2 | |
| parent | ae3dcd04880ba5b21ffd62e91713c14b4fd92ec5 (diff) | |
| download | olio-uboot-2014.01-1c68d01eea92137482b980318e2a7f7c0ebef2d4.tar.xz olio-uboot-2014.01-1c68d01eea92137482b980318e2a7f7c0ebef2d4.zip | |
powerpc/t4240: add QSGMII interface support
Also some fix for QSGMII.
1. fix QSGMII configure of Serdes2.
2. fix PHY address of QSGMII MAC9 & MAC10 for each FMAN.
3. fix dtb for QSGMII interface.
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
Acked-by: York Sun <yorksun@freescale.com>
| -rw-r--r-- | arch/powerpc/cpu/mpc85xx/t4240_serdes.c | 14 | ||||
| -rw-r--r-- | board/freescale/t4qds/eth.c | 80 | ||||
| -rw-r--r-- | drivers/net/fm/eth.c | 4 | ||||
| -rw-r--r-- | drivers/net/fm/memac.c | 1 | ||||
| -rw-r--r-- | drivers/net/fm/t4240.c | 40 | 
5 files changed, 108 insertions, 31 deletions
| diff --git a/arch/powerpc/cpu/mpc85xx/t4240_serdes.c b/arch/powerpc/cpu/mpc85xx/t4240_serdes.c index ed88602c3..ff55e3c35 100644 --- a/arch/powerpc/cpu/mpc85xx/t4240_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/t4240_serdes.c @@ -106,25 +106,25 @@ static const struct serdes_config serdes2_cfg_tbl[] = {  		SGMII_FM2_DTSEC1, SGMII_FM2_DTSEC2,  		SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4}},  	{38, {NONE, NONE, QSGMII_FM2_B, NONE, -		NONE, NONE, QSGMII_FM1_A, NONE}}, +		NONE, NONE, QSGMII_FM2_A, NONE} },  	{40, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,  		SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9, -		NONE, NONE, QSGMII_FM1_A, NONE}}, +		NONE, NONE, QSGMII_FM2_A, NONE} },  	{46, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,  		SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9, -		NONE, NONE, QSGMII_FM1_A, NONE}}, +		NONE, NONE, QSGMII_FM2_A, NONE} },  	{48, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,  		SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9, -		NONE, NONE, QSGMII_FM1_A, NONE}}, +		NONE, NONE, QSGMII_FM2_A, NONE} },  	{50, {XAUI_FM2_MAC9, XAUI_FM2_MAC9,  		XAUI_FM2_MAC9, XAUI_FM2_MAC9, -		NONE, NONE, QSGMII_FM1_A, NONE}}, +		NONE, NONE, QSGMII_FM2_A, NONE} },  	{52, {HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,  		HIGIG_FM2_MAC9, HIGIG_FM2_MAC9, -		NONE, NONE, QSGMII_FM1_A, NONE}}, +		NONE, NONE, QSGMII_FM2_A, NONE} },  	{54, {HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,  		HIGIG_FM2_MAC9, HIGIG_FM2_MAC9, -		NONE, NONE, QSGMII_FM1_A, NONE}}, +		NONE, NONE, QSGMII_FM2_A, NONE} },  	{56, {XFI_FM1_MAC9, XFI_FM1_MAC10,  		XFI_FM2_MAC10, XFI_FM2_MAC9,  		SGMII_FM2_DTSEC1, SGMII_FM2_DTSEC2, diff --git a/board/freescale/t4qds/eth.c b/board/freescale/t4qds/eth.c index c771e1795..b5f488bcb 100644 --- a/board/freescale/t4qds/eth.c +++ b/board/freescale/t4qds/eth.c @@ -172,7 +172,10 @@ static int t4240qds_mdio_init(char *realbusname, u8 muxval)  void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa,  				enum fm_port port, int offset)  { -	if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { +	int interface = fm_info_get_enet_if(port); + +	if (interface == PHY_INTERFACE_MODE_SGMII || +	    interface == PHY_INTERFACE_MODE_QSGMII) {  		switch (port) {  		case FM1_DTSEC1:  			if (qsgmiiphy_fix[port]) @@ -272,6 +275,7 @@ void fdt_fixup_board_enet(void *fdt)  	for (i = FM1_DTSEC1; i < NUM_FM_PORTS; i++) {  		switch (fm_info_get_enet_if(i)) {  		case PHY_INTERFACE_MODE_SGMII: +		case PHY_INTERFACE_MODE_QSGMII:  			switch (mdio_mux[i]) {  			case EMI1_SLOT1:  				fdt_status_okay_by_alias(fdt, "emi1_slot1"); @@ -393,7 +397,7 @@ static void initialize_qsgmiiphy_fix(void)  int board_eth_init(bd_t *bis)  {  #if defined(CONFIG_FMAN_ENET) -	int i, idx, lane, slot; +	int i, idx, lane, slot, interface;  	struct memac_mdio_info dtsec_mdio_info;  	struct memac_mdio_info tgec_mdio_info;  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); @@ -470,9 +474,9 @@ int board_eth_init(bd_t *bis)  		fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]);  		if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) {  			fm_info_set_phy_address(FM1_DTSEC9, -						slot_qsgmii_phyaddr[1][3]); -			fm_info_set_phy_address(FM1_DTSEC10,  						slot_qsgmii_phyaddr[1][2]); +			fm_info_set_phy_address(FM1_DTSEC10, +						slot_qsgmii_phyaddr[1][3]);  		}  		break;  	case 40: @@ -482,9 +486,9 @@ int board_eth_init(bd_t *bis)  		fm_info_set_phy_address(FM1_DTSEC6, slot_qsgmii_phyaddr[1][1]);  		if ((srds_prtcl_s2 != 56) && (srds_prtcl_s2 != 57)) {  			fm_info_set_phy_address(FM1_DTSEC10, -						slot_qsgmii_phyaddr[1][3]); -			fm_info_set_phy_address(FM1_DTSEC9,  						slot_qsgmii_phyaddr[1][2]); +			fm_info_set_phy_address(FM1_DTSEC9, +						slot_qsgmii_phyaddr[1][3]);  		}  		fm_info_set_phy_address(FM1_DTSEC1, slot_qsgmii_phyaddr[2][0]);  		fm_info_set_phy_address(FM1_DTSEC2, slot_qsgmii_phyaddr[2][1]); @@ -498,15 +502,31 @@ int board_eth_init(bd_t *bis)  	for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {  		idx = i - FM1_DTSEC1; -		switch (fm_info_get_enet_if(i)) { +		interface = fm_info_get_enet_if(i); +		switch (interface) {  		case PHY_INTERFACE_MODE_SGMII: -			lane = serdes_get_first_lane(FSL_SRDS_1, +		case PHY_INTERFACE_MODE_QSGMII: +			if (interface == PHY_INTERFACE_MODE_QSGMII) { +				if (idx <= 3) +					lane = serdes_get_first_lane(FSL_SRDS_1, +							QSGMII_FM1_A); +				else +					lane = serdes_get_first_lane(FSL_SRDS_1, +							QSGMII_FM1_B); +				if (lane < 0) +					break; +				slot = lane_to_slot_fsm1[lane]; +				debug("FM1@DTSEC%u expects QSGMII in slot %u\n", +				      idx + 1, slot); +			} else { +				lane = serdes_get_first_lane(FSL_SRDS_1,  						SGMII_FM1_DTSEC1 + idx); -			if (lane < 0) -				break; -			slot = lane_to_slot_fsm1[lane]; -			debug("FM1@DTSEC%u expects SGMII in slot %u\n", -				idx + 1, slot); +				if (lane < 0) +					break; +				slot = lane_to_slot_fsm1[lane]; +				debug("FM1@DTSEC%u expects SGMII in slot %u\n", +				      idx + 1, slot); +			}  			if (QIXIS_READ(present2) & (1 << (slot - 1)))  				fm_disable_port(i);  			switch (slot) { @@ -600,8 +620,8 @@ int board_eth_init(bd_t *bis)  		fm_info_set_phy_address(FM2_DTSEC4, slot_qsgmii_phyaddr[4][3]);  		fm_info_set_phy_address(FM2_DTSEC5, slot_qsgmii_phyaddr[3][0]);  		fm_info_set_phy_address(FM2_DTSEC6, slot_qsgmii_phyaddr[3][1]); -		fm_info_set_phy_address(FM2_DTSEC9, slot_qsgmii_phyaddr[3][3]); -		fm_info_set_phy_address(FM2_DTSEC10, slot_qsgmii_phyaddr[3][2]); +		fm_info_set_phy_address(FM2_DTSEC9, slot_qsgmii_phyaddr[3][2]); +		fm_info_set_phy_address(FM2_DTSEC10, slot_qsgmii_phyaddr[3][3]);  		break;  	case 40:  	case 46: @@ -641,15 +661,31 @@ int board_eth_init(bd_t *bis)  	for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {  		idx = i - FM2_DTSEC1; -		switch (fm_info_get_enet_if(i)) { +		interface = fm_info_get_enet_if(i); +		switch (interface) {  		case PHY_INTERFACE_MODE_SGMII: -			lane = serdes_get_first_lane(FSL_SRDS_2, +		case PHY_INTERFACE_MODE_QSGMII: +			if (interface == PHY_INTERFACE_MODE_QSGMII) { +				if (idx <= 3) +					lane = serdes_get_first_lane(FSL_SRDS_2, +							QSGMII_FM2_A); +				else +					lane = serdes_get_first_lane(FSL_SRDS_2, +							QSGMII_FM2_B); +				if (lane < 0) +					break; +				slot = lane_to_slot_fsm2[lane]; +				debug("FM2@DTSEC%u expects QSGMII in slot %u\n", +				      idx + 1, slot); +			} else { +				lane = serdes_get_first_lane(FSL_SRDS_2,  						SGMII_FM2_DTSEC1 + idx); -			if (lane < 0) -				break; -			slot = lane_to_slot_fsm2[lane]; -			debug("FM2@DTSEC%u expects SGMII in slot %u\n", -				idx + 1, slot); +				if (lane < 0) +					break; +				slot = lane_to_slot_fsm2[lane]; +				debug("FM2@DTSEC%u expects SGMII in slot %u\n", +				      idx + 1, slot); +			}  			if (QIXIS_READ(present2) & (1 << (slot - 1)))  				fm_disable_port(i);  			switch (slot) { diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c index 422c2c691..cb099cd84 100644 --- a/drivers/net/fm/eth.c +++ b/drivers/net/fm/eth.c @@ -341,7 +341,9 @@ static int fm_eth_startup(struct fm_eth *fm_eth)  	mac->init_mac(mac);  	/* For some reason we need to set SPEED_100 */ -	if ((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) && mac->set_if_mode) +	if (((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) || +	     (fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII)) && +	      mac->set_if_mode)  		mac->set_if_mode(mac, fm_eth->enet_if, SPEED_100);  	/* init bmi rx port, IM mode and disable */ diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c index 144e109fd..592a67f2a 100644 --- a/drivers/net/fm/memac.c +++ b/drivers/net/fm/memac.c @@ -90,6 +90,7 @@ static void memac_set_interface_mode(struct fsl_enet_mac *mac,  		if_mode |= (IF_MODE_GMII | IF_MODE_RM);  		break;  	case PHY_INTERFACE_MODE_SGMII: +	case PHY_INTERFACE_MODE_QSGMII:  		if_mode &= ~IF_MODE_MASK;  		if_mode |= (IF_MODE_GMII);  		break; diff --git a/drivers/net/fm/t4240.c b/drivers/net/fm/t4240.c index 10c141fa2..6253f22f7 100644 --- a/drivers/net/fm/t4240.c +++ b/drivers/net/fm/t4240.c @@ -114,7 +114,45 @@ phy_interface_t fman_port_enet_if(enum fm_port port)  			return PHY_INTERFACE_MODE_SGMII;  		break;  	default: -		return PHY_INTERFACE_MODE_NONE; +		break; +	} + +	/* handle QSGMII */ +	switch (port) { +	case FM1_DTSEC1: +	case FM1_DTSEC2: +	case FM1_DTSEC3: +	case FM1_DTSEC4: +		/* check lane G on SerDes1 */ +		if (is_serdes_configured(QSGMII_FM1_A)) +			return PHY_INTERFACE_MODE_QSGMII; +		break; +	case FM1_DTSEC5: +	case FM1_DTSEC6: +	case FM1_DTSEC9: +	case FM1_DTSEC10: +		/* check lane C on SerDes1 */ +		if (is_serdes_configured(QSGMII_FM1_B)) +			return PHY_INTERFACE_MODE_QSGMII; +		break; +	case FM2_DTSEC1: +	case FM2_DTSEC2: +	case FM2_DTSEC3: +	case FM2_DTSEC4: +		/* check lane G on SerDes2 */ +		if (is_serdes_configured(QSGMII_FM2_A)) +			return PHY_INTERFACE_MODE_QSGMII; +		break; +	case FM2_DTSEC5: +	case FM2_DTSEC6: +	case FM2_DTSEC9: +	case FM2_DTSEC10: +		/* check lane C on SerDes2 */ +		if (is_serdes_configured(QSGMII_FM2_B)) +			return PHY_INTERFACE_MODE_QSGMII; +		break; +	default: +		break;  	}  	return PHY_INTERFACE_MODE_NONE; |