drivers: net: ipq9574: Enable usxgmii in UNIPHY0

This change adds usxgmii support in UNIPHY0.
Earlier it was supported up to PSGMII with 4 ports.

With these changes,
UNIPHY0 supports either of the 2 modes mentioned below.
	1. PSGMII with 4 ports
	2. USXGMII with 1 port

Change-Id: Ic4ca62e3ef74d275cda92d86b459d204ee4325ed
Signed-off-by: Vandhiadevan Karunamoorthy <quic_vkarunam@quicinc.com>
This commit is contained in:
Vandhiadevan Karunamoorthy 2022-09-07 17:58:08 +05:30 committed by Gerrit - the friendly Code Review server
parent 17f3d532f3
commit d18ca4451a
4 changed files with 227 additions and 45 deletions

View file

@ -333,5 +333,9 @@
gpt_freq_hz = <24000000>;
timer_load_val = <0x00FFFFFF 0xFFFFFFFF>;
};
ess-switch {
tdm_mode = <0>;
};
};

View file

@ -883,10 +883,11 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
int linkup = 0;
int clk[4] = {0};
int phy_addr = -1, node = -1;
int aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
int sfp_port[2] = {-1, -1}, sfp_port_cnt = -1;
int aquantia_port[3] = {-1, -1, -1}, aquantia_port_cnt = -1;
int sfp_port[3] = {-1, -1, -1}, sfp_port_cnt = -1;
int sgmii_mode = -1, sfp_mode = -1, sgmii_fiber = -1;
int phy_node = -1, res = -1;
int uniphy_index = 0;
char *active_port = NULL;
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
@ -951,11 +952,13 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
}
if(phy_info[i]->phy_type == UNUSED_PHY_TYPE)
continue;
if (i == sfp_port[0] || i == sfp_port[1]) {
if (i == sfp_port[0] || i == sfp_port[1] || i == sfp_port[2]) {
status = phy_status_get_from_ppe(i);
duplex = FAL_FULL_DUPLEX;
/* SFP Port can be enabled in USXGMII0 or USXGMII1 i.e
* SFP Port can be port5 or port6 (with port id - 4 or 5).
/* SFP Port can be enabled in USXGMIIx x=0-2i.e
* SFP Port can be port5 or port6 or port0
* (with port id - 0, 4 or 5).
* Port0 (port id - 0) -> Serdes0
* Port5 (port id - 4) -> Serdes1
* Port6 (port id - 5) -> Serdes2
*/
@ -972,8 +975,13 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
return sfp_mode;
}
} else {
printf("Error: SFP Port can be enabled in USXGMII0 or USXGMII1 (Port5 or Port6) only in ipq9574 platform\n");
sfp_mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode0", -1);
if (sfp_mode < 0) {
printf("Error: switch_mac_mode0 not specified in dts\n");
return sfp_mode;
}
}
if (sfp_mode == EPORT_WRAPPER_SGMII_FIBER) {
sgmii_fiber = 1;
curr_speed[i] = FAL_SPEED_1000;
@ -1056,7 +1064,9 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
clk[1] = 0x9;
clk[2] = 0x309;
clk[3] = 0x9;
if (i == aquantia_port[0] || i == aquantia_port[1]) {
if (i == aquantia_port[0] ||
i == aquantia_port[1] ||
i == aquantia_port[2]) {
clk[1] = 0x18;
clk[3] = 0x18;
if (i == 4) {
@ -1093,7 +1103,9 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
clk[1] = 0x0;
clk[2] = 0x309;
clk[3] = 0x0;
if (i == aquantia_port[0] || i == aquantia_port[1]) {
if (i == aquantia_port[0] ||
i == aquantia_port[1] ||
i == aquantia_port[2] ) {
clk[1] = 0x4;
clk[3] = 0x4;
if (i == 4) {
@ -1127,7 +1139,9 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
clk[1] = 0x0;
clk[2] = 0x301;
clk[3] = 0x0;
if (i == aquantia_port[0] || i == aquantia_port[1]) {
if (i == aquantia_port[0] ||
i == aquantia_port[1] ||
i == aquantia_port[2] ) {
if (i == 4) {
clk[0] = 0x404;
clk[2] = 0x504;
@ -1135,7 +1149,8 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
clk[0] = 0x204;
clk[2] = 0x304;
}
} else if (i == sfp_port[0] || i == sfp_port[1]) {
} else if (i == sfp_port[0] || i == sfp_port[1]
|| i == sfp_port[2]) {
if (i == 4) {
clk[0] = 0x401;
clk[2] = 0x501;
@ -1162,7 +1177,9 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
case FAL_SPEED_2500:
clk[1] = 0x0;
clk[3] = 0x0;
if (i == aquantia_port[0] || i == aquantia_port[1]) {
if (i == aquantia_port[0] ||
i == aquantia_port[1] ||
i == aquantia_port[2] ) {
mac_speed = 0x4;
if (i == 4) {
clk[0] = 0x407;
@ -1171,7 +1188,8 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
clk[0] = 0x207;
clk[2] = 0x307;
}
} else if (i == sfp_port[0] || i == sfp_port[1]) {
} else if (i == sfp_port[0] || i == sfp_port[1]
|| i == sfp_port[2]) {
mac_speed = 0x2;
if (i == 4) {
clk[0] = 0x401;
@ -1257,27 +1275,33 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
}
}
}
if (i == sfp_port[0] || i == sfp_port[1]) {
if (i == sfp_port[0] || i == sfp_port[1] || i == sfp_port[2]) {
switch(i) {
case 0:
uniphy_index = 0;
break;
case 4:
uniphy_index = 0x1;
break;
case 5:
uniphy_index = 0x2;
break;
}
if (sgmii_fiber) { /* SGMII Fiber mode */
ppe_port_bridge_txmac_set(i + 1, 1);
if (i == 4)
ppe_uniphy_mode_set(0x1, EPORT_WRAPPER_SGMII_FIBER);
else
ppe_uniphy_mode_set(0x2, EPORT_WRAPPER_SGMII_FIBER);
ppe_port_mux_mac_type_set(i + 1, EPORT_WRAPPER_SGMII_FIBER);
ppe_uniphy_mode_set(uniphy_index,
EPORT_WRAPPER_SGMII_FIBER);
ppe_port_mux_mac_type_set(i + 1,
EPORT_WRAPPER_SGMII_FIBER);
} else if (sfp_mode == EPORT_WRAPPER_10GBASE_R) { /* 10GBASE_R mode */
if (i == 4)
ppe_uniphy_mode_set(0x1, EPORT_WRAPPER_10GBASE_R);
else
ppe_uniphy_mode_set(0x2, EPORT_WRAPPER_10GBASE_R);
ppe_port_mux_mac_type_set(i + 1, EPORT_WRAPPER_10GBASE_R);
ppe_uniphy_mode_set(uniphy_index,
EPORT_WRAPPER_10GBASE_R);
ppe_port_mux_mac_type_set(i + 1,
EPORT_WRAPPER_10GBASE_R);
} else { /* SGMII Plus Mode */
ppe_port_bridge_txmac_set(i + 1, 1);
if (i == 4)
ppe_uniphy_mode_set(0x1, EPORT_WRAPPER_SGMII_PLUS);
else if (i == 5)
ppe_uniphy_mode_set(0x2, EPORT_WRAPPER_SGMII_PLUS);
ppe_uniphy_mode_set(uniphy_index,
EPORT_WRAPPER_SGMII_PLUS);
}
}
@ -1292,10 +1316,12 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
ipq9574_port_mac_clock_reset(i);
if (i == aquantia_port[0] || i == aquantia_port[1] ||
((phy_info[i]->phy_type == QCA8084_PHY_TYPE) && (!qca8084_swt_enb))) {
i == aquantia_port[2] ||
((phy_info[i]->phy_type == QCA8084_PHY_TYPE) &&
(!qca8084_swt_enb))) {
ipq9574_uxsgmii_speed_set(i, mac_speed, duplex, status);
}
else if ((i == sfp_port[0] || i == sfp_port[1]) && sgmii_fiber == 0)
else if ((i == sfp_port[0] || i == sfp_port[1] || i == sfp_port[2]) && sgmii_fiber == 0)
ipq9574_10g_r_speed_set(i, status);
else
ipq9574_pqsgmii_speed_set(i, mac_speed, status);
@ -1909,7 +1935,7 @@ int ipq9574_edma_init(void *edma_board_cfg)
#endif /* CONFIG_QCA8084_SWT_MODE */
#endif
int node, phy_addr, mode, phy_node = -1, res = -1;
int aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
int aquantia_port[3] = {-1, -1, -1}, aquantia_port_cnt = -1;
/*
* Init non cache buffer
@ -2063,7 +2089,9 @@ int ipq9574_edma_init(void *edma_board_cfg)
phy_chip_id1 = ipq_mdio_read(phy_addr, QCA_PHY_ID1, NULL);
phy_chip_id2 = ipq_mdio_read(phy_addr, QCA_PHY_ID2, NULL);
phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
if (phy_id == aquantia_port[0] || phy_id == aquantia_port[1]) {
if (phy_id == aquantia_port[0] ||
phy_id == aquantia_port[1] ||
phy_id == aquantia_port[2]) {
phy_chip_id1 = ipq_mdio_read(phy_addr, (1<<30) |(1<<16) | QCA_PHY_ID1, NULL);
phy_chip_id2 = ipq_mdio_read(phy_addr, (1<<30) |(1<<16) | QCA_PHY_ID2, NULL);
phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;

View file

@ -339,11 +339,16 @@ int phy_status_get_from_ppe(int port_id)
{
uint32_t reg_field = 0;
ipq9574_ppe_reg_read(PORT_PHY_STATUS_ADDRESS, &reg_field);
if (port_id == (PORT5 - PPE_UNIPHY_INSTANCE1))
reg_field >>= PORT_PHY_STATUS_PORT5_1_OFFSET;
else
reg_field >>= PORT_PHY_STATUS_PORT6_OFFSET;
if (port_id == 0) {
ipq9574_ppe_reg_read(PORT_PHY_STATUS0_ADDRESS, &reg_field);
} else {
ipq9574_ppe_reg_read(PORT_PHY_STATUS_ADDRESS, &reg_field);
if (port_id == (PORT5 - PPE_UNIPHY_INSTANCE1))
reg_field >>= PORT_PHY_STATUS_PORT5_1_OFFSET;
else
reg_field >>= PORT_PHY_STATUS_PORT6_OFFSET;
}
return ((reg_field >> 7) & 0x1) ? 0 : 1;
}
@ -466,15 +471,22 @@ void ipq9574_10g_r_speed_set(int port, int status)
void ipq9574_uxsgmii_speed_set(int port, int speed, int duplex,
int status)
{
uint32_t uniphy_index;
uint32_t uniphy_index = 0;
/* Setting the speed only for PORT5 and PORT6 */
if (port == (PORT5 - PPE_UNIPHY_INSTANCE1))
uniphy_index = PPE_UNIPHY_INSTANCE1;
else if (port == (PORT6 - PPE_UNIPHY_INSTANCE1))
uniphy_index = PPE_UNIPHY_INSTANCE2;
else
switch(port) {
case 0:
uniphy_index = PPE_UNIPHY_INSTANCE0;
break;
case 4:
uniphy_index = PPE_UNIPHY_INSTANCE1;
break;
case 5:
uniphy_index = PPE_UNIPHY_INSTANCE2;
break;
default:
printf("Invalid port id , using UNIPHY0 as default \n");
break;
}
ppe_uniphy_usxgmii_autoneg_completed(uniphy_index);
ppe_uniphy_usxgmii_speed_set(uniphy_index, port + 1, speed);
@ -646,6 +658,128 @@ static void ipq9574_ppe_tdm_configuration(void)
ipq9574_ppe_reg_write(0xb000, 0x80000076);
}
static void ipq9574_ppe_tdm1_configuration(void)
{
ipq9574_ppe_reg_write(0xc000, 0x26);
ipq9574_ppe_reg_write(0xc010, 0x36);
ipq9574_ppe_reg_write(0xc020, 0x20);
ipq9574_ppe_reg_write(0xc030, 0x30);
ipq9574_ppe_reg_write(0xc040, 0x25);
ipq9574_ppe_reg_write(0xc050, 0x35);
ipq9574_ppe_reg_write(0xc060, 0x21);
ipq9574_ppe_reg_write(0xc070, 0x31);
ipq9574_ppe_reg_write(0xc080, 0x22);
ipq9574_ppe_reg_write(0xc090, 0x32);
ipq9574_ppe_reg_write(0xc0a0, 0x20);
ipq9574_ppe_reg_write(0xc0b0, 0x30);
ipq9574_ppe_reg_write(0xc0c0, 0x26);
ipq9574_ppe_reg_write(0xc0d0, 0x36);
ipq9574_ppe_reg_write(0xc0e0, 0x23);
ipq9574_ppe_reg_write(0xc0f0, 0x33);
ipq9574_ppe_reg_write(0xc100, 0x25);
ipq9574_ppe_reg_write(0xc110, 0x35);
ipq9574_ppe_reg_write(0xc120, 0x21);
ipq9574_ppe_reg_write(0xc130, 0x31);
ipq9574_ppe_reg_write(0xc140, 0x20);
ipq9574_ppe_reg_write(0xc150, 0x30);
ipq9574_ppe_reg_write(0xc160, 0x24);
ipq9574_ppe_reg_write(0xc170, 0x34);
ipq9574_ppe_reg_write(0xc180, 0x26);
ipq9574_ppe_reg_write(0xc190, 0x36);
ipq9574_ppe_reg_write(0xc1a0, 0x25);
ipq9574_ppe_reg_write(0xc1b0, 0x35);
ipq9574_ppe_reg_write(0xc1c0, 0x20);
ipq9574_ppe_reg_write(0xc1d0, 0x30);
ipq9574_ppe_reg_write(0xc1e0, 0x21);
ipq9574_ppe_reg_write(0xc1f0, 0x31);
ipq9574_ppe_reg_write(0xc200, 0x27);
ipq9574_ppe_reg_write(0xc210, 0x37);
ipq9574_ppe_reg_write(0xc220, 0x22);
ipq9574_ppe_reg_write(0xc230, 0x32);
ipq9574_ppe_reg_write(0xc240, 0x26);
ipq9574_ppe_reg_write(0xc250, 0x36);
ipq9574_ppe_reg_write(0xc260, 0x20);
ipq9574_ppe_reg_write(0xc270, 0x30);
ipq9574_ppe_reg_write(0xc280, 0x25);
ipq9574_ppe_reg_write(0xc290, 0x35);
ipq9574_ppe_reg_write(0xc2a0, 0x21);
ipq9574_ppe_reg_write(0xc2b0, 0x31);
ipq9574_ppe_reg_write(0xc2c0, 0x23);
ipq9574_ppe_reg_write(0xc2d0, 0x33);
ipq9574_ppe_reg_write(0xc2e0, 0x20);
ipq9574_ppe_reg_write(0xc2f0, 0x30);
ipq9574_ppe_reg_write(0xc300, 0x26);
ipq9574_ppe_reg_write(0xc310, 0x36);
ipq9574_ppe_reg_write(0xc320, 0x24);
ipq9574_ppe_reg_write(0xc330, 0x34);
ipq9574_ppe_reg_write(0xc340, 0x25);
ipq9574_ppe_reg_write(0xc350, 0x35);
ipq9574_ppe_reg_write(0xc360, 0x21);
ipq9574_ppe_reg_write(0xc370, 0x31);
ipq9574_ppe_reg_write(0xc380, 0x20);
ipq9574_ppe_reg_write(0xc390, 0x30);
ipq9574_ppe_reg_write(0xc3a0, 0x27);
ipq9574_ppe_reg_write(0xc3b0, 0x37);
ipq9574_ppe_reg_write(0xc3c0, 0x26);
ipq9574_ppe_reg_write(0xc3d0, 0x36);
ipq9574_ppe_reg_write(0xc3e0, 0x22);
ipq9574_ppe_reg_write(0xc3f0, 0x32);
ipq9574_ppe_reg_write(0xc400, 0x25);
ipq9574_ppe_reg_write(0xc410, 0x35);
ipq9574_ppe_reg_write(0xc420, 0x20);
ipq9574_ppe_reg_write(0xc430, 0x30);
ipq9574_ppe_reg_write(0xc440, 0x21);
ipq9574_ppe_reg_write(0xc450, 0x31);
ipq9574_ppe_reg_write(0xc460, 0x23);
ipq9574_ppe_reg_write(0xc470, 0x33);
ipq9574_ppe_reg_write(0xc480, 0x26);
ipq9574_ppe_reg_write(0xc490, 0x36);
ipq9574_ppe_reg_write(0xc4a0, 0x25);
ipq9574_ppe_reg_write(0xc4b0, 0x35);
ipq9574_ppe_reg_write(0xc4c0, 0x20);
ipq9574_ppe_reg_write(0xc4d0, 0x30);
ipq9574_ppe_reg_write(0xc4e0, 0x21);
ipq9574_ppe_reg_write(0xc4f0, 0x31);
ipq9574_ppe_reg_write(0xc500, 0x24);
ipq9574_ppe_reg_write(0xc510, 0x34);
ipq9574_ppe_reg_write(0xc520, 0x26);
ipq9574_ppe_reg_write(0xc530, 0x36);
ipq9574_ppe_reg_write(0xc540, 0x20);
ipq9574_ppe_reg_write(0xc550, 0x30);
ipq9574_ppe_reg_write(0xc560, 0x25);
ipq9574_ppe_reg_write(0xc570, 0x35);
ipq9574_ppe_reg_write(0xc580, 0x27);
ipq9574_ppe_reg_write(0xc590, 0x37);
ipq9574_ppe_reg_write(0xc5a0, 0x21);
ipq9574_ppe_reg_write(0xc5b0, 0x31);
ipq9574_ppe_reg_write(0xc5c0, 0x22);
ipq9574_ppe_reg_write(0xc5d0, 0x32);
ipq9574_ppe_reg_write(0xc5e0, 0x20);
ipq9574_ppe_reg_write(0xc5f0, 0x30);
ipq9574_ppe_reg_write(0xc600, 0x26);
ipq9574_ppe_reg_write(0xc610, 0x36);
ipq9574_ppe_reg_write(0xc620, 0x25);
ipq9574_ppe_reg_write(0xc630, 0x35);
ipq9574_ppe_reg_write(0xc640, 0x23);
ipq9574_ppe_reg_write(0xc650, 0x33);
ipq9574_ppe_reg_write(0xc660, 0x21);
ipq9574_ppe_reg_write(0xc670, 0x31);
ipq9574_ppe_reg_write(0xc680, 0x20);
ipq9574_ppe_reg_write(0xc690, 0x30);
ipq9574_ppe_reg_write(0xc6a0, 0x24);
ipq9574_ppe_reg_write(0xc6b0, 0x34);
ipq9574_ppe_reg_write(0xc6c0, 0x27);
ipq9574_ppe_reg_write(0xc6d0, 0x37);
ipq9574_ppe_reg_write(0xc6e0, 0x25);
ipq9574_ppe_reg_write(0xc6f0, 0x35);
ipq9574_ppe_reg_write(0xc700, 0x26);
ipq9574_ppe_reg_write(0xc710, 0x36);
ipq9574_ppe_reg_write(0xc720, 0x20);
ipq9574_ppe_reg_write(0xc730, 0x30);
ipq9574_ppe_reg_write(0xc740, 0x21);
ipq9574_ppe_reg_write(0xc750, 0x31);
ipq9574_ppe_reg_write(0xb000, 0x80000076);
}
/*
* ipq9574_ppe_queue_ac_enable
*/
@ -908,9 +1042,24 @@ void ipq9574_ppe_provision_init(void)
{
int i;
uint32_t queue;
int node, tdm_mode = 0;
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (node < 0) {
printf("\nError: ess-switch not specified in dts");
return;
}
tdm_mode = fdtdec_get_uint(gd->fdt_blob, node, "tdm_mode", 0);
if (tdm_mode < 0) {
printf("\nError:tdm mode not specified in dts assume tdm 0");
}
/* tdm/sched configuration */
ipq9574_ppe_tdm_configuration();
if (tdm_mode == 1)
ipq9574_ppe_tdm1_configuration();
else
ipq9574_ppe_tdm_configuration();
#ifdef CONFIG_IPQ9574_BRIDGED_MODE
/* Add CPU port 0 to VSI 2 */

View file

@ -119,6 +119,7 @@ union ipo_action_u {
#define IPQ9574_PORT_MUX_CTRL_INC 0x4
#define IPQ9574_PORT_MUX_CTRL_DEFAULT 0x0
#define PORT_PHY_STATUS0_ADDRESS 0x40
#define PORT_PHY_STATUS_ADDRESS 0x44
#define PORT_PHY_STATUS_PORT5_1_OFFSET 8
#define PORT_PHY_STATUS_PORT6_OFFSET 16