powerpc/t4240: add QSGMII interface support
authorShaohui Xie <Shaohui.Xie@freescale.com>
Mon, 19 Aug 2013 10:58:52 +0000 (18:58 +0800)
committerYork Sun <yorksun@freescale.com>
Tue, 20 Aug 2013 17:46:48 +0000 (10:46 -0700)
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>
arch/powerpc/cpu/mpc85xx/t4240_serdes.c
board/freescale/t4qds/eth.c
drivers/net/fm/eth.c
drivers/net/fm/memac.c
drivers/net/fm/t4240.c

index ed88602c3158301b73c2a2cc9f910bea1565fcc8..ff55e3c357c3371b9f078d3da40550b3710a7cd4 100644 (file)
@@ -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,
index c771e17952c888b01c6963c90fdc56f8737063b5..b5f488bcba46c6d6de8b70db79cd3afd354ba5b9 100644 (file)
@@ -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) {
index 422c2c691ed31216ae60c2e2b0768bc251ce464a..cb099cd84962fa7ba09da632683c1fd8622466ff 100644 (file)
@@ -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 */
index 144e109fd0336ec3a812ee53592afe94c2c9472a..592a67f2a58536ef2712b37150a739888e97f587 100644 (file)
@@ -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;
index 10c141fa2634b0d266c6278d63966b1fc629ac29..6253f22f75de8b938c7aeb25db8e0ae958aae49a 100644 (file)
@@ -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;