mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 09:42:19 +03:00
nvethernet: Set MGBE TX, TX_PCS and MAC_DIV clks
There are three clks for MGBE which needs to be set based on UPHY GBE mode and PHY line rate. o MGBE_MAC_DIV_CLK will be set based on PHY line rate o MGBE_MAC_TX/TX_PCS clks will be set based on UPHY GBE mode Below are the settings - UPHY GBE mode = 10G: =================== Possible MAC working rates: 10G/5G/2.5G 1) MAC DIVISOR: 312.5MHz, 312.5/2MHZ and 312.5/4MHz 2) TX CLK: 644.5MHZ 3) TX PCS_CLK: 156.5MHz UPHY GBE mode = 5G: ================== Possible MAC working rates: 5G/2.5G 1) MAC DIVISOR: 312.5/2MHz and 312.5/4MHz 2) TX CLK: 322.2MHZ 3) TX PCS_CLK: 78.125MHz Bug 200739493 Change-Id: Ie6b21f87d2077b8be621a32b2034b4eff1eb391e Signed-off-by: Bhadram Varka <vbhadram@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2541313 Reviewed-by: Rakesh Goyal <rgoyal@nvidia.com> Reviewed-by: svcacv <svcacv@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Narayan Reddy <narayanr@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Revanth Kumar Uppala
parent
8553696ea7
commit
537d6aa16b
112
drivers/net/ethernet/nvidia/nvethernet/ether_linux.c
Executable file → Normal file
112
drivers/net/ethernet/nvidia/nvethernet/ether_linux.c
Executable file → Normal file
@@ -350,6 +350,8 @@ static void ether_disable_clks(struct ether_priv_data *pdata)
|
||||
*/
|
||||
static int ether_enable_mgbe_clks(struct ether_priv_data *pdata)
|
||||
{
|
||||
unsigned int uphy_gbe_mode = pdata->osi_core->uphy_gbe_mode;
|
||||
unsigned long rate = 0;
|
||||
int ret;
|
||||
|
||||
if (!IS_ERR_OR_NULL(pdata->rx_m_clk)) {
|
||||
@@ -381,6 +383,17 @@ static int ether_enable_mgbe_clks(struct ether_priv_data *pdata)
|
||||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(pdata->tx_clk)) {
|
||||
if (uphy_gbe_mode == OSI_ENABLE)
|
||||
rate = ETHER_MGBE_TX_CLK_USXGMII_10G;
|
||||
else
|
||||
rate = ETHER_MGBE_TX_CLK_USXGMII_5G;
|
||||
|
||||
ret = clk_set_rate(pdata->tx_clk, rate);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev, "failed to set MGBE tx_clk rate\n");
|
||||
goto err_tx;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(pdata->tx_clk);
|
||||
if (ret < 0) {
|
||||
goto err_tx;
|
||||
@@ -388,6 +401,18 @@ static int ether_enable_mgbe_clks(struct ether_priv_data *pdata)
|
||||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(pdata->tx_pcs_clk)) {
|
||||
if (uphy_gbe_mode == OSI_ENABLE)
|
||||
rate = ETHER_MGBE_TX_PCS_CLK_USXGMII_10G;
|
||||
else
|
||||
rate = ETHER_MGBE_TX_PCS_CLK_USXGMII_5G;
|
||||
|
||||
ret = clk_set_rate(pdata->tx_pcs_clk, rate);
|
||||
if (ret < 0) {
|
||||
dev_err(pdata->dev,
|
||||
"failed to set MGBE tx_pcs_clk rate\n");
|
||||
goto err_tx_pcs;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(pdata->tx_pcs_clk);
|
||||
if (ret < 0) {
|
||||
goto err_tx_pcs;
|
||||
@@ -649,6 +674,64 @@ int ether_conf_eee(struct ether_priv_data *pdata, unsigned int tx_lpi_enable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set MGBE MAC_DIV/TX clk rate
|
||||
*
|
||||
* Algorithm: Sets MGBE MAC_DIV clk_rate which will be MAC_TX/MACSEC clk rate.
|
||||
*
|
||||
* @param[in] mac_div_clk: Pointer to MAC_DIV clk.
|
||||
* @param[in] speed: PHY line speed.
|
||||
*/
|
||||
static inline void ether_set_mgbe_mac_div_rate(struct clk *mac_div_clk,
|
||||
int speed)
|
||||
{
|
||||
unsigned long rate;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_2500:
|
||||
rate = ETHER_MGBE_MAC_DIV_RATE_2_5G;
|
||||
break;
|
||||
case SPEED_5000:
|
||||
rate = ETHER_MGBE_MAC_DIV_RATE_5G;
|
||||
break;
|
||||
case SPEED_10000:
|
||||
default:
|
||||
rate = ETHER_MGBE_MAC_DIV_RATE_10G;
|
||||
break;
|
||||
}
|
||||
|
||||
if (clk_set_rate(mac_div_clk, rate) < 0)
|
||||
pr_err("%s(): failed to set mac_div_clk rate\n", __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set EQOS TX clk rate
|
||||
*
|
||||
* @param[in] tx_clk: Pointer to Tx clk.
|
||||
* @param[in] speed: PHY line speed.
|
||||
*/
|
||||
static inline void ether_set_eqos_tx_clk(struct clk *tx_clk,
|
||||
int speed)
|
||||
{
|
||||
unsigned long rate;
|
||||
|
||||
switch (speed) {
|
||||
case SPEED_10:
|
||||
rate = ETHER_EQOS_TX_CLK_10M;
|
||||
break;
|
||||
case SPEED_100:
|
||||
rate = ETHER_EQOS_TX_CLK_100M;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
default:
|
||||
rate = ETHER_EQOS_TX_CLK_1000M;
|
||||
break;
|
||||
}
|
||||
|
||||
if (clk_set_rate(tx_clk, rate) < 0)
|
||||
pr_err("%s(): failed to set eqos tx_clk rate\n", __func__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adjust link call back
|
||||
*
|
||||
@@ -736,16 +819,19 @@ static void ether_adjust_link(struct net_device *dev)
|
||||
}
|
||||
|
||||
if (speed_changed) {
|
||||
clk_set_rate(pdata->tx_clk,
|
||||
(phydev->speed == SPEED_10) ? 2500 * 1000 :
|
||||
(phydev->speed ==
|
||||
SPEED_100) ? 25000 * 1000 : 125000 * 1000);
|
||||
if (phydev->speed != SPEED_10) {
|
||||
ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION;
|
||||
if (osi_handle_ioctl(pdata->osi_core, &ioctl_data) <
|
||||
0) {
|
||||
dev_err(pdata->dev,
|
||||
"failed to do pad caliberation\n");
|
||||
if (pdata->osi_core->mac == OSI_MAC_HW_MGBE) {
|
||||
ether_set_mgbe_mac_div_rate(pdata->mac_div_clk,
|
||||
phydev->speed);
|
||||
} else {
|
||||
ether_set_eqos_tx_clk(pdata->tx_clk,
|
||||
phydev->speed);
|
||||
if (phydev->speed != SPEED_10) {
|
||||
ioctl_data.cmd = OSI_CMD_PAD_CALIBRATION;
|
||||
if (osi_handle_ioctl(pdata->osi_core,
|
||||
&ioctl_data) < 0) {
|
||||
dev_err(pdata->dev,
|
||||
"failed to do pad caliberation\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5227,6 +5313,12 @@ static int ether_parse_dt(struct ether_priv_data *pdata)
|
||||
"failed to read UPHY GBE mode - default to 10G\n");
|
||||
osi_core->uphy_gbe_mode = OSI_ENABLE;
|
||||
}
|
||||
|
||||
if ((osi_core->uphy_gbe_mode != OSI_ENABLE) &&
|
||||
(osi_core->uphy_gbe_mode != OSI_DISABLE)) {
|
||||
dev_err(dev, "Invalid UPHY GBE mode - default to 10G\n");
|
||||
osi_core->uphy_gbe_mode = OSI_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable VLAN strip by default */
|
||||
|
||||
Reference in New Issue
Block a user