drivers: net: ipq6018: Support QSGMII,SGMII,SGMII_FIBER modes

Change-Id: I19c30a8054ac092e69c0e91ad2a6fc1d1cfa62eb
Signed-off-by: speriaka <speriaka@codeaurora.org>
This commit is contained in:
speriaka 2019-07-23 17:00:52 +05:30 committed by Gerrit - the friendly Code Review server
parent d0efe15871
commit b76bed491a
6 changed files with 64 additions and 67 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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 {

View file

@ -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 */