Skip to content

Commit 3f17f15

Browse files
jonasjelonekhauke
authored andcommitted
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: openwrt/openwrt#22198 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
1 parent 7a1e66e commit 3f17f15

1 file changed

Lines changed: 77 additions & 77 deletions

File tree

target/linux/realtek/files-6.12/drivers/net/pcs/pcs-rtl-otto.c

Lines changed: 77 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -3448,95 +3448,92 @@ static int rtpcs_931x_sds_cmu_page_get(enum rtpcs_sds_mode hw_mode)
34483448
}
34493449
}
34503450

3451-
static int rtpcs_931x_sds_config_cmu(struct rtpcs_serdes *sds, enum rtpcs_sds_mode hw_mode)
3451+
static int rtpcs_931x_sds_get_pll_select(struct rtpcs_serdes *sds, enum rtpcs_sds_pll_type *pll)
3452+
{
3453+
int cmu_page, pll_sel;
3454+
3455+
cmu_page = rtpcs_931x_sds_cmu_page_get(sds->hw_mode);
3456+
if (cmu_page < 0)
3457+
return cmu_page;
3458+
3459+
pll_sel = rtpcs_sds_read_bits(sds, cmu_page, 0x7, 15, 15);
3460+
if (pll_sel < 0)
3461+
return pll_sel;
3462+
3463+
*pll = (enum rtpcs_sds_pll_type)pll_sel;
3464+
return 0;
3465+
}
3466+
3467+
static int rtpcs_931x_sds_set_pll_select(struct rtpcs_serdes *sds, enum rtpcs_sds_mode hw_mode,
3468+
enum rtpcs_sds_pll_type pll)
34523469
{
34533470
struct rtpcs_serdes *even_sds = rtpcs_sds_get_even(sds);
3454-
u32 force_lc_mode_bit, force_lc_mode_val_bit;
3455-
enum rtpcs_sds_pll_type pll_type; /* SDK calls this cmu_type */
3456-
bool force_pll_spd;
3457-
int cmu_page = 0;
3471+
int cmu_page, ret, val;
3472+
int frc_lc_mode_bit;
34583473

3459-
switch (hw_mode) {
3460-
case RTPCS_SDS_MODE_OFF:
3461-
case RTPCS_SDS_MODE_XSGMII:
3462-
case RTPCS_SDS_MODE_10GBASER:
3463-
case RTPCS_SDS_MODE_USXGMII_10GSXGMII:
3464-
case RTPCS_SDS_MODE_USXGMII_10GDXGMII:
3465-
case RTPCS_SDS_MODE_USXGMII_10GQXGMII:
3466-
case RTPCS_SDS_MODE_USXGMII_5GSXGMII:
3467-
case RTPCS_SDS_MODE_USXGMII_5GDXGMII:
3468-
case RTPCS_SDS_MODE_USXGMII_2_5GSXGMII:
3469-
return 0;
3474+
cmu_page = rtpcs_931x_sds_cmu_page_get(hw_mode);
3475+
if (cmu_page < 0)
3476+
return cmu_page;
34703477

3471-
case RTPCS_SDS_MODE_QSGMII:
3472-
pll_type = RTPCS_SDS_PLL_TYPE_RING;
3473-
force_pll_spd = false;
3474-
break;
3478+
/*
3479+
* bits [5:4] (even) / [7:6] (odd) are used by RTL930x as selector. The selector
3480+
* for RTL931x SerDes is in the CMU page of each SerDes, depending on the hardware
3481+
* mode.
3482+
*
3483+
* Here, the SDK calls them 'frc_lc_mode' and 'frc_lc_mode_val'. However, they don't
3484+
* seem to have any effect and thus their purpose is unknown. So just set them as
3485+
* the SDK does.
3486+
*/
3487+
val = (pll == RTPCS_SDS_PLL_TYPE_LC) ? 0x3 : 0x1;
3488+
frc_lc_mode_bit = (sds == even_sds) ? 4 : 6;
3489+
ret = rtpcs_sds_write_bits(even_sds, 0x20, 0x12, frc_lc_mode_bit + 1,
3490+
frc_lc_mode_bit, val);
3491+
if (ret < 0)
3492+
return ret;
34753493

3476-
case RTPCS_SDS_MODE_1000BASEX:
3477-
pll_type = RTPCS_SDS_PLL_TYPE_RING;
3478-
force_pll_spd = false;
3479-
break;
3494+
return rtpcs_sds_write_bits(sds, cmu_page, 0x7, 15, 15, pll);
3495+
}
34803496

3481-
/* case MII_1000BX100BX_AUTO:
3482-
pll_type = RTPCS_SDS_PLL_TYPE_RING;
3483-
force_pll_spd = false;
3484-
break; */
3497+
static int rtpcs_931x_sds_reconfigure_to_pll(struct rtpcs_serdes *sds, enum rtpcs_sds_pll_type pll)
3498+
{
3499+
enum rtpcs_sds_pll_type tmp_pll;
3500+
enum rtpcs_sds_pll_speed speed;
3501+
enum rtpcs_sds_mode tmp_mode;
3502+
int ret;
34853503

3486-
case RTPCS_SDS_MODE_SGMII:
3487-
pll_type = RTPCS_SDS_PLL_TYPE_RING;
3488-
force_pll_spd = false;
3489-
break;
3504+
/* assume we always reconfigure to the other PLL */
3505+
tmp_pll = (pll == RTPCS_SDS_PLL_TYPE_LC) ? RTPCS_SDS_PLL_TYPE_RING : RTPCS_SDS_PLL_TYPE_LC;
34903506

3491-
case RTPCS_SDS_MODE_2500BASEX:
3492-
pll_type = RTPCS_SDS_PLL_TYPE_RING;
3493-
force_pll_spd = true;
3494-
break;
3507+
ret = rtpcs_93xx_sds_get_pll_config(sds, tmp_pll, &speed);
3508+
if (ret < 0)
3509+
return ret;
34953510

3496-
default:
3497-
pr_info("SerDes %d mode is invalid\n", sds->id);
3498-
return -EINVAL;
3499-
}
3511+
tmp_mode = sds->hw_mode;
35003512

3501-
cmu_page = rtpcs_931x_sds_cmu_page_get(hw_mode);
3502-
if (cmu_page < 0)
3503-
return -EINVAL;
3513+
/* turn off SerDes for reconfiguration */
3514+
ret = rtpcs_931x_sds_power(sds, false);
3515+
if (ret < 0)
3516+
return ret;
35043517

3505-
if (sds == even_sds) {
3506-
force_lc_mode_bit = 4;
3507-
force_lc_mode_val_bit = 5;
3508-
} else {
3509-
force_lc_mode_bit = 6;
3510-
force_lc_mode_val_bit = 7;
3511-
}
3518+
ret = rtpcs_931x_sds_set_mode(sds, RTPCS_SDS_MODE_OFF);
3519+
if (ret < 0)
3520+
return ret;
35123521

3513-
pr_info("%s: pll_type %s cmu_page %x force_pll_spd %d even_sds %d sds %d\n",
3514-
__func__, pll_type == RTPCS_SDS_PLL_TYPE_LC ? "LC" : "ring", cmu_page,
3515-
force_pll_spd, even_sds->id, sds->id);
3516-
3517-
if (pll_type == RTPCS_SDS_PLL_TYPE_RING) {
3518-
rtpcs_sds_write_bits(sds, cmu_page, 0x7, 15, 15, 0x0);
3519-
3520-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 3, 2, 0x3);
3521-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_bit,
3522-
force_lc_mode_bit, 0x1);
3523-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_val_bit,
3524-
force_lc_mode_val_bit, 0x0);
3525-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 12, 12, 0x1);
3526-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 15, 13, force_pll_spd ? 0x1 : 0x0);
3527-
} else if (pll_type == RTPCS_SDS_PLL_TYPE_LC) {
3528-
rtpcs_sds_write_bits(sds, cmu_page, 0x7, 15, 15, 0x1);
3529-
3530-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 1, 0, 0x3);
3531-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_bit,
3532-
force_lc_mode_bit, 0x1);
3533-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, force_lc_mode_val_bit,
3534-
force_lc_mode_val_bit, 0x1);
3535-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 8, 8, 0x1);
3536-
rtpcs_sds_write_bits(even_sds, 0x20, 0x12, 11, 9, force_pll_spd ? 0x1 : 0x0);
3537-
}
3522+
/* reconfigure to other PLL */
3523+
ret = rtpcs_93xx_sds_set_pll_config(sds, pll, speed);
3524+
if (ret < 0)
3525+
return ret;
35383526

