priv->xfi_rst = devm_reset_control_get_optional(dev, "xfi");
+ /* For Ethernet PCS, read the AN7581 SoC revision to check if
+ * manual rx calibration is needed. This is only limited to
+ * any SoC revision before E2.
+ */
+ if (device_is_compatible(dev, "airoha,an7581-pcs-eth") &&
+ priv->data->port_type == AIROHA_PCS_ETH) {
+ u32 val;
+
+ ret = regmap_read(priv->scu, AIROHA_SCU_PDIDR, &val);
+ if (ret)
+ return ret;
+
+ if (FIELD_GET(AIROHA_SCU_PRODUCT_ID, val) < 0x2)
+ priv->manual_rx_calib = true;
+ }
+
return 0;
}
#include <reset.h>
/* SCU*/
+#define AIROHA_SCU_PDIDR 0x5c
+#define AIROHA_SCU_PRODUCT_ID GENMASK(15, 0)
#define AIROHA_SCU_WAN_CONF 0x70
#define AIROHA_SCU_ETH_MAC_SEL BIT(24)
#define AIROHA_SCU_ETH_MAC_SEL_XFI FIELD_PREP_CONST(AIROHA_SCU_ETH_MAC_SEL, 0x0)
struct reset_ctl *xfi_rst;
struct reset_ctl_bulk rsts;
+
+ bool manual_rx_calib;
};
struct airoha_pcs_match_data {
udelay(100);
retry_calibration:
- an7581_pcs_cdr_reset(priv, interface, true);
+ an7581_pcs_cdr_reset(priv, interface, priv->manual_rx_calib);
/* Global reset clear */
regmap_update_bits(priv->xfi_pma, AIROHA_PCS_PMA_SW_RST_SET,
an7581_pcs_cdr_reset(priv, interface, false);
+ /* Manual RX calibration is required only for SoC before E2
+ * revision. E2+ SoC autocalibrate RX and only CDR reset is needed.
+ */
+ if (!priv->manual_rx_calib)
+ return 0;
+
/* It was discovered that after a global reset and auto mode gets
* actually enabled, the fl_out from calibration might change and
* might deviates a lot from the expected value it was calibrated for.