#define RTPCS_931X_SDS_MAIN_AMP_MASK GENMASK(9, 5)
#define RTPCS_931X_SDS_POST_AMP_MASK GENMASK(14, 10)
+enum rtpcs_sds_type {
+ RTPCS_SDS_TYPE_UNKNOWN,
+ RTPCS_SDS_TYPE_5G,
+ RTPCS_SDS_TYPE_10G,
+};
+
enum rtpcs_sds_mode {
RTPCS_SDS_MODE_OFF = 0,
struct rtpcs_ctrl *ctrl;
const struct rtpcs_sds_ops *ops;
const struct rtpcs_sds_regs *regs;
+ enum rtpcs_sds_type type;
enum rtpcs_sds_mode hw_mode;
u8 id;
u8 num_of_links;
static int rtpcs_838x_sds_probe(struct rtpcs_serdes *sds)
{
+ sds->type = RTPCS_SDS_TYPE_5G;
return 0;
}
struct rtpcs_serdes *even_sds = rtpcs_sds_get_even(sds);
struct rtpcs_serdes *odd_sds = rtpcs_sds_get_odd(sds);
- bool is_10g_sds = (sds->id == 8 || sds->id == 9 || sds->id == 12 ||
- sds->id == 13);
-
/* FIXME: The reset sequence seems to break some of the 5G SerDes
* though the SDK is calling it for all SerDes during init. Until
* this is solved, skip reset.
*/
- if (!is_10g_sds)
+ if (sds->type == RTPCS_SDS_TYPE_5G)
return;
- if (is_10g_sds) {
+ if (sds->type == RTPCS_SDS_TYPE_10G) {
rtpcs_sds_write_bits(odd_sds, 0x2f, 0x1d, 3, 0, 0x5);
msleep(500);
rtpcs_sds_write_bits(odd_sds, 0x2f, 0x1d, 3, 0, 0xf);
{
bool is_even = sds->id % 2 == 0;
+ if (sds->id == 8 || sds->id == 9 || sds->id == 12 || sds->id == 13)
+ sds->type = RTPCS_SDS_TYPE_10G;
+ else
+ sds->type = RTPCS_SDS_TYPE_5G;
+
/*
* This function is quite "mystic". It has been taken over from the vendor SDK function
* rtl839x_serdes_patch_init(). There is not much documentation about it but one could
* lookup the fields from the field headers. The 5G SerDes seem to work out of the box
* so only setup the 10G SerDes for now.
*/
- if (sds->id != 8 && sds->id != 9 && sds->id != 12 && sds->id != 13)
- return;
+ if (sds->type == RTPCS_SDS_TYPE_5G)
+ return 0;
/* Part 1: register setup */
rtpcs_sds_write(sds, 0x2e, 0x0, 0x5800);
rtpcs_sds_write_bits(sds, 0x2e, 0x13, 9, 9, 0x0000);
rtpcs_sds_write_bits(sds, 0x2e, 0x13, 3, 0, 0x0008);
rtpcs_sds_write_bits(sds, 0x2e, 0x13, 8, 5, 0x0008);
+
+ return 0;
}
static int rtpcs_839x_init(struct rtpcs_ctrl *ctrl)
{
+ /* reset all SerDes once after patching has been applied before */
for (int sds_id = 0; sds_id < ctrl->cfg->serdes_count; sds_id++)
rtpcs_839x_sds_reset(&ctrl->serdes[sds_id]);
* 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)
+ if (sds->type == RTPCS_SDS_TYPE_5G)
return 0;
ret = rtpcs_839x_sds_set_mode(sds, hw_mode);
u8 sds_id = sds->id;
int submode, ret;
- if (sds_id < 2 || sds_id > 9) {
+ if (sds->type != RTPCS_SDS_TYPE_10G) {
pr_err("%s: SerDes %u doesn't support USXGMII submode\n", __func__, sds_id);
return -ENOTSUPP;
}
{
u8 sds_id = sds->id;
- if (sds_id < 2 || sds_id > 9) {
+ if (sds->type != RTPCS_SDS_TYPE_10G) {
pr_err("%s: SerDes %u doesn't support USXGMII submode\n", __func__, sds_id);
return -ENOTSUPP;
}
apply_fn = is_xsgmii ? rtpcs_sds_apply_config_xsg : rtpcs_sds_apply_config;
if (hw_mode == RTPCS_SDS_MODE_QSGMII) {
- if (sds->id >= 2)
+ if (sds->type != RTPCS_SDS_TYPE_5G)
return -ENOTSUPP;
return rtpcs_sds_apply_config(sds, rtpcs_930x_sds_cfg_5g_qsgmii,
static int rtpcs_930x_sds_probe(struct rtpcs_serdes *sds)
{
+ if (sds->id < 2)
+ sds->type = RTPCS_SDS_TYPE_5G;
+ else if (sds->id <= 9)
+ sds->type = RTPCS_SDS_TYPE_10G;
+ else
+ sds->type = RTPCS_SDS_TYPE_UNKNOWN;
+
return 0;
}
static void rtpcs_931x_sds_rx_reset(struct rtpcs_serdes *sds)
{
- if (sds->id < 2)
+ if (sds->type != RTPCS_SDS_TYPE_10G)
return;
rtpcs_sds_write(sds, 0x2e, 0x12, 0x2740);
{
const struct rtpcs_sds_tx_config *tx_cfg;
- if (sds->id < 2)
+ if (sds->type != RTPCS_SDS_TYPE_10G)
return 0;
switch (sds_media) {
static int rtpcs_931x_sds_probe(struct rtpcs_serdes *sds)
{
+ if (sds->id >= 2)
+ sds->type = RTPCS_SDS_TYPE_10G;
+ else
+ sds->type = RTPCS_SDS_TYPE_UNKNOWN;
+
return 0;
}