diff --git a/drivers/net/ipq6018/ipq6018_edma.c b/drivers/net/ipq6018/ipq6018_edma.c index 1e8bf6893c..ba7686425a 100755 --- a/drivers/net/ipq6018/ipq6018_edma.c +++ b/drivers/net/ipq6018/ipq6018_edma.c @@ -888,6 +888,7 @@ static int ipq6018_eth_init(struct eth_device *eth_dev, bd_t *this) int sfp_port = -1; int phy_node = -1; int ret_sgmii_mode; + int sfp_mode, sgmii_fiber = 0; node = fdt_path_offset(gd->fdt_blob, "/ess-switch"); if (node >= 0) @@ -909,8 +910,24 @@ static int ipq6018_eth_init(struct eth_device *eth_dev, bd_t *this) if (i == sfp_port) { status = phy_status_get_from_ppe(i); - speed = FAL_SPEED_10000; duplex = FAL_FULL_DUPLEX; + sfp_mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode1", -1); + if (sfp_mode < 0) { + printf("\nError: switch_mac_mode1 not specified in dts"); + return sfp_mode; + } + if (sfp_mode == PORT_WRAPPER_SGMII_FIBER) { + sgmii_fiber = 1; + } else if (sfp_mode == PORT_WRAPPER_10GBASE_R) { + sgmii_fiber = 0; + } else { + printf("\nError: wrong mode specified for SFP Port"); + return sfp_mode; + } + if (sgmii_fiber) + speed = FAL_SPEED_1000; + else + speed = FAL_SPEED_10000; } else { if (!priv->ops[i]) { printf ("Phy ops not mapped\n"); @@ -989,6 +1006,8 @@ static int ipq6018_eth_init(struct eth_device *eth_dev, bd_t *this) mac_speed = 0x2; if (i == aquantia_port) speed_clock1 = 0x304; + else if (i == sfp_port) + speed_clock1 = 0x301; else speed_clock1 = 0x101; speed_clock2 = 0x0; @@ -1048,15 +1067,14 @@ static int ipq6018_eth_init(struct eth_device *eth_dev, bd_t *this) if (phy_node >= 0) { if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) { ret_sgmii_mode = get_sgmii_mode(i); + ppe_port_bridge_txmac_set(i + 1, 1); if (ret_sgmii_mode == 1) { - ppe_port_bridge_txmac_set(i + 1, 1); if (i == 4) ppe_uniphy_mode_set(0x1, PORT_WRAPPER_SGMII0_RGMII4); else if (i == 3) ppe_uniphy_mode_set(0x0, PORT_WRAPPER_SGMII0_RGMII4); } else if (ret_sgmii_mode == 0) { - ppe_port_bridge_txmac_set(i + 1, 1); if (i == 4) ppe_uniphy_mode_set(0x1, PORT_WRAPPER_SGMII_PLUS); else if (i == 3) @@ -1067,8 +1085,16 @@ static int ipq6018_eth_init(struct eth_device *eth_dev, bd_t *this) ipq6018_speed_clock_set(i, speed_clock1, speed_clock2); if (i == aquantia_port) ipq6018_uxsgmii_speed_set(i, mac_speed, duplex, status); - else if (i == sfp_port) - ipq6018_10g_r_speed_set(i, status); + else if (i == sfp_port) { + if (sgmii_fiber) { + ppe_port_bridge_txmac_set(i + 1, 1); + ppe_uniphy_mode_set(0x1, PORT_WRAPPER_SGMII_FIBER); + ppe_port_mux_mac_type_set(5, PORT_WRAPPER_SGMII_FIBER); + ipq6018_pqsgmii_speed_set(i, mac_speed, status); + } else { + ipq6018_10g_r_speed_set(i, status); + } + } else ipq6018_pqsgmii_speed_set(i, mac_speed, status); } diff --git a/drivers/net/ipq6018/ipq6018_edma.h b/drivers/net/ipq6018/ipq6018_edma.h index aa33c2b911..4c1493478a 100644 --- a/drivers/net/ipq6018/ipq6018_edma.h +++ b/drivers/net/ipq6018/ipq6018_edma.h @@ -317,6 +317,7 @@ extern void ipq6018_ppe_provision_init(void); extern void ipq6018_speed_clock_set(int port, int speed_clock1, int speed_clock2); extern void ipq6018_pqsgmii_speed_set(int port, int speed, int status); extern void ipq6018_uxsgmii_speed_set(int port, int speed, int duplex, int status); +extern void ppe_port_mux_mac_type_set(int port_id, int mode); extern void ppe_port_bridge_txmac_set(int port, int status); extern void ipq6018_10g_r_speed_set(int port, int status); extern int phy_status_get_from_ppe(int port_id); diff --git a/drivers/net/ipq6018/ipq6018_ppe.c b/drivers/net/ipq6018/ipq6018_ppe.c index 9f682c2706..723386b88a 100644 --- a/drivers/net/ipq6018/ipq6018_ppe.c +++ b/drivers/net/ipq6018/ipq6018_ppe.c @@ -232,8 +232,6 @@ void ipq6018_pqsgmii_speed_set(int port, int speed, int status) ipq6018_ppe_reg_write(IPQ6018_PPE_MAC_ENABLE + (0x200 * port), 0x73); } - - void ppe_xgmac_speed_set(uint32_t uniphy_index, int speed) { uint32_t reg_value = 0; @@ -1115,12 +1113,12 @@ static void ppe_port_mux_set(int port_id, int port_type, int mode) switch (port_id) { case 3: case 4: - if (mode == PORT_WRAPPER_SGMII_PLUS) { + if (mode == PORT_WRAPPER_SGMII_PLUS || mode == PORT_WRAPPER_SGMII0_RGMII4) { port_mux_ctrl.bf.port3_pcs_sel = CPPE_PORT3_PCS_SEL_PCS0_CHANNEL2; port_mux_ctrl.bf.port4_pcs_sel = CPPE_PORT4_PCS_SEL_PCS0_SGMIIPLUS; port_mux_ctrl.bf.pcs0_ch0_sel = CPPE_PCS0_CHANNEL0_SEL_SGMIIPLUS; port_mux_ctrl.bf.pcs0_ch4_sel = CPPE_PCS0_CHANNEL4_SEL_PORT5_CLOCK; - } else if (mode == PORT_WRAPPER_PSGMII) { + } else if (mode == PORT_WRAPPER_PSGMII || mode == PORT_WRAPPER_QSGMII) { if (fdtdec_get_int(gd->fdt_blob, nodeoff, "malibu2port_phy", 0)) { port_mux_ctrl.bf.port3_pcs_sel = CPPE_PORT3_PCS_SEL_PCS0_CHANNEL4; port_mux_ctrl.bf.port4_pcs_sel = CPPE_PORT4_PCS_SEL_PCS0_CHANNEL3; @@ -1134,7 +1132,8 @@ static void ppe_port_mux_set(int port_id, int port_type, int mode) } break; case 5: - if (mode == PORT_WRAPPER_SGMII_PLUS || mode == PORT_WRAPPER_SGMII0_RGMII4) { + if (mode == PORT_WRAPPER_SGMII_PLUS || mode == PORT_WRAPPER_SGMII0_RGMII4 || + mode == PORT_WRAPPER_SGMII_FIBER) { port_mux_ctrl.bf.port5_pcs_sel = CPPE_PORT5_PCS_SEL_PCS1_CHANNEL0; port_mux_ctrl.bf.port5_gmac_sel = CPPE_PORT5_GMAC_SEL_GMAC; } else if (mode == PORT_WRAPPER_PSGMII) { @@ -1152,24 +1151,19 @@ static void ppe_port_mux_set(int port_id, int port_type, int mode) ipq6018_ppe_reg_write(IPQ6018_PORT_MUX_CTRL, port_mux_ctrl.val); } -static void ppe_port_mux_mac_type_set(int port_id, int mode) +void ppe_port_mux_mac_type_set(int port_id, int mode) { uint32_t port_type; switch(mode) { case PORT_WRAPPER_PSGMII: - port_type = PORT_GMAC_TYPE; - break; case PORT_WRAPPER_SGMII0_RGMII4: - port_type = PORT_GMAC_TYPE; - break; case PORT_WRAPPER_SGMII_PLUS: + case PORT_WRAPPER_SGMII_FIBER: port_type = PORT_GMAC_TYPE; break; case PORT_WRAPPER_USXGMII: - port_type = PORT_XGMAC_TYPE; - break; case PORT_WRAPPER_10GBASE_R: port_type = PORT_XGMAC_TYPE; break; diff --git a/drivers/net/ipq6018/ipq6018_uniphy.c b/drivers/net/ipq6018/ipq6018_uniphy.c index fa246114b5..362174fb82 100644 --- a/drivers/net/ipq6018/ipq6018_uniphy.c +++ b/drivers/net/ipq6018/ipq6018_uniphy.c @@ -133,7 +133,7 @@ static void ppe_uniphy_qsgmii_mode_set(uint32_t uniphy_index) ppe_gcc_uniphy_soft_reset(uniphy_index); } -static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t channel) +static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode) { writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET); @@ -156,52 +156,29 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t channel) writel(0x0, GCC_NSS_PORT5_RX_CBCR); } - writel(0x420, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) - + PPE_UNIPHY_MODE_CONTROL); + switch (mode) { + case PORT_WRAPPER_SGMII_FIBER: + writel(0x400, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + + PPE_UNIPHY_MODE_CONTROL); + break; - ppe_gcc_uniphy_sgmii_soft_reset(uniphy_index); + case PORT_WRAPPER_SGMII0_RGMII4: + case PORT_WRAPPER_SGMII1_RGMII4: + case PORT_WRAPPER_SGMII4_RGMII4: + writel(0x420, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + + PPE_UNIPHY_MODE_CONTROL); + break; - if (uniphy_index == 0) { - writel(0x1, GCC_UNIPHY0_PORT4_RX_CBCR); - writel(0x1, GCC_UNIPHY0_PORT4_TX_CBCR); - writel(0x1, GCC_NSS_PORT4_RX_CBCR); - writel(0x1, GCC_NSS_PORT4_TX_CBCR); - } else { - writel(0x1, GCC_UNIPHY1_PORT5_RX_CBCR); - writel(0x1, GCC_UNIPHY1_PORT5_TX_CBCR); - writel(0x1, GCC_NSS_PORT5_RX_CBCR); - writel(0x1, GCC_NSS_PORT5_RX_CBCR); + case PORT_WRAPPER_SGMII_PLUS: + writel(0x820, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) + + PPE_UNIPHY_MODE_CONTROL); + break; + + default: + printf("SGMII Config. wrongly"); + break; } - ppe_uniphy_calibration(uniphy_index); -} - -static void ppe_uniphy_sgmii_plus_mode_set(uint32_t uniphy_index) -{ - writel(UNIPHY_MISC2_REG_SGMII_PLUS_MODE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET); - writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET); - udelay(500); - writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE + - (uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET); - ppe_gcc_uniphy_xpcs_reset(uniphy_index, true); - - if (uniphy_index == 0) { - writel(0x0, GCC_UNIPHY0_PORT4_RX_CBCR); - writel(0x0, GCC_UNIPHY0_PORT4_TX_CBCR); - writel(0x0, GCC_NSS_PORT4_RX_CBCR); - writel(0x0, GCC_NSS_PORT4_TX_CBCR); - } else { - writel(0x0, GCC_UNIPHY1_PORT5_RX_CBCR); - writel(0x0, GCC_UNIPHY1_PORT5_TX_CBCR); - writel(0x0, GCC_NSS_PORT5_RX_CBCR); - writel(0x0, GCC_NSS_PORT5_RX_CBCR); - } - - writel(0x820, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC) - + PPE_UNIPHY_MODE_CONTROL); - ppe_gcc_uniphy_sgmii_soft_reset(uniphy_index); if (uniphy_index == 0) { @@ -291,16 +268,11 @@ void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode) ppe_uniphy_qsgmii_mode_set(uniphy_index); break; case PORT_WRAPPER_SGMII0_RGMII4: - ppe_uniphy_sgmii_mode_set(uniphy_index, 0); - break; case PORT_WRAPPER_SGMII1_RGMII4: - ppe_uniphy_sgmii_mode_set(uniphy_index, 1); - break; case PORT_WRAPPER_SGMII4_RGMII4: - ppe_uniphy_sgmii_mode_set(uniphy_index, 4); - break; case PORT_WRAPPER_SGMII_PLUS: - ppe_uniphy_sgmii_plus_mode_set(uniphy_index); + case PORT_WRAPPER_SGMII_FIBER: + ppe_uniphy_sgmii_mode_set(uniphy_index, mode); break; case PORT_WRAPPER_USXGMII: ppe_uniphy_usxgmii_mode_set(uniphy_index); diff --git a/drivers/net/ipq_common/ipq_phy.h b/drivers/net/ipq_common/ipq_phy.h index 753c9e9862..1176e97095 100755 --- a/drivers/net/ipq_common/ipq_phy.h +++ b/drivers/net/ipq_common/ipq_phy.h @@ -96,6 +96,7 @@ enum port_wrapper_cfg { PORT_WRAPPER_QSGMII, PORT_WRAPPER_SGMII_PLUS, PORT_WRAPPER_10GBASE_R, + PORT_WRAPPER_SGMII_FIBER, }; enum phy_mode { diff --git a/include/dt-bindings/qcom/eth-ipq6018.h b/include/dt-bindings/qcom/eth-ipq6018.h index 9ab513349f..88480176b1 100644 --- a/include/dt-bindings/qcom/eth-ipq6018.h +++ b/include/dt-bindings/qcom/eth-ipq6018.h @@ -16,9 +16,12 @@ /* ESS Switch Mac Modes */ #define PORT_WRAPPER_PSGMII 0x0 +#define PORT_WRAPPER_SGMII 0x1 #define PORT_WRAPPER_USXGMII 0x2 +#define PORT_WRAPPER_QSGMII 0x5 #define PORT_WRAPPER_SGMII_PLUS 0x6 #define PORT_WRAPPER_10GBASE_R 0x7 +#define PORT_WRAPPER_SGMII_FIBER 0x8 #define UNUSED 0xFF /* ETH PHY Types */