realtek: pcs: rtl931x: use generic CMU configuration

The current CMU setup was just copied and slightly adjusted from the
SDK, lacks functionality and logic and doesn't cover all cases we need
(same in the SDK due to multiple reasons). The existing implementation
for RTL930x covers all that and can be reused for RTL931x. Previous
patches made this generic and now we can add the remaining missing
pieces to actually use it for RTL931x. This only includes
implementations for the few variant-specific actions within the
implementation, linking them properly and calling the CMU configuration.

Drop the old CMU code for RTL931x then since it's not needed anymore.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/22198
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Jonas Jelonek 2026-02-27 08:59:00 +00:00 committed by Hauke Mehrtens
parent 7a1e66e7f1
commit 3f17f15bd5

View file

@ -3448,95 +3448,92 @@ static int rtpcs_931x_sds_cmu_page_get(enum rtpcs_sds_mode hw_mode)
}
}
static int rtpcs_931x_sds_config_cmu(struct rtpcs_serdes *sds, enum rtpcs_sds_mode hw_mode)
static int rtpcs_931x_sds_get_pll_select(struct rtpcs_serdes *sds, enum rtpcs_sds_pll_type *pll)
{
int cmu_page, pll_sel;
cmu_page = rtpcs_931x_sds_cmu_page_get(sds->hw_mode);
if (cmu_page < 0)
return cmu_page;
pll_sel = rtpcs_sds_read_bits(sds, cmu_page, 0x7, 15, 15);
if (pll_sel < 0)
return pll_sel;
*pll = (enum rtpcs_sds_pll_type)pll_sel;
return 0;
}
static int rtpcs_931x_sds_set_pll_select(struct rtpcs_serdes *sds, enum rtpcs_sds_mode hw_mode,
enum rtpcs_sds_pll_type pll)
{
struct rtpcs_serdes *even_sds = rtpcs_sds_get_even(sds);
u32 force_lc_mode_bit, force_lc_mode_val_bit;
enum rtpcs_sds_pll_type pll_type; /* SDK calls this cmu_type */
bool force_pll_spd;
int cmu_page = 0;
switch (hw_mode) {
case RTPCS_SDS_MODE_OFF:
case RTPCS_SDS_MODE_XSGMII:
case RTPCS_SDS_MODE_10GBASER:
case RTPCS_SDS_MODE_USXGMII_10GSXGMII:
case RTPCS_SDS_MODE_USXGMII_10GDXGMII:
case RTPCS_SDS_MODE_USXGMII_10GQXGMII:
case RTPCS_SDS_MODE_USXGMII_5GSXGMII:
case RTPCS_SDS_MODE_USXGMII_5GDXGMII:
case RTPCS_SDS_MODE_USXGMII_2_5GSXGMII:
return 0;
case RTPCS_SDS_MODE_QSGMII:
pll_type = RTPCS_SDS_PLL_TYPE_RING;
force_pll_spd = false;
break;
case RTPCS_SDS_MODE_1000BASEX:
pll_type = RTPCS_SDS_PLL_TYPE_RING;
force_pll_spd = false;
break;
/* case MII_1000BX100BX_AUTO:
pll_type = RTPCS_SDS_PLL_TYPE_RING;
force_pll_spd = false;
break; */
case RTPCS_SDS_MODE_SGMII:
pll_type = RTPCS_SDS_PLL_TYPE_RING;
force_pll_spd = false;
break;
case RTPCS_SDS_MODE_2500BASEX:
pll_type = RTPCS_SDS_PLL_TYPE_RING;
force_pll_spd = true;
break;
default:
pr_info("SerDes %d mode is invalid\n", sds->id);
return -EINVAL;
}
int cmu_page, ret, val;
int frc_lc_mode_bit;
cmu_page = rtpcs_931x_sds_cmu_page_get(hw_mode);
if (cmu_page < 0)
return -EINVAL;
return cmu_page;
if (sds == even_sds) {
force_lc_mode_bit = 4;
force_lc_mode_val_bit = 5;
} else {
force_lc_mode_bit = 6;
force_lc_mode_val_bit = 7;
}
/*
* bits [5:4] (even) / [7:6] (odd) are used by RTL930x as selector. The selector
* for RTL931x SerDes is in the CMU page of each SerDes, depending on the hardware
* mode.
*
* Here, the SDK calls them 'frc_lc_mode' and 'frc_lc_mode_val'. However, they don't
* seem to have any effect and thus their purpose is unknown. So just set them as
* the SDK does.
*/
val = (pll == RTPCS_SDS_PLL_TYPE_LC) ? 0x3 : 0x1;
frc_lc_mode_bit = (sds == even_sds) ? 4 : 6;
ret = rtpcs_sds_write_bits(even_sds, 0x20, 0x12, frc_lc_mode_bit + 1,
frc_lc_mode_bit, val);
if (ret < 0)
return ret;
pr_info("%s: pll_type %s cmu_page %x force_pll_spd %d even_sds %d sds %d\n",
__func__, pll_type == RTPCS_SDS_PLL_TYPE_LC ? "LC" : "ring", cmu_page,
force_pll_spd, even_sds->id, sds->id);
return rtpcs_sds_write_bits(sds, cmu_page, 0x7, 15, 15, pll);
}
if (pll_type == RTPCS_SDS_PLL_TYPE_RING) {
rtpcs_sds_write_bits(sds, cmu_page, 0x7, 15, 15, 0x0);
static int rtpcs_931x_sds_reconfigure_to_pll(struct rtpcs_serdes *sds, enum rtpcs_sds_pll_type pll)
{
enum rtpcs_sds_pll_type tmp_pll;
enum rtpcs_sds_pll_speed speed;
enum rtpcs_sds_mode tmp_mode;
int ret;
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 3, 2, 0x3);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_bit,
force_lc_mode_bit, 0x1);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_val_bit,
force_lc_mode_val_bit, 0x0);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 12, 12, 0x1);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 15, 13, force_pll_spd ? 0x1 : 0x0);
} else if (pll_type == RTPCS_SDS_PLL_TYPE_LC) {
rtpcs_sds_write_bits(sds, cmu_page, 0x7, 15, 15, 0x1);
/* assume we always reconfigure to the other PLL */
tmp_pll = (pll == RTPCS_SDS_PLL_TYPE_LC) ? RTPCS_SDS_PLL_TYPE_RING : RTPCS_SDS_PLL_TYPE_LC;
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 1, 0, 0x3);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_bit,
force_lc_mode_bit, 0x1);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_val_bit,
force_lc_mode_val_bit, 0x1);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 8, 8, 0x1);
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 11, 9, force_pll_spd ? 0x1 : 0x0);
}
ret = rtpcs_93xx_sds_get_pll_config(sds, tmp_pll, &speed);
if (ret < 0)
return ret;
return 0;
tmp_mode = sds->hw_mode;
/* turn off SerDes for reconfiguration */
ret = rtpcs_931x_sds_power(sds, false);
if (ret < 0)
return ret;
ret = rtpcs_931x_sds_set_mode(sds, RTPCS_SDS_MODE_OFF);
if (ret < 0)
return ret;
/* reconfigure to other PLL */
ret = rtpcs_93xx_sds_set_pll_config(sds, pll, speed);
if (ret < 0)
return ret;
ret = rtpcs_931x_sds_set_pll_select(sds, sds->hw_mode, pll);
if (ret < 0)
return ret;
/* turn on SerDes again */
ret = rtpcs_931x_sds_set_mode(sds, tmp_mode);
if (ret < 0)
return ret;
return rtpcs_931x_sds_power(sds, true);
}
static int rtpcs_931x_sds_cmu_band_set(struct rtpcs_serdes *sds,
@ -3865,7 +3862,7 @@ static int rtpcs_931x_setup_serdes(struct rtpcs_serdes *sds,
if (ret < 0)
return ret;
ret = rtpcs_931x_sds_config_cmu(sds, hw_mode);
ret = rtpcs_93xx_sds_config_cmu(sds, hw_mode);
if (ret < 0)
return ret;
@ -4350,6 +4347,9 @@ static const struct rtpcs_serdes_ops rtpcs_931x_sds_ops = {
.xsg_write = rtpcs_931x_sds_op_xsg_write,
.set_autoneg = rtpcs_93xx_sds_set_autoneg,
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
.get_pll_select = rtpcs_931x_sds_get_pll_select,
.set_pll_select = rtpcs_931x_sds_set_pll_select,
.reconfigure_to_pll = rtpcs_931x_sds_reconfigure_to_pll,
};
static const struct rtpcs_sds_regs rtpcs_931x_sds_regs = {