3539-
return 0;
3527+
ret = rtpcs_931x_sds_set_pll_select(sds, sds->hw_mode, pll);
3528+
if (ret < 0)
3529+
return ret;
3530+
3531+
/* turn on SerDes again */
3532+
ret = rtpcs_931x_sds_set_mode(sds, tmp_mode);
3533+
if (ret < 0)
3534+
return ret;
3535+
3536+
return rtpcs_931x_sds_power(sds, true);
35403537
}
35413538

35423539
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,
38653862
if (ret < 0)
38663863
return ret;
38673864

3868-
ret = rtpcs_931x_sds_config_cmu(sds, hw_mode);
3865+
ret = rtpcs_93xx_sds_config_cmu(sds, hw_mode);
38693866
if (ret < 0)
38703867
return ret;
38713868

@@ -4350,6 +4347,9 @@ static const struct rtpcs_serdes_ops rtpcs_931x_sds_ops = {
43504347
.xsg_write = rtpcs_931x_sds_op_xsg_write,
43514348
.set_autoneg = rtpcs_93xx_sds_set_autoneg,
43524349
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
4350+
.get_pll_select = rtpcs_931x_sds_get_pll_select,
4351+
.set_pll_select = rtpcs_931x_sds_set_pll_select,
4352+
.reconfigure_to_pll = rtpcs_931x_sds_reconfigure_to_pll,
43534353
};
43544354

43554355
static const struct rtpcs_sds_regs rtpcs_931x_sds_regs = {

0 commit comments

Comments
 (0)