From: Vladimir Oltean Date: Wed, 10 Jun 2026 15:19:42 +0000 (+0300) Subject: phy: lynx-28g: generalize protocol converter accessors X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=51c25f4b0c883c1b7eee5f8f3aa0c2245eb6351a;p=thirdparty%2Fkernel%2Flinux.git phy: lynx-28g: generalize protocol converter accessors The protocol converters on the 10G Lynx are architecturally similar, but different in layout from the 28G Lynx ones. Move lynx_pccr_read(), lynx_pccr_write(), lynx_pcvt_read() and lynx_pcvt_write() from the 28G Lynx driver to the common module, and permit each SerDes driver to provide just its own bits in order to use this common API. Currently, that just means that the direct calls to lynx_28g_get_pcvt_offset() are modified to go through the lynx->info->get_pcvt_offset() indirect function call, and similarly, lynx_28g_get_pccr() through lynx->info->get_pccr(). Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20260610151952.2141019-7-vladimir.oltean@nxp.com Signed-off-by: Vinod Koul --- diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c index 5c473d6c233ed..1de663283fafc 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-28g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c @@ -269,8 +269,6 @@ #define LYNX_28G_LANE_STOP_SLEEP_US 100 #define LYNX_28G_LANE_STOP_TIMEOUT_US 1000000 -#define lynx_28g_read lynx_read -#define lynx_28g_write lynx_write #define lynx_28g_lane_rmw lynx_lane_rmw #define lynx_28g_lane_read lynx_lane_read #define lynx_28g_lane_write lynx_lane_write @@ -785,124 +783,48 @@ static bool lynx_28g_compat_lane_supports_mode(int lane, } static const struct lynx_info lynx_info_compat = { + .get_pccr = lynx_28g_get_pccr, + .get_pcvt_offset = lynx_28g_get_pcvt_offset, .lane_supports_mode = lynx_28g_compat_lane_supports_mode, .num_lanes = LYNX_28G_NUM_LANE, }; static const struct lynx_info lynx_info_lx2160a_serdes1 = { + .get_pccr = lynx_28g_get_pccr, + .get_pcvt_offset = lynx_28g_get_pcvt_offset, .lane_supports_mode = lx2160a_serdes1_lane_supports_mode, .num_lanes = LYNX_28G_NUM_LANE, }; static const struct lynx_info lynx_info_lx2160a_serdes2 = { + .get_pccr = lynx_28g_get_pccr, + .get_pcvt_offset = lynx_28g_get_pcvt_offset, .lane_supports_mode = lx2160a_serdes2_lane_supports_mode, .num_lanes = LYNX_28G_NUM_LANE, }; static const struct lynx_info lynx_info_lx2160a_serdes3 = { + .get_pccr = lynx_28g_get_pccr, + .get_pcvt_offset = lynx_28g_get_pcvt_offset, .lane_supports_mode = lx2160a_serdes3_lane_supports_mode, .num_lanes = LYNX_28G_NUM_LANE, }; static const struct lynx_info lynx_info_lx2162a_serdes1 = { + .get_pccr = lynx_28g_get_pccr, + .get_pcvt_offset = lynx_28g_get_pcvt_offset, .lane_supports_mode = lx2162a_serdes1_lane_supports_mode, .first_lane = 4, .num_lanes = LYNX_28G_NUM_LANE, }; static const struct lynx_info lynx_info_lx2162a_serdes2 = { + .get_pccr = lynx_28g_get_pccr, + .get_pcvt_offset = lynx_28g_get_pcvt_offset, .lane_supports_mode = lx2162a_serdes2_lane_supports_mode, .num_lanes = LYNX_28G_NUM_LANE, }; -static int lynx_pccr_read(struct lynx_28g_lane *lane, enum lynx_lane_mode mode, - u32 *val) -{ - struct lynx_28g_priv *priv = lane->priv; - struct lynx_pccr pccr; - u32 tmp; - int err; - - err = lynx_28g_get_pccr(mode, lane->id, &pccr); - if (err) - return err; - - tmp = lynx_28g_read(priv, pccr.offset); - *val = (tmp >> pccr.shift) & GENMASK(pccr.width - 1, 0); - - return 0; -} - -static int lynx_pccr_write(struct lynx_28g_lane *lane, - enum lynx_lane_mode lane_mode, u32 val) -{ - struct lynx_28g_priv *priv = lane->priv; - struct lynx_pccr pccr; - u32 old, tmp, mask; - int err; - - err = lynx_28g_get_pccr(lane_mode, lane->id, &pccr); - if (err) - return err; - - old = lynx_28g_read(priv, pccr.offset); - mask = GENMASK(pccr.width - 1, 0) << pccr.shift; - tmp = (old & ~mask) | (val << pccr.shift); - lynx_28g_write(priv, pccr.offset, tmp); - - dev_dbg(&lane->phy->dev, "PCCR@0x%x: 0x%x -> 0x%x\n", - pccr.offset, old, tmp); - - return 0; -} - -static int lynx_pcvt_read(struct lynx_28g_lane *lane, - enum lynx_lane_mode lane_mode, int cr, u32 *val) -{ - struct lynx_28g_priv *priv = lane->priv; - int offset; - - offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode); - if (offset < 0) - return offset; - - *val = lynx_28g_read(priv, offset + cr); - - return 0; -} - -static int lynx_pcvt_write(struct lynx_28g_lane *lane, - enum lynx_lane_mode lane_mode, int cr, u32 val) -{ - struct lynx_28g_priv *priv = lane->priv; - int offset; - - offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode); - if (offset < 0) - return offset; - - lynx_28g_write(priv, offset + cr, val); - - return 0; -} - -static int lynx_pcvt_rmw(struct lynx_28g_lane *lane, - enum lynx_lane_mode lane_mode, - int cr, u32 val, u32 mask) -{ - int err; - u32 tmp; - - err = lynx_pcvt_read(lane, lane_mode, cr, &tmp); - if (err) - return err; - - tmp &= ~mask; - tmp |= val; - - return lynx_pcvt_write(lane, lane_mode, cr, tmp); -} - static void lynx_28g_lane_remap_pll(struct lynx_lane *lane, enum lynx_lane_mode lane_mode) { diff --git a/drivers/phy/freescale/phy-fsl-lynx-core.c b/drivers/phy/freescale/phy-fsl-lynx-core.c index 5e5bcaa54d09e..f49d594622cba 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-core.c +++ b/drivers/phy/freescale/phy-fsl-lynx-core.c @@ -87,5 +87,95 @@ struct lynx_pll *lynx_pll_get(struct lynx_priv *priv, enum lynx_lane_mode mode) } EXPORT_SYMBOL_NS_GPL(lynx_pll_get, "PHY_FSL_LYNX"); +int lynx_pccr_read(struct lynx_lane *lane, enum lynx_lane_mode mode, u32 *val) +{ + struct lynx_priv *priv = lane->priv; + struct lynx_pccr pccr; + u32 tmp; + int err; + + err = priv->info->get_pccr(mode, lane->id, &pccr); + if (err) + return err; + + tmp = lynx_read(priv, pccr.offset); + *val = (tmp >> pccr.shift) & GENMASK(pccr.width - 1, 0); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(lynx_pccr_read, "PHY_FSL_LYNX"); + +int lynx_pccr_write(struct lynx_lane *lane, enum lynx_lane_mode mode, u32 val) +{ + struct lynx_priv *priv = lane->priv; + struct lynx_pccr pccr; + u32 old, tmp, mask; + int err; + + err = priv->info->get_pccr(mode, lane->id, &pccr); + if (err) + return err; + + old = lynx_read(priv, pccr.offset); + mask = GENMASK(pccr.width - 1, 0) << pccr.shift; + tmp = (old & ~mask) | (val << pccr.shift); + lynx_write(priv, pccr.offset, tmp); + + dev_dbg(&lane->phy->dev, "PCCR@0x%x: 0x%x -> 0x%x\n", + pccr.offset, old, tmp); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(lynx_pccr_write, "PHY_FSL_LYNX"); + +int lynx_pcvt_read(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr, + u32 *val) +{ + struct lynx_priv *priv = lane->priv; + int offset; + + offset = priv->info->get_pcvt_offset(lane->id, mode); + if (offset < 0) + return offset; + + *val = lynx_read(priv, offset + cr); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(lynx_pcvt_read, "PHY_FSL_LYNX"); + +int lynx_pcvt_write(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr, + u32 val) +{ + struct lynx_priv *priv = lane->priv; + int offset; + + offset = priv->info->get_pcvt_offset(lane->id, mode); + if (offset < 0) + return offset; + + lynx_write(priv, offset + cr, val); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(lynx_pcvt_write, "PHY_FSL_LYNX"); + +int lynx_pcvt_rmw(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr, + u32 val, u32 mask) +{ + int err; + u32 tmp; + + err = lynx_pcvt_read(lane, mode, cr, &tmp); + if (err) + return err; + + tmp &= ~mask; + tmp |= val; + + return lynx_pcvt_write(lane, mode, cr, tmp); +} +EXPORT_SYMBOL_NS_GPL(lynx_pcvt_rmw, "PHY_FSL_LYNX"); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Freescale Lynx SerDes core functionality"); diff --git a/drivers/phy/freescale/phy-fsl-lynx-core.h b/drivers/phy/freescale/phy-fsl-lynx-core.h index b726ff21972b0..5cd86c9543cb8 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-core.h +++ b/drivers/phy/freescale/phy-fsl-lynx-core.h @@ -4,6 +4,7 @@ #ifndef _PHY_FSL_LYNX_CORE_H #define _PHY_FSL_LYNX_CORE_H +#include #include #include @@ -37,6 +38,9 @@ struct lynx_lane { }; struct lynx_info { + int (*get_pccr)(enum lynx_lane_mode lane_mode, int lane, + struct lynx_pccr *pccr); + int (*get_pcvt_offset)(int lane, enum lynx_lane_mode mode); bool (*lane_supports_mode)(int lane, enum lynx_lane_mode mode); int first_lane; int num_lanes; @@ -87,4 +91,13 @@ bool lynx_lane_supports_mode(struct lynx_lane *lane, enum lynx_lane_mode mode); struct lynx_pll *lynx_pll_get(struct lynx_priv *priv, enum lynx_lane_mode mode); +int lynx_pccr_read(struct lynx_lane *lane, enum lynx_lane_mode mode, u32 *val); +int lynx_pccr_write(struct lynx_lane *lane, enum lynx_lane_mode mode, u32 val); +int lynx_pcvt_read(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr, + u32 *val); +int lynx_pcvt_write(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr, + u32 val); +int lynx_pcvt_rmw(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr, + u32 val, u32 mask); + #endif