1
0
Fork 0
forked from mirror/openwrt

realtek: pcs: rtl839x: add SerDes setup functionality

Add basic SerDes setup functionality which determines and sets the
hardware mode of a SerDes, and does a SerDes reset. This is restricted
to the 10G SerDes only as the 5G SerDes are setup properly by default.
Further initialization will be needed for the modes to function properly

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21360
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
This commit is contained in:
Jonas Jelonek 2025-11-09 10:58:40 +00:00 committed by Stijn Tintel
parent 7de5ba2e98
commit afec14aee1

View file

@ -63,6 +63,8 @@
#define RTPCS_838X_INT_MODE_CTRL 0x005c
#define RTPCS_838X_PLL_CML_CTRL 0x0ff8
#define RTPCS_839X_MAC_SERDES_IF_CTRL 0x0008
#define RTPCS_93XX_MAC_LINK_SPD_BITS 4
#define RTL93XX_MODEL_NAME_INFO (0x0004)
@ -643,7 +645,6 @@ static int rtpcs_838x_setup_serdes(struct rtpcs_serdes *sds,
/* RTL839X */
__maybe_unused
static void rtpcs_839x_sds_reset(struct rtpcs_serdes *sds)
{
struct rtpcs_serdes *even_sds = rtpcs_sds_get_even(sds);
@ -682,6 +683,71 @@ static void rtpcs_839x_sds_reset(struct rtpcs_serdes *sds)
rtpcs_sds_write(odd_sds, 0x0, 0x3, 0x7106);
}
static int rtpcs_839x_sds_set_mode(struct rtpcs_serdes *sds,
enum rtpcs_sds_mode hw_mode)
{
u32 mode_val, reg, shift;
switch (hw_mode) {
case RTPCS_SDS_MODE_OFF:
mode_val = 0x0;
break;
/*
case RTPCS_SDS_MODE_100BASEX:
mode_val = 0x8;
break;
case RTPCS_SDS_MODE_1000BASEX:
case RTPCS_SDS_MODE_SGMII:
mode_val = 0x7;
break;
*/
case RTPCS_SDS_MODE_QSGMII:
mode_val = 0x6;
break;
default:
return -ENOTSUPP;
}
reg = RTPCS_839X_MAC_SERDES_IF_CTRL + (sds->id / 8) * 4;
shift = (sds->id % 8) * 4;
return regmap_write_bits(sds->ctrl->map, reg, 0xf << shift,
mode_val << shift);
}
__maybe_unused
static int rtpcs_839x_init_serdes_common(struct rtpcs_ctrl *ctrl)
{
return 0;
}
__maybe_unused
static int rtpcs_839x_setup_serdes(struct rtpcs_serdes *sds,
phy_interface_t if_mode)
{
enum rtpcs_sds_mode hw_mode;
int ret;
/* Don't touch 5G SerDes, they are already properly configured
* at startup for QSGMII. Thus, connected PHYs should work out
* of the box.
*/
if (sds->id != 8 && sds->id != 9 && sds->id != 12 && sds->id != 13)
return 0;
ret = rtpcs_sds_determine_hw_mode(sds, if_mode, &hw_mode);
if (ret < 0)
return ret;
ret = rtpcs_839x_sds_set_mode(sds, hw_mode);
if (ret < 0)
return ret;
sds->hw_mode = hw_mode;
rtpcs_839x_sds_reset(sds);
return 0;
}
/* RTL930X */
/* The access registers for SDS_MODE_SEL and the LSB for each SDS within */