return (val < 0 ? BIT(sign_bit) : 0) | (abs(val) & GENMASK(sign_bit - 1, 0));
}
+static u32 rtpcs_gray_to_binary(u32 gray_code)
+{
+ u32 binary = gray_code;
+
+ gray_code &= 0x1f; /* only lower 5 bits */
+ while (gray_code >>= 1)
+ binary ^= gray_code;
+
+ return binary;
+}
+
/*
* Basic helpers
*
return rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0x16, 14, 10, leq_gray);
}
-static u32 rtpcs_930x_sds_rxcal_gray_to_binary(u32 gray_code)
-{
- u32 binary = gray_code;
-
- gray_code &= 0x1f; /* only lower 5 bits */
- while (gray_code >>= 1)
- binary ^= gray_code;
-
- return binary;
-}
-
static int rtpcs_930x_sds_rxcal_leq_get_coef(struct rtpcs_serdes *sds)
{
int bin, gray, manual, ret;
if (gray < 0)
return gray;
- bin = rtpcs_930x_sds_rxcal_gray_to_binary(gray);
+ bin = rtpcs_gray_to_binary(gray);
manual = rtpcs_sds_read_bits(sds, PAGE_ANA_10G, 0x18, 15, 15);
if (manual < 0)
return rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0xd, 6, 2, gain);
}
+static int rtpcs_931x_sds_rxeq_leq_get_coef(struct rtpcs_serdes *sds)
+{
+ int ret, gray;
+
+ ret = rtpcs_931x_sds_set_debug(sds, 0x1);
+ if (ret < 0)
+ return ret;
+
+ gray = rtpcs_sds_read_bits(sds, PAGE_WDIG, 0x14, 7, 3);
+ if (gray < 0)
+ return gray;
+
+ return rtpcs_gray_to_binary(gray);
+}
+
static int rtpcs_931x_sds_rxeq_tap_set_value(struct rtpcs_serdes *sds, unsigned int tap_id,
int tap_even, int tap_odd)
{
*/
static void rtpcs_931x_sds_rxcal_leq_adapt(struct rtpcs_serdes *sds)
{
+ dev_dbg(sds->ctrl->dev, "SerDes %u PHY-attached RX calibration...\n", sds->id);
+
rtpcs_931x_sds_rxeq_leq_set_coef(sds, 0);
rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0xd, 1, 0, 0x0); /* undocumented */
rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0xd, 13, 13, 0x0); /* undocumented */
msleep(10);
rtpcs_931x_sds_rxeq_leq_set_adapt(sds, true);
msleep(100);
+
+ dev_dbg(sds->ctrl->dev, "SerDes %u LEQ = %#x\n", sds->id,
+ rtpcs_931x_sds_rxeq_leq_get_coef(sds));
}
/*
unsigned int vth_p = 0, vth_n = 0;
int i, symerr = -1;
+ dev_dbg(dev, "SerDes %u fiber RX calibration...\n", sds->id);
/* per-port calibration offset in the SDK, kept 0 here */
rtpcs_sds_write_bits(sds, PAGE_ANA_10G, 0xc, 14, 10, 0x0);
if (rtpcs_931x_sds_rxeq_vth_get(sds, &vth_p, &vth_n) < 0)
dev_warn(dev, "SerDes %u failed to read auto-adapted VTH\n", sds->id);
+ dev_dbg(dev, "SerDes %u VTH = %#x/%#x\n", sds->id, vth_p, vth_n);
+
rtpcs_931x_sds_rxeq_tap_set_value(sds, 0, 31, 0);
rtpcs_931x_sds_rxeq_tap_set_adapt(sds, 0, false);
rtpcs_931x_sds_rxeq_vth_set_value(sds, vth_p, vth_n);
rtpcs_931x_sds_clear_symerr(sds, RTPCS_SDS_MODE_10GBASER);
msleep(300);
symerr = rtpcs_931x_sds_fiber_get_symerr(sds, RTPCS_SDS_MODE_10GBASER);
- if (symerr >= 0 && symerr <= 5)
+
+ dev_dbg(dev, "SerDes %u symErr check %d: 0x%x\n", sds->id, i + 1, symerr);
+
+ if (symerr >= 0 && symerr <= 5) {
+ dev_dbg(dev, "SerDes %u fiber RX calibration OK (check %d)\n",
+ sds->id, i + 1);
return;
+ }
}
dev_warn(dev, "SerDes %u fiber RX calibration failed after %d symErr checks\n",