[SRU][J:linux-bluefield][PATCH v1 1/1] UBUNTU: SAUCE: mlxbf-gige: Support workaround for MDIO GPIO degradation bug
Asmaa Mnebhi
asmaa at nvidia.com
Wed Nov 6 14:41:53 UTC 2024
BugLink: https://bugs.launchpad.net/bugs/2086791
Once the BF3 MDIO clock is enabled by software it is expected and intended
for it to keep toggling. BF3 has a hardware GPIO bug where constant
toggling at "high frequencies" will lead to GPIO degradation.
A workaround is to lower down the clock frequency.
That will increase the "life expectation" of the GPIO.
The lowest possible frequency we can achieve is 1.09Mhz by setting mdio_period = 0xFF.
Signed-off-by: Asmaa Mnebhi <asmaa at nvidia.com>
Reviewed-by: David Thompson <davthompson at nvidia.com>
---
.../mellanox/mlxbf_gige/mlxbf_gige_mdio.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
index 7ac06fd31011..965acdf4798f 100644
--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
+++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c
@@ -96,6 +96,7 @@ static struct mlxbf_gige_mdio_gw mlxbf_gige_mdio_gw_t[] = {
#define MLXBF_GIGE_MDIO_FREQ_REFERENCE 156250000ULL
#define MLXBF_GIGE_MDIO_COREPLL_CONST 16384ULL
#define MLXBF_GIGE_MDC_CLK_NS 400
+#define MLXBF_GIGE_BF3_MDIO_PERIOD 0xFF
#define MLXBF_GIGE_MDIO_PLL_I1CLK_REG1 0x4
#define MLXBF_GIGE_MDIO_PLL_I1CLK_REG2 0x8
#define MLXBF_GIGE_MDIO_CORE_F_SHIFT 0
@@ -178,11 +179,16 @@ static u8 mdio_period_map(struct mlxbf_gige *priv)
u8 mdio_period;
u64 i1clk;
- i1clk = calculate_i1clk(priv);
-
- mdio_period = div_u64((MLXBF_GIGE_MDC_CLK_NS >> 1) * i1clk, 1000000000) - 1;
-
- return mdio_period;
+ /* The MDIO clock frequency need to be set as low as possible to avoid
+ * a BF3 hardware GPIO degradation. The lowest frequency can be achieved
+ * by setting MdioPeriod = 0xFF.
+ */
+ if (priv->hw_version == MLXBF_GIGE_BLUEFIELD3) {
+ mdio_period = MLXBF_GIGE_BF3_MDIO_PERIOD;
+ } else {
+ i1clk = calculate_i1clk(priv);
+ mdio_period = MLXBF_GIGE_MDC_CLK_NS/2 * i1clk / 1000000000 - 1;
+ }
}
static u32 mlxbf_gige_mdio_create_cmd(struct mlxbf_gige_mdio_gw *mdio_gw, u16 data, int phy_add,
--
2.30.1
More information about the kernel-team
mailing list